OpenGL混淆了push和pop的顺序

3

我正在尝试让我的OpenGL应用程序工作,基本上在我开始使用场景图之前,每个对象都以一个推操作开始绘制,然后以一个弹出操作结束

现在我向汽车的基础部分(轮子)添加了两个子元素,并且我遇到了一些问题,在相对于基础汽车绘制它们时。如果我能贴上一些代码,我将展示绘制所有内容的调用,然后显示我的场景图调用来进行绘制,我希望这只是一个愚蠢的错误,因为目前我真的被卡住了。

void GameNode::Draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glPushMatrix();
car->Draw();
glPopMatrix();

for (int i = 0; i < MAXOBJECTS; i++)
{
    glPushMatrix();
    objects[i]->Draw();
    glPopMatrix();
}

for (int i = 0; i < MAXBUILDINGS; i++)
{
    glPushMatrix();
    build[i]->Draw();
    glPopMatrix();
}

glPushMatrix();
skyBox->Draw();
glPopMatrix();
glFlush();
glutSwapBuffers();
 }

接着在我的“车-绘画”程序里,我有场景图。以下是相关代码:

glPushMatrix();


object->Draw();
glPushMatrix();
glPopMatrix();
if(left != nullptr)
    {

        glPushMatrix();

        glPopMatrix();

        left->PreOrderDraw();
    }
if(right != nullptr)
{
    right->PreOrderDraw();
}
glPopMatrix();

所以,这基本上是将我的车轮设置在汽车底部,但当它们的位置相对于应该有偏移量时,并没有相对于底部设置它们。


我感到有义务提醒任何我看到使用过时OpenGL的人,矩阵堆栈和诸如glBegin之类的功能已被弃用并不再使用。 - Ben
我感到有义务指出,尽管这些东西已经过时了好几年,但不幸的是它仍然被广泛使用... ;) - derhass
是的,只是让他们知道,以防他们实际上不知道。有一段时间我也不知道。 - Ben
PreOrderDraw()函数内部发生了什么?看起来有过多的Push/Pops,但是从快速查看中它们都对齐得很好。我的猜测是object->Draw()会进行push操作,设置矩阵,绘制,然后弹出矩阵,这可能是为什么车轮与汽车位置不相关的原因? - Tim Beaudet
1个回答

4

我认为你对矩阵堆栈的工作原理有些困惑。我这么说是因为出现了以下问题:

glPushMatrix( );
glPopMatrix( );

if(left != nullptr)
{

    glPushMatrix();

    glPopMatrix();

   // ...

你在没有必要的情况下多次执行推入/弹出操作(除非有省略的代码)。
我建议你阅读OpenGL编程指南-第3章-操纵矩阵堆栈,幸运的是,它使用汽车及其轮子作为示例来教授如何使用堆栈。
从你的代码中可以看出,你所做的就是多次推入/弹出单位矩阵,而从未将车轮从原点平移。

嗨,感谢您提供的链接。自从发布这篇文章以来,我意识到了push和pop的作用,所以我成功地让一个轮子相对于汽车移动了。从我的观察中,第二个轮子是相对于第一个轮子移动的,所以我一定漏掉了某个push操作。谢谢,我会阅读所有内容并查看我的错误。 - user3546481
如果第二个轮子相对于第一个轮子表现正常,那么你似乎错过了一个 glPopMatrix - ssell
谢谢,我找到了,现在一切都正常了,谢谢 :D - user3546481

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接