没有OpenGL的重复OpenGL正交投影行为

zeb*_*zeb 10 c++ opengl matrix

我在没有OpenGL的环境中尝试复制OpenGL行为时遇到了问题.

基本上我需要从我的程序创建的行列表中创建一个SVG文件.这些线是使用othigraphic投影创建的.

我确信这些行是正确计算的,因为如果我尝试将它们与具有正交投影的OpenGL上下文一起使用并将结果保存到图像中,则图像是正确的.

当我使用完全相同的行而没有OpenGL时,问题就出现了.

我复制了OpenGL投影和查看矩阵,我处理每个线点,如下所示:

3D_output_point = projection_matrix * view_matrix * 3D_input_point
Run Code Online (Sandbox Code Playgroud)

然后我像这样计算它的屏幕(SVG文件)位置:

2D_point_x = (windowWidth / 2) * 3D_point_x + (windowWidth / 2)
2D_point_y = (windowHeight / 2) * 3D_point_y + (windowHeight / 2)
Run Code Online (Sandbox Code Playgroud)

我像这样计算othographic投影矩阵:

float range = 700.0f;
float l, t, r, b, n, f;

l = -range;
r = range;
b = -range;
t = range;
n = -6000;
f = 8000;

matProj.SetValore(0, 0, 2.0f / (r - l));
matProj.SetValore(0, 1, 0.0f);
matProj.SetValore(0, 2, 0.0f);
matProj.SetValore(0, 3, 0.0f);

matProj.SetValore(1, 0, 0.0f);
matProj.SetValore(1, 1, 2.0f / (t - b));
matProj.SetValore(1, 2, 0.0f);
matProj.SetValore(1, 3, 0.0f);

matProj.SetValore(2, 0, 0.0f);
matProj.SetValore(2, 1, 0.0f);
matProj.SetValore(2, 2, (-1.0f) / (f - n));
matProj.SetValore(2, 3, 0.0f);

matProj.SetValore(3, 0, -(r + l) / (r - l));
matProj.SetValore(3, 1, -(t + b) / (t - b));
matProj.SetValore(3, 2, -n / (f - n));
matProj.SetValore(3, 3, 1.0f);
Run Code Online (Sandbox Code Playgroud)

和视图矩阵这样:

CVettore position, lookAt, up;

position.AssegnaCoordinate(rtRay->m_pCam->Vp.x, rtRay->m_pCam->Vp.y, rtRay->m_pCam->Vp.z);
lookAt.AssegnaCoordinate(rtRay->m_pCam->Lp.x, rtRay->m_pCam->Lp.y, rtRay->m_pCam->Lp.z);
up.AssegnaCoordinate(rtRay->m_pCam->Up.x, rtRay->m_pCam->Up.y, rtRay->m_pCam->Up.z);

up[0] = -up[0];
up[1] = -up[1];
up[2] = -up[2];

CVettore zAxis, xAxis, yAxis;
float length, result1, result2, result3;

// zAxis = normal(lookAt - position)
zAxis[0] = lookAt[0] - position[0];
zAxis[1] = lookAt[1] - position[1];
zAxis[2] = lookAt[2] - position[2];
length = sqrt((zAxis[0] * zAxis[0]) + (zAxis[1] * zAxis[1]) + (zAxis[2] * zAxis[2]));
zAxis[0] = zAxis[0] / length;
zAxis[1] = zAxis[1] / length;
zAxis[2] = zAxis[2] / length;

// xAxis = normal(cross(up, zAxis))
xAxis[0] = (up[1] * zAxis[2]) - (up[2] * zAxis[1]);
xAxis[1] = (up[2] * zAxis[0]) - (up[0] * zAxis[2]);
xAxis[2] = (up[0] * zAxis[1]) - (up[1] * zAxis[0]);
length = sqrt((xAxis[0] * xAxis[0]) + (xAxis[1] * xAxis[1]) + (xAxis[2] * xAxis[2]));
xAxis[0] = xAxis[0] / length;
xAxis[1] = xAxis[1] / length;
xAxis[2] = xAxis[2] / length;

