我有一个代表简单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);
}
答案 0 :(得分:3)
正如我在评论中所说,您需要设置正交投影以适合您的窗口。假设您的OpenGL窗口在调整大小之前以方形开始,(-1, 1, -1, 1, ...)
假定为方形坐标系。如果您更改它以更好地反映窗口的宽高比,您应该看得更好。请尝试以下方法:
glOrtho ((float)w/(float)h, (float)-w/(float)h, -1, 1, 0.8, 100);
这应该保持坐标系统的设置,但要考虑宽高比(宽度)。
答案 1 :(得分:2)
首先,与您的问题完全无关:立即移动reshape
中显示的所有内容。是的,我知道许多教程都是按照你的方式进行的,但是请相信我,这样做会让事情变得更加清晰。
现在关于你的问题:Ortho在视图空间中设置音量,即被映射到视口坐标。 glOrtho的(下,左)角被映射到glViewport的(x,y),(top,right)被映射到glViewport的(x,y)+(宽度,高度)。
因此,您必须将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();
}
答案 2 :(得分:0)
目前,您将窗口投影到具有glOrtho(-1, 1, -1, 1, 0.8 , 100);
的二次输出,因为宽度和高度相等。您应该将前四个参数更改为窗口的当前宽高比,以防止失真。像
glOrtho(-w/2f, w/2f, -h/2f, h/2f, 0.8 , 100);
(在我的例子中,你必须让你的球体更大,因为投影平面会比你的更大。)