#include <cassert>
#include <iostream>
#include <GL/glew.h>
#include <GL/glut.h>
using namespace std;
static GLfloat mirror_x = 0;
static GLfloat mirror_y = 0;
static GLfloat mirror_z = 2;
void init()
{
glClearColor(0,0,0,0);
glClearDepth(1.0f);
glClearStencil(0);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
const GLfloat light0_pos[] =
{
5.0f, 5.0f, 0.0f, 1.0f
};
const GLfloat light0_ambient[] =
{
1.0f, 1.0f, 1.0f,1.0f
};
glLightfv(GL_LIGHT0, GL_POSITION, light0_pos);
glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
glEnable(GL_DEPTH_TEST);
glEnable(GL_STENCIL_TEST);
}
void drawSphere()
{
GLUquadric* quadric = gluNewQuadric();
assert(quadric);
glColor3f(0, 0, 0.5);
gluSphere(quadric, 0.5f, 256, 10);
gluDeleteQuadric(quadric);
}
void render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
//设置当前的矩阵为投影矩阵
glMatrixMode(GL_MODELVIEW);
glStencilFunc(GL_ALWAYS, 0x0, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glPushMatrix();
// 移动到位置(0,0,3)
glTranslatef(mirror_x, mirror_y, mirror_z);
drawSphere();
glPopMatrix();
//绘制镜面,绘制完成之后,将镜面的模板值全部设置为1
//由于镜面的Z值小于原始球体的Z值故直接调用zfail的操作
glStencilFunc(GL_ALWAYS, 0x1, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
//绘制镜面,在z=0的位置绘制镜面
//在这里我给写错成glDisable(GL_DEPTH_TEST)写成这样就不能进行深度测试
//直接就覆盖了上一个图形,应该是锁住,修改其模板值
glDepthMask(GL_FALSE); //将深度缓冲区锁住
glColor3f(0.1, 0.1, 0.1);
glRectf(-3, 3, 3, -3);
glDepthMask(GL_TRUE); //将深度缓冲区解锁
//绘制镜像球体,为了保证镜像始终在镜面内部,只对模板
//值等于1的情况进行绘制
glStencilFunc(GL_EQUAL, 0x1, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glPushMatrix();
glTranslatef(-mirror_x, -mirror_y, -mirror_z);
drawSphere();
glPopMatrix();
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, w*1.0f/h, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(1, 0, 5, 0, 0, 0, 0, 1, 0);
}
void keyborad(unsigned char key, int x, int y)
{
std::cout<<"key="<<key<<std::endl;
std::cout<<"x="<<x<<std::endl;
std::cout<<"y="<<y<<std::endl;
switch (key)
{
case '1':
{
++mirror_x;
break;
}
case '2':
{
--mirror_x;
break;
}
case '4':
{
++mirror_y;
break;
}
case '5':
{
--mirror_y;
break;
}
case '7':
{
++mirror_z;
break;
}
case '8':
{
--mirror_z;
break;
}
default:
break;
}
glutPostRedisplay();
}
int main(int argc, char **argv[])
{
glutInitDisplayMode(GLUT_RGBA | GLUT_STENCIL | GLUT_DEPTH | GLUT_DOUBLE);
glutCreateWindow("Mirror Model");
glutInitWindowPosition(300, 300);
glutInitWindowSize(600, 600);
assert(glewInit() == GLEW_NO_ERROR);
init();
glutDisplayFunc(render);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyborad);
glutMainLoop();
return 0;
}
OpenGL模板测试之镜像模型解析
最新推荐文章于 2023-05-08 19:26:29 发布