// yAxis = cross(zAxis, xAxis)
yAxis[0] = (zAxis[1] * xAxis[2]) - (zAxis[2] * xAxis[1]);
yAxis[1] = (zAxis[2] * xAxis[0]) - (zAxis[0] * xAxis[2]);
yAxis[2] = (zAxis[0] * xAxis[1]) - (zAxis[1] * xAxis[0]);

// -dot(xAxis, position)
result1 = ((xAxis[0] * position[0]) + (xAxis[1] * position[1]) + (xAxis[2] * position[2])) * -1.0f;

// -dot(yaxis, eye)
result2 = ((yAxis[0] * position[0]) + (yAxis[1] * position[1]) + (yAxis[2] * position[2])) * -1.0f;

// -dot(zaxis, eye)
result3 = ((zAxis[0] * position[0]) + (zAxis[1] * position[1]) + (zAxis[2] * position[2])) * -1.0f;

// Set the computed values in the view matrix.
matView.SetValore(0, 0, xAxis[0]);
matView.SetValore(0, 1, yAxis[0]);
matView.SetValore(0, 2, zAxis[0]);
matView.SetValore(0, 3, 0.0f);

matView.SetValore(1, 0, xAxis[1]);
matView.SetValore(1, 1, yAxis[1]);
matView.SetValore(1, 2, zAxis[1]);
matView.SetValore(1, 3, 0.0f);

matView.SetValore(2, 0, xAxis[2]);
matView.SetValore(2, 1, yAxis[2]);
matView.SetValore(2, 2, zAxis[2]);
matView.SetValore(2, 3, 0.0f);

matView.SetValore(3, 0, result1);
matView.SetValore(3, 1, result2);
matView.SetValore(3, 2, result3);
matView.SetValore(3, 3, 1.0f);
Run Code Online (Sandbox Code Playgroud)

我从OpenGL和SVG输出得到的结果是完全不同的,但在两天内我无法提出解决方案.

这是OpenGL输出 在此输入图像描述

这是我的SVG输出 在此输入图像描述

正如你所看到的,它的旋转不是正确的.

知道为什么吗?线点是相同的,矩阵也是如此,希望如此.


根据我创建的矩阵不起作用.我的意思是,我认为矩阵是错误的,因为OpenGL没有显示任何内容.所以我试着反过来,我在OpenGL中创建了矩阵并将它们与我的代码一起使用.结果更好,但还不完美.

现在我认为我做错了将3D点映射到2D屏幕点,因为我得到的点在Y中反转,我仍然有一些不完全匹配的线.

这是我使用OpenGL矩阵和我之前将3D点映射到2D屏幕空间的方法(这是SVG,而不是OpenGL渲染):

在此输入图像描述


好的,这是我从OpenGL获得的视图矩阵的内容:

在此输入图像描述

这是我从OpenGL获得的投影矩阵:

在此输入图像描述

这是我用这些矩阵得到的结果,并通过改变我的2D点Y坐标计算,如bofjas说:

在此输入图像描述

看起来似乎缺少一些轮换.我的相机在X轴和Y轴上都旋转了30°,看起来它们的计算速度不正确.

现在我使用的是OpenGL所使用的相同矩阵.因此,当我将3D点映射到2D屏幕坐标时,我认为我正在做一些错误的计算.

ybu*_*ill 2

您可以使用变换反馈来使用 OpenGL 管道计算线条的投影,而不是调试自己的代码。您可以将它们捕获到内存缓冲区中,然后直接保存到 SVG,而不是在屏幕上光栅化它们。设置这个有点复杂,并且取决于 OpenGL 代码路径的确切设置,但这可能是一个更简单的解决方案。

根据您自己的代码,看起来您要么在某处混合了 x 和 y 坐标,要么混合了行主矩阵和列主矩阵。