文档章节

OpenGL 光照和材料属性

小青_1989
 小青_1989
发布于 2014/06/05 14:41
字数 1825
阅读 416
收藏 2

首先是光照的设置,光照分为三类环境光 散射光 镜面光,根据此时的理解,记录下今天所掌握的知识,先设置3个数组后面会用到
GLfloat amb[] = {0.3f,0.3f,0.3f,1.0f};//环境光成分
GLfloat dif[] = {0.7f,0.7f,0.7f,1.0f};//散射光成分
GLfloat spe[] = {1.0f,1.0f,1.0f,1.0f};//镜面光成分
环境光是从物体的各个方向照射物体的,他产生的效果和关闭光照效果几乎相同,因为在关闭光照效果的时候,物体总是可见的并均匀着色,与他们的旋转和观察角度无关,若打开光照效果glEnable(GL_LIGHTING)而不指定环境光,这时默认的环境光是(0.2,0.2,0.2,1.0),这是非常微弱的光,画面上的物体会非常的暗淡,这时我们指定一个自己的第一个光源light0,先给他设置环境光glLightfv(GL_LIGHT0,GL_AMBIENT,amb),amb是开始定义的表示环境光成分的数组
散射光是一种有特定方向的光,在物体表面是均匀的反射的,也可以理解成漫反射光,和下面学习的经面光有些相似,若以散射光照射一个球体作为例子,正对着散射光方向的表面是亮的,背对着光线方向的表面是暗淡的,在光线掠过的侧面的亮度是介于两者之间的,这和在一个黑屋子里用手电筒照射一个篮球的效果很相似,这时给上面的光源light0指定一种散射光glLightfv(GL_LIGHT0,GL_DIFFUSE,dif),dif是开始定义的表示散射光成分的数组
最后是镜面光,这种光比较好理解,和上面的散射光一样,他也是有一定的方向,但在物体表面的反射是很强烈的,可以理解为镜面反射光,他会在物体边面形成一个亮点(光斑),在生活中强光照射在比较平整的表面就是这种效果,如在阳光照射下表面无锈迹的铁球,再给上面的光源light0加上镜面光成分,flLightfv(GL_LIGHT0,GL_SPECULAR,spe),spe是开始定义的表示镜面光成分的数组
在特定的光源设置好以后这时就可以启用这用个光源,glEnable(GL_LIGHT0);
以下就是设置并启用自定义光源的代码
glEnable(GL_LIGHTING);//启动光照效果
GLfloat amb[] = {0.3f,0.3f,0.3f,1.0f};//环境光成分
GLfloat dif[] = {0.7f,0.7f,0.7f,1.0f};//散射光成分
GLfloat spe[] = {1.0f,1.0f,1.0f,1.0f};//镜面光成分

glLightfv(GL_LIGHT0,GL_AMBIENT,amb); //添加环境光成分
glLightfv(GL_LIGHT0,GL_DIFFUSE,dif); //添加散射光成分
glLightfv(GL_LIGHT0,GL_SPECULAR,spe);//给自定义光源light0添加镜面光成分

glEnable(GL_LIGHT0);     //启用自定义的光源

光照定义完成后,还要定义物体的表面的材料属性,材料的属性对最后的效果影响也是巨大的,因为最终在屏幕上显示的效果是光源发出的光经过材料反射后才能最终确定的,材料的属性设置和光源的设置有些类似,用到的函数glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,amb)第一个参数指定了是哪个表面需要被渲染,第二个参数是哪个材料属性将要被设置,第三个参数是指定哪种颜色的光会被反射(用了上面的一个数组),一般情况下材料对环境光和对散射光的反射率是相同的,所以上面的参数用了GL_AMBIENT_AND_DIFFUSE。
上面的光源设置中用到了镜面光,若此时在材料属性中不设置镜面反射效果,则上面的镜面光也就没什么作用,镜面反射的设置和光源的镜面光设置类似glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,spe),若绘制的物体想要有光泽那么这个设置是必须的(例如光滑的大理石表面),若绘制的物体的表面没有光泽那么这个属性就不用设置(例如粗糙的石板表面),在镜面反射设置后还有一个问题需要解决,那就是高强度的镜面光和强烈的镜面反射效果会导致物体将以几乎接近白色的效果出现,如若想要在物体表面形成一个亮斑,还需要一个函数glMateriali(GL_FRONT_AND_BACK,GL_SHININESS,45);中间的一个参数是镜面指数,他指定了镜面反射加亮的大小和集中性,如果最后一个参数设置为0那表示不聚焦,也就是整个表面均匀加亮,若设置为128表示最大程度的聚焦,也就是光斑点最小的情况。
一下是材料属性设置的代码
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,amb);//材料对环境光的反射情况
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,dif);//散射光的反射情况
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,spe);//镜面光的反射情况
glMateriali(GL_FRONT_AND_BACK,GL_SHININESS,45);//镜面光的聚焦情况

