Quick Syntax
// GL 3.3 Core: vao와 vbo는 생성되었고 vbo 저장소에 Vertex 배열이 있습니다.
struct Vertex {
float position[3];
unsigned char color[4];
};
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offsetof(Vertex, position)));
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex),
reinterpret_cast<void*>(offsetof(Vertex, color)));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);<cstddef>의 offsetof를 사용합니다. 위치 0은 GLSL vec3, 위치 1은 정규화한 vec4 색 입력에 대응합니다. 입력이 ivec/uvec이면 변환용 Pointer 대신 IPointer 경로를 선택합니다.
속성 인벤토리
| 인수·상태 | 값·기본값 | 선택과 실패 조건 |
|---|---|---|
| index | 0 이상, GL_MAX_VERTEX_ATTRIBS 미만 | 셰이더 location과 일치 |
| size | 보통 1~4 성분, Pointer의 특정 형식에는 BGRA 예외 | 행렬은 여러 속성 슬롯으로 나눔 |
| type | GL_FLOAT·정수·패킹 형식 등 API별 허용 타입 | CPU 저장 타입과 다르면 바이트 해석 오류 |
| normalized | 정수→실수 변환 시 정규화 여부 | 색 255를 1.0으로 읽으려면 true |
| stride | 바이트 단위, 구형 Pointer의 0은 밀집 배치 | 구조체 패딩을 무시하면 정점이 뒤섞임 |
| pointer | 바인딩된 버퍼의 바이트 오프셋 | CPU 주소와 혼동 금지 |
| enabled | 처음에는 false | 설정만 하고 활성화하지 않으면 배열을 읽지 않음 |
부동소수 입력에는 glVertexAttribPointer, 정수 입력에는 glVertexAttribIPointer, double 입력에는 지원 환경의 glVertexAttribLPointer를 사용합니다. IPointer에는 normalized 인수가 없습니다. 정수 본 인덱스를 실수로 변환해 셰이더에서 다시 되돌리는 형태보다 정수 입력 계약을 맞춥니다.
VAO가 기억하는 연결
속성 포인터 호출 시 선택한 ARRAY_BUFFER는 해당 속성과 연결됩니다. ARRAY_BUFFER 바인딩 자체와 속성에 기록된 버퍼 참조는 다릅니다. 이후 glBindBuffer(GL_ARRAY_BUFFER, 0)은 이미 기록한 속성의 연결을 제거하지 않습니다.
ELEMENT_ARRAY_BUFFER 바인딩은 VAO 상태입니다. VAO를 바인딩한 채 요소 버퍼를 0으로 바꾸면 인덱스 연결이 사라집니다. 정리 목적으로 모든 버퍼를 0에 바인딩하는 코드를 기계적으로 넣지 않습니다. Core에서 사용할 VAO는 직접 만들고 draw 전에 선택합니다.
버전별 설정 방식
VAO는 3.0, IPointer도 3.0, double 입력의 LPointer는 4.1에 코어로 들어왔습니다. 4.3의 정점 속성 바인딩 분리는 형식과 버퍼 연결을 따로 지정합니다. 4.5 DSA는 VAO 이름을 직접 받는 함수로 이를 설정할 수 있습니다.
분리 API의 바인딩 stride 0은 기존 glVertexAttribPointer의 밀집 배치 추론과 같지 않습니다. 같은 바이트 위치를 반복 읽는 설정이 되므로 기존 코드를 옮길 때 실제 정점 간격을 지정합니다. 행렬 속성의 슬롯 수와 divisor도 별도로 유지합니다.
확인할 실패 사례
색 데이터가 unsigned char인데 type을 GL_FLOAT로 지정하면 읽을 바이트 수부터 달라집니다. stride를 성분 개수 3으로 넣는 대신 바이트 크기를 사용합니다. 인터리브 배열과 분리 배열을 바꿀 때도 offset·stride·버퍼 연결을 함께 바꿉니다. 기본 전체 흐름은 정점 전달에 있습니다.
참고 링크
4 sources