2014-06-19 9 views
0

화면의 작은 영역을 화면 밖의 텍스처로 렌더링하려고합니다. 이것은 사용자가 화면에서 영역을 선택하고이를 이미지에 저장하는 내 앱의 스크린 샷 기능의 일부입니다. 화면의 영역은 250x250 픽셀 일 수 있지만 저장된 이미지는 1000x1000 픽셀과 같이 훨씬 커질 수 있습니다.화면의 OpenGL 렌더링 부분이 텍스처로 변환됩니다.

FBO를 사용하여 텍스처를 렌더링하는 과정을 이해합니다. 스크린 샷 영역 만 렌더링되도록 장면을 클리핑하는 투영 행렬을 정의 할 때 주로 방해받습니다.

+0

나는 왜 이미지가 "훨씬 더 커질 수 있습니다"라고 생각하지 않습니다. 당신은 정교 할 수 있습니까? – peppe

+0

저는 전통적인 감각으로 스크린 샷을 찍는 것이 아니라 스크린 샷 영역 내에서만 장면을 렌더링합니다. 렌더링 행렬이 올바른 경우 뷰포트를 원하는 크기로 설정할 수 있어야합니다. – Sean

+0

선택한 사각형을 저장하기 위해'glReadPixels'을 사용할 수 없습니까? 내가 뭔가를 놓친 것 같아 :) – peppe

답변

0

gluPickMatrix의 작동 방식을 살펴보고 최신 OpenGL 방법을 사용하여 기능을 복제 할 수 있습니다. Mesa3D의 구현에서 gluPickMatrix 소스 코드를 찾을 수 있습니다.

gluPickMatrix의 원래 의도는 선택 모드 렌더링을위한 것이었지만 원하는대로 사용할 수도 있습니다.

0

저는 프로젝션 매트릭스를 변경하지 않고도이 작업을 수행 할 수 있다고 생각합니다. 결국, 당신이 생각한다면, 당신은 투영을 정말로 바꾸고 싶지 않습니다. 투영 된 지오메트리의 어느 부분이 렌더링 화면에 매핑되는지를 변경하려고합니다. 투영 후의 좌표계는 NDC (정규화 된 장치 좌표)입니다. NDC가 렌더링 표면에 매핑되는 방법을 제어하는 ​​변환은 뷰포트 변환입니다. 매개 변수를 사용하여 뷰포트 변환을 glViewport()으로 제어합니다.

뷰포트 크기를 렌더링 표면의 크기로 설정하면 [-1.0, 1.0]의 NDC 범위를 렌더링 화면에 매핑합니다. 해당 NDC 범위의 하위 범위를 표면에 렌더링하려면 지정된 뷰포트 크기를 적절하게 확대해야합니다. 원본 이미지의 1/4을 서페이스 너비에 매핑한다고 가정하면 뷰포트 너비를 서페이스 너비의 4 배로 설정합니다.

표준 NDC 범위의 하위 범위를 표면에 매핑하려면 뷰포트의 원점을 조정해야합니다. 이 경우 뷰포트 원점 값은 음수가됩니다. 앞의 예제를 계속하면 이미지의 중간에서 1/4 또는 원본 이미지를 매핑하기 위해 뷰포트 원점의 x 값이 표면 너비의 -2 배가됩니다.

다음은 뷰포트 조정 방법에 대한 설명입니다. 다음과 같은 정의를 사용 :

winWidth: width of original window 
winHeight: height of original window 
xMin: minimum x-value of zoomed region in original window coordinates 
xMax: maximum x-value of zoomed region in original window coordinates 
yMin: minimum y-value of zoomed region in original window coordinates 
yMax: maximum y-value of zoomed region in original window coordinates 
fboWidth: width of FBO you use for rendering zoomed region 
fboHeight: height of FBO you use for rendering zoomed region 

왜곡을 방지하기 위해, 당신은 아마 가로 세로 비율을 유지하는 것이 좋습니다 : 다음의 모든에서

fboWidth/fboHeight = (xMax - xMin)/(yMax - yMin) 

을, 작업 (특히 부서)의 대부분은있을 것이다 부동 소수점에서 실행된다. 원래 변수가 정수인 경우 형식 캐스트를 사용하고 결과를 정수로 다시 반올림하여 최종 결과를 얻으십시오.

xZoom = winWidth/(xMax - xMin); 
yZoom = winHeight/(yMax - yMin); 
vpWidth = xZoom * fboWidth; 
vpHeight = yZoom * fboHeight; 
xVp = -(xMin/(xMax - xMin)) * fboWidth; 
yVp = -(yMin/(yMax - yMin)) * fboHeight; 
glViewport(xVp, yVp, vpWidth, vpHeight);