使用 OpenGL,如何正确使用 gluOrtho2D 和默认投影?

Posted

技术标签:

【中文标题】使用 OpenGL,如何正确使用 gluOrtho2D 和默认投影?【英文标题】:With OpenGL, how can I use gluOrtho2D properly with default projection? 【发布时间】:2009-04-09 13:36:13 【问题描述】:

我正在尝试将 gluOrtho2D 与 glutBitmapCharacter 一起使用,以便我可以在屏幕上渲染文本以​​及我的 3D 对象。但是,当我使用 glOrtho2D 时,我的 3D 对象消失了;我认为这是因为我没有将投影设置回 OpenGL/GLUT 默认值,但我不确定那是什么。

不管怎样,这是我用来渲染文本的函数:

void GlutApplication::RenderString(Point2f point, void* font, string s)

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    gluOrtho2D(0.0, WindowWidth, 0.0, WindowHeight);

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();

    glDisable(GL_TEXTURE);
    glDisable(GL_TEXTURE_2D);

    glRasterPos2f(point.X, point.Y);
    for (string::iterator i = s.begin(); i != s.end(); ++i)
    
        glutBitmapCharacter(font, *i);
    

    glEnable(GL_TEXTURE);
    glEnable(GL_TEXTURE_2D);

    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();

而且,渲染功能类似这样:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glPushMatrix();
glLoadIdentity();

// Do some translation here.

// Draw some 3D objects.

glPopMatrix();

// For some reason, this stops the above from being rendered,
// where the camera is facing (I assume they are still being rendered).
Point2f statusPoint(10, 10);
RenderString(statusPoint, GLUT_BITMAP_9_BY_15, "Loading...");

【问题讨论】:

【参考方案1】:

当我需要类似的东西时,我没有尝试推送和弹出矩阵状态,而是每次都从头开始设置:

void set2DMode()

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(0, w, h, 0, -1, 1);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();


void set3DMode()

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(50.0, (float) w / h, 1, 1024);
        gluLookAt(0, 0, 400, 0, 0, 0, 0.0, 1.0, 0.0);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();


void cb_display(void)

        set3DMode();
        // draw some stuff

        set2DMode();
        // draw some text
        // and some more
 

【讨论】:

【参考方案2】:

您的代码看起来不错。很可能您只是在某个地方弄乱了矩阵堆栈。

我建议您检查一下您是否在某处忘记了glPopMatrix。为此,您可以通过glGet(GL_MODELVIEW_STACK_DEPTH) 获取堆栈深度。其他矩阵堆栈的吸气剂也可用。

您还可以查看当前矩阵。致电glGetFloatv(GL_MODELVIEW_MATRIX, Pointer_To_Some_Floats) 获取。每次设置模型视图或投影矩阵时,都可以打印出浮点数。这样,您应该能够找出哪个矩阵不规律地最终成为当前矩阵。

这应该会给你足够的线索来找到错误。

【讨论】:

【参考方案3】:

调用 RenderString() 函数后,您处于投影模式。不确定这是否会破坏任何东西,但它对我来说很突出。

【讨论】:

【参考方案4】:

我同意安德烈的观点。基本上,您要做的是:在 glClear 使用投影矩阵之后的第二帧和所有下一帧,因为最后一次操作是 glMatrixMode(GL_PROJECTION); 在 RenderString 的末尾。 (至少看看你发布的代码)。

尝试将:glMatrixMode(GL_MODELVIEW) 放在 glClear 之后。

【讨论】:

以上是关于使用 OpenGL,如何正确使用 gluOrtho2D 和默认投影?的主要内容,如果未能解决你的问题,请参考以下文章

Qt5中使用opengl时出现链接错误,关于gluOrtho2D

OpenGL之位图的绘制和gluOrtho2D等函数详解

[图形学]Chapter 8.4 OpenGL 二维观察函数——视口

Opengl 选择性 glClipPlane

OpenGL:使用 FBO 和视口偏移问题渲染到纹理

用OpenGL画一条任意线(即轴范围没有限制)