调整屏幕大小时消失的对象(OpenGl)

时间:2012-05-26 05:39:23

标签: c++ opengl

我正在尝试从.obj格式加载3D模型,它在scren上绘制对象没有任何问题,但是当我调整屏幕大小时,一切都消失了。这是代码:

Obj* object = new Obj();
GLuint  texture[1]; 

void handleResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0,(double)w / (double)h,1.0,200.0);
}
void initRendering() {
object->GetObj("cube.obj");
glShadeModel(GL_LINEAR);                            
glClearColor(0.0f, 0.0f, 0.0f,     0.5f);                           
glEnable(GL_DEPTH_TEST);
}
void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
    case 27:
        {
        exit(0);
        break;
        }
}
}

void drawScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW); 
glLoadIdentity();
glPushMatrix();
glRotatef(45.0,0.0,1.0,0.0);
object->DrawObj();
glPopMatrix();
glutSwapBuffers();
glFlush();

}
int _tmain(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400);


glutCreateWindow("3D");
initRendering();

glutReshapeFunc(handleResize);
glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutMainLoop();
return 0;
}

这是Obj.DrawObj()的代码:

glBegin(GL_TRIANGLES);
for(int i = 0;i < faces.capacity()-1;i++)
{
        glVertex3f(vertices[faces[i].vertex1].cordinate1,vertices[faces[i].vertex1].cordinate2,vertices[faces[i].vertex1].cordinate3);
    glVertex3f(vertices[faces[i].vertex2].cordinate1,vertices[faces[i].vertex2].cordinate2,vertices[faces[i].vertex2].cordinate3);
      glVertex3f(vertices[faces[i].vertex3].cordinate1,vertices[faces[i].vertex3].cordinate2,vertices[faces[i].vertex3].cordinate3);  
}
glEnd;

2 个答案:

答案 0 :(得分:1)

在绘图代码中设置投影矩阵,这很好。但是,您将其设置为标识。在调整大小处理程序中,您也可以设置投影矩阵,但是您不应该在那里进行投影;是的我知道这些教程都有,但这是非常糟糕的风格。您应该将当前在整形处理程序中的所有代码移动到绘图处理程序中,替换投影矩阵的当前设置。

答案 1 :(得分:1)

我可以看到你仍然因阅读你的PasteBin而感到困惑。让我试着解释一下:

您第一次绘制对象时可以看到对象的原因是您没有设置投影矩阵。所以你的对象直接用标准化的设备坐标(-1到1范围)绘制。

调整大小时,您首次设置投影矩阵,这会更改向屏幕绘制的查看区域。最初绘制的对象位于由投影矩阵定义的查看区域之外(它位于摄像机的顶部,我猜在近平面的前面。您必须将对象移回相机,使其远离相机在视锥体里面。这就是约翰威尔夫所暗示的。

但与此同时,您在代码中引入了其他错误,尤其是您停止在handleResize中重置投影矩阵。在调用gluPerspective之前,您必须始终清除投影矩阵,否则您将获得虚假结果。

如果你从你的pastebin中获取确切的代码,并将一个glLoadIdentity添加到handleResize,我认为那应该适用:

void handleResize(int w, int h) {
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);   //<--- add
    glLoadIdentity();              //<--- add
    gluPerspective(45.0,(double)w / (double)h,1.0,200.0);
} 

此外,你还是在drawScene函数期间仍然清除投影矩阵。当您清除矩阵时,您将丢弃刚刚在handleResize中设置的透视设置,您不希望这样做。

基本上是这样的:

  1. 在handleResize和初始化
  2. 中设置Projection矩阵
  3. 请勿触摸drawScene中的投影矩阵
  4. 翻译对象,使其适合视锥体。