您的位置:首页 > 运维架构

OpenGL MV矩阵

2016-04-04 21:51 405 查看
1. 影响Model矩阵的函数

glTranslate* 平移

glRotate* 旋转

glScalef* 缩放

看几个例子

1.1 glTranslatef(-1, 3, 5); 平移向量为(-1, 3, 5)

由平移变换矩阵公式

1 0 0 Tx

0 1 0 Ty

0 0 1 Tz

0 0 0 1

所以变换矩阵为

1 0 0 -1

0 1 0 3

0 0 1 5

0 0 0 1

在OpenGL中存储变换矩阵不是二维数组,而是一维数据,如float m[16]

且存储是按列存储的,

m[0] m[4] m[8] m[12]

m[1] m[5] m[9] m[13]

m[2] m[6] m[10] m[14]

m[3] m[7] m[11] m[15]

即上面的矩阵在数组中存储如下:

m[0]=1

m[1]=0

m[2]=0

m[3]=0

以上是变换矩阵的第1列

m[4]=0

m[5]=1

m[6]=0

m[7]=0

以上是变换矩阵的第2列

m[8]=0

m[9]=0

m[10]=1

m[11]=0

以上是变换矩阵的第3列

m[12]=-1

m[13]=3

m[14]=5

m[15]=1

以上是变换矩阵的第4列

1.2 glRotatef(45, 1, 1, 1); 旋转变换,注意:opengl会把方向向量单位化,故

向量(1,1,1)单位化后的向量为u=(ux,uy,uz)=(0.5773 0.5773 0.5773),c代表cos(theta)=0.7071,s代表sin(theta)=0.7071

由旋转变换公式,

c+(1-c)*ux*ux (1-c)*uy*ux-s*uz (1-c)*uz*ux+s*uy 0

(1-c)*ux*uy+s*uz c+(1-c)*uy*uy (1-c)*uz*uy-s*ux 0

(1-c)*ux*uz-s*uy (1-c)*uy*uz+s*ux c+(1-c)*uz*uz 0

0 0 0 1

变换矩阵为

0.8047 -0.3106 0.5059 0

0.5059 0.8047 -0.3106 0

-0.3106 0.5059 0.8047 0

0 0 0 1.0000

注意,存储时是以列存储的

1.3 glScalef(-3, 1, 2); 缩放变换,故变换矩阵为

由缩放变换公式

Sx 0 0 0

0 Sy 0 0

0 0 Sz 0

0 0 0 1

可知缩放矩阵为

-3 0 0 0

0 1 0 0

0 0 2 0

0 0 0 1

注意,存储时是以列存储的

如果将上述三个变换组合起来顺序是什么样呢?

后调用的先变换,即M=trans*rot*scale

M =

-2.4142 -0.3106 1.0118 -1.0000

-1.5176 0.8047 -0.6212 3.0000

0.9319 0.5059 1.6095 5.0000

0 0 0 1.0000

注意,存储时是以列存储的

2. 影响View矩阵的函数

gluLookAt(eye.x, eye.y, eye.z, look.x, look.y, look.z, up.x, up.y, up.z)

2.1 gluLookAt(4, 4, 4, 0, 1, 0, 0, 1, 0);

n=eye-look=(4,4,4)-(0,1,0)=(4,3,4)

u=up x n = (0 1 0) x (4 3 4) = (4 0 -4)

v=n x u = (4 3 4) x (4 0 -4) = (-12 32 -12)

由公式求出相机的u,n,v向量分别为(单位化后)

u=0.7071 0 -0.7071

n=0.6247 0.4685 0.6247

v=-0.3313 0.8835 -0.3313

所以View矩阵为

V=

0.7071 0 -0.7071 0

-0.3313 0.8835 -0.3313 -0.8835

0.6247 0.4685 0.6247 -6.8716

0 0 0 1.0000

如果同时有ModelView变换将如何呢?

glTranslatef(-1, 3, 5);

glRotatef(45, 1, 1, 1);

glScalef(-3, 1, 2);

gluLookAt(4, 4, 4, 0, 1, 0, 0, 1, 0);

这时MV矩阵是什么?注意后调用的先变换,即

M*V=

-0.9721 0.1996 2.4421 -7.6783

-1.7278 0.4199 0.4185 6.5578

1.4968 1.2010 0.1789 -6.5069

0 0 0 1.0000

本节测试源码如下:

#define GLUT_DISABLE_ATEXIT_HACK

#include <gl/GLUT.H>
#include <stdio.h>

void printMatrix(float m[16])
{
printf("%10f %10f %10f %10f\n"
"%10f %10f %10f %10f\n"
"%10f %10f %10f %10f\n"
"%10f %10f %10f %10f\n",
m[0], m[4], m[8], m[12],
m[1], m[5], m[9], m[13],
m[2], m[6], m[10], m[14],
m[3], m[7], m[11], m[15]
);
}

void myDisplay()
{
float m[16] = { 0 };
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(4, 4, 4, 0, 1, 0, 0, 1, 0);
glTranslatef(-1, 3, 5);
glRotatef(45, 1, 1, 1);
glScalef(-3, 1, 2);
glGetFloatv(GL_MODELVIEW_MATRIX, m);
printMatrix(m);
glFlush();
}

int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);   // RGB、单缓冲
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 400);
glutCreateWindow("MV矩阵");
glutDisplayFunc(myDisplay);
glutMainLoop();

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: