真實感球的繪製關鍵函數:
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_shininess);//設定材料反射指數
glLightfv(GL_LIGHT0, GL_POSITION, light_position);//光源位置
glShadeModel ( GL_SMOOTH ); //設定陰影模型
glViewport (0, 0, (GLsizei) w, (GLsizei) h); 視點設計
glOrtho (x1,x2,y1,y2,z1,z2); //建立平行視景體
# include < GL/glut.h > /* 初始化材料屬性、光源屬性、光照模型,開啟深度緩衝區等 */ void init(void) { GLfloat light_position [ ] = { 1.0, 1.0, 1.0, 0.0 }; GLfloat mat_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };glClearColor ( 0.0, 0.0, 1.0, 0.0 ); //設定背景色為藍色glShadeModel ( GL_SMOOTH ); //glMaterialfv(GL_FRONT,GL_AMBIENT,mat_specular); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);glLightfv ( GL_LIGHT0, GL_POSITION, light_position); glEnable (GL_LIGHTING); glEnable (GL_LIGHT0); glEnable (GL_DEPTH_TEST); } /*調用 GLUT 函數,繪製一個球*/ void display ( void ) { glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glutSolidSphere (1.0, 40, 50); //半徑為 1,40 條緯線,50 條經線glFlush (); } /* 定義 GLUT 的 reshape 函數,w、h 分別是輸出圖形的視窗的寬和高*/ void reshape (int w, int h) { glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity ( ); if (w <= h) glOrtho (-1.5, 1.5, -1.5 * ( GLfloat ) h / ( GLfloat ) w, 1.5* ( GLfloat ) h / ( GLfloat ) w, -10.0, 10.0 ); //建立平行視景體else glOrtho (-1.5 * ( GLfloat ) w / ( GLfloat ) h,1.5 * ( GLfloat ) w/( GLfloat ) h, -1.5, 1.5, -10.0, 10.0); glMatrixMode ( GL_MODELVIEW ); glLoadIdentity ( ) ; } int main(int argc, char** argv) { glutInit (&argc, argv); // GLUT 環境初始化glutInitDisplayMode (GLUT_SINGLE |GLUT_RGB |GLUT_DEPTH); // 顯示模式初始化glutInitWindowSize (300, 300); // 定義視窗大小glutInitWindowPosition (100, 100); // 定義視窗位置 glutCreateWindow ( argv [ 0 ] ); // 顯示視窗,視窗標題為執行函數名init( );glutDisplayFunc ( display ); // 註冊 OpenGL 繪圖函數(一種特殊的調用方式,下同) glutReshapeFunc ( reshape ); // 註冊視窗大小改變時的響應函數glutMainLoop( ); // 進入 GLUT 訊息迴圈,開始執行程式return 0; }
:
將init( )中的
GLfloat light_position [ ] = { 1.0, 1.0, 1.0, 0.0 }; GLfloat mat_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };glClearColor ( 0.0, 0.0, 1.0, 0.0 ); //設定背景色為藍色glShadeModel ( GL_SMOOTH ); //glMaterialfv(GL_FRONT,GL_AMBIENT,mat_specular); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
改為
GLfloat light_position [ ] = { 1.0, 1.0, 1.0, 0.0 }; GLfloat mat_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };GLfloat mat_shininess[] = { 50.0 };glClearColor ( 0.0, 0.0, 1.0, 0.0 ); //設定背景色為藍色glShadeModel ( GL_SMOOTH ); //glMaterialfv(GL_FRONT,GL_AMBIENT,mat_specular); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_diffuse); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);//設定材料反射指數
即將漫射光GL_DIFFUSE改為鏡面光GL_SPECULAR,可得效果
相應的還有環境光線GL_AMBIENT,讀者可執行嘗試。
-----------------------------------------------------------
上面的代碼是用glut,即openGL utilizing tool做的,還有一種做法是用OpenGL的AUX,要下載glaux.lib和glaux.h, 代碼如下:
#include<GL/glut.h>#include <gl/GLAUX.H>#pragma comment(lib, "glaux")void myinit(void){GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };GLfloat mat_shininess[] = { 50.0 };GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);//set material 鏡面光反射glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);//設定材料反射指數glLightfv(GL_LIGHT0, GL_POSITION, light_position);//光源位置glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);glDepthFunc(GL_LEQUAL);glEnable(GL_DEPTH_TEST);}void display(void){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);auxSolidSphere(1.0);glFlush();}void myReshape(GLsizei w, GLsizei h){glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();if (w <= h) glOrtho (-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w, 1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);else glOrtho (-1.5*(GLfloat)w/(GLfloat)h, 1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();}int main(int argc, char** argv){auxInitDisplayMode (AUX_SINGLE | AUX_RGBA | AUX_DEPTH);auxInitPosition (0, 0, 500, 500);auxInitWindow ((LPCWSTR)"Lighting Sphere");myinit();auxReshapeFunc ((AUXRESHAPEPROC)myReshape);auxMainLoop((AUXMAINPROC)display);}
效果如下:
最後還看到一組超全的光亮度模型結果,代碼在這裡。
結果