일부 용어는 약간 벗어났습니다.
- A
Vertex Array
는 float[]
꼭짓점 데이터를 포함 하는 배열 (일반적으로 a )입니다. 어떤 것에 묶일 필요가 없습니다. Vertex Array Object
또는 VAO 와 혼동하지 마십시오. 나중에 살펴 보겠습니다.
- A는
Buffer Object
, 일반적으로 언급 Vertex Buffer Object
정점을 저장, 또는 줄여서 VBO 때, 당신은 단지를 호출하는 것입니다 Buffer
.
- 어떤 것도 정점 배열에 다시 저장되지 않고
glVertexAttribPointer
정확히 동일하게 작동 glVertexPointer
하거나 glTexCoordPointer
작동합니다. 이름이 지정된 속성 대신 고유 한 속성을 지정하는 숫자를 제공하게됩니다. 이 값을 index
. 모든 glVertexAttribPointer
통화는 다음에 glDrawArrays
또는을 ( 를) 호출 할 때 대기열에 추가됩니다 glDrawElements
. VAO 바인딩이있는 경우 VAO는 모든 속성에 대한 설정을 저장합니다.
여기서 가장 중요한 문제는 정점 속성을 VAO와 혼동하고 있다는 것입니다. 정점 속성은 그리기를 위해 정점, texcoord, 법선 등을 정의하는 새로운 방법입니다. VAO는 상태를 저장합니다. 먼저 버텍스 속성을 사용하여 드로잉이 작동하는 방식을 설명하고 VAO를 사용하여 메서드 호출 수를 줄이는 방법을 설명합니다.
- 셰이더에서 속성을 사용하려면 먼저 속성을 활성화해야합니다. 예를 들어 정점을 셰이더로 보내려는 경우 첫 번째 속성 인 0으로 보낼 가능성이 높습니다. 따라서 렌더링하기 전에을 사용하여 활성화해야합니다
glEnableVertexAttribArray(0);
.
- 이제 속성이 활성화되었으므로 사용할 데이터를 정의해야합니다. 그렇게하려면 VBO-를 바인딩해야합니다
glBindBuffer(GL_ARRAY_BUFFER, myBuffer);
.
- 이제 속성을 정의 할 수 있습니다
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
. 매개 변수 순서 : 0은 정의하려는 속성, 3은 각 정점의 크기 GL_FLOAT
, 유형, GL_FALSE
각 정점을 정규화하지 않음을 의미하며 마지막 2 개의 0은 정점에 보폭이나 오프셋이 없음을 의미합니다.
- 그것으로 무언가를 그려라-
glDrawArrays(GL_TRIANGLES, 0, 6);
- 다음으로 그리는 것은 속성 0을 사용하지 않을 수 있으므로 (실제로는 사용되지만 이것은 예제입니다) 비활성화 할 수 있습니다.
glDisableVertexAttribArray(0);
그것을 glUseProgram()
호출로 감싸면 셰이더와 제대로 작동하는 렌더링 시스템이 있습니다. 하지만 5 개의 다른 속성, 정점, texcoord, 법선, 색상 및 라이트 맵 좌표가 있다고 가정 해 보겠습니다. 우선, glVertexAttribPointer
이러한 각 속성에 대해 단일 호출을 만들고 모든 속성을 미리 활성화해야합니다. 내가 나열한대로 0-4 속성을 정의한다고 가정 해 보겠습니다. 다음과 같이 모두 활성화합니다.
for (int i = 0; i < 5; i++)
glEnableVertexAttribArray(i);
그런 다음 각 속성에 대해 서로 다른 VBO를 바인딩해야합니다 (모두 하나의 VBO에 저장하고 오프셋 / 스트라이드를 사용하지 않는 한), 정점에 대해 각각 라이트 맵 좌표 에 대해 5 개의 서로 다른 glVertexAttribPointer
호출 을 수행해야합니다 .glVertexAttribPointer(0,...);
glVertexAttribPointer(4,...);
이 시스템만으로도 이해가 되길 바랍니다. 이제 이러한 유형의 렌더링을 수행 할 때 VAO를 사용하여 메서드 호출 수를 줄이는 방법을 설명하기 위해 VAO로 이동합니다. VAO를 사용할 필요는 없습니다.
A Vertex Array Object
또는 VAO는 모든 glVertexAttribPointer
호출 의 상태 와 각 glVertexAttribPointer
호출이 수행 될 때 대상이 된 VBO 를 저장하는 데 사용됩니다 .
에 대한 호출로 하나를 생성합니다 glGenVertexArrays
. 필요한 모든 것을 VAO에 저장하려면로 바인딩 glBindVertexArray
한 다음 전체 그리기 호출을 수행하십시오 . 모든 드로우 바인드 호출은 VAO에 의해 가로 채서 저장됩니다. VAO의 바인딩을 해제 할 수 있습니다.glBindVertexArray(0);
이제 개체를 그리려는 경우 모든 VBO 바인딩 또는 호출을 다시 호출 할 필요가 없습니다 glVertexAttribPointer
. VAO를 glBindVertexArray
then call glDrawArrays
또는 호출 로 바인딩 glDrawElements
하면됩니다. 모든 메소드 호출을하고있었습니다. 나중에 VAO의 바인딩을 해제하고 싶을 수도 있습니다.
VAO의 바인딩을 해제하면 모든 상태가 VAO를 바인딩하기 전의 상태로 돌아갑니다. VAO가 바인딩되어있는 동안 변경 한 내용이 유지되는지 확실하지 않지만 테스트 프로그램으로 쉽게 알아낼 수 있습니다. glBindVertexArray(0);
"기본"VAO에 바인딩하는 것으로 생각할 수 있습니다 .
업데이트 : 누군가가 실제 드로우 콜이 필요하다는 점을 알려주었습니다. 결과적으로 VAO를 설정할 때 실제로 FULL 드로우 콜을 수행 할 필요가 없습니다. 왜 더 일찍 필요하다고 생각했는지 모르겠지만 지금은 해결되었습니다.