当前位置:网站首页>OpenGL glLightfv 函数的应用以及光源的相关知识
OpenGL glLightfv 函数的应用以及光源的相关知识
2022-07-07 08:15:00 【my_angle2016】
首先介绍OpenGL的简单光照模型,它的反射光可以分为三个分量:环境反射光,漫反射光,镜面反射光。就是你要实现一个光照效果,需要设置这三个分量,三者之和达到你想要的光照效果。
1.环境光,简单来说就是环境中的光,似乎来自于各个方向
2.漫反射,来自一个方向,光它照射到物体上,则在各个方向上均匀地发散出去,不管视点在哪,物体都是一样亮。
3.镜面光,来自特定方向,并沿着另一方向反射出去。
glLightfv函数原型:void glLightfv(光源名, 类型, 赋值);
类型主要有四类:光源颜色---AMBIENT、DIFFUSE、SPECULAR和光源位置---POSITION
其中DIFFUSE的参数与光源颜色紧密,一般简单的光照模型只设置DIFFUSE就足够用了
GLfloat light0_diffuse[]= { 1.0, 0.0, 0, 1.0};
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
下面是赋值的代码:
GLfloat light0_ambient[]= { 0.2, 0.2, 0.2, 1.0 };
GLfloat light0_diffuse[]= { 1.0, 0.0, 0, 1.0};
GLfloat light0_specular[] = { 1.0, 0, 0, 1.0 };
glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR,light0_specular);
设置光源位置
GLfloat light0_position[] = { 1.0, 1.0, 1.0, 0.0 };
glLightfv(GL_LIGHT0, GL_POSITION,light0_position);
开启光源
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);表示启动光照的总开关 glEnable(GL_LIGHT0);//打开0号光源
glEnable(GL_DEPTH_TEST);//打开深度缓冲区,绘制3D图像时候使用
完整代码
#include "stdafx.h"
#include <GL/glut.h>
#include "math.h"
void reshape(int w,int h)
{
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(w<h)
glOrtho(-1.5, 1.5, -1.5,1.5 * (GLfloat)h / (GLfloat)w, -1.5,1.5);
else
glOrtho(-1.5* (GLfloat)w / (GLfloat)h, 1.5, -1.5,1.5, -1.5,1.5 );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void init ()
{
glClearColor(1.0,1.0,1.0,0.0);
glColor3f(1.0,1.0,0.0);
GLfloat light0_ambient[]= { 0.2, 0.2, 0.2, 1.0 };
GLfloat light0_diffuse[]= { 1.0, 0.0, 0, 1.0};//红色点光源
GLfloat light0_specular[] = { 1.0, 0, 0, 1.0 };
GLfloat light0_position[] = { 1.0, 1.0, 1.0, 0.0 };
glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR,light0_specular);
glLightfv(GL_LIGHT0, GL_POSITION,light0_position);
glShadeModel(GL_SMOOTH);//光滑着色,过渡色效果
glEnable(GL_LIGHTING);//启动光照,总开关
glEnable(GL_LIGHT0);//打开0号光源
glEnable(GL_DEPTH_TEST);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glutSolidTeapot(0.5);
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc,argv);
glutInitWindowPosition(200,200);
glutInitWindowSize(500,500);
glutCreateWindow("001");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
运行结果
我们发现茶壶的颜色被设置的光照给覆盖了,本身的颜色(黄色)并没有显示出来。这里引入一个新的函数---颜色材质函数glEnable(GL_COLOR_MATERIAL); 它确保了打开灯光效果之后还能保留图形颜色。使用时候放在init函数里即可。
添加后茶壶效果如下
事实上光源才是所有光照效果的基础,没有光源一切都无从谈起。OpenGL中我们可以设置8个光源,其编号分别为GL_LIGHT0、GL_LIGHT1、……、GL_LIGHT7。就相当于现实生活中有8个太阳,但每个太阳的位置、方向及它发出的光线可以完全不同。因此,OpenGL中我们设置光源时,主要就是设置其颜色、位置、方向等性质。另外,OpenGL中任何一个光源都可以发出不同强度的环境光、散射光、镜面反射光,这几个方面综合起来就决定了光源的颜色。
我们通过glLightfv(光源编号,光源特性,参数数据)来设置光源。其中,光源编号可取GL_LIGHT0、GL_LIGHT1、……、GL_LIGHT7共8个值。光源特性主要可取GL_AMBIENT(设置光源的环境光属性,默认值(0,0,0,1))、GL_DIFFUSE(设置光源的散射光属性,默认值(1,1,1,1))、GL_SPECULAR(设置光源的镜面反射光属性,默认值(1,1,1,1))、GL_POSITION(设置光源的位置,默认值(0,0,1,0))。参数数据格式要求为数组形式,即数学上的向量形式。
下面一段代码,我们将一个光源的性质进行完整设置:
GLfloat Va[]={0.4,0.4,0.4,1}; //光源环境光强度数组
GLfloat Vd[]={0.6,0.6,0.6,1}; //光源散射光强度数组
GLfloat Vs[]={0.6,0.6,0.6,1}; //光源镜面反射光强度数组
GLfloat Vp[]={1,1,1,1}; //光源位置数组
glLightfv(GL_LIGHT0,GL_AMBIENT,Va); //设置0号光源的环境光属性
glLightfv(GL_LIGHT0,GL_DIFFUSE,Vd); //设置0号光源的散射光属性
glLightfv(GL_LIGHT0,GL_SPECULAR,Vs); //设置0号光源的镜面反射光属性
glLightfv(GL_LIGHT0,GL_POSITION,Vp); //设置0号光源的位置属性
光源的性质设置完毕,还要调用glEnable(GL_LIGHT0)来打开光源。就相当于你买回手电筒、装好电池(设置光源),但如果不打开开关(打开电源),手电筒是不起作用的。
另外,对于GL_POSITION,其位置数组(x,y,z,w)定义了光源在空间中的位置。但三维空间为什么需要4个量呢?事实上这里采用的是齐次坐标,当w≠0时,它表示光源处于空间中(x,y,z)处,这时的光源称为定点光源;当w=0时,根据齐次坐标的性质,它表示光源位于无穷远处,此时光源称为定向光源,其所有光线几乎是相互平等的,如太阳。其光线方向由点(x,y,z)指向(0,0,0)。
将第2章中的正方体的例子做以下修改。修改后的void __fastcall TForm1::OpenGL1 GLPaint(TObject *Sender)处的代码如下(其余位置不变):
void __fastcall TForm1::OpenGL1GLPaint(TObject *Sender)
{
glEnable(GL_DEPTH_TEST); //隐藏表面消除
glClear(GL_DEPTH_BUFFER_BIT); //清除窗口颜色
const GLfloat glfLightAmbient1[4] = {0.1, 0.1, 0.1, 1.0};
const GLfloat glfLightAmbient2[4] = {0.4, 0.4, 0.4, 1.0};
const GLfloat glfLightDiffuse1[4] = {0, 0.8, 0.8, 1.0};
const GLfloat glfLightDiffuse2[4] = {0.8, 0.8, 0.8, 1.0};
const GLfloat glfLightSpecular1[4] = {0, 0.8, 0.8, 1.0};
const GLfloat glfLightSpecular2[4] = {0.8, 0.8, 0.8, 1.0};
const GLfloat glPosition1[4]={0,0,1,0};
const GLfloat glPosition2[4]={0.6,0.6,-0.6,1};
glLightfv(GL_LIGHT0, GL_AMBIENT, glfLightAmbient1);
glLightfv(GL_LIGHT0, GL_DIFFUSE, glfLightDiffuse1);
glLightfv(GL_LIGHT0, GL_SPECULAR, glfLightSpecular1);
glLightfv(GL_LIGHT0,GL_POSITION,glPosition1);
glLightfv(GL_LIGHT1, GL_AMBIENT, glfLightAmbient2);
glLightfv(GL_LIGHT1, GL_DIFFUSE, glfLightDiffuse2);
glLightfv(GL_LIGHT1, GL_SPECULAR, glfLightSpecular2);
glLightfv(GL_LIGHT1,GL_POSITION,glPosition2);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);//两面照亮
glEnable(GL_LIGHTING);//启用光照
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);//打开光源
glEnable(GL_COLOR_MATERIAL);//启用颜色追踪
glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);
//物体正面的材料环境颜色和散射颜色,追踪glColor所设置的颜色(比较拗口,
事实上就是让OpenGL根据glColor所设置的颜色自动设置物体的反射强度)
glShadeModel(GL_FLAT);//设置颜色填充模式
glBegin(GL_QUAD_STRIP) ;
glVertex3f(i,-i,i);
glVertex3f(i,-i,-i);
glColor3f(1,0,0);
glVertex3f(-i,-i,i);
glVertex3f(-i,-i,-i);
glColor3f(0,1,0);
glVertex3f(-i,i,i);
glVertex3f(-i,i,-i);
glColor3f(0,0,1);
glVertex3f(i,i,i);
glVertex3f(i,i,-i);
glColor3f(1,1,0);
glVertex3f(i,-i,i);
glVertex3f(i,-i,-i);
glEnd();
glBegin(GL_QUADS);
glVertex3f(i,-i,i);
glVertex3f(-i,-i,i);
glVertex3f(-i,i,i);
glColor3f(1,0,1);
glVertex3f(i,i,i);
glVertex3f(i,-i,-i);
glVertex3f(-i,-i,-i);
glVertex3f(-i,i,-i);
glColor3f(0,1,1);
glVertex3f(i,i,-i);
glEnd();
glDisable(GL_LIGHTING);//关闭光照
glDisable(GL_LIGHT0);//关闭0号光源
glDisable(GL_LIGHT1); //关闭1号光源
}
边栏推荐
- Study summary of postgraduate entrance examination in August
- Slurm资源管理与作业调度系统安装配置
- 嵌入式工程师如何提高工作效率
- Adb 实用命令(网络包、日志、调优相关)
- Can I open a stock trading account online? Is it safe
- PDF文档签名指南
- Chris Lattner, père de llvm: Pourquoi reconstruire le logiciel d'infrastructure ai
- ORM -- grouping query, aggregation query, query set queryset object properties
- Learning records - high precision addition and multiplication
- [sword finger offer] 42 Stack push in and pop-up sequence
猜你喜欢
0x0fa23729 (vcruntime140d.dll) (in classes and objects - encapsulation.Exe) exception thrown (resolved)
01 use function to approximate cosine function (15 points)
JMeter loop controller and CSV data file settings are used together
ORM model -- creation and query of data records
基于HPC场景的集群任务调度系统LSF/SGE/Slurm/PBS
Pdf document signature Guide
基于gis三维可视化技术的智慧城市建设
一文讲解单片机、ARM、MUC、DSP、FPGA、嵌入式错综复杂的关系
浅谈日志中的返回格式封装格式处理,异常处理
Yarn的基础介绍以及job的提交流程
随机推荐
Talking about the return format in the log, encapsulation format handling, exception handling
Guide de signature du Code Appx
The request object parses the request body and request header parameters
基于HPC场景的集群任务调度系统LSF/SGE/Slurm/PBS
Pdf document signature Guide
fiddler-AutoResponder
When there are pointer variable members in the custom type, the return value and parameters of the assignment operator overload must be reference types
Differences between MCU and MPU
ArcGIS operation: batch modify attribute table
Es classes and objects, prototypes
IPv4 socket address structure
字符串格式化
BigDecimal value comparison
Postman interface test V
2022.7.3DAY595
. Net configuration system
LeetCode 练习——113. 路径总和 II
UnityWebRequest基础使用之下载文本、图片、AB包
P2788 数学1(math1)- 加减算式
ORM -- grouping query, aggregation query, query set queryset object properties