我正在向屏幕绘制大量的广告牌,并且“随机”我在绘图之后或者在开始下一个绘制周期之前得到了一个glerror 1285,我无法分辨。
整个数据是1.3M~我作为顶点和索引缓冲区上传到视频卡。有20个顶点缓冲区,其中19个告诉我19个不同时间广告牌的位置和大小,20个告诉我顶点索引(所以我可以计算顶点着色器中的纹理坐标)。
每秒我都会改变两个顶点缓冲区来计算广告牌的位置和大小。尽管它们的构造方式完全相同,但是经过一段时间后它会崩溃,通常是在第4缓冲区,但并非总是如此。我每个周期可以处理的顶点数随机变化。
可能导致这种情况的原因是什么?
此代码检查错误
public static void checkGlError(String glOperation) {
int error;
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
System.out.println("error: " + error);
}
}
这段代码是我的绘制周期(或者不管它叫什么)
MyGLRenderer.checkGlError("");
sBatch.draw(MyGLRenderer.mMVPMatrix);
MyGLRenderer.checkGlError("");
我的班级代码
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);
}
这是我将缓冲区上传到视频卡的地方
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;
}
我的着色器
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;" +
"}";
修改/更新: 我从检查错误的代码中删除了“throw new RuntimeException”,并将其替换为System.out.println。通过这个我能够确定,总是有6个缓冲区导致GL_OUT_OF_MEMORY,并且在代码中的每次更改后它们都是“随机选择”的。虽然这不能帮助我找出错误的原因,但希望它能帮助别人帮助我。
答案 0 :(得分:2)
我担心这句话:
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[buffers.length - 2]);
在upload (...)
方法中,您已将缓冲区[buffers.length - 2]
声明为GL_ELEMENT_ARRAY_BUFFER
类型:
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, buffers[buffers.length-2]);
这种不一致的用法可能表明您的设计中存在更大的错误。您可能希望使用比buffers
和buffs
更具描述性的名称,这些名称可能会导致这些错误。
答案 1 :(得分:2)
原来我没有上传整个缓冲区。
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_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);
例如