note-50 GLUT light_&_material_01
openGL 灯光与材质例子. 顺带完成了一个颇复杂的平面分级算法,?修正版,列出了所有易错的地方:
?
?1. 开启了 GL_XXX_ARRAY 后一定要使用对应的pointer, 否则就把 GL_XXX_ARRAY disable 掉.
?
?2.?法线不一定要设置,?openGL会自动为每一Vertex生成一个默认的,?自己设置当然可控性更好.
?
?3.?initLights()?等GL具体到场景内容的设置必须放在?GLUT?基本设置之后(一开始就死在这个弱智的问题).
?
?4.?灯光的?GL_POSITION,?齐次坐标最后一位如果是 0,?则为平行光,?无需设置?GL_SPOT_DIRECTION?和?GL_SPOT_CUTOFF(这个值为照射角的一半).?如果是1,?则为聚光灯.
?
?5. GL 环境光对所有面都会有影响.尝试变换灯光的颜色和环境光颜色的数组值,观察其变化.?
?
?6.?材质的?SHINESS?参数, 1 端接近橡胶与织物, 128?端接近金属与清漆.?
?
? 7. 灯灯灯凳~?最麻烦的还是平面分级算法,?理论上分级越细,?关照效果越细致,?代码如下:
?
#include <gl/GLUT.h>#include <stdio.h>static GLfloat LEVEL=12;static GLfloat LENGTH=2;static GLfloat START_PT=-1*(LENGTH/2);static GLfloat END_PT=1*(LENGTH/2);GLfloat angle=0;GLfloat *vertices;//GLfloat *colors;short *indices;GLfloat *normals;//GLfloat vertices[]={-1,-1,1,//-0.3333f,-1,1,//0.3333f,-1,1,//1,-1,1,//-1,-0.3333,1,//-0.3333f,-0.3333,1,//0.3333f,-0.3333,1,//1,-0.3333,1,//-1,0.3333,1,//-0.3333f,0.3333,1,//0.3333f,0.3333,1,//1,0.3333,1,//-1,1,1,//-0.3333f,1,1,//0.3333f,1,1,//1,1,1};//short indices[]={0,1,4, 1,5,4, 1,2,5, 2,6,5, 2,3,6, 3,7,6,//4,5,8, 5,9,8, 5,6,9, 6,10,9, 6,7,10, 7,11,10,//8,9,12, 9,13,12, 9,10,13, 10,14,13, 10,11,14, 11,15,14};//lightsGLfloat lightPos[]={0,0,2.5f,1};GLfloat lightColor[]={0.6f,0.3f,0.3f,1};//redGLfloat lightDir[]={0,0,-1};//ambient lightGLfloat light_ambient[]={0.3f,0.3f,0.4f,1};//light blue//materialsGLfloat cubeColor[]={0.6f,0.6f,0.6f,1};//gray colorGLfloat cubeSpecular[]={1,1,1,1};void setMaterial(){glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,cubeColor);glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,cubeSpecular);//try to change the shiness from 1(rubber/frabic)-128(metal/clear painted)glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,20);}void drawPlane(){glVertexPointer(3,GL_FLOAT,0,vertices);//glNormalPointer(GL_FLOAT,0,normals);//glColorPointer(4,GL_FLOAT,0,colors);glDrawElements(GL_TRIANGLES,(GLsizei)((LEVEL-1)*(LEVEL-1)*2*3),GL_UNSIGNED_SHORT,indices);}void drawCube(){//set materialsetMaterial();glPushMatrix();drawPlane();glPopMatrix();glPushMatrix();glRotatef(-90,1,0,0);drawPlane();glPopMatrix();glPushMatrix();glRotatef(90,1,0,0);drawPlane();glPopMatrix();glPushMatrix();glRotatef(180,1,0,0);drawPlane();glPopMatrix();glPushMatrix();glRotatef(90,0,1,0);drawPlane();glPopMatrix();glPushMatrix();glRotatef(-90,0,1,0);drawPlane();glPopMatrix();}void rendering(void){glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);glPushMatrix();glRotatef(angle,0,1,0);drawCube();glPopMatrix();glutSwapBuffers();angle+=0.01;}void reshape(int w, int h){if(h==0){h=1;}GLfloat ratio=(GLfloat)(w/h);glMatrixMode(GL_PROJECTION);glLoadIdentity();glViewport(0,0,w,h);gluPerspective(45,ratio,0.1,1000);gluLookAt(0,5,10,0,0,0,0,1,0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();}void makeArrays(){//build vertices array for one faceGLfloat step=(GLfloat)(LENGTH/(LEVEL-1));GLint total=LEVEL*LEVEL*3;GLint oneLine=LEVEL*3;//12//printf("level: %f ", step);vertices=new GLfloat[total];for(int i=0;i<LEVEL;i++){//every point x,y,zfor(int j=0;j<LEVEL*3;j+=3){vertices[(i*oneLine)+j]=(GLfloat)(START_PT+(j*step/3));vertices[(i*oneLine)+(j+1)]=(GLfloat)(START_PT+i*step);vertices[(i*oneLine)+(j+2)]=(GLfloat)(LENGTH/2);printf("pt : x: %f, y: %f, z: %f \n", vertices[(i*oneLine)+j],vertices[(i*oneLine)+j+1],vertices[(i*oneLine)+j+2]);}}//build colors array, normal white color;/*GLint totalColor=LEVEL*LEVEL*4;colors=new GLfloat[totalColor];for(int r=0;r<totalColor;r+=4){colors[r]=1;colors[r+1]=1;colors[r+2]=1;colors[r+3]=1;}*///build index array for one face//using TRIANGLESindices=new short[(LEVEL-1)*(LEVEL-1)*2*3];//square of LEVEL-1, 2 triangles, 3 points;for(int m=0;m<LEVEL-1;m++){for(int n=0;n<LEVEL-1;n++){indices[m*((GLint)LEVEL-1)*6+n*6+0]=n+m*((GLint)LEVEL-1)+m+0;indices[m*((GLint)LEVEL-1)*6+n*6+1]=n+m*((GLint)LEVEL-1)+m+1;indices[m*((GLint)LEVEL-1)*6+n*6+2]=n+m*((GLint)LEVEL-1)+m+(LEVEL);indices[m*((GLint)LEVEL-1)*6+n*6+3]=n+m*((GLint)LEVEL-1)+m+1;indices[m*((GLint)LEVEL-1)*6+n*6+4]=n+m*((GLint)LEVEL-1)+m+(LEVEL)+1;indices[m*((GLint)LEVEL-1)*6+n*6+5]=n+m*((GLint)LEVEL-1)+m+(LEVEL);}}normals=new GLfloat[LEVEL*LEVEL*3];for(int s=0;s<LEVEL*LEVEL*3;s+=3){normals[s]=0;normals[s+1]=0;normals[s+2]=1;}}void initLights(){glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);glLightfv(GL_LIGHT0,GL_POSITION,lightPos);glLightfv(GL_LIGHT0,GL_AMBIENT,lightColor);glLightfv(GL_LIGHT0,GL_DIFFUSE,lightColor);glLightfv(GL_LIGHT0,GL_SPECULAR,lightColor);glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,lightDir);glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,45);//glLightModelfv(GL_LIGHT_MODEL_AMBIENT,light_ambient);}int main(int argc, char* args[]){//make arraysmakeArrays();//basic initglutInit(&argc,args);glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);//window initglutInitWindowPosition(100,100);glutInitWindowSize(600,600);glutCreateWindow("light cube");//functions initglutDisplayFunc(rendering);glutIdleFunc(rendering);glutReshapeFunc(reshape);//gl initglEnable(GL_DEPTH_TEST);glEnableClientState(GL_VERTEX_ARRAY);//glEnableClientState(GL_NORMAL_ARRAY);//glEnableClientState(GL_COLOR_ARRAY);glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);//init lightsinitLights();//run main loop, trigger all the funtionsglutMainLoop();return 0;}
?
?
?
?
?