- 버텍스 배열 객체 (VAO : Vertex Array Object)
- 생성 및 바인딩
- GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao); - 상태 설정
- glVertexAttribPointer
void glVertexAttribPointer(
GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * pointer )
;- index : 버텍스 속성의 인덱스
- 셰이더에서 location index
- #version 430 core
layout (location = 0) in vec4 offset;
~ - size : 각 버텍스에 대해 버퍼에 저장된 컴포넌트의 개수
- type: 데이터 타입
- normalized: 데이터를 정규화 할 것인지 (0.0~1.0 사이)
- stride: 버텍스 데이터의 시작과 다음 시작점 사이에 얼마나 많은 바이트가 있는지
- pointer: GL_ARRAY_BUFFER에 바인딩된 버퍼상에서 버텍스 속성데이터가 시작하는 위치에 대한 오프셋
- Example
- glBindBuffer(GL_ARRAY_BUFFER, buffer);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL); - 속성 0
- 4 컴포넌트
- 부동소수점
- 정규화 안함
- 촘촘히 패킹된 데이터
- 오프셋 0 (NULL 포인터)
- Shader
- #version 430 core
layout (location = 0) in vec4 position;
void main(void)
{
gl_Position = position;
} - 하드 코딩된 데이터가 삭제되고, position에 버텍스 데이터가 들어가게 된다.
- 설정
void glEnableVertexAttribArray(
GLuint index )
;- 버퍼의 데이터를 사용해서 버텍스 속성을 채우라고 지시
- 몇 번째 인덱스의 속성을 활성화 할 것인지 설정 (셰이더의 속성 활성화)
- 해제
void glDisableVertexAttribArray(
GLuint index )
;- 버텍스 속성 채우기 후 호출하여 속성 비활성화
- 그 외
- 여러 개의 버텍스 쉐이더 입력 사용하기
- Shader Example
- layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color; - 입력 위치 알아내기
- glGetAttribLocation
GLint glGetAttribLocation(
GLuint program, const GLchar *name )
;- program: 버텍스 쉐이더 프로그램
- name: 속성 이름 (쉐이더 내 변수명)
- 위의 쉐이더에서 "position"시 0을, "color"시 1을 리턴. 그 외에는 -1 리턴
- 쉐이더 코드에 위치를 설정하지 않은 경우, OpenGL이 자동으로 설정해주며 이 경우 위 함수를 사용하여 위치를 알아내야 한다.
- 버텍스 쉐이더 입력을 데이터로 연결시키는 방법
- 독립 속성
- 다른 버퍼에 위치해 있을 수 있거나, 적어도 동일한 버퍼에서 다른 위치에 있는 경우
- Example
- GLuint buffers[2];
static const GLfloat positoins[] = {...};
static const GLfloat colors[] = {...};
glGenBuffers(2, &buffers);
// positions(0)
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
// colors(1)
glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(1); - 두 속성에 값을 전달하기 위해 촘촘히 패킹된 데이터 배열을 사용
- 배열-구조체 (SoA : Structure of Arrays) 데이터 라고 함.
- 인터리브 속성
- 구조체-배열 (AoS : Array of Structures) 데이터 사용
- struct vertex
{
float x;
float y;
float z;
float r;
float g;
float b;
} - 두 개의 입력이 단일 구조체 안에 번갈아 들어 있음.
- stride 인자를 사용해야 한다.
- Example
- GLuint buffer;
static const GLfloat vertices[] = {...};
// 버퍼 객체 할당 및 초기화
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// position(0)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), (void *)offsetof(vertex, x));
glEnableVertexAttribArray(0);
// colors(1)
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), (void *)offsetof(vertex, r));
glEnableVertexAttribArray(1); - 파일로부터 객체 로딩하기
- 모델 데이터를 파일에 저장하고 애플리케이션으로 로딩하는 방법
2018년 3월 26일 월요일
5.1.3 버퍼로부터 버텍스 쉐이더에 입력 전달하기
피드 구독하기:
댓글 (Atom)
댓글 없음:
댓글 쓰기