`
huozheleisi
  • 浏览: 1236370 次
文章分类
社区版块
存档分类
最新评论

OpenGl制作3D效果

 
阅读更多

	为什么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风车。 功能如下: (1)有3个风车可供选择 (2)可任意设置四个风车扇叶的颜色; (3)可控制风车的转动和停止,可设置转动速度 (4)风车颜色可在转动过程中随速度变化; (5)可设置转动加速,风车停止和...

    学OpenGL编3D游戏[含全部源码]

    用多媒体的表现手法将学习过程完全显示在你面前,使用者可以随时查看所选章节的知识要点提示,可以观看程序的制作过程和效果,也可以马上进入到VC编辑器对范例程序修修改改,在实践中加深对知识的理解;还可以进入到...

    使用 C++ 和 OpenGL 实现简单的 3D 赛车游戏

    按键 效果 ↑ 汽车向前行驶 ↓ 倒车 ← 左转弯(需要汽车处于移动中才会生效) → 右转弯(需要汽车处于移动中才会生效) Esc 退出游戏 C 切换相机视角为固定视角/自由视角 X 切换渲染方式为线框图模式/正常模式 ...

    基于java的VR全景图+Opengl3D模型展示源码

    基于java的VR全景图+Opengl3D模型展示源码

    vc OpenGL制作动态三维的雷达扫描效果.rar

    vc OpenGL制作动态三维的雷达扫描效果,一个在VC 下应用OpenGL技术绘制三维动画的好范例,虽然这个例子挺简单,但可以为你以后使用VC 6.0编写大型的3D图像处理软件 、3D游戏开发打下基础吧。

    OpenGL超级宝典源码

    第二部分“OpenGL渲染组成”深入阐述了0penGL的使用、高级特性及特殊效果,如处理光栅图形、纹理贴图、3D建模和物体合成、混色和雾化效果,处理三角形、曲线和曲面、交互式图形,另外还介绍了如何利用OpenGL制作图像...

    [openGL超级宝典(第四版)

    第二部分“OpenGL渲染组成”深入阐述了OpenGL的使用、高级特性及特殊效果,如处理光栅图形、纹理贴图、3D建模和物体合成、混色和雾化效果,处理三角形、曲线和曲面、交互式图形,另外还介绍了如何利用OpenGL制作图像...

    opengl3d迷宫

    opengl制作的有音乐效果的鼠标键盘交互的3d迷宫场景

    OpenGL超级宝典.rar

    第二部分“OpenGL渲染组成”深入阐述了0penGL的使用、高级特性及特殊效果,如处理光栅图形、纹理贴图、3D建模和物体合成、混色和雾化效果,处理三角形、曲线和曲面、交互式图形,另外还介绍了如何利用OpenGL制作图像...

    OpenGL_参考手册.rar

    近年来,随着计算机技术的进步,我们跨入了一个三维时代,各种扣人心弦的三维游戏、能数字化地显示天气变化的气象服务、震撼人心的3D数字化特殊效果,无不使我们体验到三维世界的全新感觉。可视化、计算机动画、...

    Nehe的OpenGL教程电子书

    把渲染得图像作为纹理提取出来,在利用OpenGL本身自带的纹理过滤,就能实现这种效果,不信,你试试。 37.卡通映射 什么是卡通了,一个轮廓加上少量的几种颜色。使用一维纹理映射,你也可以实现这种效果。 ...

    OpenGL编程实例.rar

    内容包括:怎样利用Visual C 5.0 MFC中的类建立OpenGL应用程序的基本格式,建立和控制2D形状和3D形体、标准二次曲面、Bezier曲线及曲面、NURBS曲线及曲面、点光源、无限光源、聚光、基本材质、贴图材质、Mip贴图、...

    图形学实现旋转光照纹理3D效果等终极版

    图形学实现旋转光照纹理3D效果,在配置好opengl环境下,复制main.cpp和data文件夹,注意文件夹的位置。即可运行。有兴趣还可以自己加好玩的功能!

    OpenGL超级宝典(中文第二版)pdf版 part1 of 2

    如处理光栅图形、纹理贴图、3D建模和物体合成、混色和雾化效果、处理三角形、曲线和曲面、交互式图形,另外还介绍了如何利用OpenGL制作图像以及OpenGL扩展的应用; 第三部分“OpenGL for Windows: OpenGL 与 Win...

    OpenGL超级宝典(中文第二版)pdf 版 part 2 of 2

    如处理光栅图形、纹理贴图、3D建模和物体合成、混色和雾化效果、处理三角形、曲线和曲面、交互式图形,另外还介绍了如何利用OpenGL制作图像以及OpenGL扩展的应用; 第三部分“OpenGL for Windows: OpenGL 与 Win...

    [OpenGL超级宝典--第二版]

    第二部分“OpenGL渲染组成”深入阐述了0penGL的使用、高级特性及特殊效果,如处理光栅图形、纹理贴图、3D建模和物体合成、混色和雾化效果,处理三角形、曲线和曲面、交互式图形,另外还介绍了如何利用OpenGL制作图像...

    VC下编程实现3D文字

    提起3D文字制作,不少人会马上想到3DMAX等一些专门的3维制作工具,即使选用VC以编程的手段来实现也多是假手于OpenGL图形开发库来完成。熟悉OpenGL开发的编程人员一定对其初始化、材质以及灯光的渲染等一系列烦琐而...

    开源项目Android-炫酷的3D音乐播放器-各种特效OpenGL.zip

    本项目是一个专为Android平台设计的3D音乐播放器,它利用OpenGL技术实现了丰富的视觉效果和动画特效。播放器不仅支持标准的音乐文件格式,还提供了立体声和环绕声效果,为用户带来沉浸式的听觉体验。播放器界面采用...

    OpenGL ES应用开发实践 指南 iOS卷.pdf

    第4章介绍灯光模拟背后的概念,以及利用glkit并使用相对简单的应用代码演示灯光效果;第5章讲解并演示从任意视点渲染几何对象的技术;第6章介绍如何制作动画;第7章介绍了如何加载并使用模型;第8章讲解了特效的使用...

    杭州电子科技大学《实时三维图形绘制》OpenGL大作业实验报告

    要求使用OpenGL绘制多个物体(如球体、立方体、茶壶等),并实现光照效果、阴影效果等高级特性。 3. 开发一个基于OpenGL的物理引擎。要求使用OpenGL模拟物体的运动、碰撞、重力等物理行为,并实现可视化效果。 4. ...

Global site tag (gtag.js) - Google Analytics