Graphics Programming

버퍼(Buffer) 본문

Season 1/OpenGL

버퍼(Buffer)

minseoklee 2015. 9. 18. 16:02

버퍼: linear allocation of memory

 

버퍼는 이름(name)에 의해 표현된다. name은 OpenGL이 버퍼를 식별하기 위해 사용하는 opaque handle이다.

 

data store: 버퍼 개체에 할당된 메모리

 

기본적인 사용법

1. 버퍼의 이름을 얻는다.

2. 버퍼를 OpenGL 컨텍스트에 붙인다. 그러려면 버퍼를 buffer binding point(또는 target이라고 함)에 바인딩한다.

   target은 정점 셰이더의 입력 또는 셰이더들의 변수다.

 

메모리 할당: glBufferData(target, size, data, usage)

GL은 버퍼에 타입을 할당하지 않는다. 버퍼는 어느 목적으로든 쓰일 수 있다.

 

usage의 조합: GL_[STREAM/STATIC/DYNAMIC]_[DRAW/READ/COPY]

STREAM: 버퍼 내용이 한 번 설정되고 가끔 쓰임

STATIC: 버퍼 내용이 한 번 설정되고 자주 쓰임

DYNAMIC: 버퍼 내용이 자주 갱신되고 자주 쓰임

 

일반적인 사용법

GLfloat[] buf_data = { ... };

 

GLuint buffer;

glGenBuffers(1, &buffers);

glBindBuffer(GL_ARRAY_BUFFER, buffer);

glBufferData(GL_ARRAY_BUFFER, sizeof(buf_data), buf_data, GL_STATIC_DRAW);

 

기존 버퍼 갱신하기: glBufferSubData(target, offset, size, data)

 

버퍼에 데이터 쓰는 또다른 방법

1. 버퍼 개체가 나타내는 메모리에 대한 포인터를 얻는다.

2. 데이터를 그 위치에 직접 복사한다.

void* ptr = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);

memcpy(ptr, data, sizeof(data));

glUnmapBuffer(GL_ARRAY_BUFFER);

 

정점 셰이더에 버퍼 공급하기

1. 버퍼 개체의 어디에 데이터가 있는지 알린다: glVertexAttribPointer()

2. attribute의 자동 채움을 활성화한다: glEnableVertexAttribArray()

 

glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)

  ptr: 지금 GL_ARRAY_BUFFER에 바인딩된 버퍼 내에서의 오프셋

glEnableVertexAttribArray(GLuint index)

 

// 정점 셰이더에서 location = 위 함수들에서 index

...

layout(location = 0) in vec3 position;

layout(location = 1) in vec3 color;

...

 

attribute의 위치 찾기: GLint glGetAttribLocation(GLuint program, const GLchar * name)

location을 명시적으로 지정하지 않아도 이 함수로 찾을 수 있다

 

정점 셰이더 입력을 애플리케이션 데이터와 연결하는 두 가지 방법

1. separate attribute: attribute마다 버퍼를 따로 만들어 연결한다

2. interleaved attribute: 한 버퍼에 여러 종류의 데이터를 담고 각 attribute의 offset을 지정한다.

Comments