您的位置:首页 > 运维架构

opengl消隐与光照

2016-12-10 15:16 134 查看
1.      设置材料的颜色

OpenGL的光照模型根据材料反射的红、绿和蓝光的比例来模拟它的颜色。和光一样,材料也具有不同的环境、散射和镜面颜色,它们决定了材料对红、绿和蓝光的反射率。材料的环境反射属性与每种入射光的环境光成分组合,散射反射属性与入射光的散射成分组合,镜面反射属性和入射光的镜面成分组合。环境和散射属性定义了材料的颜色,它们一般很相似。

              使用的函数是glMaterial*():

void glMaterial{if} (GLenumface,
GLenumpname,
GLfloatparam);

void glMaterial{if}v (GLenumface,
GLenumpname,
constGLfloat *params);

       face可以是GL_FRONT,GL_BACK或GL_FRONT_AND BACK,表示物体的哪些面应该接受光照。pname表示设置的特定材料属性。param提供了具体的属性值。

       我们设置桌面和四条桌腿的材料如下:

void Draw_Table()
// This function draws a triangle with RGB colors
{
    //定义变量
    GLfloat specular[] = { 0.6f,0.6f,0.6f,1.0f };
    GLfloat color1[] = { 0.85f,0.65f,0.2f,1.0f };//金黄色
    GLfloat color2[] = { 1.0f,0.0f,0.0f };
    GLfloat color3[] = { 0.0f,1.0f,0.0f };
    GLfloat color4[] = { 1.0f,1.0f,0.0f };
    GLfloat color5[] = { 0.0f,1.0f,1.0f };
    GLfloat color6[] = { 0.0f,0.0f,1.0f };
    //茶壶
    glPushMatrix();
    glMaterialfv(GL_FRONT,
GL_SPECULAR, specular);//设置镜面颜色
    glMateriali(GL_FRONT,
GL_SHININESS, 50);//设置镜面指数
    glMaterialfv(GL_FRONT,
GL_AMBIENT_AND_DIFFUSE, color1);//材料的环境和散射颜色
    glTranslatef(0, 0, 4+1);
    glRotatef(90, 1, 0, 0);
    glutSolidTeapot(1);
    glPopMatrix();
    //桌面
    glPushMatrix();
    glMaterialfv(GL_FRONT,
GL_SPECULAR, color2);//设置镜面颜色
    glMaterialfv(GL_FRONT,
GL_AMBIENT_AND_DIFFUSE, color2);//材料的环境和散射颜色
    glTranslatef(0, 0, 3.5);
    glScalef(5, 4, 1);
    glutSolidCube(1.0);
    glPopMatrix();
    //四条腿
    glPushMatrix();
    glMaterialfv(GL_FRONT,
GL_SPECULAR, color3);//设置镜面颜色
    glMaterialfv(GL_FRONT,
GL_AMBIENT_AND_DIFFUSE, color3);//材料的环境和散射颜色
    glTranslatef(1.5, 1, 1.5);
    Draw_Leg();
    glPopMatrix();
 
    glPushMatrix();
    glMaterialfv(GL_FRONT,
GL_SPECULAR, color4);//设置镜面颜色
    glMaterialfv(GL_FRONT,
GL_AMBIENT_AND_DIFFUSE, color4);//材料的环境和散射颜色
    glTranslatef(-1.5, 1, 1.5);
    Draw_Leg();
    glPopMatrix();
 
    glPushMatrix();
    glMaterialfv(GL_FRONT,
GL_SPECULAR, color5);//设置镜面颜色
    glMaterialfv(GL_FRONT,
GL_AMBIENT_AND_DIFFUSE, color5);//材料的环境和散射颜色
    glTranslatef(1.5, -1, 1.5);
    Draw_Leg();
    glPopMatrix();
 
    glPushMatrix();
    glMaterialfv(GL_FRONT,
GL_SPECULAR, color6);//设置镜面颜色
    glMaterialfv(GL_FRONT,
GL_AMBIENT_AND_DIFFUSE, color6);//材料的环境和散射颜色
    glTranslatef(-1.5, -1, 1.5);
    Draw_Leg();
    glPopMatrix();
}

 

2.      光源位置及颜色设置

首先使用定义全局变量来控制光源的颜色和位置:

bool light_flag =
false;//环境光颜色
GLfloat color[] = { 1.0, 1.0, 1.0, 1.0 };
// 定义颜色  

//环境光位置
GLfloat light_x = 0.0f;
GLfloat light_y = 0.0f;
GLfloat light_z = 0.0f;
              在redraw函数中对光源进行设置:

GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 };//定义环境光颜色:白色
GLfloat light_pos[] = { 5.0 + light_x,5.0 + light_y,5.0 + light_z,1 };

//是否改变光照颜色
    if (light_flag)
        color[1] = color[3] = 0.0f;
    else
        color[1] = color[3] = 1.0f;

glLightfv(GL_LIGHT0,
GL_POSITION, light_pos);//0号光源的位置
    glLightfv(GL_LIGHT0,
GL_SMOOTH, white);//设置环境光颜色
    glLightfv(GL_LIGHT0,
GL_DIFFUSE, white);                    
//设置漫射光成分 

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

 

3.      聚光灯

可以对位置性光源的形状加以限制,使它的发射范围限于一个椎体之内,就像一个聚光灯一样。为了创建聚光灯,需要确定光锥的发射范围。为了指定光锥轴和光锥边缘之间的角度,可以使用GL_SPOT_CUTOFF参数。光锥的最大角度是这个值的两倍。

定义全局变量控制聚光灯方向和照射角度:

//聚光灯
GLfloat spot_x = 0.0f;
GLfloat spot_y = 0.0f;
GLfloat spot_z = 0.0f;
GLfloat Angle = 5.0f;//聚光灯角度
              在redraw中设置聚光灯位置、颜色以及角度等等:

glLightfv(GL_LIGHT1,
GL_AMBIENT, color);   
//设置环境光成分
    glLightfv(GL_LIGHT1,
GL_SPECULAR, white);                
//设置镜面光成分
    glLightfv(GL_LIGHT1,
GL_DIFFUSE, white);                    
//设置漫射光成分
 
    glLightfv(GL_LIGHT1,
GL_POSITION, spot_pos);
    glLightf(GL_LIGHT1,
GL_SPOT_CUTOFF, Angle);           
//裁减角度
    glLightfv(GL_LIGHT1,
GL_SPOT_DIRECTION, spot_angle);         
//光源方向
    glLightf(GL_LIGHT1,
GL_SPOT_EXPONENT, 2.);                   
//聚集度
    glEnable(GL_LIGHT1);//开启1号光源

实验结果与分析:







main.cpp
// glutEx1.cpp : 定义控制台应用程序的入口点。
//

#include <stdlib.h>
#include "glut.h"

float fTranslate;
float fRotate;
float fScale = 1.0f; // set inital scale value to 1.0f

bool bPersp = false;
bool bAnim = false;
bool bWire = false;
bool light_flag = false;//环境光颜色
GLfloat color[] = { 1.0, 1.0, 1.0, 1.0 }; // 定义颜色
int wHeight = 0;
int wWidth = 0;
//环境光
GLfloat light_x = 0.0f;
GLfloat light_y = 0.0f;
GLfloat light_z = 0.0f;
//聚光灯
GLfloat spot_x = 0.0f;
GLfloat spot_y = 0.0f;
GLfloat spot_z = 0.0f;
GLfloat Angle = 5.0f;//聚光灯角度
void Draw_Leg();

void Draw_Table() // This function draws a triangle with RGB colors
{
//定义变量
GLfloat specular[] = { 0.6f,0.6f,0.6f,1.0f };
GLfloat color1[] = { 0.85f,0.65f,0.2f,1.0f };//金黄色
GLfloat color2[] = { 1.0f,0.0f,0.0f };
GLfloat color3[] = { 0.0f,1.0f,0.0f };
GLfloat color4[] = { 1.0f,1.0f,0.0f };
GLfloat color5[] = { 0.0f,1.0f,1.0f };
GLfloat color6[] = { 0.0f,0.0f,1.0f };
//茶壶
glPushMatrix();
glMaterialfv(GL_FRONT, GL_SPECULAR, specular);//设置镜面颜色
glMateriali(GL_FRONT, GL_SHININESS, 50);//设置镜面指数
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color1);//材料的环境和散射颜色
glTranslatef(0, 0, 4+1);
glRotatef(90, 1, 0, 0);
glutSolidTeapot(1);
glPopMatrix();
//桌面
glPushMatrix();
glMaterialfv(GL_FRONT, GL_SPECULAR, color2);//设置镜面颜色
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color2);//材料的环境和散射颜色
glTranslatef(0, 0, 3.5);
glScalef(5, 4, 1);
glutSolidCube(1.0);
glPopMatrix();
//四条腿
glPushMatrix();
glMaterialfv(GL_FRONT, GL_SPECULAR, color3);//设置镜面颜色
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color3);//材料的环境和散射颜色
glTranslatef(1.5, 1, 1.5);
Draw_Leg();
glPopMatrix();

