OpenGL(二)图形绘制之平面多面体的绘制
来源:互联网 发布:linux ls命令详解 编辑:程序博客网 时间:2024/04/29 03:29
通过绘制一个三菱锥初步了解绘制平面多面体。
<span style="font-size:18px;">#include<windows.h>#include<gl/gl.h>#include<gl/glut.h>#include<gl/glu.h>#include<stdio.h>//窗口的大小GLsizei windowWidth;GLsizei windowHeight;//旋转角度参数static GLfloat xRot = 0.0f;static GLfloat yRot = 0.0f;//确定多边形的绕法的方向BOOL bDepth = FALSE; //深度测试开关BOOL bCull = FALSE; //剔除开关//初始化窗口void SetupRC(void){//设置窗口背景西颜色为黑色glClearColor(0.0f, 0.0f, 0.0f, 1.0f);//指定多变形的阴影模式为平面阴暗模式glShadeModel(GL_FLAT);}void ChangeSize(int w, int h){if (h == 0)h = 1;glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();if (w <= h){glOrtho(-100.0f, 100.0f, -100.0f*h / w, 100.0f*h / w, -100.0f, 100.0f);}else{glOrtho(-100.0f*w / h, 100.0f*w / h, -100.0f, 100.0f, -100.0f, 100.0f);}glMatrixMode(GL_MODELVIEW);glLoadIdentity();}void RenderScene(void){//清除颜色及深度缓冲区glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);//是否开启设度模式if (bDepth)glEnable(GL_DEPTH_TEST);elseglDisable(GL_DEPTH_TEST);//是否打开剔除if (bCull)glEnable(GL_CULL_FACE);elseglDisable(GL_CULL_FACE);//旋转图形glPushMatrix();//角度正负决定是顺逆时针glRotatef(xRot,1.0f,0.0f,0.0f); //使整个场景绕着x轴旋转 glRotatef(yRot, 0.0, 1.0, 0.0f);//使整个场景绕着y轴旋转 //指定顺时针绕法的多变形为正多变边形正面//glFrontFace(GL_CW);//绘制三菱锥的三个棱面 //他们的颜色分别为红、绿、蓝glBegin(GL_TRIANGLE_FAN);glVertex3f(0.0, 0.0,80);glVertex3f(0.0, 50.0,0.0);glColor3f(1.0,0.0,0.0); //红色glVertex3f(50.0,-50.0,0.0);glColor3f(0.0f, 1.0f, 0.0); //绿色glVertex3f(-50.0,-50.0,0.0);glColor3f(0.0f,0.0f,1.0f); //蓝色glVertex3f(0.0,50.0,0.0);glEnd();//绘制三菱锥的地面,其颜色为黄色glBegin(GL_TRIANGLE_FAN);glVertex3f(0.0,50.0,0.0);glVertex3f(50.0,-50.0,0.0);glColor3f(1.0,1.0,0.0); //黄色glVertex3f(-50.0,-50.0,0.0);glEnd();glPopMatrix();glutSwapBuffers(); //刷新命令缓冲区}void SpecialKeys(int key, int x, int y){if (key == GLUT_KEY_UP) xRot -= 5.0f;if (key == GLUT_KEY_DOWN) xRot += 5.0f;if (key == GLUT_KEY_LEFT) yRot -= 5.0f;if (key == GLUT_KEY_RIGHT) yRot += 5.0f;//结合glPushMatrix()和glPopMatrix()绘图模式理解旋转// 首先,glPushMateix记住来的绘图坐标(起点)//glRotatef(xRot, 1.0f, 0.0f, 0.0f);//glRotatef(yRot, 0.0f, 1.0f, 0.0f);//然后旋转相应的坐标后绘制图形//glPopMatrix 回到了坐标原来的位置(起点)printf("%lf\n", yRot);if (xRot >= 360.0f) xRot = 0.0f;if (xRot < -1.0f) xRot=355.0f;if (yRot >= 360.0f) yRot = 0.0f;if (yRot < -1.0f) yRot = 355.0f;//刷新窗口 强制glutPostRedisplay();}void ProcessMenu(int value){switch (value){case 1:bDepth = !bDepth;break;case 2:bCull = !bCull;break;default:break;}//强制刷新glutPostRedisplay();}int main(int argc, char *argv[]){//initialize the GLUT library //初始化GLUT库glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);glutCreateWindow("三菱锥");//回调函数glutDisplayFunc(RenderScene);glutReshapeFunc(ChangeSize);//设置特殊键盘相应回调函数glutSpecialFunc(SpecialKeys);//void glutSpecialFunc(void(*func)(int key,int x,int y));//special函数第一个关键字是键盘的值, x,y是获取鼠标点击的坐标// sets the special keyboard callback for the current window//the special keyboared callback is triggered when keyboard function or //directional keys are pressed//创建一个菜单glutCreateMenu(ProcessMenu);glutAddMenuEntry("深度测试",1);glutAddMenuEntry("剔除背面",2);glutAttachMenu(GLUT_RIGHT_BUTTON);SetupRC();glutMainLoop();return 0;}</span>
程序一开始运行的图片结果如下:
通过旋转和使用深度测试功能结果如下:
本次学习知识点:
在旋转的过程中,红色的棱镜始终不能显示出来,这是因为红色的棱面是最先绘制的,它总是被后面绘制的绿色,蓝色或黄色的多边形所遮挡,要改变这种状况就需要启用深度测试。
1. 深度测试 (恢复看不到的区域)
在绘制图形的过程中,有时一个物体的一部分会被其前方的物体挡住(从观察者的角度看),如果这是这个物体在档在其前面的物体绘制完成之后绘制,那么屏幕中显示的图形将不是我们所希望的,即后面的物体挡住了前面的物体。
只需启用一项称为深度测试的功能就可以解决这一问题。
启动深度测试: 调用 glEnable(GL_DEPTH_TEST);
关闭深度测试: 调用 glDisable(GL_DEPTH_TEST);
深度测试是一种移除被挡住表面的有效技术,它的过程是:在绘制一个像素时,会给他分配一个值(称为z值),这个值表示它与观察者的距离。然后,如果需要在同一个位置上绘制另一个像素,将比较新像素和已经保存的该位置的像素的z值。如果新像素的z的值比较大,即它离观察者更近因而在原来那个像素的前面,原来的像素就会被新像素挡住。这一操作在内部有深度缓冲区完成。
为了使深度缓冲区正常完成深度测试功能,每次渲染场景时,必须先清除深度缓冲区:
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
2.隐藏表面
启用深度测试之后,我们得到良好的视觉效果,但是还是付出了一些性能代价,因为每个画出的像素都必须与先前像素的z值比较。但是如果我们知道某些表面无论如何也不必画出,我们可以将其指出,这种技术称为"剔除",这种技术可以将已知永远看不到的几何图形消除掉,这样可以显著的改善性能。
那么哪些表面时永远看不到的呢?最常见的例子就是封闭物体的内部表面。一种称为回溯的技术可以消除表面的背面,通过
glEnable/glDisable(GL_CULL_FACE)
来实现。启用剔除技术后,我们发现三棱锥的底面消失了,这是因为在绘制的过程中,我们都使用了顺时针绕法的多边形正面,但这样底面的正面正对着三棱锥的内部,故此启用剔除技术后把底面剔出掉了,要改变这种状况,可以在绘制三棱锥的底面前调用函数
glFrontFace(GL_CCW);
- OpenGL(二)图形绘制之平面多面体的绘制
- [OpenGL]图形的绘制——平面多面体
- OpenGL(二)图形绘制之多边形面的绘制
- OpenGL(二)图形绘制之点线绘制
- 三 OpenGL常见平面图形绘制代码
- NeHe的OpenGL教程2(Bang翻译Delphi版)-如何绘制平面图形
- OpenGL从1.0开始--绘制规则多面体
- <<web>>css3 各种平面图形的绘制(转)
- Qt下的OpenGL 编程(3)绘制平面几何体
- Qt下的OpenGL 编程(3)绘制平面几何体
- Qt下的OpenGL 编程(3)绘制平面几何体
- 平面棋盘的绘制——Opengl之3D象棋(1)
- [OpenGL]用OpenGL图形的绘制--矩形
- opengl 绘制简单图形
- OpenGL绘制简单图形
- OpenGL简单图形绘制
- OpenGL---绘制简单图形
- OPENGL基本图形绘制
- vector::back
- 使用maven一步一步构建spring mvc项目
- cxf调用.net webservice 报错的解决方法
- IOS KeyChain
- 基于tiny4412的Linux内核移植 -- 设备树的展开
- OpenGL(二)图形绘制之平面多面体的绘制
- java,method,contructor,class,属性 程序
- {小结}2016.07.07【初中部 NOIP提高组 】模拟赛C
- ListView中的每个Item嵌套使用ToggleButton
- rk3128 控制GPIO
- Android圆形头像的绘制(三)之多人头像的实现
- Mac下IDEA的使用之常用快捷键篇
- 自定义ssl证书
- 基类指针创建子类对象 构造顺序 面试必考