Reputation: 197
I am drawing a ton of billboards to the screen, and 'randomly' i get a glerror 1285 either after the drawing, or right before starting the next draw cycle, i can't tell.
The whole data is 1.3M~ that i upload to the videocard as vertex and index buffers. There are 20 vertex buffers, 19 of them tells me the position and size of the billboard at 19 different times, and the 20th tells me the vertex index (so i can calculate texture coords in the vertex shader).
Every second i change which two vertex buffers will be used to calculate the billboard position and size. Even though they were constructed the very same way, after a while it crashes with a glerror 1285, usually at the 4th buffer, but not always. The number of vertexes that i can process per cycle varies at random.
What could be possibly be causing this?
This code checks for error
public static void checkGlError(String glOperation) {
int error;
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
System.out.println("error: " + error);
}
}
this code is my draw cycle(or whatever it's called)
MyGLRenderer.checkGlError("");
sBatch.draw(MyGLRenderer.mMVPMatrix);
MyGLRenderer.checkGlError("");
My class draw code
public void draw(float[] mvpMatrix) {
if (isPacked && !uploaded) {
upload();
}
if (!(isPacked && uploaded)) {
return;
}
GLES20.glUseProgram(GlProgram);
// ////////////////////
int time = (int) ((System.currentTimeMillis() % ((size) * 1000)) / 1000);
int off1 = time;
int off2 = time + 1;
// ///////////////////////
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[off1]);
GLES20.glEnableVertexAttribArray(0);
GLES20.glVertexAttribPointer(0, 3, GLES20.GL_FLOAT, false, 0, 0);
// ///////////////////////
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[off2]);
GLES20.glEnableVertexAttribArray(1);
GLES20.glVertexAttribPointer(1, 3, GLES20.GL_FLOAT, false, 0, 0);
// /////////////
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[buffers.length - 2]);
GLES20.glEnableVertexAttribArray(2);
GLES20.glVertexAttribPointer(2, 1, GLES20.GL_FLOAT, false, 0, 0);
// ///////////////
int TimeHandle = GLES20.glGetUniformLocation(GlProgram, "time");
GLES20.glUniform1f(TimeHandle, (System.currentTimeMillis() % 1000) / 1000f);
// /////////////
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, buffers[buffers.length - 1]);
GLES20.glDrawElements(GLES20.GL_TRIANGLE_STRIP, totalvertz, GLES20.GL_UNSIGNED_SHORT, 0);
GLES20.glDisableVertexAttribArray(0);
GLES20.glDisableVertexAttribArray(1);
GLES20.glDisableVertexAttribArray(2);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
}
This is where i upload the buffers to the video card
private void upload() {
buffers = new int[buffs.length];
if (buffers[0] != 0) {
GLES20.glDeleteBuffers(2, buffers, 0);
buffers[0] = 0;
buffers[1] = 0;
}
// ///////////////////////
int totalsize = 0;
GLES20.glGenBuffers(buffers.length, buffers, 0);
for (int i = 0; i < buffs.length-2; i++) {
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[i]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, buffs[i].capacity(), buffs[i], GLES20.GL_STATIC_DRAW);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
totalsize += buffs[i].capacity();
}
// ///////////////////////
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[buffers.length-2]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, buffs[buffs.length-2].capacity(), buffs[buffs.length-2], GLES20.GL_STATIC_DRAW);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
// //////////////
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, buffers[buffers.length-1]);
GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, IndexBuffer.capacity(), IndexBuffer, GLES20.GL_STATIC_DRAW);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
// VertexBuffer.clear();
// IndexBuffer.clear();
totalsize += buffs[buffs.length-2].capacity();
totalsize += IndexBuffer.capacity();
System.out.println(totalsize);
uploaded = true;
}
My shaders
private final String VertexShaderCode =
//"uniform mat4 uMVPMatrix;" +
"uniform float time;" +
"attribute vec4 aPosition;" +
"attribute vec4 bPosition;" +
"attribute vec4 a_pos;" +
"varying vec4 vColor;" +
"varying vec2 vTexCoordinate;" +
"void main() {" +
" highp int mo = int(a_pos.x);" +
" mo = mo - (4 * (mo / 4));" +
" vTexCoordinate = bPosition.xy;" +
" if(mo == 0){" +
" vTexCoordinate = vec2(-1, -1);" +
" }" +
" if(mo == 1){" +
" vTexCoordinate = vec2(-1, 1);" +
" }" +
" if(mo == 2){" +
" vTexCoordinate = vec2(1, -1);" +
" }" +
" if(mo == 3){" +
" vTexCoordinate = vec2(1, 1);" +
" }" +
" vColor = vec4(1,1,1,1);" +
" vec4 mPosition = mix(aPosition, bPosition, time);" +
" mPosition.z = -1.0;" +
" gl_Position = mPosition;" +
"}";
private final String FragmentShaderCode =
"precision mediump float;" +
"varying vec4 vColor;" +
"varying vec2 vTexCoordinate;" +
"void main() {" +
" const vec2 zo = vec2(0, 1);" +
" mediump float thing = vTexCoordinate.x * vTexCoordinate.x + (vTexCoordinate.y * vTexCoordinate.y);" +
" if(thing < 0.9)" +
" gl_FragColor = zo.yyyy * vColor;" +
" else if(thing < 1.0 && thing > 0.9)" +
" gl_FragColor = zo.xxxy;" +
" else " +
" gl_FragColor = zo.xxxx;" +
"}";
Edit/Update: I removed the 'throw new RuntimeException' from the code that checks for error and replaced it with a System.out.println. With this i was able to determine that, there are always 6 buffers that cause the GL_OUT_OF_MEMORY, and they are 'randomly selected' after every change int the code. While this does not help me identifying the cause of the error, hopefully it will help someone else help me.
Upvotes: 1
Views: 3953
Reputation: 197
Turns out i was not uploading the whole buffer.
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[buffers.length-2]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, buffs[buffs.length-2].capacity(), buffs[buffs.length-2], GLES20.GL_STATIC_DRAW);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
should be
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[buffers.length-2]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, buffs[buffs.length-2].capacity()*4, buffs[buffs.length-2], GLES20.GL_STATIC_DRAW);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
for instance
Upvotes: 2
Reputation: 43319
I am concerned by this line:
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[buffers.length - 2]);
In your upload (...)
method you have declared buffers [buffers.length - 2]
to be of type GL_ELEMENT_ARRAY_BUFFER
:
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, buffers[buffers.length-2]);
This sort of inconsistent usage is probably indicative of a much larger error in your design. You might want to use some more descriptive names than buffers
and buffs
while you're at it, those kinds of names can lead to these errors.
Upvotes: 2