正交和透视之间的OpenGL切换

时间:2013-11-20 00:28:18

标签: c++ opengl 3d sdl game-engine

我有一个在立即模式下使用正交投影的平铺引擎,我只是想在我的平铺场景上绘制一个三维立方体,希望我最终可以将3d模型合并到我的引擎中,而不仅仅是精灵/纹理四边形。我还想制作瓷砖3d,以获得额外的眼睛糖果。希望我最终可以将其转换为使用现代OpenGL,这样我就可以利用这些额外的功能。目前不在我的优先级列表的顶部。那就问题了。

我用这个初始化OpenGL:

void initGL()
{
    glDisable(GL_DEPTH_TEST);

    glViewport( 0,0,SCREEN_WIDTH,SCREEN_HEIGHT);

    //Initialize Projection Matrix
    glMatrixMode( GL_PROJECTION );
    glPushMatrix();
    glLoadIdentity();   

    //Initialize Modelview Matrix
    glMatrixMode( GL_MODELVIEW );
    glPushMatrix();
    glLoadIdentity();       

    glOrtho(0,SCREEN_WIDTH,SCREEN_HEIGHT,0,0,1);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);     
    //...setting some various other attributes, omitted for brevity...

    glEnable(GL_TEXTURE_2D);
    glClearColor( 0, 0, 0, 0 );
}

我有一个绘制可行的立方体的功能。

void draw_cube()
{
     /* position object */
    glRotatef(30.0F, 1.0F, 0.0F, 0.0F);
    glRotatef(30.0F, 0.0F, 1.0F, 0.0F);    

    /* draw six faces of a cube */
    glBegin(GL_QUADS);
    ...vertices... (removed for brevity)
    glEnd();             
}

我设置了2个用于设置2d和3d投影模式的功能。

void set3d()
{
    glEnable(GL_DEPTH_TEST);
    glClear(GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(0,SCREEN_WIDTH,0,SCREEN_HEIGHT, 0,1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}
void set2d()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glDisable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0,SCREEN_WIDTH,SCREEN_HEIGHT,0,0,1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

为了完整起见,我的纹理四边形图的一些 伪代码 ..

pushmatrix();
translate();
rotate();
-translate();

glbegin();
...vertices
glend();
popmatrix();

到目前为止,我已经设法让立方体在瓷砖上绘制,但它在大约1秒后消失,再也不会再看到,直到我再次运行程序。

基本上我在主循环中所做的是:

move objects around, process collisions, etc.

set2d();
draw textured quads, lines, text, etc. in 2d mode.

set3d();
draw_cube();

我的问题是:为什么立方体消失了,我的set2d()和set3d()函数中是否有任何错误?

1 个答案:

答案 0 :(得分:3)

您在此代码中遇到了很多问题,实际上在评论中列出的内容太多了。

  1. 您的投影矩阵正在改变后投影坐标空间的惯性,这将影响多边形缠绕。

    • 坚持单手,除非你想要反转用于前/后面多边形面(glFrontFace (...))的方向 - 默认情况下它是CCW,但你必须将它改为CW时您使用set3d (...)来保持一致的行为。
    • 出现此问题是因为您的Y轴朝向不同的方向

  2. 您所描述的行为,对象短暂出现然后消失,表明您的矩阵堆栈存在问题。

    • 您是否在软件中多次调用initGL (...)?如果你这么做的话,你会遇到堆栈溢出,因为你不必要地将当前矩阵推入堆栈并且永远不会将其弹出。

  3. 您不能将 0.0 用于带有透视投影矩阵的zNear,这将导致在转换为之后<\ n> 转换为剪辑时的透视分割步骤中的数学成绩空间;深度缓冲区无法正常工作。

    • 实际上,glFrustum (...)会产生GL_INVALID_VALUE错误,并且如果您传递的值< 0.0,则会完全 对于zNear。在相关的说明中,gluPerspective (...)不会这样做,因为它实际上不是OpenGL的一部分,但将这样的值传递给gluPerspective (...)同样无效的行为。