【狼】openGL 光照的学习

时间:2022-09-17 13:35:05

小狼学习原创,欢迎批评指正

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,那就是平面着色,没有渐变效果,都是一个颜色,

而这只有在定点颜色不同时才有区别,

【狼】openGL 光照的学习

作为光滑smooth模式,右图为flat平面模式

应用光滑处理模式时,多边形所有点的法向是由内插生成的,具有一定的连续性,因此每个点的颜色也相应内插,故呈现不同色。这种模式下,插值方法采用的是双线性插值法

【狼】openGL 光照的学习

通常算法为:先用多边形顶点的光强线性插值出当前扫描线与多边形边交点处的光强,然后再用交点的光强线插值处扫描线位于多边形内区段上每一象素处的光强值。

图中显示出一条扫描线与多边形相交,交线的端点是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)

这些设置的都是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这个光源

    ok,接下来就用以前的知识加上茶壶就可以了,加了光的壶就此完成

【狼】openGL 光照的学习的更多相关文章

  1. OpenGL光照3:光源

    本文是个人学习记录,学习建议看教程 https://learnopengl-cn.github.io/ 非常感谢原作者JoeyDeVries和多为中文翻译者提供的优质教程 的内容为插入注释,可以先跳过 ...

  2. OpenGL光照和颜色

    OpenGL光照和颜色 转自:http://www.cnblogs.com/kekec/archive/2011/08/16/2140789.html OpenGL场景中模型颜色的产生,大致为如下的流 ...

  3. OpenGL光照测试

    OpenGL光照测试 花了大概半个月,研究了OpenGL的光照.请注意是固定管线渲染的光照,如果使用着色器的高手们请飘过.这个程序是通过光照对模型的照射,来研究OpenGL光照的性质.以后可以通过这个 ...

  4. 浅析OpenGL光照

    浅析OpenGL光照 之前从来都没有涉及光照的内容,心想只要能通过常规的方法渲染出几何体甚至是模型就可以了,然而没有光照的日子注定是苦涩的,因为仅凭几何体和模型的颜色无法达到真是渲染的效果,在实际中有 ...

  5. OpenGL光照设置

    一.设置光源 (1)光源的种类 环境光 环境光是一种无处不在的光.环境光源放出的光线被认为来自任何方向.因此,当你仅为场景指定环境光时,所有的物体无论法向量如何,都将表现为同样的明暗程度. 点光源 由 ...

  6. OpenGL光照2:材质和光照贴图

    本文是个人学习记录,学习建议看教程 https://learnopengl-cn.github.io/ 非常感谢原作者JoeyDeVries和多为中文翻译者提供的优质教程 的内容为插入注释,可以先跳过 ...

  7. OpenGL光照1:颜色和基础光照

    本文是个人学习记录,学习建议看教程 https://learnopengl-cn.github.io/ 非常感谢原作者JoeyDeVries和多为中文翻译者提供的优质教程 的内容为插入注释,可以先跳过 ...

  8. Unity预计算光照的学习&lpar;速度优化&comma;LightProb&comma;LPPV&rpar;

    1.前言 写这篇文章一方面是因为unity的微博最近出了关于预计算光照相关的翻译文章,另一方面一些美术朋友一直在抱怨烘培速度慢 所以抱着好奇的心态来学习一下unity5的PRGI预计算实时光照 2.基 ...

  9. 关于OpenGL和DX学习的取舍

    大家多知道左右就肯定要与显卡打交道.两大图形图像IPA.OpenGL(图形),DX(图形,声音,键盘控制,网络) OpenGL的兴起可能取决于苹果公司的适用,吸引看大部分开发者适用,它有跨平台的有点. ...

随机推荐

  1. 怎样在Windows资源管理器中添加右键菜单以及修改右键菜单顺序

    有时,我们需要在Windows资源管理器的右键菜单中添加一些项,以方便使用某些功能或程序. 比如我的电脑上有一个免安装版的Notepad++,我想在所有文件的右键菜单中添加一项用Notepad++打开 ...

  2. 1&period;ssh访问限制

    1.要求:限制my133.t.org(172.168.1.0/24)这个攻击域的主机访. 2.操作:vim /etc/host.deny 忘记可^tab ,在最末尾添加行:sshd:  172.168 ...

  3. 粘帖屏幕截图到web页面插件 screenshot-paste

    在很多场合下,我们可能有这样的需求:提供个屏幕截图上传到系统,作为一个凭证.传统的操作方式是:屏幕截图,保存文件到本地,在web页面上选择本地文件并上传,这里至少需要三步.有没有可能直接将截图粘帖到w ...

  4. Mysql日期函数,时间函数使用的总结

    一.MySQL 获得当前日期时间 函数 1.1 获得当前日期+时间(date + time)函数:now() mysql> select now();+--------------------- ...

  5. zoj2729 Sum Up&lpar;模拟&rpar;

    Sum Up Time Limit: 2 Seconds      Memory Limit: 65536 KB Vivid has stored a piece of private informa ...

  6. 使用zabbix监控mysql的三种方式

    使用zabbix监控mysql的三种方式 1.只是安装agent 2.启用模板监控 3.启用自定义脚本的模板监控 zabbix中默认有mysql的监控模板.默认已经在zabbix2.2及以上的版本中. ...

  7. frames&period;contentWindow&period;document InvalidCastException 转换错误异常。

    http://bbs.csdn.net/topics/210027068   和 https://bytes.com/topic/c-sharp/answers/248557-threading-pr ...

  8. &lbrack; Java面试题 &rsqb; 集合篇

    1.ArrayList和Vector的区别 这两个类都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的 ...

  9. 海马玩模拟器——搭建React Native环境

    Visual Studio Emulator for Android 模拟器国内这网络环境不太用,所以使用海马玩模拟器,给大家推荐一下! 下面开始配置环境: 1)下载1.8+JDK,配置JDK环境参考 ...

  10. github使用方法

    1:fork别人的项目后,更新别人最新的提交 https://blog.csdn.net/qq1332479771/article/details/56087333 2:在idea中push工程    ...