为什么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风车。 功能如下: (1)有3个风车可供选择 (2)可任意设置四个风车扇叶的颜色; (3)可控制风车的转动和停止,可设置转动速度 (4)风车颜色可在转动过程中随速度变化; (5)可设置转动加速,风车停止和...
用多媒体的表现手法将学习过程完全显示在你面前,使用者可以随时查看所选章节的知识要点提示,可以观看程序的制作过程和效果,也可以马上进入到VC编辑器对范例程序修修改改,在实践中加深对知识的理解;还可以进入到...
按键 效果 ↑ 汽车向前行驶 ↓ 倒车 ← 左转弯(需要汽车处于移动中才会生效) → 右转弯(需要汽车处于移动中才会生效) Esc 退出游戏 C 切换相机视角为固定视角/自由视角 X 切换渲染方式为线框图模式/正常模式 ...
基于java的VR全景图+Opengl3D模型展示源码
vc OpenGL制作动态三维的雷达扫描效果,一个在VC 下应用OpenGL技术绘制三维动画的好范例,虽然这个例子挺简单,但可以为你以后使用VC 6.0编写大型的3D图像处理软件 、3D游戏开发打下基础吧。
第二部分“OpenGL渲染组成”深入阐述了0penGL的使用、高级特性及特殊效果,如处理光栅图形、纹理贴图、3D建模和物体合成、混色和雾化效果,处理三角形、曲线和曲面、交互式图形,另外还介绍了如何利用OpenGL制作图像...
第二部分“OpenGL渲染组成”深入阐述了OpenGL的使用、高级特性及特殊效果,如处理光栅图形、纹理贴图、3D建模和物体合成、混色和雾化效果,处理三角形、曲线和曲面、交互式图形,另外还介绍了如何利用OpenGL制作图像...
opengl制作的有音乐效果的鼠标键盘交互的3d迷宫场景
第二部分“OpenGL渲染组成”深入阐述了0penGL的使用、高级特性及特殊效果,如处理光栅图形、纹理贴图、3D建模和物体合成、混色和雾化效果,处理三角形、曲线和曲面、交互式图形,另外还介绍了如何利用OpenGL制作图像...
近年来,随着计算机技术的进步,我们跨入了一个三维时代,各种扣人心弦的三维游戏、能数字化地显示天气变化的气象服务、震撼人心的3D数字化特殊效果,无不使我们体验到三维世界的全新感觉。可视化、计算机动画、...
把渲染得图像作为纹理提取出来,在利用OpenGL本身自带的纹理过滤,就能实现这种效果,不信,你试试。 37.卡通映射 什么是卡通了,一个轮廓加上少量的几种颜色。使用一维纹理映射,你也可以实现这种效果。 ...
内容包括:怎样利用Visual C 5.0 MFC中的类建立OpenGL应用程序的基本格式,建立和控制2D形状和3D形体、标准二次曲面、Bezier曲线及曲面、NURBS曲线及曲面、点光源、无限光源、聚光、基本材质、贴图材质、Mip贴图、...
图形学实现旋转光照纹理3D效果,在配置好opengl环境下,复制main.cpp和data文件夹,注意文件夹的位置。即可运行。有兴趣还可以自己加好玩的功能!
如处理光栅图形、纹理贴图、3D建模和物体合成、混色和雾化效果、处理三角形、曲线和曲面、交互式图形,另外还介绍了如何利用OpenGL制作图像以及OpenGL扩展的应用; 第三部分“OpenGL for Windows: OpenGL 与 Win...
如处理光栅图形、纹理贴图、3D建模和物体合成、混色和雾化效果、处理三角形、曲线和曲面、交互式图形,另外还介绍了如何利用OpenGL制作图像以及OpenGL扩展的应用; 第三部分“OpenGL for Windows: OpenGL 与 Win...
第二部分“OpenGL渲染组成”深入阐述了0penGL的使用、高级特性及特殊效果,如处理光栅图形、纹理贴图、3D建模和物体合成、混色和雾化效果,处理三角形、曲线和曲面、交互式图形,另外还介绍了如何利用OpenGL制作图像...
提起3D文字制作,不少人会马上想到3DMAX等一些专门的3维制作工具,即使选用VC以编程的手段来实现也多是假手于OpenGL图形开发库来完成。熟悉OpenGL开发的编程人员一定对其初始化、材质以及灯光的渲染等一系列烦琐而...
本项目是一个专为Android平台设计的3D音乐播放器,它利用OpenGL技术实现了丰富的视觉效果和动画特效。播放器不仅支持标准的音乐文件格式,还提供了立体声和环绕声效果,为用户带来沉浸式的听觉体验。播放器界面采用...
第4章介绍灯光模拟背后的概念,以及利用glkit并使用相对简单的应用代码演示灯光效果;第5章讲解并演示从任意视点渲染几何对象的技术;第6章介绍如何制作动画;第7章介绍了如何加载并使用模型;第8章讲解了特效的使用...
要求使用OpenGL绘制多个物体(如球体、立方体、茶壶等),并实现光照效果、阴影效果等高级特性。 3. 开发一个基于OpenGL的物理引擎。要求使用OpenGL模拟物体的运动、碰撞、重力等物理行为,并实现可视化效果。 4. ...