【发布时间】:2012-11-01 07:07:55
【问题描述】:
我正在使用 OpenGL 中的顶点缓冲区对象渲染 2 组几何图形 - 一组带有纹理,另一组没有。由于遗留代码,我没有使用可编程管道。
我发现如果我先渲染带纹理的几何图形,然后再渲染非纹理几何图形,一切看起来都很好。但如果我反过来做,纹理几何就不会被绘制出来。
我使用的是交错数组,这里是渲染代码:
void MyClass::render()
{
// 3*v + 3*c + 3*n + (2*t)
const char *base = NULL;
GLsizei stride = _enableTexture ? 11*sizeof(GLfloat) : 9*sizeof(GLfloat);
GLvoid* vOffset = (GLvoid*)0;
GLvoid* cOffset = (GLvoid*)(3*sizeof(GLfloat));
GLvoid* nOffset = (GLvoid*)(6*sizeof(GLfloat));
GLvoid* tOffset = (GLvoid*)(9*sizeof(GLfloat));
// prepare vertex VBO
glBindBuffer(GL_ARRAY_BUFFER, _iBuffer);
// enable vertex array
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, stride, vOffset);
// enable color array
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(3, GL_FLOAT, stride, cOffset);
// enable normal array
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, stride, nOffset);
// texture coords
if(_enableTexture) {
// enable texture array
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, stride, tOffset);
}
// draw geometry
glDrawArrays(GL_TRIANGLES, 0, _nVertices);
// disable/unbind
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
if(_enableTexture) {
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
这行得通:
myClassTextured->render();
myClassNonTextured->render();
这失败了:
myClassNonTextured->render();
myClassTextured->render();
我做错了什么?
【问题讨论】:
-
听起来不错的旧“OpenGL 是一个状态机”-问题。
-
你在代码的什么地方绑定了纹理本身?我敢打赌它在调用之前是绑定的,然后在第一次渲染之后它是未绑定的,并且不会再次绑定。 (或者可能以类似的方式打开/关闭另一个 OpenGL 状态。)
-
请显示您的其余代码。特别是启用和绑定纹理,调用
MyClass::render等。当然,您的render函数不会告诉任何人任何事情,因为它不会做任何与纹理相关的事情。 -
@TalDarom 和 Christian Rau:我不认为这是一个 bin/unbind 问题,因为我正在这样做,而且整个纹理几何都丢失了 - 不仅仅是纹理本身。我也认为这是一个状态机问题,但我发现很难发布整个代码,因为它是一个大型应用程序,而且这些东西都在传播。
-
@M-V:如果您的代码太大而无法发布,那么您需要找到一种方法使其更小。您的问题是由于各种系统的相互作用造成的;如果没有看到这些系统,我们就无法神奇地知道这个问题是什么。如果你不能让它更小,那么你将不得不自己调试它。
标签: opengl