我正在尝试在 OpenGL 中创建镜像。我发现的大多数参考资料都建议使用模板缓冲区来定义镜子本身的边界,并结合使用平移和缩放矩阵来进行实际反射。当观察场景时,我设法让它工作,这样镜子前面就没有物体了。然而,当一个物体在镜子前面时,重叠部分不会显示出来,使它看起来好像它在镜子后面。我很有可能误解了模板缓冲区的工作原理,因为这是我第一次尝试使用它,但我也可能在深度或其他方面犯了一些错误。我会很感激任何建议。这是代码。
#include <gl/glut.h>
// perspective
void view(void) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-2.0, 2.0, -2.0, 2.0, -2.0, 2.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(-85.0, 1.0, 0.0, 0.0);
glScalef(0.25, 0.25, 0.25);
}
void init(void) {
glEnable(GL_DEPTH_TEST);
glClearStencil(0);
glEnable(GL_STENCIL_TEST);
}
void mirror(GLboolean inside, GLfloat vertSet[4][3]) {
GLint i;
if(inside)
glBegin(GL_QUADS); // draw inside of mirror
else
glBegin(GL_LINE_LOOP); // draw frame of mirror
for(i = 0; i < 4; i++)
glVertex3fv(vertSet[i]);
glEnd();
}
void scene(void) {
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glRotatef(90.0, 1.0, 0.0, 0.0);
glutSolidTeapot(1.0);
glPopMatrix();
}
void display(void) {
GLfloat vertSet1[4][3] = {{-3.0, 3.0, 0.0}, {2.0, 3.0, 0.0},
{2.0, 3.0, 2.0}, {-3.0, 3.0, 2.0}};
view();
// store mirror shape in the stencil buffer.
glClear(GL_STENCIL_BUFFER_BIT);
glStencilFunc(GL_ALWAYS, 1, 1);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
mirror(true, vertSet1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// draw mirror frame.
glColor3f(0.0, 0.0, 0.0);
mirror(false, vertSet1);
// draw scene outside mirror
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glStencilFunc(GL_NOTEQUAL, 1, 1);
scene();
// draw reflection of scene in mirror
glStencilFunc(GL_EQUAL, 1, 1);
glTranslatef(0.0, 3.0, 0.0);
glScalef(1.0, -1.0, 1.0);
glTranslatef(0.0, -3.0, 0.0);
scene();
glFlush();
glutSwapBuffers();
glutPostRedisplay();
}
int main (int argc, char **argv) {
glutInit(&argc, argv);
glutInitWindowSize(500, 500);
glutInitWindowPosition(0, 0);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_STENCIL | GLUT_DEPTH);
glutCreateWindow("");
glClearColor(1.0, 1.0, 1.0, 0.0);
init();
glutDisplayFunc(display);
glutMainLoop();
}