1. 程式人生 > >小白學opengl之 獲取模型檢視矩陣和投影矩陣

小白學opengl之 獲取模型檢視矩陣和投影矩陣

<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裡的 模型檢視矩陣和投影矩陣是 全域性變數 初始值都是單位矩陣
前四個分量表示 矩陣的第一個列向量,而不是行向量
投影變換函式決定了 視景體的 大小,也就是 座標範圍滿足視景體內的 會被投影到螢幕
檢視變換函式一般用來指定 自己想要圖形中點的座標,但是如果該圖形不在視景體內 ,則不會被顯示。
如果螢幕沒有顯示圖形,可以通過上面兩種方法實現顯示