加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 没有OpenGL的OpenGL正面投影行为的重复

发布时间:2020-12-16 06:44:18 所属栏目:百科 来源:网络整理
导读:我试图在没有OpenGL的环境中复制OpenGL行为时遇到问题. 基本上我需要从我的程序创建的行列表创建一个SVG文件.这些线是使用一个ostique投影创建的. 我确定这些行是正确计算的,因为如果我尝试使用OpenGL上下文与正投影并将结果保存到图像中,图像是正确的. 当我
我试图在没有OpenGL的环境中复制OpenGL行为时遇到问题.

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

我确定这些行是正确计算的,因为如果我尝试使用OpenGL上下文与正投影并将结果保存到图像中,图像是正确的.

当我使用没有OpenGL的完全相同的行时,会出现这个问题.

我已经复制了OpenGL投影和查看矩阵,并且我像这样处理每个线点:

3D_output_point = projection_matrix * view_matrix * 3D_input_point

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

2D_point_x = (windowWidth / 2) * 3D_point_x + (windowWidth / 2)
2D_point_y = (windowHeight / 2) * 3D_point_y + (windowHeight / 2)

我计算这个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,2.0f / (r - l));
matProj.SetValore(0,1,0.0f);
matProj.SetValore(0,2,3,0.0f);

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

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

matProj.SetValore(3,-(r + l) / (r - l));
matProj.SetValore(3,-(t + b) / (t - b));
matProj.SetValore(3,-n / (f - n));
matProj.SetValore(3,1.0f);

和视图矩阵这样:

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,xAxis[0]);
matView.SetValore(0,yAxis[0]);
matView.SetValore(0,zAxis[0]);
matView.SetValore(0,0.0f);

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

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

matView.SetValore(3,result1);
matView.SetValore(3,result2);
matView.SetValore(3,result3);
matView.SetValore(3,1.0f);

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

这是OpenGL输出

这是我的SVG输出

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

任何想法为什么?线点也是一样的,也是矩阵,希望.

正在创建的矩阵不正常.我的意思是,矩阵是错误的,我认为,因为OpenGL没有显示任何东西.
所以我试着做相反的,我在OpenGL中创建了矩阵,并用我的代码.结果更好,但还不完美.

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

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

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

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

这就是我用这些矩阵和通过改变我的二维点Y坐标计算得到的结果,如bofjas所说:

看起来有些旋转丢失了.我的相机在X轴和Y轴都有30°的旋转,看起来它们的计算不正确.

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

解决方法

而不是调试自己的代码,您可以使用 transform feedback来使用OpenGL管道来计算线条的投影.而不是在屏幕上光栅化它们,您可以将它们捕获在内存缓冲区中,并直接保存到SVG中.设置它有点涉及,取决于您的OpenGL编码方法的确切设置,但它可能是一个更简单的解决方案.

根据你自己的代码,它看起来像是将x和y坐标混合在一起,或者是行主要和列主要矩阵.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读