OpenGL可以设置至少8种光源,它们的标号为GL_LIGHT0,GL_LIGHT1,GL_LIGHT2……。在这里我们使用了两种光源,一种是环境光,另一种是聚光灯。

在设置光照时,我们需要考虑这样三种光:环境反射光、镜面反射光、漫反射光。在Phong光照模型中,就是通过这三种分量的取值来模拟真实光照的。其中,环境反射光是光源多次反射后的光,可以理解为背景光,镜面反射和漫反射反映了物体表面的粗糙/光滑程度,两者的和是一定的。

在OpenGL中,如果我们想要使用光源,需要输入以下语句开启光照模式:

glEnable( GL_LIGHTING );  // 开启光照模式

对于一个光源,我们首先需要确定它的位置,这个光源可以是点光源,也可以是平行光源,我们写如下函数,如果是点光源,第四个参数为1,前三个参数代表光源位置;如果是平行光源,第四个参数是0,前三个参数表示方向。其中light_pos是一个数组。

在本次试验中,我们采用的是点光源。

glLightfv(GL_LIGHT0,GL_POSITION, light_pos);//设置第0号光源的光照位置

同时,设置漫反射、镜面反射、环境反射的颜色参数:

glLightfv(GL_LIGHT0,GL_SPECULAR, color);//设置镜面反射光照

glLightfv(GL_LIGHT0,GL_DIFFUSE, color); //设置漫射光成分

glLightfv(GL_LIGHT0,GL_AMBIENT, color);  //设置第0号光源多次反射后的光照颜色(环境光颜色)

在本次实验中,我们把环境光设为指定的颜色(在这里,我们选择了白色和绿色),而镜面反射光和漫反射光都设置为白色。

使用如下函数,开启灯光:

glEnable(GL_LIGHT0);//开启第0号光源

 

      聚光灯我们另外使用GL_LIGHT1光源。除了基本的三种光,还包含了其他属性,分别是裁剪角度、光源方向和聚集度:

glLightf(GL_LIGHT1,GL_SPOT_CUTOFF, spotangle);            //裁减角度

glLightfv(GL_LIGHT1,GL_SPOT_DIRECTION, lightDir);         //光源方向

glLightf(GL_LIGHT1,GL_SPOT_EXPONENT, 2.);                   //聚集度

对于聚光灯,我们设置和环境光一样。

在设置完了基本的光照后,我们来关注物体的材质,这里的材质并不是指我们理解意义上的材质,而是物体在不同光照下反射的颜色。我们知道,物体的显示效果和光照有着很大的关联,比如在黑暗中,我们看到的物体就是黑色的。我们所看到的物体颜色是由灯光以及物体反射颜色共同决定的。

glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR, color);

glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE, color);

glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT, color);

其中,第一个参数代表了操作对象的正面还是反面,参数包括GL_FRONT、GL_BACK、GL_FRONT_AND_BACK;第二个参数代表了材质的颜色是在什么光照下表现的;第三个参数是光照下材质的颜色。

对于茶壶,我们设置镜面指数为50,镜面反射为0.6f, 0.6f, 0.6f,漫反射为0.85f, 0.65f, 0.2f。

对于桌面和腿,我们把镜面反射和漫反射的颜色设为相同的指定颜色。

实验数据记录和处理 

(数据设置仅供参考)

目前桌子腿的效果不太真实,但是实验要求中也只要求了一种颜色,所以没有做过多优化。如果有好的数据设置,也可以分享一下。

环境反射

漫反射

镜面反射

白色环境光/聚光灯

(1,1,1)

(1,1,1)

(1,1,1)

绿色环境光/聚光灯

(0,1,0)

(1,1,1)

(1,1,1)

茶壶

/

(0.6, 0.6, 0.6)

(0.85, 0.65, 0.2)

桌面

/

(1,0,0)

(1,0,0)

桌脚1

/

(0,1,0)

(0,1,0)

桌脚2

/

(1,1,0)

(1,1,0)

桌脚3

/

(0,1,1)

(0,1,1)

桌脚4

(0,0,1)

(0,0,1)

