VAO (OpenGL Vertex Array Object)에 어떤 상태가 저장되며 VAO를 올바르게 사용하려면 어떻게해야합니까?


25

OpenGL VAO에 어떤 상태가 저장되어 있는지 궁금합니다. VAO에는 버퍼링 된 버텍스의 버텍스 사양 (버퍼에있는 속성 및 바인딩 된 버퍼 등)과 관련된 상태가 포함되어 있음을 이해했습니다. VAO의 올바른 사용법을 더 잘 이해하기 위해 VAO의 상태를 정확히 알고 싶습니다.


VAO를 사용해야한다고 가정하는 방법

간단한 예에서 VAO의 올바른 사용법은 다음과 같습니다.

설정

Generate VAO
BindVAO
---- Specify vertex attributes
---- Generate VBO's
---- BindVBO's
-------- Buffer vertex data in VBO's
---- Unbind VBO's
Unbind VAO

표현

Bind VAO
---- Draw
Unbind VAO

이것으로부터, 나는 적어도 버텍스 버퍼 바인딩버텍스 속성 스펙 이 VAO에 저장되어 있다고 가정한다 . 그러나이 사용 패턴이 (다중) 텍스처와 (다중) 셰이더 프로그램이 작동하는 상황으로 어떻게 확장되는지 잘 모르겠습니다. 는 IS 활성 쉐이더 프로그램 VAO에 저장된? 그리고 있습니다 텍스처 바인딩 (그와 샘플링 / 포장 설정 뿐만 아니라 VAO에 저장)은? 제복을 위한 Ditto ?


따라서 내 질문은 다음과 같습니다.

  • OpenGL VAO 에는 어떤 정확한 상태 가 저장되어 있습니까? (VBO 바인딩, 속성 사양, 액티브 셰이더 프로그램, 텍스처 바인딩, 텍스처 샘플링 / 래핑 설정, 유니폼 ...?)
  • 어떻게합니까 제대로 VAO의 사용 보다에서 복잡한 렌더링 설정 관련 샘플링 / 포장 설정 곳 (복수) 텍스처 (여러) 쉐이더 프로그램과 유니폼이 관여?

1
VAO는 정점 속성 위치에 대한 데이터를 저장합니다. 또한 이러한 속성이 포함 된 VBO의 ID를 저장합니다. 무언가를 그릴 때 VBO를 바인딩 할 필요가 없습니다. VAO를 만들 때 glVertexAttribPointer ()를 호출하기 전에 VBO를 바인딩해야합니다.
HolyBlackCat

답변:


18

VAO는 정점 속성 위치에 대한 데이터를 저장합니다. (그리고 그들과 관련된 다른 데이터)
"VBO bindings, active shader program, texture bindings, texture sampling/wrapping settings, uniforms"는 완전히 관련이 없습니다.

VBO 바인딩을 기억하지 못하는 이유를 물을 수 있습니다. VBO를 바인딩하여 무언가를 그릴 필요가 없으므로 VAO를 만들 때 VBO를 바인딩하면됩니다. glVertexAttribPointer(...)VAO는 VBO가 현재 바인딩 된 것을 기억합니다. VAO는 VBO가 현재 바인딩되어 있지 않더라도 VBO를 그릴 때 이러한 VBO에서 속성을 가져옵니다.


또한 VAO와 VBO는 약간 다르게 사용해야합니다.

이 작동하지 않습니다

Generate VAO
BindVAO
---- Specify vertex attributes
---- Generate VBO's
---- BindVBO's
-------- Buffer vertex data in VBO's
---- Unbind VBO's
Unbind VAO

속성 위치를 지정하려면 VBO를 바인딩해야하기 때문입니다.

따라서 다음과 같이해야합니다.

Generate VAO
BindVAO
Generate VBO's
BindVBO's
Specify vertex attributes

원할 때마다 VBO의 데이터를 변경할 수 있지만 그 전에 바인딩해야합니다.

그리고 그림은 다음과 같아야합니다.

Bind VAO
Draw


알다시피, unbind목록에서 전화를 제거했습니다 . 그들은 거의 완전히 쓸모가 없으며 프로그램을 약간 느리게 할 것이므로 호출 할 이유가 없습니다.


9
"그래서 전화 할 이유가 없다" 실수로 변경하는 것을 방지합니다. 타사 라이브러리를 사용할 때 특히 문제가됩니다.
ratchet freak

큰 답변 감사합니다! 간단히 말해 VAO는 꼭짓점 속성 위치 만 저장합니다. VAO는 VAO를 바인딩 할 때 속성을 찾기위한 버퍼를 알고 있으므로 VBO는 리바운드되지 않습니다. 다른 모든 상태는 전역 OpenGL 상태에 포함됩니다.
Jelle van Campen

