glEnable(GL_LIGHTING);
這個函數調用告訴OpenGL使用材料屬性和光照參數去決定每個頂點的顏色值。如果沒有開啟這個函數,則看到的物體是昏暗的。開啟光照後會根據你的材料屬性和光照參數計算頂點的顏色值。下圖對比未開啟光照和開啟光照的效果。
(未開啟光照)
(開啟光照)
OpenGL提供了一種全局的環境光。這種光是一種向所有方向均勻發射的光源。它可以照明沒有被光源直接照射的物體的背面。
在OpenGL中通過glLightModel這個函數來設置全局環境光。第一個參數是GL_LIGHT_MODEL_AMBIETN。
//明亮的白光
GLfloat ambientLight[] = {1.0f, 1.0f, 1.0f, 1.0f};
//開啟光照
glEnable(GL_LIGHTING);
//設置全局環境光為白光
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);
全局環境光照的默認RGBA值是(0.2, 0.2, 0.2, 1.0),這個值是比較昏暗的。
設置好了全局環境光源後,我們需要為設置材料屬性。有兩種設置材料屬性的方式,第一種是在指定多邊形之前調用glMaterial函數。例子:
//灰色的材料屬性glMaterialfv的第一個參數是指定正面, 反面, 正面和反面。第二個參數是告訴Opengl設置哪個屬性。GL_AMBIENT_AND_DIFFUSE指定環境光反射屬性和漫反射屬性為同一個值。最後一個參數是一個RGBA值的數組。 在絕大多數情況下,環境光和漫反射光的成分是相同的,除非需要特殊的鏡面光的效果。在多邊形頂點之前需要調用glMaterial函數,並設置一個包含各種顏色成分的數組。這個操作還是相當繁瑣的。下面介紹一種更簡單的方式 第二種方法顏色追蹤較為簡單。使用顏色追蹤,可以通過glColor來設置材料屬性。第一步啟用顏色追蹤 glEnable(GL_COLOR_MATERIAL); 然後通過glColorMaterial指定需要顏色追蹤的材料屬性。下面的例子的設置 追蹤多邊形正面的環境光和漫反射的材料屬性。 glColorMaterial(GL_FRONT, GL_AMBIENT_ANDDIFFUSE); 下面的例子使用顏色追蹤的方式重寫上面的例子:
GLfloat gray[] = {0.75f, 0.75f, 0.75f, 1.0f};
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, gray);
glBegin(GL_TRIANGLES);
glVertex3f(-15.0f, 0.0f, 30.0f);
glVertex3f(0.0f, 15.0f, 30.0f);
glVertex3f(0.0f, 0.0f, -56.0f);
glEnd();
//開啟顏色追蹤設置環境的例子:
glEnable(GL_COLOR_MATERIAL);
//設置顏色追蹤的材料屬性以及多邊形的面
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
//設置顏色
glColor3f(0.75f, 0.75f, 0.75f);
glBegin(GL_TRIANGLES);
glVertex3f(-15.0f, 0.0f, 30.0f);
glVertex3f(0.0f, 15.0f, 30.0f);
glVertex3f(0.0f, 0.0f, -56.0f);
glEnd();
void SetupRC()開啟明亮的環境光效果: 把環境光調成原來的一半的效果: GLfloat ambientLight[] = {0.5f, 0.5f, 0.5f, 1.0f};
{
GLfloat ambientLight[] = {1.0f, 1.0f, 1.0f, 1.0f};
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
//設置光照模型
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);
//設置材料追蹤
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glClearColor(0.0f, 0.0f, 05.f,1.0f);
}
完整的例子:
#include "gltools.h" // System and OpenGL Stuff
// Rotation amounts
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;
// Called to draw scene
void RenderScene(void)
{
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Save matrix state and do the rotation
glPushMatrix();
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_TRIANGLES);
//機頭
glVertex3f(-15.0f, 0.0f, 30.0f);
glVertex3f(15.0f, 0.0f, 30.0f);
glVertex3f(0.0f, 0.0f, 60.0f);
glColor3f(0.0f, 0.0f, 0.0f);
glVertex3f(-15.0f, 0.0f, 30.0f);
glVertex3f(0.0f, 0.0f, 60.0f);
glVertex3f(0.0f, 15.0f, 30.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 60.0f);
glVertex3f(15.0f, 0.0f, 30.0f);
glVertex3f(0.0f, 15.0f, 30.0f);
//機身
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(-15.0f, 0.0f, 30.0f);
glVertex3f(0.0f, 15.0f, 30.0f);
glVertex3f(0.0f, 0.0f, -53.0f);
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(0.0f, 15.0f, 30.0f);
glVertex3f(15.0f, 0.0f, 30.0f);
glVertex3f(0.0f, 0.0f, -53.0f);
glColor3f(0.5f, 0.5f, 0.3f);
glVertex3f(15.0f, 0.0f, 30.0f);
glVertex3f(-15.0f, 0.0f, 30.0f);
glVertex3f(0.0f, 0.0f, -53.0f);
//機尾巴
glColor3f(0.3f, 1.0f, 0.2f);
glVertex3f(0.0f, 0.0f, -53.0f);
glVertex3f(0.0f, 0.0f, -70.0f);
glVertex3f(0.0f, 15.0f, -70.0f);
glColor3f(0.7f, 0.5f, 0.3f);
glVertex3f(-15.0f, 0.0f, -70.0f);
glVertex3f(0.0f, 0.0f, -53.0f);
glVertex3f(0.0f, 0.0f, -70.0f);
glColor3f(0.2f, 0.2f, 0.8f);
glVertex3f(15.0f, 0.0f, -70.0f);
glVertex3f(0.0f, 0.0f, -70.0f);
glVertex3f(0.0f, 0.0f, -53.0f);
//由於背面被消除,背面再畫一次
glColor3f(0.3f, 1.0f, 0.2f);
glVertex3f(0.0f, 0.0f, -70.0f);
glVertex3f(0.0f, 0.0f, -53.0f);
glVertex3f(0.0f, 15.0f, -70.0f);
glColor3f(0.7f, 0.5f, 0.3f);
glVertex3f(0.0f, 0.0f, -53.0f);
glVertex3f(-15.0f, 0.0f, -70.0f);
glVertex3f(0.0f, 0.0f, -70.0f);
glColor3f(0.2f, 0.2f, 0.8f);
glVertex3f(0.0f, 0.0f, -70.0f);
glVertex3f(15.0f, 0.0f, -70.0f);
glVertex3f(0.0f, 0.0f, -53.0f);
// 左翼
glColor3ub(128,128,128);
glVertex3f(0.0f,2.0f,27.0f);
glVertex3f(-60.0f, 2.0f, -8.0f);
glVertex3f(60.0f, 2.0f, -8.0f);
glColor3ub(64,64,64);
glVertex3f(60.0f, 2.0f, -8.0f);
glVertex3f(0.0f, 7.0f, -8.0f);
glVertex3f(0.0f,2.0f,27.0f);
glColor3ub(192,192,192);
glVertex3f(60.0f, 2.0f, -8.0f);
glVertex3f(-60.0f, 2.0f, -8.0f);
glVertex3f(0.0f,7.0f,-8.0f);
//右翼
glColor3ub(64,64,64);
glVertex3f(0.0f,2.0f,27.0f);
glVertex3f(0.0f, 7.0f, -8.0f);
glVertex3f(-60.0f, 2.0f, -8.0f);
glEnd();
glPopMatrix();
// Display the results
glutSwapBuffers();
}
// This function does any needed initialization on the rendering
// context.
void SetupRC()
{
GLfloat ambientLight[] = {0.5f, 0.5f, 0.5f, 1.0f};
glEnable(GL_DEPTH_TEST); // Hidden surface removal
glEnable(GL_CULL_FACE); // Do not calculate inside of jet
glFrontFace(GL_CCW); // Counter clock-wise polygons face out
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
// Nice light blue
glClearColor(0.0f, 0.0f, 05.f,1.0f);
}
void SpecialKeys(int key, int x, int y)
{
if(key == GLUT_KEY_UP)
xRot-= 5.0f;
if(key == GLUT_KEY_DOWN)
xRot += 5.0f;
if(key == GLUT_KEY_LEFT)
yRot -= 5.0f;
if(key == GLUT_KEY_RIGHT)
yRot += 5.0f;
if(key > 356.0f)
xRot = 0.0f;
if(key < -1.0f)
xRot = 355.0f;
if(key > 356.0f)
yRot = 0.0f;
if(key < -1.0f)
yRot = 355.0f;
// Refresh the Window
glutPostRedisplay();
}
void ChangeSize(int w, int h)
{
GLfloat nRange = 80.0f;
// Prevent a divide by zero
if(h == 0)
h = 1;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);
// Reset coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Establish clipping volume (left, right, bottom, top, near, far)
if (w <= h)
glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange);
else
glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800,600);
glutCreateWindow("Jet");
glutReshapeFunc(ChangeSize);
glutSpecialFunc(SpecialKeys);
glutDisplayFunc(RenderScene);
SetupRC();
glutMainLoop();
return 0;
}
OpenGL超級寶典 第4版 中文版PDF+英文版+源代碼 見 http://www.linuxidc.com/Linux/2013-10/91413.htm
OpenGL編程指南(原書第7版)中文掃描版PDF 下載 http://www.linuxidc.com/Linux/2012-08/67925.htm
OpenGL 渲染篇 http://www.linuxidc.com/Linux/2011-10/45756.htm
Ubuntu 13.04 安裝 OpenGL http://www.linuxidc.com/Linux/2013-05/84815.htm
OpenGL三維球體數據生成與繪制【附源碼】 http://www.linuxidc.com/Linux/2013-04/83235.htm
Ubuntu下OpenGL編程基礎解析 http://www.linuxidc.com/Linux/2013-03/81675.htm
如何在Ubuntu使用eclipse for c++配置OpenGL http://www.linuxidc.com/Linux/2012-11/74191.htm
更多《OpenGL超級寶典學習筆記》相關知識 見 http://www.linuxidc.com/search.aspx?where=nkey&keyword=34581