小白學opengl之 獲取模型檢視矩陣和投影矩陣
阿新 • • 發佈:2019-01-10
<pre name="code" class="cpp">#include <iostream> #include <stdlib.h> #include <stdio.h> #include <GL/glut.h> #include <GL/glu.h> using namespace std; static int shoulder=0,elbow=0,finger=0; void init(void) { glClearColor(0,0,0,0); glShadeModel(GL_FLAT); } void display(void) { //printf("use display\n"); glClear(GL_COLOR_BUFFER_BIT); float mat[16]; glGetFloatv(GL_MODELVIEW_MATRIX, mat); for(int i=0;i<16;++i) { printf("%f ",mat[i]); }
輸出結果:printf("\n"); glGetFloatv(GL_PROJECTION_MATRIX, mat); for(int i=0;i<16;++i) { printf("%f ",mat[i]); } printf("\n"); glPushMatrix(); glTranslatef(-3,0,0);//1 glRotatef((GLfloat)shoulder,0,0,1);//2 glTranslatef(1,0,0);//3 glPushMatrix();//top 1,2,3 glScalef(2,0.4,1); glutWireCube(1); glPopMatrix();//1,2,3,top=I glTranslatef(1,0,0);//4 glRotatef((GLfloat)elbow,0,0,1);//5 glTranslatef(1,0,0);//6 glPushMatrix();//top 1,2,3,4,5,6 glScalef(2,0.4,1); glutWireCube(1); glPopMatrix();//1,2,3,4,5,6 glTranslatef(1,0,0);//7 glRotatef((GLfloat)finger,0,0,1);//8 glTranslatef(1,0,0);//9 glPushMatrix();//top=1,2,3,4,5,6,7,8,9 glScalef(2,0.4,1); glutWireCube(1); glPopMatrix(); glPopMatrix(); glutSwapBuffers(); } void reshape(int w,int h) { printf("use reshape\n"); glViewport(0,0,(GLsizei)w,(GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity();//如果註釋,每次呼叫reshape都會累加結果 gluPerspective(65,(GLfloat)w/(GLfloat)h,1,20); glMatrixMode(GL_MODELVIEW); glLoadIdentity();//如果註釋,每次呼叫reshape都會累加結果 glTranslatef(0,0,-5); } void keyboard(unsigned char key,int x,int y) { switch(key) { case 's': shoulder=(shoulder+5)%360; glutPostRedisplay();//會再次呼叫display函式 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; case 'f': finger=(finger+5)%360; glutPostRedisplay(); break; default: break; } } int main(int argc,char* argv[]) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB); glutInitWindowSize(500,500); glutInitWindowPosition(100,100);//(0,0)表示視窗的左上角對齊螢幕的左上角,(0,100)窗會向下移100 glutCreateWindow("test"); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; }
use reshape
1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 -5.000000 1.000000
1.569686 0.000000 0.000000 0.000000 0.000000 1.569686 0.000000 0.000000 0.000000 0.000000 -1.105263 -1.000000 0.000000 0.000000 -2.105263 0.000000
從結果上可以看出 reshape函式對 display函式的影響 相當於把兩個函式拼在了一起。但是如果事件發生時反覆只調用display函式,那麼diplay裡面的初始模型檢視矩陣和投影矩陣都是最近一次reshape函式裡的結果。
以上結果說明,opengl裡的 模型檢視矩陣和投影矩陣是 全域性變數 初始值都是單位矩陣
前四個分量表示 矩陣的第一個列向量,而不是行向量
投影變換函式決定了 視景體的 大小,也就是 座標範圍滿足視景體內的 會被投影到螢幕
檢視變換函式一般用來指定 自己想要圖形中點的座標,但是如果該圖形不在視景體內 ,則不會被顯示。
如果螢幕沒有顯示圖形,可以通過上面兩種方法實現顯示