glPushMatrix();
glMaterialfv(GL_FRONT, GL_SPECULAR, color4);//设置镜面颜色
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color4);//材料的环境和散射颜色
glTranslatef(-1.5, 1, 1.5);
Draw_Leg();
glPopMatrix();

glPushMatrix();
glMaterialfv(GL_FRONT, GL_SPECULAR, color5);//设置镜面颜色
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color5);//材料的环境和散射颜色
glTranslatef(1.5, -1, 1.5);
Draw_Leg();
glPopMatrix();

glPushMatrix();
glMaterialfv(GL_FRONT, GL_SPECULAR, color6);//设置镜面颜色
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color6);//材料的环境和散射颜色
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); // Reset The Current Viewport

glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix

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); // Select The Modelview Matrix
}

void reshape(int width, int height)
{
if (height==0) // Prevent A Divide By Zero By
{
height=1; // Making Height Equal One
}

wHeight = height;
wWidth = width;

updateView(wHeight, wWidth);
}

void idle()
{
glutPostRedisplay();
}

float eye[] = {0, 0, 8};
float center[] = {0, 0, 0};

void key(unsigned char k, int x, int y)
{
switch(k)
{
case 27://ESC
case 'q': {exit(0); break; }//quit
case 'p': {bPersp = !bPersp; break; }//显示模式

case ' ': {bAnim = !bAnim; break;}//旋转
case 'o': {bWire = !bWire; break;}//线框

case 'd': {//右
eye[0] -= 0.2f;
center[0] -= 0.2f;
break;
}
case 'a': {//左
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 += 0.2f;
break;
}
case 'l': {//环境光右
light_x -= 0.2f;
break;
}
case 'i': {//环境光上
light_y += 0.2f;
break;
}
case 'k': {//环境光下
light_y -= 0.2f;
break;
}
case 'n': {//环境光前
light_z += 0.2f;
break;
}
case ',': {//环境光后
light_z -= 0.2f;
break;
}
case 'u': {//环境光颜色切换
light_flag = !light_flag;
break;
}
case 'f': {//聚光灯左移
spot_x -= 0.05f;
break;
}
case 'h': {
spot_x += 0.05f;
break;
}
case 't': {
spot_y -= 0.05f;
break;
}
case 'g': {
spot_y += 0.05f;
break;
}
case 'v': {//聚光灯前移
spot_z += 0.05f;
break;
}
case 'b': {//聚光灯后移
spot_z -= 0.05f;
break;
}
case 'r': {//角度变大
if (Angle <= 89.0f)
Angle += 0.2f;
break;
}
case 'y': {
if (Angle >= 1.0f)
Angle -= 0.2f;
break;
}
}

updateView(wHeight, wWidth);
}

void redraw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity(); // Reset The Current Modelview Matrix

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 white[] = { 1.0, 1.0, 1.0, 1.0 };//定义环境光颜色:白色
GLfloat light_pos[] = { 5.0 + light_x,5.0 + light_y,5.0 + light_z,1 };
//定义聚光灯位置
GLfloat spot_pos[] = { 0.0f,5.0f,0.0f,1.0f };
//定义聚光灯照射方向
GLfloat spot_angle[] = { 0.0f + spot_x,-1.0f + spot_y,0.0f + spot_z };
//是否改变光照颜色
if (light_flag)
color[1] = color[3] = 0.0f;
else
color[1] = color[3] = 1.0f;

glLightfv(GL_LIGHT0, GL_POSITION, light_pos);//0号光源的位置
glLightfv(GL_LIGHT0, GL_SMOOTH, 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, spot_pos);
glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, Angle); //裁减角度
glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, spot_angle); //光源方向
glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 2.); //聚集度
glEnable(GL_LIGHT1);//开启1号光源

// glTranslatef(0.0f, 0.0f,-6.0f); // Place the triangle at Center
glRotatef(fRotate, 0, 1.0f, 0); // Rotate around Y axis
glRotatef(-90, 1, 0, 0);
glScalef(0.2, 0.2, 0.2);
Draw_Table(); // Draw triangle

if (bAnim) fRotate += 0.5f;
glutSwapBuffers();
}

int main (int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(480,480);
int windowHandle = glutCreateWindow("Simple GLUT App");

glutDisplayFunc(redraw);
glutReshapeFunc(reshape);
glutKeyboardFunc(key);
glutIdleFunc(idle);

glutMainLoop();
return 0;
}

如有错误,请批评指正(*/ω╲*)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  opengl