수색…


프레임 버퍼의 기본 사항

Framebuffer 는 메모리에있는 픽셀의 색상 값, 깊이스텐실 정보를 저장하는 버퍼 유형입니다. OpenGL에서 무언가를 그릴 때 출력은 기본 프레임 버퍼에 저장되고 화면에이 버퍼의 색상 값이 실제로 표시됩니다. 그레이 스케일, 블러, 피사계 심도, 왜곡, 반사 등과 같은 멋진 후 처리 효과를 많이내는 데 사용할 수있는 자체 프레임 버퍼를 만들 수도 있습니다.

시작하려면 프레임 버퍼 객체 ( FBO )를 만들고 OpenGL에서 다른 객체처럼 바인딩해야합니다.

unsigned int FBO;
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);  

이제 적어도 하나의 첨부 파일 (색, 깊이 또는 스텐실)을 프레임 버퍼에 추가해야합니다. 첨부 파일은 프레임 버퍼의 버퍼 역할을하는 메모리 위치입니다. 텍스처 또는 렌더 버퍼 객체 일 수 있습니다. 텍스처 사용의 이점은 사후 처리 쉐이더에서이 텍스처를 쉽게 사용할 수 있다는 것입니다. 텍스처를 생성하는 것은 일반적인 텍스처와 비슷합니다.

unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

widthheight 렌더링 윈도우 크기와 같아야합니다. 메모리를 할당하고 텍스처에 데이터를 채우지 않으려 고하기 때문에 텍스처 데이터 포인터가 NULL 입니다. 텍스처가 준비되었으므로 실제로 프레임 버퍼에 텍스처를 첨부 할 수 있습니다.

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);  

프레임 버퍼는 사용할 준비가되어 있어야하지만 깊이 부착 또는 깊이 및 스텐실 첨부를 추가 할 수도 있습니다. 그것들을 텍스쳐 첨부물로 추가하고 (일부 처리를 위해 그것들을 사용하는 경우), 위와 같은 다른 텍스쳐를 생성 할 수 있습니다. 유일한 차이점은 다음과 같습니다.

glTexImage2D(
    GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, 
    GL_DEPTH_COMPONENT, GL_FLOAT, NULL
);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture, 0);

또는 단일 텍스처에서 깊이 스텐실 첨부를 사용하려면 다음을 수행하십시오.

glTexImage2D(
    GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, width, height, 0, 
    GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL
);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texture, 0);

나중에 값을 처리하지 않으려는 경우 깊이 및 스텐실 버퍼의 첨부 파일로 텍스처 대신 렌더 버퍼 를 사용할 수도 있습니다. (다른 예에서 설명 할 것입니다 ...)

프레임 버퍼가 성공적으로 생성되고 오류없이 완료되었는지 확인할 수 있습니다.

if(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
    // do something...

마지막으로 실수로 프레임 버퍼를 렌더링하지 않도록 프레임 버퍼를 바인딩 해제하는 것을 잊지 마십시오.

glBindFramebuffer(GL_FRAMEBUFFER, 0);  

제한

컬러 상기 OGL 함수에 의해 결정될 수있는 하나의 프레임 버퍼에 부착 될 수있는 버퍼의 최대 수 glGetIntegerv , 파라미터 이용한 GL_MAX_COLOR_ATTACHMENTS :

GLint maxColAttchments = 0;
glGetIntegerv( GL_MAX_COLOR_ATTACHMENTS, &maxColAttchments );

프레임 버퍼 사용

사용법은 아주 간단합니다. 먼저 프레임 버퍼 를 바인드하고 장면을 렌더링합니다. 렌더링 버퍼가 보이지 않기 때문에 아직 아무 것도 볼 수 없습니다. 따라서 두 번째 부분은 프레임 버퍼를 화면에 전체 화면 쿼드의 텍스처로 렌더링하는 것입니다. 그냥 그대로 렌더링하거나 후 처리 효과를 낼 수 있습니다.

다음은 전체 화면 쿼드의 정점입니다.

float vertices[] = {
//   positions     texture coordinates
    -1.0f,  1.0f,  0.0f, 1.0f,
    -1.0f, -1.0f,  0.0f, 0.0f,
     1.0f, -1.0f,  1.0f, 0.0f,

    -1.0f,  1.0f,  0.0f, 1.0f,
     1.0f, -1.0f,  1.0f, 0.0f,
     1.0f,  1.0f,  1.0f, 1.0f
};

VBO에 저장하거나 속성 포인터를 사용하여 렌더링해야합니다. 또한 전체 화면 쿼드를 텍스처로 렌더링하기위한 기본 쉐이더 프로그램이 필요합니다.

버텍스 쉐이더 :

in vec2 position;
in vec2 texCoords;

out vec2 TexCoords;

void main()
{
    gl_Position = vec4(position.x, position.y, 0.0, 1.0); 
    TexCoords = texCoords;
}  

조각 쉐이더 :

in vec2 TexCoords;
out vec4 color;

uniform sampler2D screenTexture;

void main()
{ 
    color = texture(screenTexture, TexCoords);
}

참고 : GLSL 버전의 쉐이더를 조정해야 할 수도 있습니다.

이제 실제 렌더링을 수행 할 수 있습니다. 위에서 설명했듯이 첫 번째는 장면을 FBO로 렌더링하는 것입니다. 그렇게하기 위해서는 간단히 FBO를 바인딩하고, 그것을 지우고 씬을 그립니다 :

glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
// draw your scene here...   

참고 : glClear 함수에서 사용중인 모든 프레임 버퍼 첨부 파일을 지정해야합니다 (이 예제에서는 색상 및 깊이 첨부).

이제 기본 프레임 버퍼에서 FBO를 전체 화면 쿼드로 렌더링하여 볼 수 있습니다. 이렇게하려면 FBO를 바인딩 해제하고 쿼드를 렌더링하면됩니다.

glBindFramebuffer(GL_FRAMEBUFFER, 0); // unbind your FBO to set the default framebuffer
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

shader.Use(); // shader program for rendering the quad  

glBindTexture(GL_TEXTURE_2D, texture); // color attachment texture
glBindBuffer(GL_ARRAY_BUFFER, VBO); // VBO of the quad
// You can also use VAO or attribute pointers instead of only VBO...
glDrawArrays(GL_TRIANGLES, 0, 6); 
glBindBuffer(GL_ARRAY_BUFFER, 0);

그리고 그게 전부입니다! 모든 것을 올바르게했으면 이전과 동일한 장면을 보게되지만 전체 화면 쿼드에 렌더링해야합니다. 시각적 출력은 이전과 동일하지만 프래그먼트 셰이더를 편집하여 포스트 프로세싱 효과를 쉽게 추가 할 수 있습니다. (다른 예제에서 효과를 추가하고 여기에 링크 할 것입니다)



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow