2017年5月15日 星期一

Week12 閻覃的上課筆記

Week12 閻覃的上課筆記.md

Week12 閻覃的上課筆記

測試投影示範程式

8EA2956D-7D39-47BD-8AD9-580D299BC161

設定相機

這個函式可以設定相機的相關參數。

 
3
1
void gluLookAt (GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ, 
2
                GLdouble centerX, GLdouble centerY, GLdouble centerZ,
3
                GLdouble upX, GLdouble upY, GLdouble upZ) 

eye是相機的位置,center是觀察點的位置,up是相機豎直向上的方向。

旋轉相機

 
6
1
eye[0] = cos(angle);
2
eye[2] = sin(angle);
3
angle+=0.01;
4
5
glutDisplayFunc(display);
6
glutIdleFunc(display);

透視效果

 
4
1
glMatrixMode(GL_PROJECTION);
2
glLoadIdentity();
3
gluPerspective(60, 1, 0.001, 10.);
4
glMatrixMode(GL_MODELVIEW);

其中,gluPerspective是透視的設定。

 
1
1
void gluPerspective (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)

fov是field of view的縮寫,意思是透視的角度。透視角度越大,觀察的範圍越大,畫面中物體的大小就越小。一般60度就可以。

aspect是長寬比,一般為1。

zNear和zFar是前後的限制,一般zNear要盡可能小,zFar要盡可能大,才能防止被觀察的物體被切掉或忽略。

83C681B6-6A79-4DE7-AF15-8E703BA61A0A

 
1
1
void glLoadIdentity (void);

載入單位矩陣,防止乘很多次矩陣被破壞。

TRT

0494479A-9E58-4F13-8985-79FDAA41D9CE

為了使讀入的obj能夠正確的縮放,我在 glmReadOBJ(path)后呼叫了glmScale(pmodel, scale);

這樣就可以統一縮放的大小。

