OpenGL光源位置
一、OpenGL光源简介
OpenGL提供了多种形式的光源,如点光源、平行光源和聚光灯光源等。所有光源都使用 glLight*接口来设置光源属性,其中包括 glLight{if} 和 glLight{if}v 两类。
1、示例光源
GLfloat ambient[] = {0.3f, 0.3f, 0.3f, 1.0f}; // 环境强度
GLfloat diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f}; // 散射强度
GLfloat specular[] = {1.0f, 1.0f, 1.0f, 1.0f}; // 镜面强度
// 点光源, GL_POSITION属性的最后一个参数为1
GLfloat position[] = {-3.0f, -3.4f, -8.8f, 1.0f};
glLightfv(GL_LIGHT0, GL_POSITION, position);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
// 平行光源, GL_POSITION属性的最后一个参数为0
GLfloat direction[] = {-3.0f, -3.4f, -8.8f, 0.0f};
glLightfv(GL_LIGHT1, GL_POSITION, direction);
glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT1, GL_SPECULAR, specular);
// 聚光灯光源, 需要指定位置、方向、光锥半角
GLfloat spot_direction[] = {-3.0f, -3.4f, -8.8f};
glLightfv(GL_LIGHT2, GL_POSITION, position);
glLightfv(GL_LIGHT2, GL_SPOT_DIRECTION, spot_direction);
glLightfv(GL_LIGHT2, GL_SPOT_CUTOFF, 45.0);
glLightfv(GL_LIGHT2, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT2, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT2, GL_SPECULAR, specular);
2、注意事项
- 最大光源数:不同的硬件支持的光源数量不一样,但至少会支持8个光源。表示光源的常量有
GL_LIGHT0、GL_LIGHT1、GL_LIGHT2、...、GL_LIGHT7、...等。在片段着色中可通过gl_LightSource[0]、gl_LightSource[1]、gl_LightSource[2]、...、gl_LightSource[7]、...等内建变量访问各个光源的参数; - 启用和关闭光源 :可通过
glEnable(GL_LIGHTING)启用光照机制,然后使用glEnable(GL_LIGHTx)与glDisable(GL_LIGHTx)打开或关闭相应光源(其中x代表光源序号); - 模型顶点必须指定法向:OpenGL光照机制是通过计算物体表面法向与入射光线的夹角来确定表面的亮度。故若传入的模型没有指定法向,则最终结果会变得一片漆黑;若法向有问题,最终结果也会莫名其妙。
二、控制光源的位置和方向
控制光源的矩阵变换和控制图元的矩阵变换相同,故最终光源表现出来的性质(如点光源位置是固定在世界坐标系某点还是跟随镜头移动,平行光源的方向在世界坐标系下是不变的还是跟随相机移动等)与提交光源位置或朝向(glLight*())和视点变换(gluLookAt())的先后顺序是息息相关的。据此我们可以定义出各式各样的常见光源,如太阳光、白炽灯、汽车前照灯等。
1、定义在世界坐标系下的光源
如果在视点变换后提交光源位置或朝向,那么光源就可以看作一个普通的几何对象,提交的坐标是在世界坐标系中度量的,对普通几何对象的各种变换同样适用于光源。可通俗的理解为视图变换矩阵作用于光源的位置或朝向参数上,此过程就如同世界坐标系下的普通物体转换至观察坐标系下。如果程序里没有视点变换,说明世界坐标系和摄像机坐标系重合,光源也可以看作一个普通的几何对象。表现出这种性质的常见光源有太阳光,家里的白炽灯等。示例代码如下:
void myDisplay()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, 0, 0, 0, -1, 0, 1, 0);
GLfloat sun_light_position[] = {-139.5f, -153.4f, -68.8f, 0.0f};
glLightfv(GL_LIGHT0, GL_POSITION, sun_light_position); // 光源的其他参数可在程序初始化时设置
glPushMatrix();
glTranslated(-2.5, 6.9, -184.8);
glRotated(87.4, 0, 0, 1);
drawOBJ();
glPopMatrix();
...
}
注意:光源位置或朝向的指定不能处于某个模型的模型变换代码之间(如上例中的glPushMatrix()与glPopMatrix()之间),否则光源参数会受到影响。所以最好将光源位置或朝向设置代码放在紧跟gluLookAt之后。
2、定义在相机坐标系下的光源
如果在视点变换前提交光源位置,视点和光源将捆绑在一起,即二者相对位置不变,一起运动。此时,可以理解为提交的光源位置是在相机坐标系中度量的(位置参数的默认值是(0.0, 0.0, 1.0, 0.0), 就是在摄像机坐标系中度量的)。亦可通俗的理解为视图变换矩阵未作用于光源的位置或朝向参数上。光源的位置朝向参数在观察坐标系的值会保持不变。表现出这种性质的常见光源有汽车前照灯(以驾驶员的视角观察视角)或矿工头上的矿灯。示例代码如下:
void myDisplay()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLfloat sun_light_position[] = {-139.5f, -153.4f, -68.8f, 0.0f};
glLightfv(GL_LIGHT0, GL_POSITION, sun_light_position); // 光源的其他参数可在程序初始化时设置
gluLookAt(0, 0, 0, 0, 0, -1, 0, 1, 0);
glPushMatrix();
glTranslated(-2.5, 6.9, -184.8);
glRotated(87.4, 0, 0, 1);
drawOBJ();
glPopMatrix();
...
}
OpenGL光源位置的更多相关文章
- openGL光源概念
1. 光照模型 环境光——经过多次反射而来的光称为环境光,无法确定其最初的方向,但当特定的光源关闭后,它们将消失. 全局环境光——每个光源都能对场景提供环境光.此外,还有一个环境光,它不来自 ...
- OpenGL中glPushMatrix和glPopMatrix的原理
glPushMatrix.glPopMatrix操作事实上就相当于栈里的入栈和出栈. 很多人不明确的可能是入的是什么,出的又是什么. 比如你当前的坐标系原点在你电脑屏幕的左上方.如今你调用glPush ...
- 使用glPushMatrix和glPopMatrix的原因
转自 百度百科 glPushMatrix 函数将当前矩阵堆栈推送,通过一个,复制当前矩阵. 这就是后 glPushMatrix 的调用堆栈的顶部矩阵是它下面的相同的. 1. 原理讲解 终于明白 ...
- OpenGL光照3:光源
本文是个人学习记录,学习建议看教程 https://learnopengl-cn.github.io/ 非常感谢原作者JoeyDeVries和多为中文翻译者提供的优质教程 的内容为插入注释,可以先跳过 ...
- Opengl使用模型视图变换移动光源
光源绕一个物体旋转,按下鼠标左键时,光源位置旋转. #include <GL/glut.h> static int spin = 0;static GLdouble x_1 = 0.0;s ...
- opengl 笔记(2)
/*- * Opengl Demo Test * * Fredric : 2016-7-10 */ #include <GLUT/GLUT.h> #include <stdlib.h ...
- CSharpGL(39)GLSL光照示例:鼠标拖动太阳(光源)观察平行光的漫反射和镜面反射效果
CSharpGL(39)GLSL光照示例:鼠标拖动太阳(光源)观察平行光的漫反射和镜面反射效果 开始 一图抵千言.首先来看鼠标拖动太阳(光源)的情形. 然后是鼠标拖拽旋转模型的情形. 然后我们移动摄像 ...
- OpenGL阴影,Shadow Volumes(附源程序,使用 VCGlib )
实验平台:Win7,VS2010 先上结果截图: 本文是我前一篇博客:OpenGL阴影,Shadow Mapping(附源程序)的下篇,描述两个最常用的阴影技术中的第二个,Shadow Volu ...
- OpenGL阴影,Shadow Mapping(附源程序)
实验平台:Win7,VS2010 先上结果截图(文章最后下载程序,解压后直接运行BIN文件夹下的EXE程序): 本文描述图形学的两个最常用的阴影技术之一,Shadow Mapping方法(另一种是Sh ...
随机推荐
- BZOJ1599: [Usaco2008 Oct]笨重的石子
1599: [Usaco2008 Oct]笨重的石子 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 758 Solved: 513[Submit][ ...
- redis3.0集群使用发现的一些问题
1.看了官方文档,没有发现有关整个集群关闭再启动的方法.集群是多机器多节点运行,一般情况不可能出现所有机器都挂掉.但万一同时挂掉,数据丢失的可能性就极大了. 验证方法:手动关闭了集群中所有节点,然后再 ...
- HDU-4972 A simple dynamic programming problem
http://acm.hdu.edu.cn/showproblem.php?pid=4972 ++和+1还是有区别的,不可大意. A simple dynamic programming proble ...
- Selenium如何实现dropbar移动
遇到这个拖拽的dropbar,如何实现呢,, 经过网上查找,可以用Action的方式实现或者js来控制 原理:移动按钮的同时,数字也随着变化 解决方法:1.最简单的就是直接在文本框输入相应的数字 2. ...
- sql2005如何附加数据库
1.首先把mdf(数据库主文件)和ldf(数据库日志文件)放到C:\Program Files (x86)\Microsoft SQL Server\MSSQL.1\MSSQL\Data 2.登陆sq ...
- 基础排序算法之快速排序(Quick Sort)
快速排序(Quick Sort)同样是使用了分治法的思想,相比于其他的排序方法,它所用到的空间更少,因为其可以实现原地排序.同时如果随机选取中心枢(pivot),它也是一个随机算法.最重要的是,快速排 ...
- 真机测试---iOS证书(.p12)和描述文件(.mobileprovision)
iOS证书和描述文件: 证书类型 使用场景 开发(Development)证书和描述文件 用于开发测试,在starain中打包后可在真机环境通过Safari调试 发布(Distribution)证书和 ...
- string.Format字符串格式说明
先举几个简单的应用案例: 1.格式化货币(跟系统的环境有关,中文系统默认格式化人民币,英文系统格式化美元) string.Format("{0:C}",0.2) 结果为:¥0.20 ...
- 高性能、高流量Java Web站点打造的22条建议
@http://www.csdn.net/article/2013-12-20/2817861-22-recommendations-for-building-effective-high-traff ...
- 从注冊流程 分析怎样安全退出多个Activity 多种方式(附DEMO)
前言 因为一个同学问到我怎样依照一个流程走好之后回到首页.我曾经看到过4个解决方式,后来发现有做个记录和总结的必要,就写了这篇博文. (之前看小强也写过一篇,这里通过自身的分析完整的总结一下下面6种方 ...