1

我有一个代表简单 3D 场景的学习项目。我正在修改模型视图矩阵以将视点移动到某个非原点,gluLookAt()然后我将线球放置在原点。最后,我正在修改投影矩阵以接收带有一些参数的正交投影,使用glOrtho(). 但是当调整窗口大小时,球体会变形。我想我应该修改reshape()glOrtho()函数,但是如何?

void display(void){
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3b(197, 96, 63);
    glLoadIdentity();    
    gluLookAt(2, 0.5 ,2, 0, 0, 0, 0, 1, 0);
    glutWireSphere(0.2, 20, 10);  
    glFlush();
}

void reshape(int w, int h){
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-1, 1, -1, 1, 0.8 , 100);
    glMatrixMode(GL_MODELVIEW);
}
4

3 回答 3

3

正如我在评论中所说,您需要设置正交投影以适合您的窗口。假设您的 OpenGL 窗口在调整大小之前以正方形开始,(-1, 1, -1, 1, ...)则假设是正方形坐标系。如果您更改它以更好地反映窗口的纵横比,您应该会得到更好的外观。尝试以下操作:

glOrtho ((float)w/(float)h, (float)-w/(float)h, -1, 1, 0.8, 100);

这应该保持您设置的坐标系,但尊重纵横比(按宽度)。

于 2013-02-27T09:11:40.510 回答
2

首先,与您的问题完全无关:将您现在拥有的所有内容移入reshape以显示。是的,我知道很多教程都是按照您的方式进行的,但是请相信我,如果不以这种方式进行操作,它会使事情变得更加清晰。


现在关于您的问题:Ortho 在视图空间中设置体积,将其映射到视口坐标。glOrtho 的 (bottom,left) 角映射到 glViewport 的 (x,y) 并且 (top,right) 映射到 glViewport 的 (x,y)+(width,height)。

所以你必须将 glOrtho 参数调整为视口的纵横比。很简单:

void display(void)
{
    int const win_width  = glutGet(GLUT_WINDOW_WIDTH);
    int const win_height = glutGet(GLUT_WINDOW_HEIGHT);
    float const win_aspect = (float)win_width / (float)win_height;

    glClear(GL_COLOR_BUFFER_BIT);
    glViewport(0, 0, win_width, win_height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-win_aspect, win_aspect, -1, 1, 0.8 , 100);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();    
    gluLookAt(2, 0.5 ,2, 0, 0, 0, 0, 1, 0);

    glColor3b(197, 96, 63);
    glutWireSphere(0.2, 20, 10);  
    glFlush();
}
于 2013-02-27T09:22:16.217 回答
0

目前,您将窗口投影到具有 的二次输出glOrtho(-1, 1, -1, 1, 0.8 , 100);,因为宽度和高度相等。您应该将前四个参数更改为窗口的当前纵横比,以防止失真。像

glOrtho(-w/2f, w/2f, -h/2f, h/2f, 0.8 , 100);

(在我的示例中,您必须使球体更大,因为投影平面会比您的更大。)

于 2013-02-27T09:10:24.813 回答