2014-10-06 149 views
10

我遇到了嘗試在沒有OpenGL的環境中複製OpenGL行爲的問題。在沒有OpenGL的情況下複製OpenGL正投影行爲

基本上我需要從我的程序創建的行列表中創建一個SVG文件。這些線是使用潦草的投影創建的。

我確定這些行的計算是正確的,因爲如果我嘗試使用正交投影的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) 

我計算這樣的攝影投影矩陣:

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); 

and the vie w ^矩陣是這樣的:

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); 

結果我從OpenGL和從SVG輸出得到有很大的不同,但在兩天內我不能拿出一個解決方案。

這是OpenGL的輸出 enter image description here

這是我的SVG輸出 enter image description here

正如你可以看到,它的轉動不corrent。

任何想法爲什麼?希望的是,線條點和矩陣也是一樣的。


爲我創建的矩陣無效。我的意思是,矩陣錯了,我想,因爲OpenGL沒有顯示任何東西。 所以我試着做相反的事情,我在OpenGL中創建了矩陣,並將它們與我的代碼一起使用。結果會更好,但還不完美。

現在我認爲我做錯了將3D點映射到2D屏幕點,因爲我得到的點在Y中是倒置的,而且我仍然有一些線不完全匹配。

這是我得到使用OpenGL的矩陣和我以前的方法來繪製3D點到2D屏幕空間(這是SVG,不是OpenGL的渲染):

enter image description here


確定這在視圖矩陣的內容從我的OpenGL得到:

enter image description here

這是投影矩陣我從OpenGL的獲得:

enter image description here

這是結果我與矩陣獲得,並通過改變我的2D點Y座標的計算像bofjas說:

enter image description here

它看起來像一些輪換缺失。我的相機在X和Y軸上的旋轉角度都是30°,看起來他們的計算不正確。

現在我使用的是同一個矩陣的OpenGL一樣。所以我認爲當我將3D點映射到2D屏幕座標時,我正在做一些錯誤的計算。

+1

僅供參考:你的方法缺乏投影變換後的均勻劃分。對於正射投影而言無關緊要,但對透視投影起作用至關重要。至於你的SVG情況下的不良輪換,我還得研究一下。 – datenwolf 2014-10-06 16:32:21

+0

BTW:如果您加載您創建的矩陣轉換成OpenGL和嘗試渲染使用這些圖像會發生什麼? 'glMatrixMode(...); glLoadMatrix(...)'在你使用固定功能流水線的情況下。 – datenwolf 2014-10-06 16:33:44

+0

和btw你可以打印矩陣的內容。 – joojaa 2014-10-06 16:38:54

回答

1

比調試自己的代碼,相反,你可以使用transform feedback來計算用OpenGL管道的線路的預測。而不是在屏幕上柵格化它們,您可以將它們捕獲到內存緩衝區中,然後直接保存到SVG中。設置它有點牽扯,取決於OpenGL代碼路徑的確切設置,但它可能是一個更簡單的解決方案。

根據你自己的代碼,它看起來像你要麼混合X和Y座標的地方,或行優先和列優先矩陣。

0

我在一個非常簡單的方法解決了這個問題。因爲當我使用OpenGL繪製它時,我剛剛在OpenGL中創建了矩陣,然後使用glGet()檢索它們。使用這些矩陣,一切都很好。

+0

在你的文章的最後一部分,你說「我使用相同的矩陣OpenGL」,你仍然有問題。如果不是'glGet'命令,你還能確定它們是否是相同的矩陣? – ybungalobill 2015-06-01 21:25:24