隨後還需要將對應的部分移動到坐標中心,所以在glm中新增一個函式,仿造glmUnitize即可。這樣就可以把對應的物件移動到坐標中心,方便之後的調整。

 
45
1
2
GLvoid
3
glmCenter(GLMmodel* model)
4
{
5
    GLuint  i;
6
    GLfloat maxx, minx, maxy, miny, maxz, minz;
7
    GLfloat cx, cy, cz;
8
9
    assert(model);
10
    assert(model->vertices);
11
12
    /* 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];
21
22
        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];
26
27
        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
    }
32
33
    /* calculate center of the model */
34
    cx = (maxx + minx) / 2.0;
35
    cy = (maxy + miny) / 2.0;
36
    cz = (maxz + minz) / 2.0;
37
38
39
    /* 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(平移)是為了將最後的結果平移到指定的位置。

完整的程式碼如下

 
219
1
#include <string.h>
2
#include <stdlib.h>
3
#include <math.h>
4
#include "glm.h"
5
#include <GLUT/glut.h>
6
7
8
float eye[] = {0, 0.5, 1};
9
float center[] = {0, 0, 0};
10
float up[] = {0, 1, 0};
11
12
GLMmodel *armLUpper = NULL;
13
GLMmodel *armRUpper = NULL;
14
GLMmodel *armLLower = NULL;
15
GLMmodel *armRLower = NULL;
16
GLMmodel *legLUpper = NULL;
17
GLMmodel *legRUpper = NULL;
18
GLMmodel *legLLower = NULL;
19
GLMmodel *legRLower = NULL;
20
GLMmodel *body = NULL;
21
22
void drawArms();
23
24
void drawLegs();
25
26
void drawBody();
27
28
void display() {
29
    static float angle = 90;
30
31
    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);
38
39
40
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
41
    angle += 0.01;
42
43
    glPushMatrix();
44
    {
45
46
        gluLookAt(eye[0], eye[1], eye[2],
47
                  center[0], center[1], center[2],
48
                  up[0], up[1], up[2]);
49
50
        glTranslatef(0, 0.2, 0);
51
52
        drawBody();
53
        drawArms();
54
        drawLegs();
55
    }
56
    glPopMatrix();
57
    glutSwapBuffers();
58
}
59
60
void drawBody() {
61
    glPushMatrix();
62
    {
63
        glmDraw(body, GLM_SMOOTH | GLM_MATERIAL); // draw body
64
    }
65
    glPopMatrix();
66
}
67
68
void drawLegs() {
69
    const float
70
            legTransUpper[] = {0.04, -0.22, 0.02},
71
            legTransLower[] = {0, -0.14, 0.02};
72
73
    glPushMatrix();
74
    {
75
76
        glTranslatef(-legTransUpper[0], legTransUpper[1], legTransUpper[2]);
77
        glmDraw(legRUpper, GLM_SMOOTH | GLM_MATERIAL);
78
79
        glTranslatef(-legTransLower[0], legTransLower[1], legTransLower[2]);
80
        glmDraw(legRLower, GLM_SMOOTH | GLM_MATERIAL);
81
82
    }
83
    glPopMatrix();
84
85
    glPushMatrix();
86
    {
87
88
        glTranslatef(legTransUpper[0], legTransUpper[1], legTransUpper[2]);
89
        glmDraw(legLUpper, GLM_SMOOTH | GLM_MATERIAL);
90
91
        glTranslatef(legTransLower[0], legTransLower[1], legTransLower[2]);
92
        glmDraw(legLLower, GLM_SMOOTH | GLM_MATERIAL);
93
94
    }
95
    glPopMatrix();
96
97
}
98
99
100
void drawArms() {
101
    static float armAngle = 0;
102
    static float flag = 1;
103
104
    if(armAngle > 60)
105
        flag = -1;
106
    if(armAngle < 0)
107
        flag = 1;
108
    armAngle += flag*2;
109
110
111
    const float
112
            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};
116
117
118
    glPushMatrix();
119
    {
120
121
        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);
125
126
127
        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);
131
132
    }
133
    glPopMatrix();
134
135
    glPushMatrix();
136
    {
137
138
        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);
142
143
144
        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);
148
149
    }
150
    glPopMatrix();
151
152
}
153
154
const GLfloat light_ambient[] = {0.0f, 0.0f, 0.0f, 1.0f};
155
const GLfloat light_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
156
const GLfloat light_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};
157
const GLfloat light_position[] = {2.0f, 5.0f, 5.0f, 0.0f};
158
159
const GLfloat mat_ambient[] = {0.7f, 0.7f, 0.7f, 1.0f};
160
const GLfloat mat_diffuse[] = {0.8f, 0.8f, 0.8f, 1.0f};
161
const GLfloat mat_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};
162
const GLfloat high_shininess[] = {100.0f};
163
164
void initModel(char *path, GLMmodel *&pmodel, float scale) {
165
    pmodel = glmReadOBJ(path);
166
    if (!pmodel) exit(0);
167
    //glmUnitize(pmodel);
168
169
    glmScale(pmodel, scale);
170
    glmCenter(pmodel);
171
    glmFacetNormals(pmodel);
172
    glmVertexNormals(pmodel, 90.0);
173
}
174
175
int main(int argc, char **argv) {
176
177
    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);
187
188
    glutInit(&argc, argv);
189
    glutInitWindowSize(640, 640);
190
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB);
191
    glutCreateWindow("05052553");
192
193
    glutDisplayFunc(display);
194
    glutIdleFunc(display);
195
196
    glClearColor(1, 1, 1, 1);
197
    //glEnable(GL_CULL_FACE);
198
    //glCullFace(GL_BACK);
199
200
    glEnable(GL_DEPTH_TEST);
201
    glDepthFunc(GL_LESS);
202
203
    glEnable(GL_LIGHT0);
204
    glEnable(GL_NORMALIZE);
205
    glEnable(GL_COLOR_MATERIAL);
206
    glEnable(GL_LIGHTING);
207
208
    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);
212
213
    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);
217
218
    glutMainLoop();
219
}

沒有留言:

張貼留言