計算機圖形學-光照紋理模型
阿新 • • 發佈:2019-02-17
話不多說,看圖和程式碼註釋
#include <stdlib.h> #define GLUT_DISABLE_ATEXIT_HACK #include <GL/glut.h> GLfloat *currentCoeff; GLenum currentPlane; GLint currentGenMode; float roangles = 45.0; #define stripeImageWidth 32 GLubyte stripeImage[4 * stripeImageWidth]; //自定義初始化opengl函式 void makeStripeImage(void) { //生成紋理 for (int j = 0; j < stripeImageWidth; j++) { stripeImage[4 * j + 0] = (GLubyte)((j <= 4) ? 255 : 0); stripeImage[4 * j + 1] = (GLubyte)((j > 4) ? 255 : 0); stripeImage[4 * j + 2] = (GLubyte)0; stripeImage[4 * j + 3] = (GLubyte)255; } } void init(void) { GLfloat xequalzero[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat slanted[] = { 1.0, 1.0, 1.0, 0.0 }; glClearColor(0.0, 0.0, 0.0, 0.0); glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); makeStripeImage(); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); /* glTexParameteri()指定紋理的各種屬性:這些屬性包括: GL_TEXTURE_MIN/MAG_FILTER 當紋理貼圖需要被放大或縮小時的插值方式 此屬性通常必須要指定,否則可能看不到貼圖 GL_TEXTURE_MIN/MAG_LOD 設定紋理的最小和最大LOD級別(可為正負) GL_TEXTURE_MAX_LOD 設定最小的那個mipmap的序號 GL_TEXTURE_MAX_LEVE設定最大的那個mipmap的序號 GL_TEXTURE_WRAP_S/T/R 設定紋理座標的擴充套件方式,在這個引數下,可以使用的擴充套件方式有:GL_CLAMP(夾緊), GL_CLAMP_TO_BORDER, GL_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT, or GL_REPEAT(重複),各種鋪陳方式的效果如圖: GL_TEXTURE_BORDER_COLOR 設定紋理的邊界(BORDER)顏色 GL_TEXTURE_PRIORITY 設定紋理在GPU快取中的優先順序,通常為了效能考慮,紋理會被放在GPU的快取中,但是存放的數量是有限的,這個引數可以設定在GPU中的存放優先順序 GL_GENERATE_MIPMAP 設定當base mipmap改變後是否更新所有的mipmap GL_TEXTURE_COMPARE_MODE GL_TEXTURE_COMPARE_FUNC和GL_DEPTH_TEXTURE_MODE屬性是專門為陰影貼圖 */ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //紋理對映 glTexImage1D(GL_TEXTURE_1D, 0, 4, stripeImageWidth, 0, GL_RGBA, GL_UNSIGNED_BYTE, stripeImage); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);//紋理環境 currentCoeff = xequalzero; currentGenMode = GL_OBJECT_LINEAR; currentPlane = GL_OBJECT_PLANE; glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, currentGenMode);//自動生成紋理座標,設定生成紋理的平面參考方式 glTexGenfv(GL_S, currentPlane, currentCoeff);//來設定這個平面 glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_1D); //glShadeModel(GL_SMOOTH); // 設定光源 GLfloat sun_light_position[] = { 1.0f, 1.0f, 1.0f, 0.0f }; GLfloat sun_light_ambient[] = { 0.2f, 0.2f, 0.2f, 1.0f }; GLfloat sun_light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f }; GLfloat sun_light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; glLightfv(GL_LIGHT0, GL_POSITION, sun_light_position);//第0號光源位置 glLightfv(GL_LIGHT0, GL_AMBIENT, sun_light_ambient);//0號光源環境光屬性 //經過很多次反射後最終遺留在環境中的光線強度(顏色) glLightfv(GL_LIGHT0, GL_DIFFUSE, sun_light_diffuse);//散射光屬性 glLightfv(GL_LIGHT0, GL_SPECULAR, sun_light_specular);//鏡面反射光屬性 //OPENGL在後面的渲染中使用光照,預設情況下是關閉的 glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); glFrontFace(GL_CW); // 設定材質 GLfloat earth_mat_ambient[] = { 0.5f, 1.0f, 0.5f, 1.0f }; GLfloat earth_mat_diffuse[] = { 0.5f, 1.0f, 0.5f, 1.0f }; GLfloat earth_mat_specular[] = { 0.0f, 0.5f, 0.5f, 1.0f }; GLfloat earth_mat_emission[] = { 0.0f, 0.0f, 0.0f, 1.0f }; GLfloat earth_mat_shininess = 50.0f; glMaterialfv(GL_FRONT, GL_AMBIENT, earth_mat_ambient);//材質環境顏色 glMaterialfv(GL_FRONT, GL_DIFFUSE, earth_mat_diffuse);//材質散射顏色 glMaterialfv(GL_FRONT, GL_SPECULAR, earth_mat_specular);//材質鏡面反射顏色 glMaterialfv(GL_FRONT, GL_EMISSION, earth_mat_emission);//材質發射光顏色 glMaterialf(GL_FRONT, GL_SHININESS, earth_mat_shininess);//鏡面反射指數 //GL_FRONT、GL_BACK或GL_FRONT_AND_BACK,指出材質屬性將應用於物體的哪面。 /* GL_AMBIENT(0.2,0.2,0.2,1.0)材質的環境顏色 GL_DIFFUSE(0.8,0.8,0.8,1.0)材質的散射顏色 GL_AMBIENT_AND_DIFFUSE材質的環境顏色和散射顏色 GL_SPECULAR(0.0,0.0,0.0,1.0)材質的鏡面反射顏色 GL_SHININESS 0.0 鏡面反射指數 GL_EMISSION (0.0,0.0,0.1,1.0)材質的發射光顏色 GL_COLOR_INDEXES (0, 1, 1)環境顏色索引、散射顏色索引和鏡面反射顏色索引 */ } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glRotatef(roangles, 0.0, 0.0, 1.0); //glTranslatef(Move_x, Move_y, Move_z); glutSolidSphere(1.0, 32, 32); glPopMatrix(); //glEnable/glDisable —— 開啟和關閉伺服器端GL功能 glDisable(GL_DEPTH_TEST);//啟用深度測試 glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_1D);//對活動的材質進行貼圖 glDisable(GL_LIGHTING);//關閉光源 glDisable(GL_LIGHT0);//關閉光源, glDisable(GL_AUTO_NORMAL);//執行後,圖形能把光反射到各個方向 glDisable(GL_NORMALIZE);//在轉換之後和光照之前將法線向量標準化成單位長度 glFlush(); } 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); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(500, 500); glutInitWindowPosition(100, 100); glutCreateWindow("球"); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMainLoop(); return 0; }