Week12 閻覃的上課筆記
測試投影示範程式

設定相機
這個函式可以設定相機的相關參數。
31void gluLookAt (GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ, 2 GLdouble centerX, GLdouble centerY, GLdouble centerZ,3 GLdouble upX, GLdouble upY, GLdouble upZ) eye是相機的位置,center是觀察點的位置,up是相機豎直向上的方向。
旋轉相機
61eye[0] = cos(angle);2eye[2] = sin(angle);3angle+=0.01;45glutDisplayFunc(display);6glutIdleFunc(display);透視效果
41glMatrixMode(GL_PROJECTION);2glLoadIdentity();3gluPerspective(60, 1, 0.001, 10.);4glMatrixMode(GL_MODELVIEW);其中,gluPerspective是透視的設定。
11void gluPerspective (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)fov是field of view的縮寫,意思是透視的角度。透視角度越大,觀察的範圍越大,畫面中物體的大小就越小。一般60度就可以。
aspect是長寬比,一般為1。
zNear和zFar是前後的限制,一般zNear要盡可能小,zFar要盡可能大,才能防止被觀察的物體被切掉或忽略。

11void glLoadIdentity (void);載入單位矩陣,防止乘很多次矩陣被破壞。
TRT

為了使讀入的obj能夠正確的縮放,我在 glmReadOBJ(path)后呼叫了glmScale(pmodel, scale);
這樣就可以統一縮放的大小。
隨後還需要將對應的部分移動到坐標中心,所以在glm中新增一個函式,仿造glmUnitize即可。這樣就可以把對應的物件移動到坐標中心,方便之後的調整。
4512GLvoid3glmCenter(GLMmodel* model)4{5 GLuint i;6 GLfloat maxx, minx, maxy, miny, maxz, minz;7 GLfloat cx, cy, cz;89 assert(model);10 assert(model->vertices);1112 /* get the max/mins */13 maxx = minx = model->vertices[3 + 0];14 maxy = miny = model->vertices[3 + 1];15 maxz = minz = model->vertices[3 + 2];16 for (i = 1; i <= model->numvertices; i++) {17 if (maxx < model->vertices[3 * i + 0])18 maxx = model->vertices[3 * i + 0];19 if (minx > model->vertices[3 * i + 0])20 minx = model->vertices[3 * i + 0];2122 if (maxy < model->vertices[3 * i + 1])23 maxy = model->vertices[3 * i + 1];24 if (miny > model->vertices[3 * i + 1])25 miny = model->vertices[3 * i + 1];2627 if (maxz < model->vertices[3 * i + 2])28 maxz = model->vertices[3 * i + 2];29 if (minz > model->vertices[3 * i + 2])30 minz = model->vertices[3 * i + 2];31 }3233 /* calculate center of the model */34 cx = (maxx + minx) / 2.0;35 cy = (maxy + miny) / 2.0;36 cz = (maxz + minz) / 2.0;373839 /* translate around center then scale */40 for (i = 1; i <= model->numvertices; i++) {41 model->vertices[3 * i + 0] -= cx;42 model->vertices[3 * i + 1] -= cy;43 model->vertices[3 * i + 2] -= cz;44 }45}TRT很簡單, 第一次T(平移)是為了將旋轉中心平移至坐標原點。
R(旋轉),即以坐標原點為旋轉中心開始旋轉。
第二次T(平移)是為了將最後的結果平移到指定的位置。
完整的程式碼如下
21912345678float eye[] = {0, 0.5, 1};9float center[] = {0, 0, 0};10float up[] = {0, 1, 0};1112GLMmodel *armLUpper = NULL;13GLMmodel *armRUpper = NULL;14GLMmodel *armLLower = NULL;15GLMmodel *armRLower = NULL;16GLMmodel *legLUpper = NULL;17GLMmodel *legRUpper = NULL;18GLMmodel *legLLower = NULL;19GLMmodel *legRLower = NULL;20GLMmodel *body = NULL;2122void drawArms();2324void drawLegs();2526void drawBody();2728void display() {29 static float angle = 90;3031 glMatrixMode(GL_PROJECTION);32 glLoadIdentity();33 gluPerspective(60, 1, 0.001, 10);34 glMatrixMode(GL_MODELVIEW);35 eye[0] = cos(angle);36 //eye[1] = -cos(angle);37 eye[2] = sin(angle);383940 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);41 angle += 0.01;4243 glPushMatrix();44 {4546 gluLookAt(eye[0], eye[1], eye[2],47 center[0], center[1], center[2],48 up[0], up[1], up[2]);4950 glTranslatef(0, 0.2, 0);5152 drawBody();53 drawArms();54 drawLegs();55 }56 glPopMatrix();57 glutSwapBuffers();58}5960void drawBody() {61 glPushMatrix();62 {63 glmDraw(body, GLM_SMOOTH | GLM_MATERIAL); // draw body64 }65 glPopMatrix();66}6768void drawLegs() {69 const float70 legTransUpper[] = {0.04, -0.22, 0.02},71 legTransLower[] = {0, -0.14, 0.02};7273 glPushMatrix();74 {7576 glTranslatef(-legTransUpper[0], legTransUpper[1], legTransUpper[2]);77 glmDraw(legRUpper, GLM_SMOOTH | GLM_MATERIAL);7879 glTranslatef(-legTransLower[0], legTransLower[1], legTransLower[2]);80 glmDraw(legRLower, GLM_SMOOTH | GLM_MATERIAL);8182 }83 glPopMatrix();8485 glPushMatrix();86 {8788 glTranslatef(legTransUpper[0], legTransUpper[1], legTransUpper[2]);89 glmDraw(legLUpper, GLM_SMOOTH | GLM_MATERIAL);9091 glTranslatef(legTransLower[0], legTransLower[1], legTransLower[2]);92 glmDraw(legLLower, GLM_SMOOTH | GLM_MATERIAL);9394 }95 glPopMatrix();9697}9899100void drawArms() {101 static float armAngle = 0;102 static float flag = 1;103104 if(armAngle > 60)105 flag = -1;106 if(armAngle < 0)107 flag = 1;108 armAngle += flag*2;109110111 const float112 armTransUpper2[] = {0.08, 0.05, -0.01},113 armTransUpper1[] = {0.05, 0.01, 0},114 armTransLower2[] = {0.05, 0, 0.01},115 armTransLower1[] = {0.08, 0, 0};116117118 glPushMatrix();119 {120121 glTranslatef(-armTransUpper2[0], armTransUpper2[1], armTransUpper2[2]);122 glRotatef(armAngle,-1,0,0);123 glTranslatef(-armTransUpper1[0], armTransUpper1[1], armTransUpper1[2]);124 glmDraw(armRUpper, GLM_SMOOTH | GLM_MATERIAL);125126127 glTranslatef(-armTransLower2[0], armTransLower2[1], armTransLower2[2]);128 glRotatef(armAngle,0,1,0);129 glTranslatef(-armTransLower1[0], armTransLower1[1], armTransLower1[2]);130 glmDraw(armRLower, GLM_SMOOTH | GLM_MATERIAL);131132 }133 glPopMatrix();134135 glPushMatrix();136 {137138 glTranslatef(armTransUpper2[0], armTransUpper2[1], armTransUpper2[2]);139 glRotatef(armAngle,-1,0,0);140 glTranslatef(armTransUpper1[0], armTransUpper1[1], armTransUpper1[2]);141 glmDraw(armLUpper, GLM_SMOOTH | GLM_MATERIAL);142143144 glTranslatef(armTransLower2[0], armTransLower2[1], armTransLower2[2]);145 glRotatef(-armAngle,0,1,0);146 glTranslatef(armTransLower1[0], armTransLower1[1], armTransLower1[2]);147 glmDraw(armLLower, GLM_SMOOTH | GLM_MATERIAL);148149 }150 glPopMatrix();151152}153154const GLfloat light_ambient[] = {0.0f, 0.0f, 0.0f, 1.0f};155const GLfloat light_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};156const GLfloat light_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};157const GLfloat light_position[] = {2.0f, 5.0f, 5.0f, 0.0f};158159const GLfloat mat_ambient[] = {0.7f, 0.7f, 0.7f, 1.0f};160const GLfloat mat_diffuse[] = {0.8f, 0.8f, 0.8f, 1.0f};161const GLfloat mat_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};162const GLfloat high_shininess[] = {100.0f};163164void initModel(char *path, GLMmodel *&pmodel, float scale) {165 pmodel = glmReadOBJ(path);166 if (!pmodel) exit(0);167 //glmUnitize(pmodel);168169 glmScale(pmodel, scale);170 glmCenter(pmodel);171 glmFacetNormals(pmodel);172 glmVertexNormals(pmodel, 90.0);173}174175int main(int argc, char **argv) {176177 float const scale = 0.003;178 initModel("IronMan/leg_l_upper.obj", legLUpper, scale);179 initModel("IronMan/leg_l_lower.obj", legLLower, scale);180 initModel("IronMan/leg_r_upper.obj", legRUpper, scale);181 initModel("IronMan/leg_r_lower.obj", legRLower, scale);182 initModel("IronMan/arm_l_upper.obj", armLUpper, scale);183 initModel("IronMan/arm_l_lower.obj", armLLower, scale);184 initModel("IronMan/arm_r_upper.obj", armRUpper, scale);185 initModel("IronMan/arm_r_lower.obj", armRLower, scale);186 initModel("IronMan/body.obj", body, scale);187188 glutInit(&argc, argv);189 glutInitWindowSize(640, 640);190 glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB);191 glutCreateWindow("05052553");192193 glutDisplayFunc(display);194 glutIdleFunc(display);195196 glClearColor(1, 1, 1, 1);197 //glEnable(GL_CULL_FACE);198 //glCullFace(GL_BACK);199200 glEnable(GL_DEPTH_TEST);201 glDepthFunc(GL_LESS);202203 glEnable(GL_LIGHT0);204 glEnable(GL_NORMALIZE);205 glEnable(GL_COLOR_MATERIAL);206 glEnable(GL_LIGHTING);207208 glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);209 glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);210 glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);211 glLightfv(GL_LIGHT0, GL_POSITION, light_position);212213 glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);214 glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);215 glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);216 glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);217218 glutMainLoop();219}
沒有留言:
張貼留言