티스토리 뷰

CG

[OpenGL] buffer

4whomtbts 2020. 7. 4. 01:42

https://www.khronos.org/opengl/wiki/Buffer_Object

 

OpenGL에서 Buffer object란 OpenGL context로 부터(GPU로 알려진) 할당된 포맷되지 않은 메모리들의 배열이다.

vertex data, 이미지나 framebuffer로 부터 가져온 pixel data를 저장 및 이 외에 여러가지 것들을 저장하기 위해 사용한다.

일단 buffer를 사용하기 위해서는 glGenBuffers 함수를 불러서 만들고, 사용후에는 glDeleteBuffers를 이용해서 지워야한다.

표준 OpenGL 객체 패러다임에서는, glGenBuffer는 객체에 대한 참조와, 객체의 이름만 생성하므로, 내부 상태를 설정하기 위해서는

context에 bind해주는 작업이 필요한데, glBindBuffer가 이러한 역할을 해준다.

OpenGL의 예제를 보았을 때, glGenBuffer 와 glBindBuffer가 항상 쌍으로 나오는 이유이다.

glBindBuffer는 위와 같은 파라미터를 받는데, target은 buffer object를 어떤 방식으로 바인딩할지 결정합니다. 

자주 쓰이는 예시로는, GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER 등이 있습니다 .

2번 째 파라미터인 bufferName 은 glGenBuffers 를 할 때 넣은 id 값을 넘겨주게 되는 것입니다.

 

Mutable Storage 

glBufferData 함수를 이용해서 buffer object를 위한 mutable storage를 만들 수 있습니다.

target 파라미터는 glBindBuffer에서 사용하는 것과 동일한 것이고, 이것으로 어떤 buffer를 조작할지 알려주는 것 입니다.

size는 buffer object에 얼마나 많은 사이즈를 할당할지 정해주는 것 입니다.

 

마지막에 usage란 것이 있는데, 문서에서도 매우 헷갈릴 수 있는 개념이라고 언급해놓았습니다.

버퍼 오브젝트는 OpenGL에 의해서 할당된 범용적인 메모리 스토리지 블록들인데, 매우매우 다양한 방법으로

쓰여지도록 되어있습니다. 버퍼 오브젝트 데이터가 정확히 무엇이 될 지에 대한 사항에 대해 구현상에서 많은 유연성을 주게 되어있는데,

여기서 최적화를 위해서 사용자에게 힌트를 받아서 최적화에 사용하는 것 입니다. 

usage 패턴에는 두 가지 독립적인 파트가 있는데, 사용자가 어떻게 버퍼로 부터 혹은 버퍼로 읽거나 혹은 쓸지

또, 유저가 이 데이터를 변화시키는 것과 사용하는 것의 상대성은 얼마나 되는지 같은 항목입니다.

버퍼 오브젝트에 데이터 내용을 바꾸는데는 두 가지 방법이 있는데, 하나는 유저가 명시적으로 이진 데이터를 업로드 하는 것이고,

나머지 하나는 유저가 GL 커맨드를 사용해서 버퍼가 채워지도록 하는 방법입니다.

 

유저가 제공할 수 있는 힌트에는 3가지가 있습니다. 이것들은 유저가 버퍼를 가지고 무엇을 할지를 바탕으로 결정하는데

유저가 직접 데이터를 읽고 쓸지 아닌지에 기반합니다.

DRAW: 유저가 데이터를 버퍼에 쓴다. 하지만 읽지는 않는다

READ: 유저가 데이터를 쓰지 않고 읽기만 한다.

COPY: 유저가 읽지도, 쓰지도 않는다

일반적으로 버텍스 데이터를 가지고 있는 버퍼 오브젝트는 DRAW 로 명시되어 있습니다. 

READ는 버퍼 오브젝트가 OpenGL 명령어의 목적지일 경우입니다. 

COPY는 버퍼 오브젝트가 OpenGL의 한 지점에서 다른 지점으로 데이터를 넘길 때 사용합니다. 

예를 들어서, 버퍼로 부터 데이터 이미지를 읽어서, draw call에서 이미지 데이터를 버텍스 데이터로 사용하는 경우가 있습니다. 

 

'CG' 카테고리의 다른 글

glBindBuffer, glEnableVertexAttribArray  (0) 2020.07.06
댓글