2014-10-06 2 views
10

OpenGL이없는 환경에서 OpenGL 동작을 복제하는 동안 문제가 발생했습니다.OpenGL없이 중복 된 OpenGL 정방 투영 동작

기본적으로 내 프로그램에서 만드는 행 목록에서 SVG 파일을 만들어야합니다. 이 선은 Othigraphic 투영을 사용하여 작성됩니다.

OpenGL 컨텍스트와 정사영 투영을 사용하여 결과를 이미지에 저장하려고하면 이미지가 올바르게 표시되므로이 선이 올바르게 계산 된 것입니다.

OpenGL없이 정확히 같은 줄을 사용하면 문제가 발생합니다.

나는 OpenGL을 투사 볼 행렬을 복제 한 내가 이런 모든 선의 점 처리 :

2D_point_x = (windowWidth/2) * 3D_point_x + (windowWidth/2) 
2D_point_y = (windowHeight/2) * 3D_point_y + (windowHeight/2) 
: 나는 계산

3D_output_point = projection_matrix * view_matrix * 3D_input_point 

하고 그것을 화면은 다음과 같이 (SVG 파일)의 위치입니다

다음과 같은 등 투영 투영 행렬을 계산합니다.

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

매트릭스 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 출력에서 ​​얻을 결과지만, 이틀에 내가 해결책을 마련 할 수 없었다. 그것은 회전 corrent되지이다,

는 OpenGL을 출력 enter image description here

입니다 그리고 당신이 볼 수 있듯이이 내 SVG 출력 enter image description here

입니다.

왜 그런가? 라인 포인트는 동일하고 매트릭스도 역시 잘하면 있습니다.


작성중인 행을 취소하면 작동하지 않습니다. OpenGL이 아무 것도 보여주지 않았기 때문에 매트릭스가 틀렸다고 생각합니다. 그래서 반대쪽을 시도해 보았습니다. OpenGL에서 행렬을 만들고 코드와 함께 사용했습니다. 그 결과는 더 좋지만 완벽한 것은 아닙니다.

이제 3D 포인트를 2D 스크린 포인트로 매핑하는 것이 잘못되었다고 생각합니다. 포인트가 Y에서 반전되고 일부 라인이 완벽하게 일치하지 않기 때문입니다.

enter image description here


이 확인 :

내가 2D 화면 공간에 3D 점을 (이는 SVG입니다 렌더링 OpenGL은하지 않음) 매핑 할 OpenGL은 매트릭스 내 이전 방법을 사용하여 무엇을 얻을 나는 OpenGL을에서보기 매트릭스의 내용을 얻을 수있다 :

enter image description here

이것은 투영 행렬 I입니다 OpenGL을에서 얻을 :

enter image description here

을 그리고 이것은 내가 그 행렬에 얻을 결과 내 2D 포인트를 변경하여 Y는 bofjas 같은 좌표 계산 말했다

enter image description here

그것은 약간의 회전과 같은 를 찾을 수 없다. 내 카메라는 X 축과 Y 축 모두에서 30 °의 회전을 가지며 올바르게 계산되지 않은 것처럼 보입니다.

이제 OpenGL과 동일한 행렬을 사용하고 있습니다. 그래서 3D 점을 2D 화면 좌표로 매핑 할 때 잘못된 계산을하고 있다고 생각합니다.

+1

그냥 FYI : 귀하의 방법은 투영 변환 후 균질 분할이 없습니다. 직교 투영은 중요하지 않지만 원근 투영이 작동하려면 매우 중요합니다. 당신의 SVG 케이스에서 잘못된 회전에 관해서는, 나는 그것을 아직 조사해야 할 것입니다. – datenwolf

+0

BTW : 만든 행렬을 OpenGL에로드하고이를 사용하여 이미지를 렌더링하면 어떻게됩니까? 'glMatrixMode (...); glLoadMatrix (...)'함수를 호출합니다. – datenwolf

+0

그리고 행렬의 내용을 인쇄 할 수 있습니다. – joojaa

답변

1

자신의 코드를 디버깅하는 대신 transform feedback을 사용하여 OpenGL 파이프 라인을 사용하여 선의 투영을 계산할 수 있습니다. 화면에서 래스터 화하는 대신 메모리 버퍼에 캡처하여 나중에 SVG에 직접 저장할 수 있습니다. 이 설정은 조금 복잡하고 OpenGL 코드 패드의 정확한 설정에 따라 다르지만 더 간단한 해결책 일 수 있습니다.

코드에 따라 x 및 y 좌표를 어딘가에 혼합하거나 행 및 행렬 행렬을 혼합 한 것처럼 보입니다.

0

정말 간단한 방법으로이 문제를 해결했습니다. OpenGL을 사용하여 그릴 때부터, OpenGL에서 행렬을 작성한 다음 glGet()을 사용하여 검색했습니다. 그 행렬을 사용하면 모든 것이 괜찮습니다.

+0

게시물의 마지막 섹션에서 "OpenGL과 동일한 행렬을 사용하고 있습니다."라고 말하면서 문제가 발생했습니다. 'glGet' 명령을 사용하지 않으면 그 행렬들이 같은 행렬인지 어떻게 알 수 있습니까? – ybungalobill