Jay*_*rod 26
首先,一些背景.在3D图形中,您需要担心几个向量空间:
[-1, +1]每个维度的间隔.坐标是均匀指定的,因此每个矢量都有分量(x, y, z, w),其中w是比例因子.您可以获得3空格中的坐标(x/w, y/w, z/w).某些变换需要缩放因子,例如透视投影,这对非均匀坐标是不可能的.
需要4x4矩阵来将坐标从一个向量空间转换为另一个向量空间.你可以有三种不同的矩阵:
您可以C使用以下公式将坐标投影到屏幕上:
C' = P * V * M * C
Run Code Online (Sandbox Code Playgroud)
OpenGL内部维护两个矩阵:modelview(模型和视图相乘)和投影.还有一个我们不会担心的纹理矩阵.当你打电话时glMatrixMode,你正在这些矩阵之间切换.使用标识矩阵替换当前矩阵glLoadIdentity.您应用转换到当前的矩阵状的功能glTranslatef,glRotatef或gluProjection.这些函数中的每一个只创建一个4x4矩阵,即特定变换的实现,然后将当前矩阵乘以它.您可以在OpenGL 2.1参考页面中看到转换矩阵是什么.
现在为实际答案.您需要为场景中的每个对象维护一个4x4模型矩阵.模型矩阵将包含将模型坐标更改为世界坐标所需的所有变换.例如,每次调用时glTranslate,都会更新模型矩阵:
T = [ 1 0 0 x ]
[ 0 1 0 y ]
[ 0 0 1 z ]
[ 0 0 0 1 ]
M' = M * T
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用模型矩阵将坐标转换为世界空间(确保它们首先是同质坐标; w = 1如果不是,则设置它们):
V' = V * M
Run Code Online (Sandbox Code Playgroud)
由于您并行维护这些转换,因此实际上不需要维护OpenGL模型视图矩阵.您可以将模型矩阵作为制服传递到着色器.您可以用类似的方式维护自己的视图和投影矩阵.这在最近的OpenGL版本中是必需的; 不推荐使用所有矩阵处理函数.
您可以使用虚拟摄像机视图矩阵的逆(V -1)乘以对象的模型视图矩阵(V * M)的乘积来获得世界坐标。
您可以使用以下命令在gluLookAt()函数之后获得V:
glGetFloatv(GL_MODELVIEW_MATRIX,camViewMatrix)
然后将矩阵求逆并存储(用于稍后在代码中相乘)。
在使用相同的GL函数执行所有glTranslatef(),glRotatef()和glScale()命令之后,您将在要绘制对象的点得到V * M:
glGetFloatv(GL_MODELVIEW_MATRIX,objectsModelViewMatrix);
V -1 *(V * M)== M
然后将两个矩阵相乘,结果矩阵包含位置m12 = x,m13 = y和m14 = z
有关C代码的更多详细信息,请访问:https : //sourceforge.net/p/openantz/wiki/Local_to_World_Coordinates/