【问题标题】:OpenGL vertex buffer objects and ordering of textured vs non-textured geometryOpenGL顶点缓冲区对象和纹理与非纹理几何的排序
【发布时间】: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


【解决方案1】:

要检查两件事:

首先,如果_enableTexture 为假,您应该在render() 中禁用GL_TEXTURE_COORD_ARRAY。正如 TalChristian 已经指出的那样,您为什么不在render() 中启用/禁用GL_TEXTURE_2D 呢?更容易理解和调试。

第二,你是怎么分配_iBuffer的,之后_enableTexture可以改吗?如所写,您的render() 方法仅在_iBuffer 为每个顶点分配9 个浮点数时才有效,如果_enableTexture 为假,则为11 个如果为真。但是,如果您为 _iBuffer 分配了足够的空间用于纹理坐标,无论您是否最终使用它们,步幅值都应始终为 11。

【讨论】:

  • +1 表示关于步幅的分数。听起来是个不错的猜测。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-07-31
  • 1970-01-01
  • 2015-04-14
  • 1970-01-01
  • 2013-01-13
  • 2015-11-15
  • 1970-01-01
相关资源
最近更新 更多