MRT(多纹理输出OPENEXR)

来源:互联网 发布:淘宝时光机链接 编辑:程序博客网 时间:2024/05/29 18:45
主要讲述在CG下如何进行多纹理输出:

1:为读入的纹理和输出的 多纹理分配内存:
    Rgba = ReadEXR(filename+".exr", FileSize);
    Rgba1 = new half[4 * FileSize.x * FileSize.y];
    Rgba2 = new half[4 * FileSize.x * FileSize.y];
    Rgba3 = new half[4 * FileSize.x * FileSize.y];

2:生成纹理,FBO
    ///////////////////////////////////////////////////////////////////////////////////////////////
    glGenFramebuffersEXT(1, &fbo);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

    // Create the render buffer for depth   
    glGenRenderbuffersEXT(1, &depthBuffer);
    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, FileSize.x, FileSize.y);

    ///////////////////////////////////////////////////////////////////////////////////////////////
    glGenTextures (4, Texture_Id);


    glBindTexture (target, Texture_Id[0]);
    glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri (target, GL_TEXTURE_WRAP_S,        GL_CLAMP_TO_EDGE);
    glTexParameteri (target, GL_TEXTURE_WRAP_T,        GL_CLAMP_TO_EDGE);
    glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
    glTexImage2D (target, 0, GL_FLOAT_RGBA16_NV, FileSize.x, FileSize.y, 0,  GL_RGBA, GL_HALF_FLOAT_NV, Rgba);

    ///////////////////////////////////////////////////////////////////////////////////////////////
    glBindTexture (target, Texture_Id[1]);
    glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri (target, GL_TEXTURE_WRAP_S,        GL_CLAMP_TO_EDGE);
    glTexParameteri (target, GL_TEXTURE_WRAP_T,        GL_CLAMP_TO_EDGE);
    glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
    glTexImage2D (target, 0, GL_FLOAT_RGBA16_NV, FileSize.x, FileSize.y, 0,  GL_RGBA, GL_HALF_FLOAT_NV, Rgba1);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, Texture_Id[1], 0);

    glBindTexture (target, Texture_Id[2]);
    glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri (target, GL_TEXTURE_WRAP_S,        GL_CLAMP_TO_EDGE);
    glTexParameteri (target, GL_TEXTURE_WRAP_T,        GL_CLAMP_TO_EDGE);
    glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
    glTexImage2D (target, 0, GL_FLOAT_RGBA16_NV, FileSize.x, FileSize.y, 0,  GL_RGBA, GL_HALF_FLOAT_NV, Rgba2);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, target, Texture_Id[2], 0);

    glBindTexture (target, Texture_Id[3]);
    glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri (target, GL_TEXTURE_WRAP_S,        GL_CLAMP_TO_EDGE);
    glTexParameteri (target, GL_TEXTURE_WRAP_T,        GL_CLAMP_TO_EDGE);
    glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
    glTexImage2D (target, 0, GL_FLOAT_RGBA16_NV, FileSize.x, FileSize.y, 0,  GL_RGBA, GL_HALF_FLOAT_NV, Rgba3);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, target, Texture_Id[3], 0);

    ///////////////////////////////////////////////////////////////////////////////////////////////

    // Attach the depth render buffer to the FBO as it's depth attachment
    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBuffer);

    // Define an array which contains the targets we wish to render to...
    GLenum mrt[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT};
    // ... then inform OpenGL that we wish to render to these two targets
    glDrawBuffers(3,mrt);

    GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    if(status != GL_FRAMEBUFFER_COMPLETE_EXT)
        exit(1);

    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);    // Unbind the FBO for now

    ///////////////////////////////////////////////////////////////////////////////////////////////

    CgFragmentParam_image = cgGetNamedParameter(CgFragmentProgram, "image");
    checkForCgError("getting decal parameter");

    cgGLSetTextureParameter(CgFragmentParam_image, Texture_Id[0]);
    checkForCgError("setting decal 2D texture");

    cgGLEnableTextureParameter(CgFragmentParam_image);
    checkForCgError("enable decal texture");

3:对多纹理进行输入
    glGetIntegerv(GL_DRAW_BUFFER, &_currentDrawbuf);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

    glBegin (GL_QUADS);
        glTexCoord2f (0.0,    0.0);    glVertex2f(0.0,    0.0);
        glTexCoord2f (FileSize.x, 0.0);    glVertex2f(FileSize.x, 0.0);
        glTexCoord2f (FileSize.x, FileSize.y); glVertex2f(FileSize.x, FileSize.y);
        glTexCoord2f (0.0,    FileSize.y); glVertex2f(0.0,    FileSize.y);
    glEnd ();

    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    glDrawBuffer(_currentDrawbuf);

4:查看多纹理输出是否成功

    glBindTexture(target,Texture_Id[1]);
    glGetTexImage(target,0,GL_RGBA,GL_HALF_FLOAT_NV,Rgba1);
    WriteEXR("1.exr", Rgba1, FileSize);

    glBindTexture(target,Texture_Id[2]);
    glGetTexImage(target,0,GL_RGBA,GL_HALF_FLOAT_NV,Rgba2);
    WriteEXR("2.exr", Rgba2, FileSize);

    glBindTexture(target,Texture_Id[3]);
    glGetTexImage(target,0,GL_RGBA,GL_HALF_FLOAT_NV,Rgba3);
    WriteEXR("3.exr", Rgba3, FileSize);

5:cg文件
struct Out
{
    half4 color0 : COLOR0;
    half4 color1 : COLOR1;
    half4 color2 : COLOR2;
};

Out PS_Filter (float2 texCoord : TEXCOORD0,
      uniform samplerRECT image)
{
    Out output;

    half4 pixel = h4texRECT (image, texCoord);

    output.color0 = half4(1,0,0,1);
    output.color1 = half4(0,1,0,1);
    output.color2 = half4(0,0,1,1);

    //output.color = pixel;

    return output;
}