这样就可以渲染出比原来更为真实的三位物体,但还有一点不足 ,就是当物体的颜色经常发生变化时,那么必须每次进行材料反射属性的更改,将调用一次glMaterialfv(),那将是件很麻烦的工作,这里可以用到一个方法,也是以后最常用到的方法,叫做颜色追踪。若使用了这种方法,可以在以后的渲染中通过调用glColor来设置材料的属性,方法如下
glEnable(GL_COLOR_MATERIAL);         //启用颜色追踪
glColorMaterial(GL_FRONT_AND_BACK,FL_AMBIENT_AND_DIFFUSE); //正面和反面,环境光和散射光
设置好后,以后就可以通过调用glColor来设置材料的反射属性了。
以下是今天程序的完整代码和makefile


//文件名ball_light.c
//2008/2/14
//made by hsw
#include <GL/glx.h>
#include <GL/gl.h>
#include <GL/glut.h>

GLfloat position_x = -25.0f;
GLfloat position_y = 25.0f;
GLfloat change_x = 0.1f;
GLfloat change_y = 0.1f;
GLfloat Height = 100.0f;
GLfloat Width = 100.0f;

GLfloat temp = 1.0f ;
void TimeFunction(void)
{
glutPostRedisplay();
glutTimerFunc(33,TimeFunction,1);

}
void RenderScene(void)
{
static GLint angle_x = 0;
static GLint angle_y = 0;
static GLint angle_z = 0;
GLint temp_i,temp_j;
angle_x += 1;
angle_y += 2;
angle_z += 4;
 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
 glColor3f(0.0f,0.95f,0.24f);
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();


glPushMatrix();
 glTranslatef(0.0f,0.0f,-50.0f);
 glRotatef(angle_x++,0.0f,1.0f,0.0f);
 glutSolidTorus(1,8,30,40);
 glColor3f(1.0f,0.0f,0.0f);
 glutSolidSphere(3.5f,40,40);
glPopMatrix();

glPushMatrix();
 glTranslatef(0.0f,0.0f,-50.0f);
    glPushMatrix();
 glTranslatef(-30.0f,10.0f,0.0f);
 glColor3f(1.0f,0.0f,0.0f);
 glutSolidSphere(3.5f,40,40);
    glPopMatrix();

    glPushMatrix();
 glTranslatef(-30.0f,25.0f,0.0f);
 glColor3f(1.0f,0.0f,0.0f);
 glutSolidSphere(3.5f,40,40);
    glPopMatrix();

glPopMatrix();
glPushMatrix();
 glColor3f(1.0f,1.0f,0.0f);
 glTranslatef(30.0f,0.0f,-50.0f);
 glutSolidSphere(5.0f,40,40);
glPopMatrix();
 //glutSolidSphere(12.0f,40,40);
 //glutSolidTeapot(12.0f);
//以下是地面的绘制
//底色

glColor3f(1.0f,1.0f,1.0f);
glBegin(GL_TRIANGLE_FAN);
    glVertex3f(-1500.0f,-30.5f,0.0f);
    glVertex3f(-1500.0f,-30.5f,-2500.0f);
    glVertex3f(1500.0f,-30.5f,-2500.0f);
    glVertex3f(1500.0f,-30.5f,0.0f);
glEnd();

 glutSwapBuffers();
}
void SetupRC(void)
{
 GLfloat amb[] = {0.4f,0.4f,0.4f,1.0f};
 GLfloat dif[] = {6.0f,6.0f,6.0f,1.0f};
 GLfloat spe[] = {1.0f,1.0f,1.0f,1.0f};
 GLfloat pos[] = {-50.0f,50.0f,100.0f,1.0f};
 glClearColor(0.0f,0.0f,0.0f,1.0f);
 glEnable(GL_DEPTH_TEST);
 //glLightModelfv(GL_LIGHT_MODEL_AMBIENT,amb);
 glEnable(GL_LIGHTING);
 glLightfv(GL_LIGHT0,GL_AMBIENT,amb);
 //glLightfv(GL_LIGHT0,GL_DIFFUSE,dif);
 glLightfv(GL_LIGHT0,GL_SPECULAR,spe);
 glLightfv(GL_LIGHT0,GL_POSITION,pos);
//glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,60.0f);
 glEnable(GL_LIGHT0);

 glEnable(GL_COLOR_MATERIAL);
 glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
 glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,spe);
 glMateriali(GL_FRONT_AND_BACK,GL_SHININESS,128);
}

