多种渲染目标:MRT - MartinRGB/GLES30_ProgrammingGuide_NDK GitHub Wiki
多重渲染目标
MRT 允许应用一次渲染到多个 颜色缓冲区,应用到高级渲染算法中,例如延迟着色和快速环境这比估算。
方法:
1.glGenFramebuffers 和 glBindFramebuffer 初始化 FBO
2.glGenTextures 和 glBindTexure 初始化纹理
3.glFramebufferTexture2D 将纹理绑定到 FBO
int InitFBO ( ESContext *esContext )
{
UserData *userData = esContext->userData;
int i;
GLint defaultFramebuffer = 0;
const GLenum attachments[4] =
{
GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2,
GL_COLOR_ATTACHMENT3
};
glGetIntegerv ( GL_FRAMEBUFFER_BINDING, &defaultFramebuffer );
// Setup fbo
glGenFramebuffers ( 1, &userData->fbo );
glBindFramebuffer ( GL_FRAMEBUFFER, userData->fbo );
// Setup four output buffers and attach to fbo
userData->textureHeight = userData->textureWidth = 400;
glGenTextures ( 4, &userData->colorTexId[0] );
for (i = 0; i < 4; ++i)
{
glBindTexture ( GL_TEXTURE_2D, userData->colorTexId[i] );
glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGBA,
userData->textureWidth, userData->textureHeight,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
// Set the filtering mode
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glFramebufferTexture2D ( GL_DRAW_FRAMEBUFFER, attachments[i],
GL_TEXTURE_2D, userData->colorTexId[i], 0 );
}
glDrawBuffers ( 4, attachments );
if ( GL_FRAMEBUFFER_COMPLETE != glCheckFramebufferStatus ( GL_FRAMEBUFFER ) )
{
return FALSE;
}
// Restore the original framebuffer
glBindFramebuffer ( GL_FRAMEBUFFER, defaultFramebuffer );
return TRUE;
}
4.glDrawBuffers 为渲染指定颜色附着
///
// Copy MRT output buffers to screen
//
void BlitTextures ( ESContext *esContext )
{
UserData *userData = esContext->userData;
// set the fbo for reading
glBindFramebuffer ( GL_READ_FRAMEBUFFER, userData->fbo );
// Copy the output red buffer to lower left quadrant
glReadBuffer ( GL_COLOR_ATTACHMENT0 );
glBlitFramebuffer ( 0, 0, userData->textureWidth, userData->textureHeight,
0, 0, esContext->width/2, esContext->height/2,
GL_COLOR_BUFFER_BIT, GL_LINEAR );
// Copy the output green buffer to lower right quadrant
glReadBuffer ( GL_COLOR_ATTACHMENT1 );
glBlitFramebuffer ( 0, 0, userData->textureWidth, userData->textureHeight,
esContext->width/2, 0, esContext->width, esContext->height/2,
GL_COLOR_BUFFER_BIT, GL_LINEAR );
// Copy the output blue buffer to upper left quadrant
glReadBuffer ( GL_COLOR_ATTACHMENT2 );
glBlitFramebuffer ( 0, 0, userData->textureWidth, userData->textureHeight,
0, esContext->height/2, esContext->width/2, esContext->height,
GL_COLOR_BUFFER_BIT, GL_LINEAR );
// Copy the output gray buffer to upper right quadrant
glReadBuffer ( GL_COLOR_ATTACHMENT3 );
glBlitFramebuffer ( 0, 0, userData->textureWidth, userData->textureHeight,
esContext->width/2, esContext->height/2, esContext->width, esContext->height,
GL_COLOR_BUFFER_BIT, GL_LINEAR );
}
///
// Render to MRTs and screen
//
void Draw ( ESContext *esContext )
{
UserData *userData = esContext->userData;
GLint defaultFramebuffer = 0;
const GLenum attachments[4] =
{
GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2,
GL_COLOR_ATTACHMENT3
};
glGetIntegerv ( GL_FRAMEBUFFER_BINDING, &defaultFramebuffer );
// FIRST: use MRTs to output four colors to four buffers
glBindFramebuffer ( GL_FRAMEBUFFER, userData->fbo );
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glDrawBuffers ( 4, attachments );
DrawGeometry ( esContext );
// SECOND: copy the four output buffers into four window quadrants
// with framebuffer blits
// Restore the default framebuffer
glBindFramebuffer ( GL_DRAW_FRAMEBUFFER, defaultFramebuffer );
BlitTextures ( esContext );
}
5.fragment中声明和使用多个着色器输出 例如 fragData0 ~ fragData3 分别复制到绘图缓冲区 0 ~ 3
char fShaderStr[] =
"#version 300 es \n"
"precision mediump float; \n"
"layout(location = 0) out vec4 fragData0; \n"
"layout(location = 1) out vec4 fragData1; \n"
"layout(location = 2) out vec4 fragData2; \n"
"layout(location = 3) out vec4 fragData3; \n"
"void main() \n"
"{ \n"
" // first buffer will contain red color \n"
" fragData0 = vec4 ( 1, 0, 0, 1 ); \n"
" \n"
" // second buffer will contain green color \n"
" fragData1 = vec4 ( 0, 1, 0, 1 ); \n"
" \n"
" // third buffer will contain blue color \n"
" fragData2 = vec4 ( 0, 0, 1, 1 ); \n"
" \n"
" // fourth buffer will contain gray color \n"
" fragData3 = vec4 ( 0.5, 0.5, 0.5, 1 ); \n"
"}