OpenGL顶点缓冲区对象和纹理与非纹理几何体的排序
我正在使用OpenGL中的顶点缓冲区对象渲染两组几何体-一组有纹理,另一组没有纹理。由于遗留代码,我没有使用可编程管道 我发现,如果我先渲染纹理几何体,然后渲染非纹理几何体,一切看起来都很好。但是如果我做相反的操作,纹理几何体不会被绘制 我使用的是交错数组,下面是渲染代码:OpenGL顶点缓冲区对象和纹理与非纹理几何体的排序,opengl,Opengl,我正在使用OpenGL中的顶点缓冲区对象渲染两组几何体-一组有纹理,另一组没有纹理。由于遗留代码,我没有使用可编程管道 我发现,如果我先渲染纹理几何体,然后渲染非纹理几何体,一切看起来都很好。但是如果我做相反的操作,纹理几何体不会被绘制 我使用的是交错数组,下面是渲染代码: void MyClass::render() { // 3*v + 3*c + 3*n + (2*t) const char *base = NULL; GLsizei stride = _enab
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();
我做错了什么 需要检查两件事:
首先,如果\u enableTexture
为false,则应在render()
中禁用GL\u TEXTURE\u COORD\u ARRAY
。正如Tal和Christian已经指出的,为什么不在render()中启用/禁用GL\u TEXTURE\u 2D
?更容易理解和调试
其次,您如何分配iBuffer\u以及\u enableTexture
之后是否可以更改?如前所述,您的render()
方法仅在\u iBuffer
为每个顶点分配9个浮点数时有效,如果\u enableTexture
为false,则为11个浮点数。但是,如果您为纹理坐标分配了足够的空间,不管您是否真正使用了它们,步长值应该始终为11。听起来像是一个很好的老生常谈“OpenGL是一个状态机”—问题。在您的代码中,哪里绑定了纹理本身?我敢打赌,它在调用之前绑定,然后在第一次渲染之后解除绑定,不再绑定。(或者另一个OpenGL状态以类似方式打开/关闭。)请显示其余代码。特别是启用和绑定纹理,调用MyClass::render
等等。当然,你的render
函数不会告诉任何人任何事情,因为它不会做任何与纹理相关的事情。@TalDarom&Christian Rau:我不认为这是一个bin/unbind问题,因为我正在做这件事,而且整个纹理几何体也丢失了——不仅仅是纹理本身。我还认为这是一个状态机问题,但我发现很难发布整个代码,因为它是一个大型应用程序,而且这些东西到处都是。@M-V:如果您的代码太大而无法发布,那么您需要找到一种方法将其缩小。你的问题是由于各种系统的相互作用;如果不看到这些系统,我们就无法神奇地知道这个问题是什么。如果你不能使它变小,那么你必须自己调试它。关于步幅的分数+1。听起来是个不错的猜测。