Graphics Programming
트랜스폼 피드백 버퍼(Transform Feedback Buffer) 본문
Transorm Feedback
- 정점, 테셀레이션, 기하 셰이더의 결과를 하나 이상의 버퍼 개체에 저장하기 위한 기능
- front end의 마지막 단계
- 프로그래밍 불가능, 고정 기능 스테이지
- 현 파이프라인의 마지막 단계에서 출력된 attribute들 중 명시한 것들이 버퍼에 기록된다
- 기하 셰이더가 없을 경우: 정점/테셀레이션 출력 정점들이 기록됨
- 기하 셰이더가 있을 경우: EmitVertex()에 의해 생성된 정점들이 저장됨 => 데이터 양이 변함
- Transform Feedback Buffer: 셰이더들의 출력을 포착하기 위해 쓰이는 버퍼
data -> TFB
-> glGetBufferSubData()
-> glMapBuffer()
사용법: GL에게 우리가 기록하길 원하는 출력을 알려준다
glTransformFeedbackVaryings(program, count, varying, bufferMode)
- varying: C 문자열의 배열
- bufferMode: GL_SEPARATE_ATTRIBS, GL_INTERLEAVED_ATTRIBS
// 셰이더
out vec4 vs_pos_out;
out vec4 vs_color_out;
out vec3 vs_norm_out;
// 애플리케이션
static const char *names[] = {"vs_pos_out", "vs_color_out", "vs_norm_out"};
const int num = sizeof(names) / sizeof(names[0]);
glTransformFeedbackVaryings(program, num, names, GL_INTERLEAVED_ATTRIBS);
단편 셰이더가 사용하지 않는 출력을 TFB에 저장할 수도 있다
-> inactive 취급이라 glLinkProgram()을 다시 호출해야 함
* 트랜스폼 피드백이 어떤 varying을 포착할 지를 변경했으면 프로그램 개체를 다시 링크해야 효과가 있다
GL에게 무엇을 포착할 지만 말했다. 어디에 저장되는가?
-> 버퍼를 만들어 TFB 바인딩 포인트에 바인딩한다.
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffer);
glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, size, NULL, GL_DYNAMIC_COPY);
mode = GL_INTERLEAVED_ATTRIBS -> 전부 한 버퍼에 저장
- 어떤 버퍼에 데이터를 기록하는가: 버퍼를 indexed TF binding point 중 하나에 바인딩
- GL_TRANSFORM_FEEDBACK_BUFFER의 바인딩 포인트는 여러 개
- 개념적으로는 분리되어 있지만 일반적인 바인딩 포인트와 연관된다
- glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, index, buffer);
- glBindBufferBase() 말고는 추가적인 바인딩 포인트를 가리킬 방법이 없다.
- glBindBufferRange(target, index, buffer, offset, size):
- 버퍼의 일부를 indexed binding point에 바인딩
- glGetInterv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
특수 varying들: "gl_SkipComponent1" ~ "gl_SkipComponent4", "gl_NextBuffer"
버퍼 명시 끝 - 트랜스폼 피드백 활성화
glBeginTransformFeedback(GLenum primitiveMode)
- primitiveMode: GL_POINTS, GL_LINES, GL_TRIANGLES
- front end의 마지막 단계는 반드시 이들 중 하나를 출력해야 한다
- 그리기 함수의 primitive 매개변수 또는 기하 셰이더의 출력 타입
glBeginTransformFeedback()
glResumeTransformFeedback()
glEndTransformFeedback()
glBeginTransformFeedback() 호출할 때마다 기록 위치 초기화
기록 시작 ~ 끝 사이에는 트랜스폼 피드백의 상태 변경 불가
트랜스폼 피드백으로 파이프라인 끝내기
glEnable(GL_RASTERIZER_DISCARD)