【狼】openGL 光照的学习
小狼学习原创,欢迎批评指正
http://www.cnblogs.com/zhanlang96/p/3859439.html
先上代码
- #include "stdafx.h"
- #include <windows.h>
- #include "iostream"
- #include "GL/glut.h"
- #include "math.h"
- #define windowsWidth 500
- #define windowsHeight 500
- using namespace std;
- int preX,preY;
- bool leftState=false;
- bool rightState=false;
- float angleX=0.0;
- float angleY=0.0;
- float angleY1=0.0;
- float angleY2=0.0;
- float angleX1=0.0;
- float angleX2=0.0;
- void init()
- {
- GLfloat mat_diffuse[] = {0.5,0.5,0.5,};
- GLfloat mat_specular[] = {,,,};
- GLfloat mat_ambient[] = {,,,};
- GLfloat light_position[] = {,,,};
- glClearColor(,,,);
- glShadeModel(GL_SMOOTH);
- glEnable(GL_DEPTH_TEST);
- glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient);//环境光(全局环境光)
- glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);//散射光(很微弱的光,感觉像是从各种的物体反射的光)
- glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);//反射光(像高光)
- glMaterialf(GL_FRONT,GL_SHININESS,25.0);
- glLightfv(GL_LIGHT0,GL_POSITION,light_position);
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
- glColorMaterial(GL_FRONT,GL_DIFFUSE);
- glEnable(GL_COLOR_MATERIAL);
- glClear(GL_COLOR_BUFFER_BIT);
- glRotatef(angleX1,0.0,1.0,0.0);
- glRotatef(angleY1,-1.0,0.0,0.0);
- glBegin(GL_DIFFUSE);
- glColor3f(0.0f,0.0f,1.0f);
- glutSolidTeapot(0.6f);
- cout<<"init"<<endl;
- }
- void KeyPressFunc(int key, int x, int y)
- {
- if(key==GLUT_KEY_UP)
- {
- angleY1 = ;
- angleX1 = ;
- glutPostRedisplay();//重绘图像
- }
- else if(key==GLUT_KEY_DOWN)
- {
- angleY1 = -;
- angleX1 = ;
- glutPostRedisplay();
- }
- else if(key==GLUT_KEY_RIGHT)
- {
- angleX1 = ;
- angleY1 = ;
- glutPostRedisplay();
- }
- else if(key==GLUT_KEY_LEFT)
- {
- angleX1 =- ;
- angleY1 = ;
- glutPostRedisplay();
- }
- }
- void randerScene()
- {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- init();
- glFlush();
- //ERROR
- cout<<"shuaxin"<<endl;
- }
- void reshape(int w, int h)
- {
- glViewport(,,(GLsizei)w,(GLsizei)h);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- if (w <= h)
- {
- glOrtho(-1.5,1.5,-1.5*(GLfloat)w/(GLfloat)h,1.5*(GLfloat)w/(GLfloat)h,-,);
- }
- else
- {
- glOrtho(-1.5*(GLfloat)w/(GLfloat)h,1.5*(GLfloat)w/(GLfloat)h,-1.5,1.5,-,);
- }
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- randerScene();
- }
- void IdleFunc()
- {
- angleY1 = ;
- angleX1 = 0.1;
- glutPostRedisplay();//重绘图像
- }
- void setupRc()
- {
- glClearColor(0.5f,0.5f,0.5f,1.0f);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
- glShadeModel (GL_FLAT);//光滑着色
- }
- int main(int argc, char *argv[])
- {
- glutInit(&argc, argv);
- glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH | GLUT_STENCIL );
- glutInitWindowPosition(, );
- glutInitWindowSize(, );
- glutCreateWindow("teapot");
- init();
- glutDisplayFunc(randerScene);
- setupRc();
- glutSpecialFunc(KeyPressFunc);
- // glutIdleFunc(IdleFunc);//空闲状态执行函数(取消注释茶壶自行旋转)
- glutReshapeFunc(&reshape);
- glutMainLoop();
- return ;
- }
这是一个受很多光照着Front(前面)的蓝色小茶壶,
分析下代码,从init(初始化)开始,
glShadeModel();这个是选择着色方式的函数,
如果里面的参数是GL_SMOOTH,那就是光滑着色,有渐变的效果,
如果参数是GL_FLAT,那就是平面着色,没有渐变效果,都是一个颜色,
而这只有在定点颜色不同时才有区别,
作为光滑smooth模式,右图为flat平面模式
应用光滑处理模式时,多边形所有点的法向是由内插生成的,具有一定的连续性,因此每个点的颜色也相应内插,故呈现不同色。这种模式下,插值方法采用的是双线性插值法
通常算法为:先用多边形顶点的光强线性插值出当前扫描线与多边形边交点处的光强,然后再用交点的光强线插值处扫描线位于多边形内区段上每一象素处的光强值。
图中显示出一条扫描线与多边形相交,交线的端点是A点和B点,P点是扫描线上位于多边形内的任一点,多边形三个顶点的光强分别为I1、I2和I3.
取A点的光强Ia为I1和I2的线性插值,B点的光强Ib为I1和I3的线性插值,P点的光强Ip则为Ia和Ib的线性插值。
处理后可以使用多边形表示的曲面光强连续,而且计算量很小。这种算法还可以以增量的形式改进,且能用硬件直接实现算法,从而广泛用于计算机实时图形生成
接下来是光照部分的重点函数,glMaterial(),
他有glMaterialf, glMateriali, glMaterialfv, glMaterialiv。这四种形式,
如果是
- void glMaterialf(GLenum face,
- GLenum pname,
- GLfloat para)
- void glMateriali(GLenum face,
- GLenum pname,
- GLint para)
这两个函数pname只能是GL_SHININESS(镜面指数)的属性,因为只有镜面指数是一个值(para)控制的
参数
- face
- 哪一面被刷新. 是 GL_FRONT, GL_BACK, 或GL_FRONT_AND_BACK中的一个
- pname
- 什么光照属性,这里只能是是 GL_SHININESS.
- param
- GL_SHININESS 的属性值.
- 如果是
-
- void glMaterialfv(GLenum face,
- GLenum pname,
- const GLfloat *params)
- void glMaterialiv(GLenum face,
- GLenum pname,
- const GLint *params)
因为函数后缀是v(vectors向量),所以要预先设置glfloat数组的值
参数
- face
- 哪一面被刷新. 是 GL_FRONT, GL_BACK, 或GL_FRONT_AND_BACK中的一个
- pname
- 什么光照属性,这里可以是 GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_EMISSION, GL_SHININESS, GL_AMBIENT_AND_DIFFUSE, 或 GL_COLOR_INDEXES的其中之一
- param
- 属性值(数组)
- GL_AMBIENT 环境光的颜色
- GL_DIFFUSE 散射光的颜色
- GL_SPECULAR 镜面反射光(高光)的颜色
- GL_EMISSION 发射颜色(自发光的颜色)
- GL_SHININESS 镜面指数(取值范围为[0.0, 128.0],数值越大,高光越小,亮度越高)
- GL_AMBIENT_AND_DIFFUSE 环境光和散射光的颜色
- GL_COLOR_INDEXES 环境光,散射光,镜面光的颜色索引(index)
- void glMaterialfv(GLenum face,
这些设置的都是GL_LIGHTn的属性(GL_LIGHT0,GL_LIGHT1,GL_LIGHT2。。。。一个又一个的光源),
GL_LIGHT0属性的默认值与其他不同,需要注意
第二个重要的函数是glLight()
他有glLightf, glLighti, glLightfv, glLightiv这四种形式
- void glLightf(GLenum light,
- GLenum pname,
- GLfloat param)
- void glLighti(GLenum light,
- GLenum pname,
- GLint param)
参数
- light
- 光源GL_LIGHTn , 0 <= n< GL_MAX_LIGHTS,(GL_LIGHT0,GL_LIGHT1,GL_LIGHT2。。。。)
- pname
- 光源的属性 ,接下来要被设定的值,有GL_SPOT_EXPONENT, GL_SPOT_CUTOFF, GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION, 和 GL_QUADRATIC_ATTENUATION .
- param
- 设定属性的值.
同上,v系列
- void glLightfv(GLenum light,
- GLenum pname,
- const GLfloat *params)
- void glLightiv(GLenum light,
- GLenum pname,
- const GLint *params)
PARAMETERS
- light
- 光源GL_LIGHTn , 0 <= n< GL_MAX_LIGHTS,(GL_LIGHT0,GL_LIGHT1,GL_LIGHT2。。。。)
- pname
- 光源的属性 ,接下来要被设定的值,有GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_POSITION, GL_SPOT_DIRECTION, GL_SPOT_EXPONENT, GL_SPOT_CUTOFF, GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION,和 GL_QUADRATIC_ATTENUATION
- params
- 设定属性的值.
- GL_AMBIENT 环境光的颜色
- GL_DIFFUSE 散射光的颜色
- GL_SPECULAR 镜面光的颜色
- GL_POSITION 光源的位置坐标
- GL_SPOT_DIRECTION 聚光灯的方向
- GL_SPOT_EXPONENT 聚光指数(可以指定聚光灯光锥体内的光线聚集程度)
- GL_SPOT_CUTOFF 聚光灯的切角(锥形光的锥角大小)
- GL_CONSTANT_ATTENUATION 常量衰减因子(现实环境下,随着光照射的距离增加,亮度逐渐减弱,随之衰减)
- GL_LINEAR_ATTENUATION 线性衰减因子
- GL_QUADRATIC_ATTENUATION 二次衰减因子
- 可以位于无限远处的光源(方向性光源,像太阳),照射的是平行光,所以不存在衰减,
- 可能有的人会不理解这些因子是什么,openGL将根据这三种衰减因子得出运算出最终衰减因子,然后把光源的强度乘以衰减因子,算出这种真实性,
- 公式如下:
- d = 光源位置到物体顶点的距离
Kc = GL_CONSTANT_ATTENUATION 常数衰减因子
Kl = GL_LINER_ATTENUATION 线性衰减因子
Kq = GL_QUADRATIC_ATTENUATION 二次衰减因 - 衰减因子 = 1/(kc+kld+kqd^2)
- 由于openGL是一个状态机,我们定义的这些光源属性都要手动开启
-
- glEnable(GL_LIGHTING);启用灯光
- glEnable(GL_LIGHT0);启用GL_LIGHT0这个光源
- glEnable(GL_LIGHTING);启用灯光
ok,接下来就用以前的知识加上茶壶就可以了,加了光的壶就此完成
【狼】openGL 光照的学习的更多相关文章
- OpenGL光照3:光源
本文是个人学习记录,学习建议看教程 https://learnopengl-cn.github.io/ 非常感谢原作者JoeyDeVries和多为中文翻译者提供的优质教程 的内容为插入注释,可以先跳过 ...
- OpenGL光照和颜色
OpenGL光照和颜色 转自:http://www.cnblogs.com/kekec/archive/2011/08/16/2140789.html OpenGL场景中模型颜色的产生,大致为如下的流 ...
- OpenGL光照测试
OpenGL光照测试 花了大概半个月,研究了OpenGL的光照.请注意是固定管线渲染的光照,如果使用着色器的高手们请飘过.这个程序是通过光照对模型的照射,来研究OpenGL光照的性质.以后可以通过这个 ...
- 浅析OpenGL光照
浅析OpenGL光照 之前从来都没有涉及光照的内容,心想只要能通过常规的方法渲染出几何体甚至是模型就可以了,然而没有光照的日子注定是苦涩的,因为仅凭几何体和模型的颜色无法达到真是渲染的效果,在实际中有 ...
- OpenGL光照设置
一.设置光源 (1)光源的种类 环境光 环境光是一种无处不在的光.环境光源放出的光线被认为来自任何方向.因此,当你仅为场景指定环境光时,所有的物体无论法向量如何,都将表现为同样的明暗程度. 点光源 由 ...
- OpenGL光照2:材质和光照贴图
本文是个人学习记录,学习建议看教程 https://learnopengl-cn.github.io/ 非常感谢原作者JoeyDeVries和多为中文翻译者提供的优质教程 的内容为插入注释,可以先跳过 ...
- OpenGL光照1:颜色和基础光照
本文是个人学习记录,学习建议看教程 https://learnopengl-cn.github.io/ 非常感谢原作者JoeyDeVries和多为中文翻译者提供的优质教程 的内容为插入注释,可以先跳过 ...
- Unity预计算光照的学习(速度优化,LightProb,LPPV)
1.前言 写这篇文章一方面是因为unity的微博最近出了关于预计算光照相关的翻译文章,另一方面一些美术朋友一直在抱怨烘培速度慢 所以抱着好奇的心态来学习一下unity5的PRGI预计算实时光照 2.基 ...
- 关于OpenGL和DX学习的取舍
大家多知道左右就肯定要与显卡打交道.两大图形图像IPA.OpenGL(图形),DX(图形,声音,键盘控制,网络) OpenGL的兴起可能取决于苹果公司的适用,吸引看大部分开发者适用,它有跨平台的有点. ...
随机推荐
- PHP的数据库 之 关闭问题
首先,PHP由于有垃圾回收机制,所以数据库即使你不手动关闭,也有自动去关闭的机制, 这里就和操作文本流不同,文本流需要手动去关闭,不然会发生内存浪费现象 并且,PHP在同时连接多个DB的时候,连接到一 ...
- mvc5 + ef6 + autofac搭建项目(四)
在列表页面,点击新增,弹出窗口实现视屏上传,这里存在一个问题,就是大文件上传的问题,iis出于安全问题,有限制,当然这不是大问题,解决也很容易: 见截图: 请忽略视屏文件,看得懂的请装作不懂. 源码 ...
- Delphi Excel
用delphi写excel文件 2007-03-18 21:12 1.引用: Excel2000, OleServer,Comobj, StdCtrls 2.声明变量: ExcelA ...
- 设置lable内容不上下居中
转载自:http://dong-zsh.github.io/2015/10/14/%E8%AE%BE%E7%BD%AElable%E5%86%85%E5%AE%B9%E4%B8%8D%E4%B8%8A ...
- PHP 学习笔记 (三)
stream_context_create()函数的用法: $url = "http://www.someweb.com" $context = stream_context_cr ...
- Java OOP考试错题分析
解析: A.ArrayList 可以存储NULL值,也可以存储重复的值,对集合没有任何影响. B.一旦实例化不可改变自身大小,这是数组的特性.集合的容量是自身扩容的. C.ArrayList可以存 ...
- ueditor之ruby on rails 版
最近公司的项目开始要使用ueditor了,但是ueditor却没有提供rails的版本,因此需要自己去定制化ueditor来满足项目的需求.不多说了,先简要说明下使用方法: ueditor目录下: 注 ...
- mssql 获取表结构信息
SELECT (case when a.colorder=1 then d.name else null end) 表名, a.colorder 字段序号,a.name 字段名, (case when ...
- WPF扩展标记
标记扩展和 WPF XAML,标记扩展是 XAML 语言以及 XAML 服务的 .NET 实现的常规功能 XAML 处理器和标记扩展 XAML 分析器可将特性值解释为可转换成基元的文本字符串,或可通过 ...
- 简单学C——第六天
指针 指针是c语言中很灵活的一个内容,当然,灵活的都是较难掌握的.不过,只要理解其实质,学习,运用指针还是一件很轻松的事情的. 首先理解,1.什么是指针? 在c语言中,指针也同Int ,doub ...