文档章节

OpenGL 光照和材料属性

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

首先是光照的设置,光照分为三类环境光 散射光 镜面光,根据此时的理解,记录下今天所掌握的知识,先设置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
博文 44
码字总数 12913
作品 0
大连
程序员
iOS-OpenGL ES入门教程(四)光照

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

安东_Ace ⋅ 06/14 ⋅ 0

图片和图形之构建一个OpenGL ES环境(10)

原文 概要 构建一个OpenGL ES环境 为了在Android应用程序中使用OpenGL ES绘制图形,您必须为它们创建一个视图容器。其中一种更直接的方法是实现a GLSurfaceView和a GLSurfaceView.Renderer。...

lichong951 ⋅ 05/26 ⋅ 0

关于opengl中多重纹理,离屏与渲染到屏幕切换,可编程管线有固定管线切换的理解

最近用opengl写项目时遇见几个问题,感觉比较通用写下啦分享; 一, opengl多重纹理的使用 二, opengl离屏渲染与渲染到屏幕切换使用 三, opengl可编程管线与固定管线切换使用 经过一个成功...

lixiaoguang20 ⋅ 04/23 ⋅ 0

u3d shader着色器学习笔记(一)

基础知识:MeshFilter 存储一个mesh(网格,模型网格,模型由哪些三角面组成,组成什么样子的模型,三角面的一些顶点信息) MeshRender 根据MeshFilter 存储的三角面顶点信息 用来渲染一个模...

nihao561 ⋅ 05/24 ⋅ 0

苹果弃用 OpenCL 和 OpenGL ,OpenCL 或遭全面淘汰

随着昨天 MacOS 10.14 Mojave 的发布,苹果悄然证实,他们已弃用 OpenGL 和 OpenCL 。 在 MacOS 10.14 的更新文档中,苹果表示使用 OpenGL 和 OpenCL 构建的应用可以继续在 macOS 10.14 中运...

王练 ⋅ 06/06 ⋅ 0

跨平台图像引擎 - Octoon

Octoon 是一个免费和开源的跨平台图形引擎,采用MIT协议。 用户可以使用一组统一的API轻松创建图形应用程序。 应用程序可以导出到许多平台,包括Linux,Mac OSX,Windows,Android和HTML5。 ...

匿名 ⋅ 05/27 ⋅ 0

OpenGL实现物体动画和视频特效

OpenGL实现视频的水印、滤镜?OpenGL实现视频的剪裁、旋转? 2D/3D物体的 旋转,平移,缩放? OpenGL图片滤镜与视频滤镜? 矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合,最早来自于方...

shareus ⋅ 04/24 ⋅ 0

OpenGL入门(一)freeglut和glew的编译

写在前面 最近对OpenGL编程又双叒产生了浓厚的兴趣,决定把学习OpenGL过程中学到的知识都整理到博客中来,一来方便日后查看,而来也是为了和诸位大佬共勉。有不当的地方还望诸位批评指正,谢...

renkai0406 ⋅ 04/23 ⋅ 0

图片和图形之用OpenGL ES显示图形(9)

原文 概要 Android框架提供了大量用于创建有吸引力的功能性图形用户界面的标准工具。但是,如果您想要更多地控制应用程序在屏幕上绘制的内容,或者冒险进入三维图形,则需要使用其他工具。A...

lichong951 ⋅ 05/26 ⋅ 0

完全用Deepin Linux娱乐、工作、学习(2)-- 显卡驱动篇

在前面《完全用Deepin Linux娱乐、工作、学习(1)》一文中,我简单和各位分享了关于Deepin Linux的基础体验。对于Deepin Linux来说其中有它的好也有它的不足,我相信任何人、任何事、任何物...

levinbin ⋅ 04/19 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

如何使用serverchan微信推送告警

之前实现推送告警信息到微信的方法有如下几种: 1、通过企业公众号实现----收费: 2、通过QQ邮箱,在微信平台上开启收到邮件进行提醒; 3、第三方告警平台API,一般也是收费的; 不过最近看文...

问题终结者 ⋅ 8分钟前 ⋅ 0

TCP的RPC

RPC就是远程方法调用(Remote Process Call ),包含了客户端和服务端,涉及了对象的序列化传输。 1.服务端启动,注册远程调用的类2.客户端发送请求信息包含类、方法、参数的一些信息、序列化传...

Cobbage ⋅ 28分钟前 ⋅ 0

IOS-UI UI初步代码布局添加事件

ISO开发界面,UI是必须学习的一部分,其实很早之前想学来了,一直没有沉下心来学习。看到IOS的代码风格和布局就别扭的不行,跟java代码和android布局比较显得不是那么方便,所以一直到现在。...

京一 ⋅ 38分钟前 ⋅ 0

浅谈OpenDaylight的二次开发

OpenDaylight作为一款开源SDN网络控制器,依托于强大的社区支持以及功能特性,成为了目前主流的SDN网络控制器开发平台。在比较稳定的OpenDaylight Helium版本中,已经为开发者提供了大量的网...

wangxuwei ⋅ 48分钟前 ⋅ 0

API 开发中可选择传递 token 接口遇到的一个坑

在做 API 开发时,不可避免会涉及到登录验证,我使用的是jwt-auth 在登录中会经常遇到一个token过期的问题,在config/jwt.php默认设置中,这个过期时间是一个小时,不过为了安全也可以设置更...

等月人 ⋅ 48分钟前 ⋅ 0

Java NIO之文件处理

程序要操作本地操作系统的一个文件,可以分为以下三个部分: 对文件位置的操作 对文件的操作 对文件内容的操作 其中,对文件内容的操作在 Java NIO之Channel 中已经有了介绍,通过FileChann...

士别三日 ⋅ 53分钟前 ⋅ 0

Maven的pom.xml配置文件详解

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.......

小海bug ⋅ 今天 ⋅ 0

解决httpclient超时设置不生效的问题

最近公司有项目需要通过http调用第三方服务,且第三方服务偶有超时,故需要设置一定的超时时间防止不响应的情况出现。 初始设置如下: [java] view plain copy //超时设置 RequestConfig re...

Mr_Tea伯奕 ⋅ 今天 ⋅ 0

过滤器Filter和拦截器HandlerInterceptor

过滤器 依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,获取我们想要...

hutaishi ⋅ 今天 ⋅ 0

Redis入门详解(转)

Redis入门详解 Redis简介 Redis安装 Redis配置 Redis数据类型 Redis功能 持久化 主从复制 事务支持 发布订阅 管道 虚拟内存 Redis性能 Redis部署 Redis应用场景 Redis总结 Redis简介: Redi...

xiaoyaoyoufang ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部