2009-11-13 7 views
9

OpenGL 3.x 자체에 대한 최신 정보는 거의없는 것 같지만 실제로 OpenGL의 낮은 수준의 조작은 비교적 간단합니다. 그러나 저는 동적 인 세계를 만들기 위해 어떻게 VBO를 조작하는지 개념화하려고하는 데 심각한 문제가 있습니다.어떻게하면 OpenGL 3.x VBO를 사용하여 역동적 인 세계를 렌더링 할 수 있습니까?

당연히 예전 모드 방식은 적용 할 수 없지만 거기에서 나는 어디로 가야합니까? 일종의 장면 구조를 작성한 다음이를 정점 집합으로 변환하고 VBO로 스트리밍하면 변환 데이터가 어떻게 저장됩니까? 그렇다면 어떻게 코드 현명하게 보일까요?

계속하는 방법을 기본적으로 잘 모릅니다.

답변

9

전체 세계가 진정으로 동적 인 경우, 당신은 GL_STREAM_DRAW_ARB 사용 플래그를 사용할 수 있습니다 각 프레임의 데이터를 재설정하십시오. 그것을 다루는 것을 괴롭히지 말고 가능한 한 효율적으로 스트리밍하십시오.

그러나 서로에 대해 상대적으로 움직이는 여러 개의 강체로 구성된 장면이 있다고 가정합니다. 이 경우 각 개체에 하나의 VBO를 사용하고 GL_STATIC_DRAW_ARB 사용 플래그를 지정하십시오. 그런 다음 객체의 각 인스턴스에 대해 modelview 변형을 설정하고 인스턴스 당 하나의 그리기 호출을 사용하여 렌더링 할 수 있습니다.

(PC에서) 경험적 규칙은 CPU의 MHz 당 하나 이상의 그리기 호출을 발행하는 것입니다. 이것은 미숙 한 견적이지만, 그것에 대한 진실이 있습니다. 이 제한을 벗어나면 여러 개의 독립적 인 객체를 단일 VBO 또는 다른 성능 트릭에 배치하는 것에 대해 걱정할 필요가 없습니다.

+1

+1 요즘 그래픽 코딩에서 가장 큰 문제로 일괄 처리를 인식하고 있습니다. 일부 OpenGL ES iPhone 코딩 후에는 Mhz 당 1 회의 드로 콜이 나에게 낙관적으로 보입니다. - 괜찮은 프레임 속도를 유지하기 위해 30-40 배치로 제한됩니다. – tsalter

+0

이 규칙은 휴대 기기에 직접 적용되지 않을 수도 있습니다. 몇 년 전 GDC 슬라이드에서 처음 보았습니다. Windows PC에서도 잘 작동했습니다. –

+0

Btw, 방금 슬라이드를 찾았습니다 : http://ati.amd.com/developer/gdc/D3DTutorial3_Pipeline_Performance.pdf (주로 D3D9, 28 페이지의 OpenGL) –

5

VBO를 사용한다고해서 단 한 번의 그리기 호출로 전체 장면을 렌더링해야한다는 것은 아닙니다. 여전히 여러 개의 그리기 호출을 발행 할 수 있으며 그 과정에서 다양한 변형 행렬을 설정할 수 있습니다.

예를 들어 장면 그래프를 사용하는 경우 장면 그래프의 각 모델은 단일 그리기 호출에 해당 할 수 있습니다. 이러한 경우 VBO를 사용하는 가장 쉬운 방법은 각 모델에 대해 별도의 VBO를 만드는 것입니다.

최적화로 여러 모델을 단일 VBO로 결합한 다음 그리기 호출을 할 때 0이 아닌 오프셋을 전달할 수 있습니다. 이것은 VBO에서 올바른 모델을 추출합니다. 또한 여러 그리기 호출을 단일 그리기 호출로 결합하는 것이 바람직하지만 독립 변환이 필요한 경우 불가능합니다. (실제로는 인스 턴싱 또는 정점 블렌딩을 사용하는 경우 는 특정 상황에서 가능하지만, 내가 먼저 비켜 기초를 얻는 것이 좋습니다.)

9

짧은 답변 :

사용 glMapBufferRange 만 수정이 필요한 부분 범위를 업데이트합니다.

긴 대답은 :

비결은 glMapBufferRange에 이미 존재하는 버퍼를지도하고 단지 당신이 필요로하는 범위를 매핑하는 것이다. 이러한 가정을 감안할 때 :

  • 당신의 형상
  • 모델의 정점 수를 모핑 당 정점 애니메이션을 사용하는 애니메이션 동안 일정입니다.

그런 다음 당신은 단지 변화 부분을 업데이트 glMapBufferRange을 사용할 수 있으며, 단독으로 나머지 데이터를 둡니다. glBufferData을 사용한 전체 업로드는 오래된 메모리 저장소를 삭제하고 새 메모리를 할당하기 때문에 거북이처럼 느립니다. 새로운 데이터를 업로드하는 것 외에도 glMapBufferRange은 기존 데이터를 읽거나 쓸 수있게하며, 할당이나 할당 해제는 수행하지 않습니다.

그러나 골격 애니메이션을 사용하는 경우 정점 변환을 정점 쉐이더에 정점 쉐이더에 4x4 매트릭스로 전달하고 거기에서 계산하십시오. 버텍스 별 데이터는 물론 glVertexAttribPointer으로 지정됩니다.

또한 버텍스 쉐이더에서 텍스처 데이터를 읽을 수 있으며 OpenGL 3.1에 몇 가지 새로운 인스턴스 드로 콜 호출이 있음을 기억하십시오. glDrawArraysInstancedglDrawElementsInstanced. 결합 된 인스턴스는 인스턴스 별 조회에 사용될 수 있습니다. 즉, 동일한 지오메트리 데이터 바운드를 사용하여 인스턴스 그리기 호출을 수행 할 수 있지만 필요한 모든 정점 데이터를 텍스처 또는 텍스처 배열로 보냅니다. 이렇게하면 서로 다른 버텍스 배열 데이터 세트를 혼합하고 매치시키지 않아도됩니다.

동일한 모델이지만 위치 나 색 구성표가 다른 100 개의 인스턴스를 렌더링하려는 경우를 상상해보십시오. 또는 텍스처 맵.