OpenGl制作3D效果
来源:互联网 发布:access导入sql文件 编辑:程序博客网 时间:2024/04/28 17:08
为什么3D作图常常能产生另人震惊的效果?因为利用3D作图,你可以生成一些现实中难得实现的真实的感受。特别是一些特殊的光影效果。 其实光源前面已经讲的很全面了,只是缺少一些专门的例子。这里我们来稍微加深一下认识,我们将在例子中看到一个地方的光源对不同物体发出不同的光 这在现实中是少见的吧? 1.双面光照: void glLightModeli(LIGHT_MODEL_TWO_SIDE,GL_TRUE); 光照计算通常是对多边形进行的。一般设置光照的条件总是对正面的多边形,而不考虑背面,但是如果考虑一个物体被劈开,光源的个数又会影响可见性,那么 有必要对多边形双面都进行计算,这就是上面函数的功能;取消这一功能只须把第三个参数改为GL_FALSE。 2.聚光源 定义聚光源的函数仍是利用glLightfv(),需要设定的参数包括:光源位置、光源发散半角和光源聚光方向。 具体实现可以看下面例子: ////////////////////////////////////////////////////////// //sample.cpp #include <gl/gl.h>#include <gl/glu.h>#include <gl/glaux.h>#pragma comment(lib, "OpenGl32.lib")#pragma comment(lib, "glu32.lib")#pragma comment(lib, "glaux.lib")#pragma warning(disable : 4244)// MIPS#pragma warning(disable : 4136)// X86#pragma warning(disable : 4051)// ALPHA void myinit(void); void CALLBACK display(void); void CALLBACK reshape(GLsizei w,GLsizei h); void initlights(void) { //定义物体材质特性的数值 GLfloat mat_ambient[]={0.2,0.2,0.2,1.0}; GLfloat mat_diffuse[]={0.8,0.8,0.8,1.0}; GLfloat mat_specular[]={1.0,1.0,1.0,1.0}; GLfloat mat_shininess[]={80.0}; //定义第0个光源的属性(这是平行的环境光,没有聚光效果) GLfloat light0_diffuse[]={0.0,0.0,1.0,1.0}; GLfloat light0_position[]={1.0,1.0,1.0,0.0}; //定义第一个光源的属性(聚光灯一) GLfloat light1_ambient[]={0.2,0.2,0.2,1.0}; GLfloat light1_diffuse[]={1.0,0.0,0.0,1.0}; GLfloat light1_specular[]={1.0,0.6,0.6,1.0}; GLfloat light1_position[]={-3.0,-3.0,3.0,1.0}; GLfloat spot_direction[]={1.0,1.0,-1.0}; //定义第二个光源的属性(聚光灯二) GLfloat light2_ambient[]={0.2,0.6,0.2,1.0}; GLfloat light2_diffuse[]={0.0,1.0,0.0,1.0}; GLfloat light2_specular[]={0.0,1.0,0.0,1.0}; GLfloat light2_position[]={-3.0,-3.0,3.0,1.0}; GLfloat spot2_direction[]={1.0,1.0,-1.0}; //!!!我们看到第一和第二个聚光源除了在颜色的定义上一个偏红,一个偏绿 //其他没有任何不同,所以如果象我们后面作的,对一个物体开启一个光源,对 //另一个物体开启另一个光源,就会产生一个点光源对不同物体发出不同光的效果 //将前面的属性定义加以应用 glLightfv(GL_LIGHT0,GL_DIFFUSE,light0_diffuse); glLightfv(GL_LIGHT0,GL_POSITION,light0_position); glLightfv(GL_LIGHT1,GL_AMBIENT,light1_ambient); glLightfv(GL_LIGHT1,GL_DIFFUSE,light1_diffuse); glLightfv(GL_LIGHT1,GL_SPECULAR,light1_specular); glLightfv(GL_LIGHT1,GL_POSITION,light1_position); //定义聚光灯发散角 glLightf(GL_LIGHT1,GL_SPOT_CUTOFF,30.0); //定义聚光灯发射方向的向量 glLightfv(GL_LIGHT1,GL_SPOT_DIRECTION,spot_direction); glLightfv(GL_LIGHT2,GL_AMBIENT,light2_ambient); glLightfv(GL_LIGHT2,GL_DIFFUSE,light2_diffuse); glLightfv(GL_LIGHT2,GL_SPECULAR,light2_specular); glLightfv(GL_LIGHT2,GL_POSITION,light2_position); glLightf(GL_LIGHT2,GL_SPOT_CUTOFF,30.0); glLightfv(GL_LIGHT2,GL_SPOT_DIRECTION,spot2_direction); glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient); glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular); glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glEnable(GL_LIGHT2); } void myinit(void) { auxInitDisplayMode(AUX_SINGLE|AUX_RGBA); auxInitPosition(0,0,500,500); auxInitWindow("sample1"); glClearColor(0.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); initlights(); // glShadeModel(GL_FLAT); } void CALLBACK reshape(GLsizei w,GLsizei h) { glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(w<=h) glOrtho(-5.0,5.0,-5.0*(GLfloat)h/(GLfloat)w, 5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0); else glOrtho(-5.0*(GLfloat)h/(GLfloat)w, 5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0,-5.0,5.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void CALLBACK display(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //首先标出聚光源一、二的位置(同一位置) glPushMatrix(); glTranslated(-3.0,-3.0,3.0); glDisable(GL_LIGHTING); glColor3f(1.0,0.0,0.0); auxWireCube(0.1); glEnable(GL_LIGHTING); glPopMatrix(); //关掉第二个光源,只启用第一个光源(红),绘制球体一 glPushMatrix(); glDisable(GL_LIGHT2); glTranslated(0.0,2.0,0.0); auxSolidSphere(2.0); glPopMatrix(); //关掉第一个光源,只启用第二个光源(绿),绘制球体二 glPushMatrix(); glDisable(GL_LIGHT1); glEnable(GL_LIGHT2); glTranslated(0.0,-2.0,0.0); auxSolidSphere(2.0); glPopMatrix(); glFlush(); } void main(void) { myinit(); auxReshapeFunc(reshape); auxMainLoop(display); } //end of sample /////////////////////////////////////////////////////////////// 一个现实中难以见到的情景出现了。还不快试试? 结束光源之前,再给出一个光源移动的例子,其中用到了鼠标消息的响应,实现 非常简单,以OPENGL的辅助库提供的方式调用一个CALLBACK函数即可,和以前讲 的响应键盘输入的方法完全一样。 ////////////////////////////////////////////////////////////// //sample.cpp #include <gl/gl.h>#include <gl/glu.h>#include <gl/glaux.h>#pragma comment(lib, "OpenGl32.lib")#pragma comment(lib, "glu32.lib")#pragma comment(lib, "glaux.lib")#pragma warning(disable : 4244)// MIPS#pragma warning(disable : 4136)// X86#pragma warning(disable : 4051)// ALPHA
void myinit(void); void CALLBACK display(void); void CALLBACK reshape(GLsizei w,GLsizei h); //控制光源移动的变量 static int step=0; //鼠标响应的CALLBACK函数 void CALLBACK movelight(AUX_EVENTREC *event) { step=(step+15)%360; } void initlights(void) { GLfloat mat_ambient[]={0.2,0.2,0.2,1.0}; GLfloat mat_diffuse[]={0.8,0.8,0.8,1.0}; GLfloat mat_specular[]={1.0,1.0,1.0,1.0}; GLfloat mat_shininess[]={80.0}; GLfloat light0_diffuse[]={0.0,0.0,1.0,1.0}; GLfloat light0_ambient[]={0.2,0.5,0.5,1.0}; glLightfv(GL_LIGHT0,GL_DIFFUSE,light0_diffuse); glLightfv(GL_LIGHT0,GL_AMBIENT,light0_ambient); glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient); glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular); glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); } void myinit(void) { auxInitDisplayMode(AUX_SINGLE|AUX_RGBA); auxInitPosition(0,0,500,500); auxInitWindow("sample1"); glClearColor(0.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); initlights(); // glShadeModel(GL_FLAT); } void CALLBACK reshape(GLsizei w,GLsizei h) { glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(w<=h) glOrtho(-5.0,5.0,-5.0*(GLfloat)h/(GLfloat)w, 5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0); else glOrtho(-5.0*(GLfloat)h/(GLfloat)w, 5.0*(GLfloat)h/(GLfloat)w,-5.0,5.0,-5.0,5.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void CALLBACK display(void) { GLfloat position[]={0.0,0.0,1.5,1.0}; glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslatef(0.0,0.0,-5.0); glPushMatrix(); //光源的位置只由旋转变量step决定,每按下鼠标左键一下,step的值便会改变 //导致光源位置的改变 glRotated((GLdouble)step,-1.0,1.0,1.0); glLightfv(GL_LIGHT0,GL_POSITION,position); glTranslated(0.0,0.0,1.5); glDisable(GL_LIGHTING); glColor3f(1.0,1.0,0.0); auxWireSphere(0.25); glEnable(GL_LIGHTING); glPopMatrix(); auxSolidTorus(0.5,2.5); glPopMatrix(); glFlush(); } void main(void) { myinit(); auxMouseFunc(AUX_LEFTBUTTON,AUX_MOUSEDOWN,movelight); auxReshapeFunc(reshape); auxMainLoop(display); } //end of sample ///////////////////////////////////////////////////////////// 在例子中,黄色的小球表示当前光源的位置,它的旋转导致了环状体表面受光照部分的光影的变化,每按下鼠标左键一下,光源就会作响应的旋转。
- OpenGl制作3D效果
- opengl 3d卷轴效果
- opengl 制作 3D 彩色旋转三角形
- 【绝对经典】opengl 3d卷轴效果
- 使用openGl创建3d效果
- css3制作的3d效果
- css3制作3d翻转效果
- 制作3D效果的按钮
- CSS制作3D魔方效果
- HTML制作3D粒子效果Demo
- 使用CSS3制作3D动态效果
- Android OpenGL实战三——3D空间效果
- Flash AS3.0 制作旋转图片3D效果
- Coco2dx制作一个3D旋转的效果
- 用scrollview制作3D效果的导航页
- EDIUS中的3D图层效果该如何制作
- 使用css3 background属性制作3D易拉罐效果
- OpenGL ES 20 用2D纹理伪造3D效果 Demo
- OpenGL曲面
- VC++动态链接库(DLL)编程深入浅出(带图)
- Log4Net 配置和使用
- Flash Builder 4.5 的新增功能
- android之socket网络编程
- OpenGl制作3D效果
- 对“Android输入事件流程中的EventHub分析及源码演示”的补充
- Android 添加窗口对象
- 在C#中运用 SQLite
- Android一些学习的小点
- 码斗士的修炼之路 -- 如何保持并提升战斗力
- Jrebel 工具的使用
- 97编程大赛第一名的神奇程序
- OpenGL的特殊效果