OpenGL 中的左手计算

发布于 2024-12-01 18:10:18 字数 261 浏览 3 评论 0原文

中断两年后,我又回到了游戏编程领域。不幸的是,我对 3D 数学的大部分知识都相当生疏。所以请耐心听我说。

我的引擎和游戏最初是为 DirectX 设计的,它是一个使用行主矩阵结构的左手系统。我的数学代码都是自制的,并且在该系统的范围内完美运行。我现在想为我的游戏提供 OpenGL 渲染器。由于我所有的数学都使用左手行主矩阵系统(例如,创建投影矩阵),因此将我的数学移植到 OpenGL 的左手列主系统有多难?

是转置矩阵并将值粘贴到列主结构中的问题吗?或者我是否过于简化了?

I'm jumping back into the world game programming after a 2yr hiatus. Unfortunately, most of my knowledge pertaining to 3D math is rather rusty. So bear with me.

My engine and game were originally designed for DirectX, which is a left-handed system that uses a row-major Matrix structure. My math code is all home-brew and works perfectly within the confines of that system. I'm at a point where I want to give my game an OpenGL renderer. Since all my math uses a left-handed, row-major Matrix system (for example, to create a projection matrix), how hard would it be to port my math to OpenGL's left-handed, column major system?

Is it a matter of transposing the matrix and sticking the values into a column-major struct? Or am I simplifying this too much.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

凉月流沐 2024-12-08 18:10:18

这取决于。我们谈论的是基于着色器的 OpenGL 还是固定功能 (FF)?

在 FF 领域,您需要做的是使用 gluPerspective(或 glFrustum)生成透视矩阵,使用与在 D3D 下为代码提供的类似参数。然后,您需要转置为 D3D 计算的矩阵(忽略计算的投影部分)以实现列主化,这正是 glLoad/MultMatrix 想要的方式。

然后,您需要生成一个矩阵来翻转场景,并将其放在 GL_MODELVIEW 堆栈的最底部。弄清楚要做什么的最简单方法就是渲染所有内容并查看世界是如何反转的。然后在那里粘贴一个沿轴取负的矩阵;如果这解决了问题,那么你就完成了。

在伪代码中,您要做的是:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(/*Projection parameters here*/);

glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(/*Your flip matrix here*/);
glPushMatrix();

//Render your stuff here.
//When rendering an object:
Matrix mat = ComputeD3DModelToCameraMatrixForObject();
mat = Transpose(mat);
glPushMatrix();
glMultMatrixf(GetMatrixAsFloatArray(mat));
//Draw the object.
glPopMatrix();

//When finished rendering stuff:
glPopMatrix();

在着色器中,事情更简单。这假设您使用自己的制服将矩阵传递给 GLSL。

实际上,您需要做的就是查看 OpenGL 使用的剪辑空间和 D3D 使用的剪辑空间之间的差异。剪辑空间是顶点着色器输出的顶点位置的空间。您可以像平常一样将矩阵传递给 GLSL,因为 glUniformMatrix 函数有一个参数,允许您指定矩阵是否转置(行优先)。一旦您像 D3D 那样计算了 D3D 剪辑空间位置,只需根据 OpenGL 的预期修改结果即可。

我不记得这些差异,但 OpenGL 规范第 2.13 节(在版本 3.3 中,对于其他版本可能是不同的部分)非常明确地详细说明了预期的坐标系,以及随后到窗口空间的转换。

It depends. Are we talking shader-based OpenGL or fixed-function (FF)?

In FF land, what you need to do is use gluPerspective (or glFrustum) to generate your perspective matrix, using similar parameters that you would give to your code under D3D. Then, you need to transpose the matrices you would compute for D3D (leaving out the projection component of the computation) to make the column-major, the way that glLoad/MultMatrix wants.

And then, you need to generate a matrix to flip your scene, which you put at the very bottom of the GL_MODELVIEW stack. The easiest way to figure out what to do is to just render everything and see how the world is inverted. Then stick a matrix there which negates along an axis; if that fixes it, you're done.

In pseudo-code, what you do is this:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(/*Projection parameters here*/);

glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(/*Your flip matrix here*/);
glPushMatrix();

//Render your stuff here.
//When rendering an object:
Matrix mat = ComputeD3DModelToCameraMatrixForObject();
mat = Transpose(mat);
glPushMatrix();
glMultMatrixf(GetMatrixAsFloatArray(mat));
//Draw the object.
glPopMatrix();

//When finished rendering stuff:
glPopMatrix();

In shaders, things are simpler. This assumes that you're using your own uniforms to pass matrices to GLSL.

Really, all you need to do is look at the differences between the clip-space that OpenGL uses and the clip-space that D3D uses. Clip-space is the space of the vertex positions output from the vertex shader. You can pass your matrices to GLSL as normal, since the glUniformMatrix functions have a parameter that allows you to specify if the matrix is transposed (row-major). Once you have computed the D3D clip-space positions as you would have for D3D, simply modify the results based on what OpenGL expects.

I don't recall the differences off-hand, but the OpenGL specification section 2.13 (in version 3.3, it may be a different section for other versions) very explicitly details the coordinate system expected, as well as the subsequent transformations to window-space.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文