// glutEx1.cpp : 定义控制台应用程序的入口点。
//#include <stdlib.h>
#include "glut.h"
#include <stdio.h>float fTranslate;
float fRotate;
float fScale     = 1.0f;
float color_b = 1.0f;bool bPersp = false;
bool bAnim = false;
bool bWire = false;
bool isWhite = true;int wHeight = 0;
int wWidth = 0;GLfloat color[] = { 1.0, 1.0, 1.0, 1.0 }; // 定义颜色  float eye[] = { 0, 0, 8 };
float center[] = { 0, 0, 0 };GLfloat spotangle = 5.0f; //角度//环境光位置
GLfloat light_x = 0.0f;
GLfloat light_y = 0.0f;
GLfloat light_z = 0.0f;//聚光灯方向
GLfloat dir_x = 0.0f;
GLfloat dir_y = 0.0f;
GLfloat dir_z = 0.0f;void Draw_Leg();void Draw_Triangle() // This function draws a triangle with RGB colors
{GLfloat mat_specular[] = { 0.6f, 0.6f, 0.6f, 1.0f };GLfloat mat_diffuse0[] = { 0.85f, 0.65f, 0.2f, 1.0f };GLfloat mat_diffuse1[] = { 1.0f, 0.0f, 0.0f };GLfloat mat_diffuse2[] = { 0.0f, 1.0f, 0.0f };GLfloat mat_diffuse3[] = { 1.0f, 1.0f, 0.0f };GLfloat mat_diffuse4[] = { 0.0f, 1.0f, 1.0f };GLfloat mat_diffuse5[] = { 0.0f, 0.0f, 1.0f };//画茶壶glPushMatrix();glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);// 设置多边形正面的镜面反射属性glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 50);// 指定镜面指数glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse0); //设置多边形正面漫反射属性glTranslatef(0, 0, 4+1);glRotatef(90, 1, 0, 0);glutSolidTeapot(1);glPopMatrix();//画桌面 glPushMatrix();glMaterialfv(GL_FRONT, GL_SPECULAR, mat_diffuse1);// 设置多边形正面的镜面反射属性glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse1);//设置多边形正面漫反射属性glTranslatef(0, 0, 3.5);glScalef(5, 4, 1);glutSolidCube(1.0);glPopMatrix();//画四条腿  glPushMatrix();glMaterialfv(GL_FRONT, GL_SPECULAR, mat_diffuse2);// 设置多边形正面的镜面反射属性glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse2);//设置多边形正面漫反射属性glTranslatef(1.5, 1, 1.5);Draw_Leg();glPopMatrix();glPushMatrix();glMaterialfv(GL_FRONT, GL_SPECULAR, mat_diffuse3);// 设置多边形正面的镜面反射属性glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse3);//设置多边形正面漫反射属性glTranslatef(-1.5, 1, 1.5);Draw_Leg();glPopMatrix();glPushMatrix();glMaterialfv(GL_FRONT, GL_SPECULAR, mat_diffuse4);// 设置多边形正面的镜面反射属性glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse4);//设置多边形正面漫反射属性glTranslatef(1.5, -1, 1.5);Draw_Leg();glPopMatrix();glPushMatrix();glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_diffuse5);// 设置多边形正面的镜面反射属性glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse5);//设置多边形正面漫反射属性glTranslatef(-1.5, -1, 1.5);Draw_Leg();glPopMatrix();}//绘制腿部
void Draw_Leg()
{glScalef(1, 1, 3);glutSolidCube(1.0);
}void updateView(int width, int height)
{glViewport(0,0,width,height);//设置视窗大小glMatrixMode(GL_PROJECTION);//设置矩阵模式为投影 glLoadIdentity(); //初始化矩阵为单位矩阵    float whRatio = (GLfloat)width/(GLfloat)height;  //设置显示比例  if (bPersp) {gluPerspective(45.0f, whRatio,0.1f,100.0f); //透视投影  //glFrustum(-3, 3, -3, 3, 3,100);} else {glOrtho(-3 ,3, -3, 3,-100,100);  //正投影}glMatrixMode(GL_MODELVIEW);     //设置矩阵模式为模型
}void reshape(int width, int height)
{if (height==0)       //如果高度为0{height=1; //让高度为1(避免出现分母为0的现象)}wHeight = height; wWidth = width;updateView(wHeight, wWidth); //更新视角
}void idle()
{glutPostRedisplay(); //调用当前绘制函数
}void key(unsigned char k, int x, int y)
{switch (k){case 27:case 'q': {exit(0); break; }case 'p': {bPersp = !bPersp; break; }case ' ': {bAnim = !bAnim; break; }case 'o': {bWire = !bWire; break; }case 'a': { //整体左移eye[0] += 0.2f;center[0] += 0.2f;break;}case 'd': {//整体右移eye[0] -= 0.2f;center[0] -= 0.2f;break;}case 'w': {//整体上移eye[1] -= 0.2f;center[1] -= 0.2f;break;}case 's': {//整体下移eye[1] += 0.2f;center[1] += 0.2f;break;}case 'z': {//整体前移eye[2] -= 0.2f;center[2] -= 0.2f;break;}case 'c': {//整体后移eye[2] += 0.2f;center[2] += 0.2f;break;}case 'j': {//环境光左移light_x = light_x - 0.2f;break;}case 'l': {//环境光右移light_x = light_x + 0.2f;break;}case 'i': {//环境光上移light_y = light_y + 0.2f;break;}case 'k': {//环境光下移light_y = light_y - 0.2f;break;}case 'n': {//环境光前移light_z = light_z + 0.2f;break;}case 'm': {//环境光后移light_z = light_z - 0.2f;break;}case 'r': {//环境光颜色切换isWhite = !isWhite;break;}case 'f': {//聚光灯左移dir_x = dir_x - 0.05f;break;}case 'h': {//聚光灯右移dir_x = dir_x + 0.05f;break;}case 't':{//聚光灯上移dir_y = dir_y - 0.05f;break;}case 'g':{//聚光灯下移dir_y = dir_y + 0.05f;break;}case 'v': {//聚光灯后移dir_z = dir_z - 0.05f;break;}case 'b': {//聚光灯前移dir_z = dir_z + 0.05f;break;}case 'x': { //聚光灯角度变大if (spotangle <= 89.0f) {spotangle = spotangle + 0.2f;}break;}case 'y': { //聚光灯角度变小if (spotangle >= 1.0f) {spotangle = spotangle - 0.2f;}break;}}updateView(wHeight, wWidth);
}void redraw()
{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  //清除颜色缓存和深度缓存  glLoadIdentity(); //初始化矩阵为单位矩阵  gluLookAt(eye[0], eye[1], eye[2],center[0], center[1], center[2],0, 1, 0);             // 场景(0,0,0)的视点中心 (0,5,50),Y轴向上if (bWire) {glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//设置多边形绘制模式:正反面,线型}else {glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);//设置多边形绘制模式:正反面,填充    }glEnable(GL_DEPTH_TEST);//开启深度测试  glEnable(GL_LIGHTING);  //开启光照模式  //GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };GLfloat light_pos[] = {5.0 + light_x ,5.0 + light_y,5.0 + light_z,1}; //定义环境光位置  GLfloat light_pos1[] = { 0.0f, 5.0f, 0.0f, 1.0f }; //定义聚光灯位置GLfloat lightDir[] = { 0.0f + dir_x ,-1.0f + dir_y ,0.0f + dir_z }; //角度GLfloat white[] = { 1.0f, 1.0f, 1.0f, 1.0f }; //定义白色if (isWhite) {color[0] = 1.0f, color[1] = 1.0f, color[2] = 1.0f, color[3] = 1.0f;}else {color[0] = 0.0f, color[1] = 1.0f, color[2] = 0.0f, color[3] = 1.0f;}glLightfv(GL_LIGHT0, GL_POSITION, light_pos); //设置第0号光源的光照位置  glLightfv(GL_LIGHT0, GL_SPECULAR, white); //设置镜面反射光照颜色glLightfv(GL_LIGHT0, GL_DIFFUSE, white);                     //设置漫射光成分glLightfv(GL_LIGHT0, GL_AMBIENT, color);   //设置第0号光源多次反射后的光照颜色(环境光颜色)glEnable(GL_LIGHT0); //开启第0号光源 glLightfv(GL_LIGHT1, GL_AMBIENT, color);             //设置环境光成分glLightfv(GL_LIGHT1, GL_SPECULAR, white);                    //设置镜面光成分glLightfv(GL_LIGHT1, GL_DIFFUSE, white);                     //设置漫射光成分glLightfv(GL_LIGHT1, GL_POSITION, light_pos1);glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, spotangle);             //裁减角度glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, lightDir);          //光源方向glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 2.);                    //聚集度glEnable(GL_LIGHT1);glRotatef(fRotate, 0, 1.0f, 0);  //旋转glRotatef(-90, 1, 0, 0); //旋转glScalef(0.2, 0.2, 0.2);  //缩放Draw_Triangle(); //绘制场景if (bAnim) fRotate    += 0.5f; //旋转因子改变glutSwapBuffers(); //交换缓冲区
}int main (int argc,  char *argv[])
{glutInit(&argc, argv);//对glut的初始化   glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);//初始化显示模式:RGB颜色模型,深度测试,双缓冲     glutInitWindowSize(480,480);//设置窗口大小   int windowHandle = glutCreateWindow("Simple GLUT App");//设置窗口标题 glutDisplayFunc(redraw); //注册绘制回调函数   glutReshapeFunc(reshape);   //注册重绘回调函数   glutKeyboardFunc(key); //注册按键回调函数 glutIdleFunc(idle);//注册全局回调函数:空闲时调用 glutMainLoop();  // glut事件处理循环 return 0;
}

[OpenGL] 茶壶与光照相关推荐

  1. OpenGL ES 3. 光照-散射光

    大家好,接下来将为大家介绍OpenGL ES 3. 光照-散射光. OpenGL ES 3.0 中采用的光照模型相对现实世界进行了很大的简化,将光照分成了 3 种组成元素(也可以称为 3 个通道),包 ...

  2. OpenGL材质和光照(转)part1

    真实感图形绘制是计算机图形学的一个重要组成部分,它综合利用数学.物理学.计算机科学和其它科学知识在计算机图形设备上生成象彩色照片那样的具有真实感的图形.一般说来,用计算机在图形设备上生成真实感图形必须 ...

  3. OpenGL材质和光照(转)part2

    10.4.3 材质RGB值和光源RGB值的关系 材质的颜色与光源的颜色有些不同.对于光源,R.G.B值等于R.G.B对其最大强度的百分比.若光源颜色的R.G.B值都是1.0,则是最强的白光:若值变为0 ...

  4. OpenGL学习笔记——光照(一)

    文章目录 一.颜色 二.光照基础 2.1环境光照 2.2漫反射光照 2.3镜面光照 如何才能更为真实的表现出生活中的环境呢?其实现实生活它已经给了我们答案,就是光照.了解光与颜色构造之间的关系,我们才 ...

  5. OpenGL学习之光照中的材质

    本文参考LearnOpenGL CN 在现实世界中,每个物体会对光产生不同的反应.比如:钢看起来通常会比陶瓷瓶更闪闪发光,木头箱子也不会像钢制箱子那样对光产生很强的反射.每个梧桐对镜面高光也有不同的反 ...

  6. 【OpenGL学习】光照贴图

    光照贴图 上节中我们给物体添加了材质,使得物体能够对光照做出不同的反应,但是有个问题就是,使用该种材质的物体,只能够表现出我们所定义的一种性质,而实际生活中我们的一个物体往往具有多种材质,因此本节中我 ...

  7. OpenGl L24高级光照

    一.Blinn-Phong模型 冯式光照(Phong模型)对真实光照有一定的近似,但镜面反射有一些问题,反光度比较低的时候,导致了大片的高光区域,而高光边缘却出现了一道明显的断层. 出现断层的原因是因 ...

  8. 基于C++OpenGL实现的小桌茶壶纹理图形绘制

    资源下载地址:https://download.csdn.net/download/sheziqiong/85628707 资源下载地址:https://download.csdn.net/downl ...

  9. OpenGL笔记之矩阵变换(Matrix Transformation)

    本文是学习OpenGL过程中的一篇笔记.在学习过程中,主要参照了大名鼎鼎的 <OpenGL Programming Guide>(中文名<OpenGL编程指南>,有些人还称之为 ...

最新文章

  1. 元旦快乐!今天我居然登上了数据派头条!
  2. 公司CRM的三个阶段
  3. 如何保留5个有效数字输出c不4舍5入_10 个C语言课设小项目拿走不谢~
  4. Cloudera Manager 5 和 CDH5 本地(离线)安装指南(Hadoop集群搭建)
  5. Python学习笔记-DNS域名轮循业务监控
  6. 成功解决AttributeError: ‘JointGrid‘ object has no attribute ‘annotate‘
  7. 输变电设备物联网节点设备无线组网协议_U-Link 物联网(工业互联网)服务平台
  8. jquery基本操作笔记
  9. std::thread详解
  10. C++之第一个程序Hello World,使用IO库输出Hello World
  11. Memory barrier(内存屏障)
  12. python 管道游戏_用python写游戏之 Flappy Bird
  13. 汇编语言实验八核心考点
  14. 强烈推荐!程序员必备的15 款工具(含阿里内部工具)
  15. 开发客户的渠道+方法
  16. 通过Dialer拨号盘输暗码启动某个apk
  17. 科大讯飞AI学习机T10测评:一台平板,就能实现减负增效?
  18. android平板开发板,基于ARM Cortex A9开发板平板电脑实战项目
  19. 抖音云控PHP 18.7框架图 autojs脚本
  20. PMP-27项目范围管理-创建工作分解结构

热门文章

  1. openssh默认版本升级至8.9 脚本
  2. excel导出图片方格居中
  3. 记录:jeecg boot 路由带多种参数的配置
  4. 晚清《江南制造局记》一书中记载的英度单位究竟是什么
  5. 使用 html5-qrcode 扫码
  6. JAVA基础-U7 面向对象编程(基础部分)-可变参数
  7. linux pythonide_用于Linux程序员的8个最佳Python IDE
  8. oneinStack配置无域名网站
  9. 我真的服了自己了,原来用python调整视频数据速率(码率)如此简单
  10. GVoice错误码8193没声音