2017-09-25 67 views
3

我正在计算很多顶点,然后用四条带显示3D曲面图。glPushMatrix()和glBegin()之间有连接吗?

我对某些顶点有奇怪的行为,以不可预知的方式改变颜色。我尝试修复它,并巧合,我发现问题解决了,当我把glPushMatrix()glPopMatrix之前和之后。有谁知道底层问题可能是什么?我应该通常使用glBegin/glEnd左右的推/流行音乐吗?

这里我的工作代码:

for (int i = 1; i < vec.size(); i++) { 
    glPushMatrix(); 
    glBegin(GL_QUAD_STRIP); 
     for (int j = 0; j < vec[i].size(); j++) { 
      glNormal3dv(vertex_normal[i][j]); 
      glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, reflectance[i][j]); 
      glVertex3d(vec[i][j].x(), vec[i][j].y(),vec[i][j].z()); 

      glNormal3dv(vertex_normal[i-1][j]); 
      glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, reflectance[i-1][j]); 
      glVertex3d(vec[i-1][j].x(), vec[i-1][j].y(), vec[i-1][j].z()); 
     } 
    glEnd(); 
    glPopMatrix(); 
} 
+0

您不应该使用弃用的API。 –

回答

5
  1. 堆栈大小有限!!!

    所以vec.size()必须小于或等于您的OpenGL执行矩阵堆栈大小 - 它使用的层循环之前。这使你的黑客有点危险。

  2. 使用glGetError

    使用(同时调试也适用它,直到它返回没有错误)每个主要gl东西后,你应该检查glGetError。还有一些像glIntercept这样的工具可以帮助你。它应该揭示问题的真相。

  3. 缺少glEnd()

    由于您使用的是旧的API尝试循环之前加几次glEnd();。如果这可以帮助你失去glEnd();某个地方,这是一个常见的新手问题,因为glEnd;也是可编译的,但什么都不做。

    这可以通过OpenGL复位后矩阵推/流,但这是从我身边的纯粹推测。

  4. 主叫glMaterialfv内部glBegin/glEnd

    OpenGL docs的状态:

    材料参数可以在任何时间进行更新。特别是,可以在对glBegin的调用和对应于glEnd的调用之间调用glMaterial。 如果只有一个材料参数是针对每个顶点更改的,则glColorMaterial优先于glMaterial(参见glColorMaterial)。

    我会尽量避免使用glMaterialglBegin/glEnd因为我的经验是坏的OpenGL实现(如英特尔)不符合规格的信,并可能导致在某些平台上的问题/与罕见的使用情况如果不是现在,然后在未来...

因此,要回答你的问题:没有glBegin/glEnd不应由glPushMatrix/glPopMatrix和VI的影响如果使用正确(在glBegin/glEnd内不允许按下/弹出,并且不能超过堆栈限制)。

+1

我摆脱了'glMaterial'电话,这解决了这个问题。感谢您的非常有用的答案。 –

4

我会采取不同的立场,并说,添加额外的push和pop应该没有什么区别。

在老式的OpenGL中,有几个矩阵堆栈。除了一堆修改堆栈顶部的任何操作(其中没有任何操作),还提供了推送和弹出窗口。推送重复任何在堆栈的顶部。所以如果堆栈是A B C D那么它就变成了A B C D D。 Pop只是删除堆栈顶部的任何东西 - 它会让你从A B C D D回到A B C D

这给出了一个很适合调用堆栈的结构。通过获取旧版本的副本,您将继承迄今为止的更改。然后,你可以做出任何你想要的改变,然后退出,而且你所呼叫的人做什么都没有关系。

这与glBeginglEnd完全正交,它们只是说“开始一批几何图形”和“结束那批几何图形”。几何图形受适当堆栈顶部的当前值影响,但实际上并未改变该值。

所以我假设你正在遭受未定义的行为,并且发生在你的特定机器的安慰剂修复中。