Software Development/Graphics

OpenGL VBO로 큐브 그리기

huiyu 2018. 7. 7. 17:56

SDL을 이용한 OpenGL 샘플로 기본적인 SDL 세팅 및 코드 사용법은 아래를 참고하세요.
(SDL 코드 설명 및 shader 생성 및 사용에 대한 설명)
*여기

SDL+Cube 샘플은 아래에서 받을 수 있다.
*샘플코드


VBO(Vetex Buffer Object)

- 버텍스(정점)에 대한 정보를 저장해두는 정점들의 집합 버퍼
- 데이터의 위치정보, 색 정보, normal 정보 등등...
- 버텍스 정보가 저장된 버퍼를 GPU memory에 올려두고 사용


*일반적인 3D 오브젝트는 3D 공간상의 (x,y,z)좌표로 이루어져 있다.
이 정보를 메모리에 올려두고 gl을 통해 그리도록 명령한다.

이 샘플에선, 색 정보(rgb)와 위치 정보(xyz)를 다루는 버퍼를 생성 후 데이터 저장, 그리는 과정을 설명한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//큐브의 
static const float cube_colors[] = {
   0.00.01.0,
   0.00.01.0,
   ....
}
 
//큐브의 위치 정보 저장
static const float cube_vertices[] = {
   0.50.50.5,
   -0.5-0.50.5,
    ....
}
    
 
void generateAndBindBuffer(appdata_s* ad)
{
        glGenBuffers(1&ad->colorBuffer);
        glGenBuffers(1&ad->vbo);
 
        //vertex position buffer
        glBindBuffer(GL_ARRAY_BUFFER, (ad->vbo));
        glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices), cube_vertices, GL_STATIC_DRAW);
 
        glVertexAttribPointer(03, GL_FLOAT, GL_FALSE, sizeof(float* 30);
        glEnableVertexAttribArray(0);
 
        //vertex color buffer
        glBindBuffer(GL_ARRAY_BUFFER, (ad->colorBuffer));
        glBufferData(GL_ARRAY_BUFFER, sizeof(cube_colors), cube_colors, GL_STATIC_DRAW);
 
        glVertexAttribPointer(13, GL_FLOAT, GL_FALSE, sizeof(float* 30);
        glEnableVertexAttribArray(1);
 
}
cs

샘플상에 generateAndBindBuffer()는 데이터 저장을 위한 VBO를 생성하고 실제 데이터를 갖고 있는 (cube_colors, cube_vertices)를 바인딩 하고 있다.
각각의 함수에 대해 알아보면,


glGenBuffers : 새로운 버퍼를 생성

1
2
3
void glGenBuffers(    
GLsizei n,
     GLuint * buffers);
cs

- n : 새로 생성하는 버퍼의 갯수.
- buffers : 생성된 버퍼객체의 이름이 저장되는 공간


glBindBuffer : 생성한 버퍼에 타겟을 할당

1
2
3
void glBindBuffer(    
GLenum target,
     GLuint buffer);
cs

- target : 버퍼 객체가 바인딩 되는 대상

아래와 같이 정의되어 있다. 샘플에서 사용하는 GL_ARRAY_BUFFER는 정점에 대한 데이터를 생성한 버퍼에 넣는다는 의미이다.

Buffer Binding Target

Purpose

GL_ARRAY_BUFFER

Vertex attributes

GL_ATOMIC_COUNTER_BUFFER

Atomic counter storage

GL_COPY_READ_BUFFER

Buffer copy source

GL_COPY_WRITE_BUFFER

Buffer copy destination

GL_DISPATCH_INDIRECT_BUFFER

Indirect compute dispatch commands

GL_DRAW_INDIRECT_BUFFER

Indirect command arguments

GL_ELEMENT_ARRAY_BUFFER

Vertex array indices

GL_PIXEL_PACK_BUFFER

Pixel read target

GL_PIXEL_UNPACK_BUFFER

Texture data source

GL_QUERY_BUFFER

Query result buffer

GL_SHADER_STORAGE_BUFFER

Read-write storage for shaders

GL_TEXTURE_BUFFER

Texture data buffer

GL_TRANSFORM_FEEDBACK_BUFFER

Transform feedback buffer

GL_UNIFORM_BUFFER

Uniform block storage


glBufferData : 실제 버퍼에 데이터를 넣는다.

1
2
3
4
5
void glBufferData(    
    GLenum target,
     GLsizeiptr size,
     const GLvoid * data,
     GLenum usage);
cs

 - target : 버퍼 객체가 바인딩 되는 대상(위 표 참고)
 - size : 데이터의 크기, 생성된 버퍼의 크기
 - data : 실제 넣을 데이터의 주소값
 - usage : 데이터의 사용 패턴, 샘플에서 사용하는 GL_STATIC_DRAW의 경우, 한번 데이터가 저장되면 변경되지 않음을 의미한다.
  *usage의 값은 아래와 같이 있다.

    1) STREAM : The data store contents will be modified once and used at most a few times.
    2) STATIC : The data store contents will be modified once and used many times.
    3) DYNAMIC : The data store contents will be modified repeatedly and used many times.
                       The nature of access may be one of these:
    4) DRAW : The data store contents are modified by the application, and used as the source for GL drawing and image specification commands.
    5) READ : The data store contents are modified by reading data from the GL, and used to return that data when queried by the application.
    6) COPY : The data store contents are modified by reading data from the GL, and used as the source for GL drawing and image specification commands.


glVertexAttribPointer : 저장한 데이터의 속성 정보 지정, 아직까진 저장된 데이터가 어떤값인지 알지 못해 이 함수로 지정해주어야 한다.

1
2
3
4
5
6
7
8
void glVertexAttribPointer(    
GLuint index,
     GLint size,
     GLenum type,
     GLboolean normalized,
     GLsizei stride,
     const GLvoid * pointer);
 
cs

 - index : 정점 속성의 인덱스 지정(샘플에선 위치-0, 색상 정보-1로 지정)
 - size : 속성의 구성 요수의 수(1~4, 샘플은 rgb와 xyz임으로 3 지정)
 - type : 구성 요소의 데이터 유형 지정
 - normalized : 고정 소수점 데이터 값을 정규화할지(GL_TRUE), 고정 소수점 값으로 직접 변환할지 지정(GL_FALSE)
 - stride : byte offset 지정
 - pointer : 각 데이터의 첫번째 데이터간의 offset


glEnableVertexAttribArray() : 위에 생성한 index 버퍼를 활성화. 이 함수를 호출해주어야 제대로 동작(Enable/Disable)

1
2
3
void glEnableVertexAttribArray(    GLuint index);
 
void glDisableVertexAttribArray(    GLuint index);
cs


728x90