我正在编写一个OpenGL应用程序。程序需要在中心具有简单的形状,并且用户可以将视图从正交视图改变为透视视图,反之亦然。我在处理正交视图方面没有任何问题,但我无法从正交视角切换到视角,即使gluPerspective
看起来非常简单。
我写的代码看起来像这样:
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0, 0, -3);
glRotatef(xRot, 1.0, 0.0, 0.0);
glRotatef(yRot, 0.0, 1.0, 0.0);
glRotatef(zRot, 0.0, 0.0, 1.0);
glScalef(scale, scale, scale);
glPushAttrib(GL_ENABLE_BIT);
if (currentStyle) {
if (currentStyle == STYLE_DOTTED) glLineStipple(currentStyle, 0xAAAA);
else glLineStipple(currentStyle, 0x0F0F * currentStyle);
glEnable(GL_LINE_STIPPLE);
}
setColor();
drawObjectOfType();
glPopAttrib();
glFlush();
}
void myKeyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 'p':
isOrtho = !isOrtho;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(!isOrtho) {
gluPerspective(55,1,5,3);
gluLookAt(0,0,-7,0,0,0,0,1,0);
} else {
glOrtho(-2.0, 2.0, -2.0, 2.0, -10.0, 10.0);
}
glMatrixMode(GL_MODELVIEW);
break;
}
glutPostRedisplay();
}
该计划也有照明。这是处理光照的init函数。
void init()
{
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess = { 100.0 };
GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_position[] = { 0.0, 0.0, 10.0, 0.0 };
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
createMenus();
glEnable(GL_DEPTH_TEST);
glClearColor(0.0, 0.0, 0.0, 1.0);
}
此代码发生的变化是视图从正交到透视的变化,但摄像机和多边形之间的距离似乎已恢复,这意味着多边形越接近摄像机,它看起来越小。例如,我有一个立方体作为形状,靠近我的脸看起来更小,而对立面应该是这样。
答案 0 :(得分:1)
gluPerspective()
的最后两个参数是zNear
和zFar
。您已将近剪裁平面设置得比远剪裁平面更远,这反转了透视校正。
答案 1 :(得分:0)
gluLookAt
定义了一个查看转换,因此应该成为您的MODELVIEW转换的一部分。您的代码将其乘以PROJECTION转换。尝试使用这样的序列作为透视设置案例:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(55,1,3,5);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,-7,0,0,0,0,1,0);
然后在glPushMatrix
函数中使用glPopMatrix
和glLoadIdentity
代替myDisplay
。
你的近处和远处的飞机彼此非常接近。我们在代码中没有看到您发布的对象坐标范围。你要小心它会在你的近距离和远距离之间结束,这样它就不会被夹住。