【循序渐进学图形学之】OpenGL视图和模型变换中各变换发生顺序的思考

在视图模型变换中,顶点v的变换是按照相反的顺序发生的,而不是按照它的代码中先后顺序出现的。下面举例说明。

考虑下面的代码:

glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMultMatrixf(N); glMultMatrixf(M); glMultMatrixf(L); glBegin(GL_POINTS); glVertex3dv(v); glEnd();

在这段代码中,模型视图矩阵按顺序分别包含I、N、NM,最后是NML,其中I表示单位矩阵。经过变化的顶点是NMLv。因此顶点变换就是N(M(Lv))。

下面看绘制机器人手臂的display()函数的代码:

void display() { glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); glTranslatef(-1.0,0.0,0.0); glRotatef((GLfloat)shoulder,0.0,0.0,1.0); glTranslatef(1.0,0.0,0.0); //绘制第一段手臂 glPushMatrix(); glScalef(2.0,0.4,1.0); glutWireCube(1.0); glPopMatrix(); glTranslatef(1.0,0.0,0.0); glRotatef((GLfloat)elbow,0.0,0.0,1.0); glTranslatef(1.0,0.0,0.0); //绘制第二段手臂 glPushMatrix(); glScalef(2.0,0.4,1.0); glutWireCube(1.0); glPopMatrix(); glPopMatrix(); glutSwapBuffers(); }

我们通过逐步调试运行来查看效果。

现在注释掉代码:

glTranslatef(-1.0,0.0,0.0); glRotatef((GLfloat)shoulder,0.0,0.0,1.0); glTranslatef(1.0,0.0,0.0);

以及绘制第二段手臂的代码:

//绘制第二段手臂 glPushMatrix(); glScalef(2.0,0.4,1.0); glutWireCube(1.0); glPopMatrix();

只保留绘制第一段的代码,便于查看效果。

运行结果:

显示的是经过缩放了的立方体。

然后解除下面这行代码的注释:glTranslatef(1.0,0.0,0.0);(位于旋转之下的代码)

运行结果:

显示的是经过缩放、平移的结果。

在解除这行代码的注释:glRotatef((GLfloat)shoulder,0.0,0.0,1.0);

运行结果:

显示的是经过缩放、平移、再旋转地结果。

再解除这行代码的注释:glTranslatef(-1.0,0.0,0.0);(位于旋转之上的代码)

运行结果:


可以看出是上一步的结果又平移之后的效果。

从上面的单步效果可以看出,乘法的出现顺序和他们的代码中得出现顺序相反。


最后给出绘制两端机器人手臂整个代码:

//绘制机器人手臂 #include static int shoulder = 0,elbow = 0;//两段手臂旋转的角度 void init () { glClearColor(0.0,0.0,0.0,0.0); glShadeModel(GL_FLAT); } void display() { glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); glTranslatef(-1.0,0.0,0.0); glRotatef((GLfloat)shoulder,0.0,0.0,1.0); glTranslatef(1.0,0.0,0.0); //绘制第一段手臂 glPushMatrix(); glScalef(2.0,0.4,1.0); glutWireCube(1.0); glPopMatrix(); glTranslatef(1.0,0.0,0.0); glRotatef((GLfloat)elbow,0.0,0.0,1.0); glTranslatef(1.0,0.0,0.0); //绘制第二段手臂 glPushMatrix(); glScalef(2.0,0.4,1.0); glutWireCube(1.0); glPopMatrix(); glPopMatrix(); glutSwapBuffers(); } void reshape(int w,int h) { glViewport(0,0,(GLsizei)w,(GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(65.0,(GLfloat) w/ (GLfloat)h,1.0,20.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0,0.0,-5.0); } void keyboard(unsigned char key,int x,int y) { switch(key)//s和e键控制两端手臂的旋转角度 { case 's': shoulder = (shoulder + 5)% 360; glutPostRedisplay(); break; case 'S': shoulder = (shoulder - 5)% 360; glutPostRedisplay(); break; case 'e': elbow = (elbow + 5) % 360; glutPostRedisplay(); break; case 'E': elbow = (elbow - 5) % 360; glutPostRedisplay(); break; default: break; } } int main(int argc,char** argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(400,400); glutInitWindowPosition(100,100); glutCreateWindow(argv[0]); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; }运行效果(通过s和e键可以控制两端手臂的旋转角度):




转载于:https://www.cnblogs.com/xiajun/archive/2011/12/03/2298626.html

你可能感兴趣的:(【循序渐进学图形学之】OpenGL视图和模型变换中各变换发生顺序的思考)