[GPU프로그래밍] 4. Working with GLSL Programs2
◾ Program Pipelines
- Uniform변수의 값은 쉐이더 프로그램에는 저장되지만, 각 쉐이더 오브젝트에는 저장되지 않는다.
- ex) 1개의 vertex 쉐이더
A
, 2개의 fragment 쉐이더 B
, C
- 첫번째 프로그램은 A, B / 두번째 프로그램은 A, C인 경우
- 첫번째 프로그램에서 설정해준 Uniform변수가 두번째 프로그램에 적용되지 않는다. (쉐이더 오브젝트에는 공유X)
- 각 프로그램마다 Uniform변수 설정이 필요하다 (같은 Vertex Shader임에도 불구하고!)
- 이러한 번거로운 상황을 Program Pipeline을 사용하면 해결가능!
◾ Separable Shader Program
- OpenGL 4.1에 도입된 기능
- 원래는 최소 vert, frag 두 개의 쉐이더가 있어야 쉐이더 프로그램을 만들 수 있는데, 한 개의 쉐이더 만으로도 쉐이더 프로그램을 만들 수 있음 (렌더링은 안됨) -> Separable
- 쉐이더 프로그램에는 Uniform변수의 값을 저장할 수 있으므로, 각 단일 쉐이더로 만든 프로그램에 Uniform변수를 설정
- Pipeline(어떤 단계에 어떤 프로그램을 사용할지를 연결해줌)을 만들어 프로그램 연결
(mix and match the stages of separable programs)
이점
- Uniform변수는 이미 다 세팅되어있으므로, 프로그램 연결만 해주면 바로 사용 가능
- shader stage가 바뀔 때, Uniform변수 세팅이 사라질 일 없음
- Uniform변수를 공유하는 또 다른 방법 (언급만 하심)
- 메모리 블럭을 만들어서 두 개의 프로그램에서 한 블럭을 쉐어
- 유니폼 변수를 저장할 수 있는 메모리를 쉐어
📃 Sample code
- Separable shader Program 생성
glCreateProgram
대신 glCreateShaderProgramv
사용
- Program Pipeline 생성
- Pipeline object를 생성하고, 단계별로 어떤 쉐이더 프로그램을 사용할 것인지 지정
- Separable shader Program에 Uniform변수 세팅
glUniform##
대신 glProgramUniform##
사용
- 만들어둔 Separable shader Program 중 어떤 프로그램에 Unifrom변수를 세팅할건지 알려줘야함
- Unbinding
- 렌더링 시작 전에 (파이프라인 사용 전에) 아무것도 binding되어있지 않도록 해야함
- 렌더링 과정에서 프로그램이 아니라 파이프라인이 binding돼야하기 때문!
- 파이프라인 사용
- 렌더링 과정에서 미리 세팅된 파이프라인을 binding
Debug Message
- OpenGL Program에서 오류가 발생했을 때, 에러 메세지 받기
1. geGetError()
- 옛날 버전의 함수 (아 이만큼 귀찮았다~..)
- 에러가 발생할 것 같은 곳, 의심가는 곳에 코드를 작성
- 바로 직전 함수에서 에러가 발생하면 에러 코드 반환
2. Debug Callback Function
- OpenGL 4.3버전
- 조건(오류) 만족 시 호출
📃 Sample Code
- 디버그 컨텍스트 생성
- 디버그 메세지를 enable (default라서 안해도 되긴 함)
- Callback Function 등록
- 모든 에러 다 출력 (모든 messages, sources, levels, IDs.. 에 대한)
- 특정 에러만 확인하고 싶을 때
- Callback Function (오류 종류에 따라 출력만 구현된 상태)