矩阵类 Directx & OpenGL

发布于 2024-08-13 13:25:25 字数 1513 浏览 2 评论 0原文

我有以下 C++ 矩阵类:

transform.h transform.cpp

我将其与渲染器结合使用,其中有一个 opengl 和一个 directx 实现。

我有一个测试示例,其中窗口内鼠标的坐标用于将图形定位在光标下方。这在 OpenGL 下按预期工作。

因为 directx 是行主,而 opengl 是列主,所以我按如下方式反转矩阵,并在渲染之前将其传递给 directx:

        if(o->tree){
            CObjectTransform* t = o->tree->GetTransform(o->transformID);
            D3DMATRIX d;
            float* m = (float*)&d;
            for (int u=0; u<4; u++){
                for (int v=0; v<4; v++){
                    m[u +v*4] = t->worldtransform.matrix[v+u*4];
                }
            }
            pd3dDevice->SetTransform(D3DTS_WORLD, &d);
        }

其结果是,无论我将光标放在这里,图形的可见区域中都没有显示任何内容。

那么:

  1. 我的转换类是否正确实现?
  2. 我如何让它与 directx 一起工作?

编辑:

设置了以下代码:

            float* m = (float*)&d;
            for (int u=0; u<4; u++){
                for (int v=0; v<4; v++){
                    m[u +v*4] = t->worldtransform.matrix[v+u*4];
                }
            }
            float test[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
            memcpy(test,&d,sizeof(d));

矩阵类的值:

1,0,0,0
0,1,0,0
0,0,1,0
47,-30,0,1

交换矩阵的值:

1,0,0,47
0,1,0,-30
0,0,1,0
0,0,0,1

所以矩阵正在被交换。这排除了交换轮代码作为问题原因的可能性。

I have the following C++ matrix class:

transform.h transform.cpp

I am using this coupled with a renderer, for which there is an opengl and a directx implementation.

I have a test example where the coordinates of the mouse within the window are used to position a graphic under the cursor. This works as expected under OpenGL.

Because directx is row major and opengl is column major, I reverse the matrix as follows and pass it to directx before rendering:

        if(o->tree){
            CObjectTransform* t = o->tree->GetTransform(o->transformID);
            D3DMATRIX d;
            float* m = (float*)&d;
            for (int u=0; u<4; u++){
                for (int v=0; v<4; v++){
                    m[u +v*4] = t->worldtransform.matrix[v+u*4];
                }
            }
            pd3dDevice->SetTransform(D3DTS_WORLD, &d);
        }

The result of this is nothing is shown in the visible area from the graphics, regardless of here I put my cursor.

So:

  1. Is my transform class correctly implemented?
  2. How do I get it working with directx?

edit:

the following code was setup:

            float* m = (float*)&d;
            for (int u=0; u<4; u++){
                for (int v=0; v<4; v++){
                    m[u +v*4] = t->worldtransform.matrix[v+u*4];
                }
            }
            float test[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
            memcpy(test,&d,sizeof(d));

The values of the matrix class:

1,0,0,0
0,1,0,0
0,0,1,0
47,-30,0,1

The values of the swapped matrix:

1,0,0,47
0,1,0,-30
0,0,1,0
0,0,0,1

So the matrix is being swapped around. This rules out the swapping round code as the cause of the problem.

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

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

发布评论

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

评论(3

半步萧音过轻尘 2024-08-20 13:25:25

OpenGL 和 DirectX 具有相反的矩阵表示形式,但它们也具有相反的向量 * 矩阵 顺序:

  • OpenGL:M * v。 M 是 DirectX 内存中的主列
  • v * M。 M 是内存中的主行,

因为乘法是相反的,您必须转置 OpenGL 矩阵才能传递给 DX。但由于DX使用行专业,所以必须再次转置。转置两次真是恒等式。

您尝试完全不进行任何转换怎么样?

OpenGL and DirectX have opposing matrix representations, but they also have opposite vector * matrix order:

  • OpenGL: M * v. M is column major in memory
  • DirectX: v * M. M is row major in memory

since the multiplication is reversed, you have to transpose your OpenGL matrix to pass to DX. But since DX uses row major, you have to transpose again. Transpose twice is really the identity.

How about you try with no transformation at all ?

吐个泡泡 2024-08-20 13:25:25

我假设您将其编译为 C++。
这:

m[u,v] = t->worldtransform.matrix[v,u];

可能没有做你想做的事。在 C++ 中,二维数组的索引为 m[u][v]
该行实际上所做的是使用 , 运算符来计算其语句,因此 m[u,v] 实际上返回了 float v 坐标。

你可能想做的是这样的:

m[u + 4*v] = t->worldtransform.matrix[v + 4*u];

I'm assuming you're compiling this as C++.
This:

m[u,v] = t->worldtransform.matrix[v,u];

Probably doesn't do what you want it to do. in C++, a 2D array is indexed as m[u][v].
What this line actually does is use the , operator which evaluates to its statement, so m[u,v] actually returns the float of the v coordinates.

what you probably want to do is this:

m[u + 4*v] = t->worldtransform.matrix[v + 4*u];
虫児飞 2024-08-20 13:25:25

您会发现,在上面显示的 2 个矩阵中,第一个是正确的 DirectX 矩阵。第二个在 DX 下根本不起作用......

You appreciate that, of the 2 matrices you show above, the first is a correct DirectX matrix. The second will not work under DX at all ...

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