我在 Android 上使用 OpenGL ES 2.0,但我认为这个问题是一个通用的 OpenGL 问题。
我正在学习 OpenGL,并试图准确了解每一帧必须调用哪些 API,而不是只调用一次。我最初在每一帧都调用glVertexAttribPointer
,glEnableVertexAttribArray
但是当我将测试程序更改为每个着色器程序只调用一次时,我得到的行为不是我所期望的。
它似乎glVertexAttribPointer
并且glEnableVertexAttribArray
应该只需要调用一次,而不是每一帧,因为它们仅在特定着色器程序的上下文中才有意义。我这样说是glVertexAttribPointer
因为它是第一个GLuint index
返回的参数,glGetAttribLocation
它指定了一个与着色器程序中的变量名相对应的字符串。因此,数据似乎与特定着色器程序中的特定“属性”变量相关联。
我的测试程序使用两个完全不同的程序渲染两个不相交的形状(三角形) - 不同的片段着色器源,不同的顶点着色器源,单独调用glLinkProgram
等。我最初为每一帧运行以下代码,一切都按预期工作 - 我明白了两个形状都正确渲染。
m_glhook.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
// Shape/Program 1
m_glhook.glUseProgram(m_iGlProgramId);
int iPositionLocation = m_glhook.glGetAttribLocation(m_iGlProgramId, "a_Position");
m_bfVertices.rewind();
m_glhook.glVertexAttribPointer(iPositionLocation, 4, GLES20.GL_FLOAT, false, STRIDE, m_bfVertices);
m_glhook.glEnableVertexAttribArray(iPositionLocation);
gl.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
// Shape/Program 2
m_glhook.glUseProgram(m_iGlProgramId2);
int iPositionLocation2 = m_glhook.glGetAttribLocation(m_iGlProgramId2, "a_Position");
m_bfVertices2.rewind();
m_glhook.glVertexAttribPointer(iPositionLocation2, 4, GLES20.GL_FLOAT, false, STRIDE, m_bfVertices2);
m_glhook.glEnableVertexAttribArray(iPositionLocation2);
gl.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
然后我修改了对每一帧的调用,如下所示。 m_bFirstDraw
第一帧为真,后续帧为假。
m_glhook.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
// Shape/Program 1
m_glhook.glUseProgram(m_iGlProgramId);
if (m_bFirstDraw)
{
int iPositionLocation = m_glhook.glGetAttribLocation(m_iGlProgramId, "a_Position");
m_bfVertices.rewind();
m_glhook.glVertexAttribPointer(iPositionLocation, 4, GLES20.GL_FLOAT, false, STRIDE, m_bfVertices);
m_glhook.glEnableVertexAttribArray(iPositionLocation);
}
gl.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
// Shape/Program 2
m_glhook.glUseProgram(m_iGlProgramId2);
if (m_bFirstDraw)
{
int iPositionLocation2 = m_glhook.glGetAttribLocation(m_iGlProgramId2, "a_Position");
m_bfVertices2.rewind();
m_glhook.glVertexAttribPointer(iPositionLocation2, 4, GLES20.GL_FLOAT, false, STRIDE, m_bfVertices2);
m_glhook.glEnableVertexAttribArray(iPositionLocation2);
}
gl.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
m_bFirstDraw = false;
我在上面的代码中看到的行为是,对于第一帧,一切都很好(这是有道理的,因为对于第一帧,调用序列完全相同)。但是对于连续的帧,Shape1 是用 Shape2 的顶点绘制的。所以我只看到 Shape2,因为它完全绘制在 Shape1 之上。
请帮助我理解这一点......为什么为一个程序设置数据(形状顶点)会影响另一个程序在连续帧中使用的数据?我错过了一些东西...