旋转时物体晃动
Objects shake when rotating
我的 opengl 代码遇到问题
我正在尝试建造一座房子,并将其旋转 360°,为简单起见,我们假设房子的前墙有 window 和 dor,还有一堵后墙。
我正在使用 DEPTH_BUFFER 在查看前墙时看不到后墙,反之亦然,但是当我旋转房子时,门和 window 开始摇晃并且被扭曲了。
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(0.0, 0.0, 0.0);
glLoadIdentity();
gluLookAt(0.0, 0.0, 40.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glRotatef(angle, 0.0, 1.0, 0.0);
glEnable(GL_DEPTH_TEST);
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(8.0, 3.0, 0.0);
glVertex3f(8.0, -10.0, 0.0);
glVertex3f(1.0, -10.0, 0.0);
glVertex3f(1.0, 3.0, 0.0);
glEnd();
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(-9.0, -4.0, 0.0);
glVertex3f(-9.0, 3.0, 0.0);
glVertex3f(-2.0, 3.0, 0.0);
glVertex3f(-2.0, -4.0, 0.0);
glEnd();
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(10.0, -10.0, -20.0);
glVertex3f(-10.0, -10.0, -20.0);
glVertex3f(-10.0, 10.0, -20.0);
glVertex3f(10.0, 10.0, -20.0);
glEnd();
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(10.0, -10.0, 0.0);
glVertex3f(10.0, 10.0, 0.0);
glVertex3f(-10.0, 10.0, 0.0);
glVertex3f(-10.0, -10.0, 0.0);
glEnd();
glDisable(GL_DEPTH_TEST);
glutSwapBuffers();
这个问题叫做 Z-fighting。这是因为 "door"、"window" 和 "wall" 的深度相等。顶点坐标由模型视图矩阵和投影矩阵转换,并为被多边形覆盖的每个片段进行插值。这会导致最终 z 坐标(深度)不准确。
在绘制墙壁之前启用多边形填充偏移 (glPolygonOffset
),以解决问题:
glEnable(GL_DEPTH_TEST);
glDisable( GL_POLYGON_OFFSET_FILL );
// draw door and window
// ...
glEnable( GL_POLYGON_OFFSET_FILL );
glPolygonOffset( 1, 1 );
// draw walls
// ...
多边形填充偏移以最小量操纵片段的深度。这导致 "walls" 的深度与 "window" 和 "door" 的深度不同,即使经过模型视图和投影矩阵的变换。
由于向 "wall" 的深度添加了偏移量,因此 "wall" 始终位于 window 和门之后,与视角无关。
我的 opengl 代码遇到问题
我正在尝试建造一座房子,并将其旋转 360°,为简单起见,我们假设房子的前墙有 window 和 dor,还有一堵后墙。
我正在使用 DEPTH_BUFFER 在查看前墙时看不到后墙,反之亦然,但是当我旋转房子时,门和 window 开始摇晃并且被扭曲了。
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(0.0, 0.0, 0.0);
glLoadIdentity();
gluLookAt(0.0, 0.0, 40.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glRotatef(angle, 0.0, 1.0, 0.0);
glEnable(GL_DEPTH_TEST);
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(8.0, 3.0, 0.0);
glVertex3f(8.0, -10.0, 0.0);
glVertex3f(1.0, -10.0, 0.0);
glVertex3f(1.0, 3.0, 0.0);
glEnd();
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(-9.0, -4.0, 0.0);
glVertex3f(-9.0, 3.0, 0.0);
glVertex3f(-2.0, 3.0, 0.0);
glVertex3f(-2.0, -4.0, 0.0);
glEnd();
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(10.0, -10.0, -20.0);
glVertex3f(-10.0, -10.0, -20.0);
glVertex3f(-10.0, 10.0, -20.0);
glVertex3f(10.0, 10.0, -20.0);
glEnd();
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(10.0, -10.0, 0.0);
glVertex3f(10.0, 10.0, 0.0);
glVertex3f(-10.0, 10.0, 0.0);
glVertex3f(-10.0, -10.0, 0.0);
glEnd();
glDisable(GL_DEPTH_TEST);
glutSwapBuffers();
这个问题叫做 Z-fighting。这是因为 "door"、"window" 和 "wall" 的深度相等。顶点坐标由模型视图矩阵和投影矩阵转换,并为被多边形覆盖的每个片段进行插值。这会导致最终 z 坐标(深度)不准确。
在绘制墙壁之前启用多边形填充偏移 (glPolygonOffset
),以解决问题:
glEnable(GL_DEPTH_TEST);
glDisable( GL_POLYGON_OFFSET_FILL );
// draw door and window
// ...
glEnable( GL_POLYGON_OFFSET_FILL );
glPolygonOffset( 1, 1 );
// draw walls
// ...
多边形填充偏移以最小量操纵片段的深度。这导致 "walls" 的深度与 "window" 和 "door" 的深度不同,即使经过模型视图和投影矩阵的变换。
由于向 "wall" 的深度添加了偏移量,因此 "wall" 始终位于 window 和门之后,与视角无关。