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

用OpenGL实现三维点到屏幕空间的投影

2011-03-07 15:19 316 查看
有两种方法,一种是利用gluProject函数:

GLdouble modelview[16];
GLdouble projection[16];
GLdouble out[3], in[3];
// 对in赋值……
glPushMatrix();
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
gluProject(in[0],in[1],in[2],modelview,projection,viewport,&(out[0]),&(out[1]),&(out[2]));


gluProject源码:

/*
Transform a point(column vector) by a 4x4 matrix. Then, out = m * in
Input: m ----- the 4x4 matrix, in ---- the 4x1 vector
Output: out ---- the resulting 4x1 vector
*/
static void transform_point(GLdouble out[4], const GLdouble m[16], const GLdouble in[4])
{
#define M(row,col) m[col*4+row]
out[0] =
M(0, 0) * in[0] + M(0, 1) * in[1] + M(0, 2) * in[2] + M(0, 3) * in[3];
out[1] =
M(1, 0) * in[0] + M(1, 1) * in[1] + M(1, 2) * in[2] + M(1, 3) * in[3];
out[2] =
M(2, 0) * in[0] + M(2, 1) * in[1] + M(2, 2) * in[2] + M(2, 3) * in[3];
out[3] =
M(3, 0) * in[0] + M(3, 1) * in[1] + M(3, 2) * in[2] + M(3, 3) * in[3];
#undef M
}
// gluProject source code (说明见OpenGL API文档)
GLint gluProject(GLdouble objx, GLdouble objy, GLdouble objz, const GLdouble  modelMatrix[16], const GLdouble projMatrix[16], const GLint viewport[4], GLdouble *winx, GLdouble *winy, GLdouble *winz)
{
// matrice transformation
GLdouble in[4], out[4];
//initialize matrice and column vector as a transformer
in[0] = objx;
in[1] = objy;
in[2] = objz;
in[3] = 1.0;
transform_point(out, modelMatrix, in);  //乘以模型视图矩阵
transform_point(in, projMatrix, out);   //乘以投影矩阵
//齐次向量的第四项不能为0
if(in[3] == 0.0)
return GL_FALSE;
//向量齐次化标准化
in[0] /= in[3];
in[1] /= in[3];
in[2] /= in[3];
//视口向量的作用
*winx = viewport[0] + (1 + in[0]) * viewport[2] / 2;
*winy = viewport[1] + (1 + in[1]) * viewport[3] / 2;
*winz = (1 + in[2]) / 2;
return GL_TRUE;
}


第二种方法就是实现gluProject,照着源码实现就可以了,需要注意的是OpenGL的矩阵是列主序存储的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: