2016-10-02 3 views
1

매 프레임마다 sceenshots를 가져와야하고 매우 높은 성능이 필요합니다 (저는 freeGlut을 사용하고 있습니다). 내가 알아 낸 것은 참으로 작업을 수행하지만 그것으로 큰 문제가, 정말 느리다는 glutIdleFunc(thisCallbackFunction)왜 glReadPixels가 느리고 다른 대안이 있습니까?

GLubyte *data = (GLubyte *)malloc(3 * m_screenWidth * m_screenHeight); 
glReadPixels(0, 0, m_screenWidth, m_screenHeight, GL_RGB, GL_UNSIGNED_BYTE, data); 
// and I can access pixel values like this: data[3*(x*512 + y) + color] or whatever 

내에서 다음과 같이 수행 할 수 있다는 것입니다. 내 윈도우가 512x512 일 때 큐브 만 렌더링 될 때 초당 90 프레임보다 빠른 속도로 실행됩니다.이 두 라인은 6500FPS에서 실행되지 않습니다! 우리는 그래픽 엔진으로 Irrlicht을 비교하면, 거기에 나는이

// irrlicht code 
video::IImage *screenShot = driver->createScreenShot(); 
const uint8_t *data = (uint8_t*)screenShot->lock(); 
// I can access pixel values from data in a similar manner here 

와 512 × 512 창에도 큰 메쉬 (퀘이크 3 맵)로드 400 FPS로 작동 할 수있다! irrlicht 내에서 OpenGL을 드라이버로 사용하고 있다는 점을 감안하십시오. 내 경험이없는 눈에 그것은 (uint8_t*)screenShot->lock() 그냥 이미 존재하는 배열에 대한 포인터를 복사하는 동안 glReadPixels 한 곳에서 다른 모든 픽셀 데이터를 복사하는 것 같습니다. FreeGlut을 사용하여 후자와 비슷한 것을 할 수 있습니까? irrlicht보다 빠를 것으로 기대합니다. 으로 Irrlicht가 너무 OpenGL을 사용하는 것이

주 (물론 그것뿐만 아니라 DirectX와 다른 옵션을 제공하지만 내가 위에서 준 예제에서 나는 OpenGL을 사용하고 그런데 그것이 가장 빠른 다른 옵션 비교 하였다)

+1

비동기 적으로 처리 할 수있는 픽셀 버퍼 객체를 찾으십시오. – immibis

+2

코드를 유휴 기능에 넣으면 프레임 당 두 번 이상 호출 될 수 있습니다. 또한 할당 한 데이터를 절대 사용하지 않으면 메모리가 누출됩니다. –

+0

@RetoKoradi 글쎄, 아니, 나는 문자 그대로 '유휴'가 호출 될 때마다이 줄을 실행하지 않는다. 'data'는 생성자에서 한 번만 할당되며, 반복해서 사용합니다. 이제 PBO를 조사하고 있습니다 .... –

답변

2

의 OpenGL 방법은 렌더링 파이프 라인을 관리하는 데 사용됩니다. 본질적으로, 그래픽 카드가 뷰어에게 이미지를 보여주는 동안, 다음 프레임의 계산이 수행되고 있습니다. 전화 할 때 glReadPixels; 그래픽 카드는 현재 프레임이 완료 될 때까지 기다린 후 픽셀을 읽고 다음 프레임 계산을 시작합니다. 따라서 파이프 라인은 정지되고 순차적이됩니다.

버퍼를 두 개 잡고 그래픽 카드에 각 프레임을 교환하는 버퍼로 데이터를 읽도록 지시 할 수 있다면; 버퍼 1 프레임에서 늦게 읽을 수 있지만 파이프 라인을 지연시키지 않습니다. 이를 이중 버퍼링이라고합니다. 2 프레임 늦게 다시 읽기 등으로 트리플 버퍼링을 수행 할 수도 있습니다. 현상 여기 구현을 설명하는 비교적 오래된 웹 페이지가 있습니다

: http://www.songho.ca/opengl/gl_pbo.html 또한 프레임 버퍼 및 웹에 텍스처로 렌더링에 대한 자습서 많이 있습니다

. 그들 중 하나는 여기에 있습니다 : http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-14-render-to-texture/

+0

텍스처로 렌더링하는 방법을 알아 냈습니다 만이 텍스처를 메인 버퍼로 옮겨서 화면에 표시되도록하는 방법을 모릅니다. 인덱스를 사용하여이 텍스처의 픽셀 값에 액세스합니다 (질문에서 보았 듯이). 어떻게해야합니까? –

+0

백 버퍼를'DRAW_BUFFER'로 바인딩하고 텍스쳐 프레임 버퍼를'READ_BUFFER' apriori로 바인딩함으로써'glBlitFramebuffer'를 사용할 수 있습니다. 이것은 이미지를 화면에 표시하기위한 것입니다. 픽셀 값을 읽으려면 픽셀 버퍼 객체 (a.k.a. PBO)를 사용하십시오. – zahir

+0

프레임 버퍼 객체 (내 장면을 렌더링 한 곳)에서 메인 버퍼로 이미지를 이동하여 화면에 표시되도록했지만 여전히 픽셀 값에 액세스 할 수 없었습니다. 이 튜토리얼 (http://www.songho.ca/opengl/gl_pbo.html)은 나를 따라 가기가 쉽지 않은데, 소스 코드는 600 줄이고, 외모는 정말 복잡합니다. 어떻게해야합니까? 그것에 대해 다른 질문을 구체적으로 물어보십시오. 나는 정확히 무엇을 물어야하는지조차 모른다.어떤 조언을 주시면 감사하겠습니다. –

관련 문제