void ChangeSize(GLsizei w,GLsizei h)
{
GLfloat aspectRatio;
if(h == 0)
 h = 1;
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
temp = aspectRatio = (GLfloat)w/(GLfloat)h;
    if(w <= h)
 //glOrtho(-100.0,100.0,-100/aspectRatio,100.0/aspectRatio,0.0,100.0);
 gluPerspective(60,temp,0.1f,1000.0f);
    else
 //glOrtho(-100.0*aspectRatio,100.0*aspectRatio,-100.0,100.0,0.0,100.0);
 gluPerspective(60,temp,0.1f,1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

int main(int argc ,char *argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);

glutCreateWindow("Color Material");
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
glutTimerFunc(33,TimeFunction,1);
SetupRC();
glutMainLoop();

return 0;
}
//代码结束
//////////////////////////////////////////////////////////////////////
以下是makefile

ball_light:ball_light.o
 gcc -o ball_light ball_light.o -lGL -lGLU -lglut -lm
ball_light.o:ball_light.c
 gcc -c ball_light.c


本文转载自:http://hsw625728.blog.163.com/blog/static/3957072820081151004846/

共有 人打赏支持
小青_1989
粉丝 3
博文 75
码字总数 12913
作品 0
大连
程序员
私信 提问
opengl超级宝典笔记—Using OpenGL(三)

OpenGL状态机 绘制3D图形是一项复杂的任务。我们需要许多的属性,比如光照属性,材料属性,纹理等。如果我们在每次绘制图形的时候,都去设置这些属性,或者以参数的形式传进去。那工作量非常...

Mario_Q
2013/09/05
0
0
OpenGL超级宝典笔记——光照参数与材料属性

添加光照 glEnable(GLLIGHTING); 这个函数调用告诉OpenGL使用材料属性和光照参数去决定每个顶点的颜色值。如果没有开启这个函数,则看到的物体是昏暗的。开启光照后会根据你的材料属性和光照...

Mario_Q
2013/10/07
0
0
opengl超级宝典笔记——Using Opengl

第二章 使用OpenGL (一)OpenGl 的工作原理 OpenGL是过程式的而非描述性的图形API。开发人员只须规定必要的步骤去实现显示的效果。这些步骤包含了许多OpenGL的命令。这些命令用于绘制许多的...

Mario_Q
2013/09/02
0
0
OpenGL开发之旅基础知识介绍

OpenGL开发之旅基础知识介绍 glLoadIdentity();gluortho2D(-1.0,1.0,-1.0,1.0) glEnd(); glPushMatrix();glPopMatrix(); 0000FF;">void) { // 清除颜色缓冲区 glClear(GLCOLORBUFFERBIT); /......

andyhe91
2013/05/11
0
0
iOS-OpenGL ES入门教程(四)光照

前言 前面的基础文章列表 iOS-零基础学习OpenGL ES入门教程(一) iOS-OpenGL ES入门教程(二)最简单的纹理Demo iOS-OpenGL ES入门教程(三)纹理取样,混合,多重纹理 下面来讲一下光照 光...

安东_Ace
06/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

0015-如何使用Sentry管理Hive外部表权限

1.文档编写目的 本文档主要讲述如何使用Sentry对Hive外部表权限管理,并基于以下假设: 1.操作系统版本:RedHat6.5 2.CM版本:CM 5.11.1 3.集群已启用Kerberos和Sentry 4.采用具有sudo权限的...

Hadoop实操
29分钟前
1
0
边缘计算与数据中心的发展趋势

导读 Gartner研究表明,人工智能、物联网和5G助力下一代商业创新,由此产生大量数据,2020年前企业将使用超过75亿台联网设备。 在几乎每个方面,社会的节奏都正变得更快。我们希望客户服务问...

问题终结者
42分钟前
4
0
toString();

package com.atguigu.java1; import java.util.Date; /** * toString()的使用: * * 1.java.lang.Object类中toString()定义如下: * public String toString() { return getClass().getName......

architect刘源源
今天
1
3
不可不说的Java“锁”事

前言 Java提供了种类丰富的锁,每种锁因其特性的不同,在适当的场景下能够展现出非常高的效率。本文旨在对锁相关源码(本文中的源码来自JDK 8)、使用场景进行举例,为读者介绍主流锁的知识点...

Java干货分享
今天
1
0
Java GoEasy 实现服务端推送和Web端推送

项目中需要消息推送,又想降低开发成本。Java服务器端推送,Web端接收推送信息。 具体需求: 需求一:系统框架实现全局异常捕获并录入日志表,实现实时推送消息到客户端页面展示。 需求二:系...

Gibbons
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部