Quick Syntax
// GL 3.3 Core: program은 링크 성공했고 tint uniform을 실제 사용합니다.
glUseProgram(program);
GLint tint = glGetUniformLocation(program, "tint");
if (tint >= 0) glUniform4f(tint, 1.0f, 0.5f, 0.2f, 1.0f);위치는 프로그램별로 링크 결과에서 얻는 값입니다. 다른 프로그램의 위치를 재사용하지 않습니다. 필수 uniform이 -1이면 조용히 넘어가기보다 이름·활성 여부·링크 결과를 먼저 확인합니다.
타입과 호출 형태
| GLSL 대상 | 호출 계열 | 인수의 의미 |
|---|---|---|
| float·vec2/3/4 | glUniform*f, *fv | 성분 수와 자료형을 맞춤 |
| int·ivec, bool 계열 | glUniform*i, *iv | bool은 0/비0의 의미 |
| uint·uvec | glUniform*ui, *uiv | 부호 없는 정수 경로 |
| mat2/3/4·비정방 행렬 | glUniformMatrix*fv | count는 행렬 개수, transpose는 저장 해석 |
| sampler | glUniform1i/1iv | 텍스처 객체 이름이 아닌 유닛 인덱스 |
명시적 초기값이 없는 활성 uniform은 성공한 링크 뒤 0으로 초기화됩니다. 행렬도 단위행렬이 아니므로 필요한 값을 반드시 업로드합니다. uniform 값은 다음 성공한 링크나 값 변경까지 프로그램에 남으며, 매 draw마다 무조건 같은 값을 다시 보낼 필요는 없습니다.
배열과 행렬
// GLSL: uniform vec3 lights[2]; 두 원소를 사용하는 프로그램을 전제로 합니다.
const float lights[] = {1, 2, 3, 4, 5, 6};
glUseProgram(program);
GLint location = glGetUniformLocation(program, "lights[0]");
glUniform3fv(location, 2, lights);count 2는 float 여섯 개라는 뜻이 아니라 vec3 두 개입니다. 배열 범위와 실제 사용하는 원소 수를 확인합니다. 구조체 멤버는 light.position 같은 이름으로 조회하며, 임의의 uniform 간 위치가 연속이라고 가정하지 않습니다.
행렬의 곱 순서·transpose는 행렬 전달에서 다룹니다. UBO 안의 멤버는 일반 glGetUniformLocation·glUniform 경로가 아니라 버퍼 레이아웃과 블록 바인딩을 사용합니다.
-1과 재링크
사용되지 않아 최적화된 uniform, 잘못된 이름, 블록 멤버 등은 일반 위치를 얻지 못할 수 있습니다. location -1에 대한 업로드는 무시됩니다. 이것을 성공 증거로 해석하지 않습니다. 유효하지 않은 다른 위치나 타입 불일치는 오류가 될 수 있습니다.
재링크하면 위치가 바뀌고 값도 다시 초기화될 수 있습니다. 캐시한 위치를 폐기하고 필요한 값을 다시 설정합니다. 프로그램 A를 선택한 상태에서 프로그램 B에서 얻은 위치로 glUniform을 호출하는 실수를 막으려면 위치와 소유 프로그램을 함께 관리합니다.
버전 차이
기본 uniform API는 2.0부터이고 uint 계열은 3.0부터입니다. 4.1의 glProgramUniform*는 프로그램을 직접 지정해 갱신하므로 현재 사용 프로그램을 바꾸지 않아도 됩니다. 4.3의 명시적 uniform location은 소스에서 위치를 지정하지만 타입·중복·배열 범위 계약을 제거하지 않습니다. 세 기능을 한 버전의 옵션처럼 섞지 않습니다.
참고 링크
3 sources