Quick Flow
각 program에 PROGRAM_SEPARABLE 설정 → 단계별 컴파일·링크 확인
→ program pipeline 생성 → 단계별 program 연결
→ glUseProgram(0) → pipeline 선택 → 인터페이스 검증·drawGL 4.1 또는 ARB_separate_shader_objects 경로입니다. 3.3의 기본 통합 프로그램을 무조건 분리할 필요는 없습니다. 단계 재사용이 실제로 필요한 경우에 선택합니다.
조합과 우선순위
// GL 4.1 Core: vertexProgram과 fragmentProgram은 separable로 링크 성공했습니다.
GLuint pipeline = 0;
glGenProgramPipelines(1, &pipeline);
glUseProgramStages(pipeline, GL_VERTEX_SHADER_BIT, vertexProgram);
glUseProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT, fragmentProgram);
glUseProgram(0);
glBindProgramPipeline(pipeline);통합 프로그램이 glUseProgram으로 선택되어 있으면 파이프라인을 바인딩한 것만으로 그 프로그램을 대체하지 않습니다. 분리 경로를 사용할 때 현재 통합 프로그램 상태도 명시합니다.
| 선택 | 장점 | 비용·조건 |
|---|---|---|
| 통합 프로그램 | 링크 시 단계 조합을 한 번에 확인 | 조합마다 링크 프로그램 관리 |
| 분리 프로그램 | 단계 프로그램 재사용 | 단계 인터페이스·조합·갱신 대상 관리 |
| pipeline 객체 | 단계 연결을 보관 | shader 객체나 실행 코드 저장소 자체와 다름 |
생성·검증·갱신
일반 프로그램을 separable로 만들려면 링크 전에 glProgramParameteri(program, GL_PROGRAM_SEPARABLE, GL_TRUE)를 지정합니다. 기본은 false입니다. 링크 성공이 없는 프로그램을 UseProgramStages에 넣지 않습니다. CreateShaderProgramv 경로를 쓰더라도 링크 상태·로그를 확인해야 합니다.
파이프라인은 glValidateProgramPipeline과 상태·로그 조회로 현재 조합을 확인합니다. 필요한 단계가 빠졌거나 인터페이스가 맞지 않으면 올바른 출력이 생기지 않습니다. 분리 프로그램의 단계 연결은 명시적 위치를 사용하는 등 해당 버전의 인터페이스 규칙을 따릅니다.
uniform은 값을 소유한 프로그램에 갱신합니다. glProgramUniform*를 쓰면 파이프라인 전체가 아니라 해당 프로그램을 직접 지정할 수 있습니다. 같은 이름의 uniform이 여러 프로그램에 있으면 각각의 위치·값을 관리합니다.
단계 프로그램 생성과 조합 오류 읽기
GL 4.1에서는 소스 문자열 배열을 glCreateShaderProgramv에 주어 separable 프로그램을 만들 수 있습니다. vertexSource와 fragmentSource는 각각 GLSL 410 core의 널 종료된 소스이고, 필요한 단계 간 입출력 위치·타입을 맞춘 상태입니다.
GLuint vertexProgram = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &vertexSource);
GLuint fragmentProgram = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &fragmentSource);
GLint vertexLinked = GL_FALSE, fragmentLinked = GL_FALSE;
if (vertexProgram != 0) glGetProgramiv(vertexProgram, GL_LINK_STATUS, &vertexLinked);
if (fragmentProgram != 0) glGetProgramiv(fragmentProgram, GL_LINK_STATUS, &fragmentLinked);
// 생성값 0 또는 링크 실패면 program 로그를 읽고 생성된 객체를 정리합니다.
// 둘 다 성공한 경우에만 앞의 pipeline 연결 구간을 실행합니다.이미 성공한 vertexProgram·fragmentProgram을 pipeline에 연결한 뒤에는 다음처럼 조합의 진단을 읽습니다. 컴파일·링크 로그와 파이프라인 로그는 다른 객체에서 얻습니다. <vector>, <cstdio>가 필요합니다.
glValidateProgramPipeline(pipeline);
GLint valid = GL_FALSE;
glGetProgramPipelineiv(pipeline, GL_VALIDATE_STATUS, &valid);
if (!valid) {
GLint length = 0;
glGetProgramPipelineiv(pipeline, GL_INFO_LOG_LENGTH, &length);
std::vector<char> log(length > 0 ? length : 1);
glGetProgramPipelineInfoLog(pipeline, static_cast<GLsizei>(log.size()), nullptr, log.data());
std::fprintf(stderr, "%s\n", log.data());
}uniform 갱신은 glProgramUniform4f(fragmentProgram, location, ...)처럼 값을 가진 프로그램을 직접 지정하는 경로가 단순합니다. glUniform 경로를 쓸 때는 pipeline의 active shader program 선택까지 구분해야 합니다. 마지막 사용 후 pipeline을 해제·삭제하고 두 프로그램도 각각 삭제합니다.
정리와 버전
마지막 사용 후 pipeline을 해제·삭제하고 프로그램의 소유권도 정리합니다. pipeline 삭제가 모든 연결 프로그램 삭제를 대신하지 않습니다. Compute 단계 비트는 4.3 이후 조건이며 4.1의 분리 프로그램 기능과 같은 시점에 도입된 것은 아닙니다.
1.x 고정 기능 파이프라인과 이름이 비슷하지만 같은 객체는 아닙니다. 여기서 pipeline은 현대 단계 프로그램의 조합을 뜻합니다. 통합 링크는 셰이더 컴파일에 있습니다.
참고 링크
5 sources