OpenGL

[OpenGL] VRAM와 VBO(Vertex Buffer Objects)

usingsystem 2024. 4. 18. 15:55
728x90

VBO(Vertex Buffer Objects)란?

VBO는 그래픽스에서 사용되는 데이터를 어디에 저장하는 것이 좋을까에서부터 시작된다.

 

그래픽스 프로그램에서는 그래픽 카드에 있는 GPU에서 돌아가는 Vertex Shader에다 메모리가 전달되어 수행한다.

즉 메인인 메모리인 Ram에 있던 데이터가 데이터버스를 통해 GPU로 흘러가야 Vertex Shader에서 실행되게된다.

 

하지만 1초에 30~60번의 그림을 그리기위해 그때마다 메인 메모리에 있던 데이터가 GPU를 향해서 전송되어 그림을 그리게 된다면 그래픽 프로그램에서는 오브젝트의 위치가 변경 되더라도 사실상 같은 모양을 반복해서 그리는 경우가 많게된다.

 

그래서 기존에 매번 데이터를 보내는 것보다 그러지 말고 그래픽 카드에도 별도의 메모리(VRAM 혹은 비데오 메모리)를 설치해서 이 비디오 메모리에대가 데이터를 일단 전송한다. 즉 메인 메모리에서 GPU로 데이터를 보내는 게 아니고 GPU 바로 옆에 있는 VRAM에서 GPU 쪽으로 메모리를 보내주면 훨씬 짧은 거리에 왔다 갔다 하면서 데이터를 효율적으로 사용할 수 있을것이라는 개념이 VBO의 기본적인 아이디어이다.

 

VBO를 쓰기 전 메인 메모리에 있는 데이터들이 직접 Attribute 레지스터로 연결된다.(Address사용)

VBO를 사용하게 되면 메모리의 주소를 정의하여 내가 데이터를 어디에 놓을지를 직접 컨트롤 할 수 있게된다.(Offset사용)

 

VBO 사용 시나리오

  1. draw에 사용하는 array를 buffer 영역으로 전환한다.
    • glGenBuffers - n개의 buffer를 생성하고 생성한 buffer에 id를 부여한다. (실제로 size가 부여되진 않는다)
    • glBindBuffers - target = 생성한 buffer 하나하나를 실제로 attribute register에 결합한다.GL_ARRAY_BUFFER
  2. Ram에 있던 data를 VRAM으로 전송
    • glBufferData - buffer 전체크기를 결정하며 버퍼데이터를 카피하는 기능을 갖는다.
    • glBufferSubData - buffer 일부
  3. buffer 영역의 삭제
    • glDeleteBuffers
GLuint vbo[1];//buffer에 id가 입력되는 부분

void prepareVBO(void) {
	glGenBuffers(1, vbo);
	glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
	glBufferData(GL_ARRAY_BUFFER, 2 * 18 * 4 * sizeof(GLfloat), NULL, GL_STATIC_DRAW);
	glBufferSubData(GL_ARRAY_BUFFER, 0, 18 * 4 * sizeof(GLfloat), vertPos);
	glBufferSubData(GL_ARRAY_BUFFER, 18 * 4 * sizeof(GLfloat), 18 * 4 * sizeof(GLfloat), vertColor);
}

 

vertex data를 저장하는 다른 방법

vertex data를 struct나 class를 만들어 한번에 저장하면 위에서 subdata를 사용할 필요없이 한번에 저장가능하다.

struct vertex{
 glm::vec4 pos;
 glm::vec4 color;
};
728x90