@JellevanCampen 그렇습니다. 참고로, 속성의 오프 / 온 상태 ( gl{Enable|Disable}VertexAttribArray()), 기본값 ( glVertexAttrib*()), 인스 턴싱 모드 ( glVertexAttribDivisor()) 및 아마도 다른 것을 저장합니다.
HolyBlackCat

@HolyBlackCat 기본 상태 (glVertexAttrib ())가 VAO 상태의 일부입니까? OpenGL 위키는 문맥 상 상황이라고 말하면서 그렇지 않다고 주장합니다.
rdb

@ndb 아니요, 잘 모르겠습니다. 나는 그들이 VAO 국가의 일부가 될 것으로 기대했지만 확인하지 않았다.
HolyBlackCat

4

꼭짓점 바인딩과 인덱스 버퍼 바인딩 만 저장합니다.

이것이 glVertexAttribPointer호출 될 때 Vertex_Array_buffer에 바인딩 된 버퍼와 바인딩 된 Element_Array_buffer 의 모든 매개 변수입니다 glVertexAttribPointer.

유니폼은 현재 프로그램의 일부입니다.

그 밖의 모든 것은 세계적인 상태입니다.

의심의 여지없이 사용중인 버전의 사양에서 상태 테이블을 확인할 수 있습니다.


답변 주셔서 감사합니다! 이것은 나를 위해 일을 정리합니다.
Jelle van Campen

4

여기에 간단하지만 효과적인 설명이 있습니다. 기본적으로 버퍼 객체에는 단순히 원시 데이터의 비트로 해석 될 수있는 정보가 있습니다. 그 자체로는 아무 의미가 없으므로 실제로 어떤 방식 으로든 볼 수있는 데이터입니다.

i.e float vbo[]={1.0,2.0,34.0...}

OpenGL이 작동하도록 설계된 방식은 다양한 셰이더에 전달할 데이터가 셰이더에 표시 될 데이터를 정의해야한다는 것입니다.

데이터를 읽는 방법, 데이터의 형식, 데이터와 관련된 작업 및 사용 방법 및이 정보가 VAO에 저장되는 방식을 정의해야합니다.

예를 들어 다음과 같이 배열에 저장된 데이터를 선언 할 수 있습니다 float vbo = {11.0,2.0,3.0,4.0}

이 시점에서 다음에 필요한 것은 VAO에서 VBO의 데이터를 해석하는 방법이며 그 의미는 다음과 같습니다.

VAO는 꼭짓점 당 2 개의 부동 소수점을 읽도록 설정하거나 (2 차원 x, y를 갖는 2 개의 벡터로 만들 것입니다) vao에게 4 차원, 즉 x, y, z, w 등 1 개의 벡터로 해석하도록 지시 할 수 있습니다.

또한 해당 데이터의 다른 속성은 데이터 형식과 같이 VAO에 정의되고 저장됩니다 (float의 배열을 선언 했음에도 불구하고 시스템은 원시 데이터를 부동 소수점에서 정수까지의 프로세스로, 그러한 상황에서 수행 할 고유 규칙 세트가 있습니다)

따라서 기본적으로 VBO는 데이터이며 VAO는 해당 데이터를 해석하는 방법을 저장합니다. 쉐이더와 OpenGL 서버는 매우 코가 없도록 설계되었으며 처리 방법과 처리 방법 및 위치를 결정하기 전에 모든 것을 알아야합니다. 그것을 넣어

물론 실제로 코가 아니며 실제로 데이터를 그래픽 서버 메모리에 저장해야하므로 가장 효율적이고 빠른 처리를 얻을 수 있기 때문에 실제로 가장 효율적으로 보입니다. 데이터는 이러한 방식으로 처리되지 않고 자주 액세스하지 않는 다른 정보에 사용되지 않습니다.) 따라서 데이터 처리 방법 및 처리 방법에 대한 세부 정보가 VAO에 저장되어야하는 이유는 무엇입니까? VAO는 헤더와 같고 VBO는 VBO가 하나의 VAO에 의해서만 사용되도록 제한되지 않는 것을 제외하고 헤더가 사용하고 정의하는 (이 경우 쉐이더 정점 속성에 전달되는) 순수 원시 데이터와 같습니다. 예를 들어 다음과 같이 많은 VAO에 사용되고 재사용 될 수 있습니다.

당신이 할 수있는 일은 하나의 버퍼 객체를 VAO1에 바인딩하고 동일한 버퍼 객체를 각각 다르게 해석하여 VAO2에 (별도로) 바인딩 할 수 있으므로 셰이더가 데이터를 처리하는 위치에 따라 VAO가 어느 VAO인지에 따라 바운드는 동일한 원시 데이터를 frambuffer (윈도우로 그리기 픽셀)와 다르게 처리하여 VAO에서 사용을 어떻게 정의했는지에 따라 동일한 데이터를 다르게 표시합니다.


이것이 가장 좋은 대답입니다!
CodingMadeEasy 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.