OpenGL ES 2.0 VBO 问题
Posted
技术标签:
【中文标题】OpenGL ES 2.0 VBO 问题【英文标题】:OpenGL ES 2.0 VBO issue 【发布时间】:2013-02-09 07:16:05 【问题描述】:我正在尝试切换到 VBO,暂时没有索引。但我得到的只是一个空白屏幕。有人能指出为什么它是空白的吗?如果我注释掉特定于 vbo 的代码并将 glVertexAttribPointer 中的 0(offset) 替换为 mFVertexBuffer,则相同的代码可以正常工作,即不使用 VBO。
这是我的 onDraw 方法
GLES20.glClearColor(0.50f, 0.50f, 0.50f, 1.0f);
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
// Bind default FBO
// GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
GLES20.glUseProgram(mProgram);
checkGlError("glUseProgram");
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, id);
int vertexCount = mCarVerticesData.length / 3;
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[0]);
checkGlError("1");
GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT,false, 0, 0);
checkGlError("2");
GLES20.glEnableVertexAttribArray(positionHandle);
checkGlError("3 ");
transferTexturePoints(getTextureHandle());
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
checkGlError("glDrawArrays");
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
GLES20.glDisableVertexAttribArray(positionHandle);
GLES20.glDisable(GLES20.GL_BLEND);
这是我的 vbo 设置:
// Allocate and handle vertex buffer
ByteBuffer vbb2 = ByteBuffer.allocateDirect(mCarVerticesData.length
* FLOAT_SIZE_BYTES);
vbb2.order(ByteOrder.nativeOrder());
mFVertexBuffer = vbb2.asFloatBuffer();
mFVertexBuffer.put(mCarVerticesData);
mFVertexBuffer.position(0);
// Allocate and handle vertex buffer
this.buffers = new int[1];
GLES20.glGenBuffers(1, buffers, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[0]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, mFVertexBuffer.capacity()
* FLOAT_SIZE_BYTES, mFVertexBuffer, GLES20.GL_STATIC_DRAW);
在链接我的程序之前:
GLES20.glBindAttribLocation(program, 0, "aPosition");
checkGlError("bindAttribLoc");
我的顶点着色器是:
uniform mat4 uMVPMatrix;
attribute vec4 aPosition;
attribute vec2 aTextureCoordinate;
varying vec2 v_TextureCoordinate;
void main()
gl_Position = uMVPMatrix * aPosition;
v_TextureCoordinate = aTextureCoordinate;
gl_PointSize= 10.0;
【问题讨论】:
【参考方案1】:你还需要生成一个元素数组并调用这样的东西来渲染你的“对象”:
// Bind the vertex buffer
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, _bufferIds.get(2));
GLES20.glVertexAttribPointer(4, 4, GLES20.GL_FLOAT, false, 4*4, 0);
// Bind the elements buffer and draw it
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, _bufferIds.get(1));
GLES20.glDrawElements(GLES20.GL_TRIANGLES, _numElements, GLES20.GL_UNSIGNED_SHORT, 0);
希望对您有所帮助。
【讨论】:
感谢您的评论。但这不只适用于带有索引的 glDrawElements 吗?编辑:我试图画出很多我可能会改变每一帧的点。在这样的设置中,索引是不必要的(如果我错了,请纠正我)!现在,我正在尝试使用 VBO 来查看它在“流”输入下的表现。 你错了,你需要指数。索引就是opengl用来解决应该绘制哪些点的东西(在你的情况下很简单,只是一个从0开始到max_points-1结束的索引的线性数组)。没有索引,屏幕上不会显示任何内容。 我尝试在我的代码中包含索引,但我仍然无法让它工作。 getGLError 返回 0,所以那里没有错误。如果我尝试包含一些没有 VBO 的代码,它会很好地显示非 VBO 对象。此外,谷歌搜索确实告诉我索引只需要索引渲染,我不需要,因为我没有多个共享顶点的对象。我的应用程序主要显示点精灵。 另外,VBO 会比客户端数组更快地显示点精灵,其位置每帧都会更新吗?我正在使用 STREAM 提示,因为我想测试每帧更新客户端数组与更新 VBO 之间的性能差异,然后选择更好的方法。位置是从另一个线程获取的,无法在顶点着色器上计算。 我的 VBO 设置和绘图与此类似。我正在使用glDrawArrays,就像在链接中一样,而不是前面提到的@TraxNet 中的glDrawElements。 en.wikipedia.org/wiki/Vertex_Buffer_Object【参考方案2】:我通过重写上传顶点数据的方式解决了这个问题。我正在修改它,所以我需要再次调用 glBindBufferData 才能上传它。而且我能够在不使用 glDrawElements 和索引的情况下使用 VBO,而且效果很好。
【讨论】:
以上是关于OpenGL ES 2.0 VBO 问题的主要内容,如果未能解决你的问题,请参考以下文章