NightRainXiaoxiang 2016-06-06 00:54 采纳率: 0%
浏览 2096

关于opengl帧缓存对象FBO深度缓存的问题

各位老师好,在下opengl菜鸟一枚,最近学习opengl和glsl的过程中,使用FBO的深度缓存做延时渲染的时候遇到了一些问题。
我想实现个shadowmap,在光源视角下将深度缓存渲染进fbo,但是渲染第一次结束后,附加到fbo中的深度纹理里面的值却全部都为0。后来为了测试问题,我删除掉了第二个shader,只保留了第一个用来产生shadowmap的shader,发现fbo深度缓存依然都是0。如能指教迷津,不胜感激。一下是我的代码:
main函数

#include <stdio.h>
#include "Declaration.h"
#include "LoadShaders.h"
#include <gl/glew.h>
#include <gl/freeglut.h>
#include "cv.h"
#include "highgui.h"
#include "cxcore.h"
#include "StructDef.h"
GLuint *FBOUsedVAOs;
GLuint *FBOUsedBuffers;
GLuint *programs;
GLuint *FBOs;
GLuint *DepthTextureIDs;
void init()
{
  DepthTextureIDs = (GLuint*)malloc(sizeof(GLuint));//申请深度纹理对象ID的内存
    glGenTextures(1, DepthTextureIDs);//产生深度纹理ID
    glBindTexture(GL_TEXTURE_2D, DepthTextureIDs[0]);//绑定深度纹理ID
    //设置纹理参数 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 512, 512, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);

    glBindTexture(GL_TEXTURE_2D, 0);//解绑纹理ID


  FBOs = (GLuint*)malloc(sizeof(GLuint));//申请帧缓存对象的内存
  glGenFramebuffers(1,FBOs);//产生帧缓存对象
  glBindFramebuffer(GL_FRAMEBUFFER, FBOs[0]);//绑定帧缓存对象
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, DepthTextureIDs[0], 0);
  glDrawBuffer(GL_NONE);
  glReadBuffer(GL_NONE);
  glBindFramebuffer(GL_FRAMEBUFFER, 0);//解绑帧缓存对象
    programs = (GLuint*)malloc(sizeof(GLuint));//申请着色程序内存
    ShaderInfo FBOShader[3] = {            //用于渲染shadowmap的着色器
        { GL_VERTEX_SHADER, "FBOShader.vert" },
        { GL_FRAGMENT_SHADER, "FBOShader.frag" },
        { GL_NONE, NULL }
    };
  programs[0] = LoadShaders(FBOShader);  //加载着色器
  //计算各种坐标转换矩阵
    float ModelMat[16];
    float ViewMat[16];
    float PerspectiveProjectMat[16];

    float MAngle321[3] = {0, 0, 0.0};
    float MOffset[3] = {0.0, 0.0, 0.0};

    float VAngle321[3] = {0, 1.57, 0.0};
    float VOffset[3] = {0, 0, 5.0};

    float FOV = 1.57;
    float Aspect = 1;
    float NearDist = 1.0;
    float FarDist = 6;

  ModelMatCal(ModelMat, MAngle321, MOffset);
  ViewMatCal(ViewMat, VAngle321, VOffset);
  PerspectiveProjectMatCal(PerspectiveProjectMat, FOV, Aspect, NearDist, FarDist);

  float MVMat[16];
    float MVPMat[16];

  MatMultiplyMat4(MVMat, ViewMat, ModelMat);
  MatMultiplyMat4(MVPMat, PerspectiveProjectMat, MVMat);
    //将矩阵传递进FBOShader
    glUseProgram(programs[0]);//必须放在向shader中传Uniform数据的前面
  GLint MVPMatLoc;
    MVPMatLoc = glGetUniformLocation(programs[0],"MVPMat");
    glUniformMatrix4fv(MVPMatLoc, 1, GL_FALSE, MVPMat);
     //设置顶点数组
  #define  BUFFER_OFFSET(offset) ((void *)(NULL+offset))
  FBOUsedVAOs = (GLuint*)malloc(sizeof(GLuint));
  FBOUsedBuffers = (GLuint*)malloc(sizeof(GLuint));
    glGenVertexArrays(1, FBOUsedVAOs);
    glGenBuffers(1, FBOUsedBuffers);

    float FBOUsedVertices[24]= {
         1.0f,  1.0f,  3.0f, 1.0f,
         -1.0f,  1.0f,  3.0f, 1.0f,
         -1.0f, -1.0f, 3.0f, 1.0f,

         1.0f,  1.0f,  3.0f, 1.0f,
         -1.0f, -1.0f,  3.0f, 1.0f,
         1.0f, -1.0f, 3.0f, 1.0f
    };
    glBindVertexArray(FBOUsedVAOs[0]);

    glBindBuffer(GL_ARRAY_BUFFER, FBOUsedBuffers[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(FBOUsedVertices), FBOUsedVertices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
    glEnableVertexAttribArray(0);
}
void display()
{
      //向帧缓存对象中渲染数据
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBindFramebuffer(GL_FRAMEBUFFER, FBOs[0]);//绑定帧缓存对象
    glUseProgram(programs[0]);//选定shader
    glBindVertexArray(FBOUsedVAOs[0]);
    glDrawArrays(GL_TRIANGLES, 0, 6);

      float *DepthPixel = (float *)malloc(sizeof(float));
    glReadPixels(256,256,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,DepthPixel);

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
        glFlush();
}
int main(int argc, char** argv)
{
       glutInit(&argc, argv);
       glutInitDisplayMode(GLUT_RGBA);
       glutInitWindowSize(512, 512);
       glutInitContextVersion(4, 3);
       glutInitContextProfile(GLUT_CORE_PROFILE);                   
       glutCreateWindow(argv[0]);

       glewExperimental = GL_TRUE;
       if (glewInit())
      {
            cerr << "Unable to initialize GLEW ... exiting" << endl;
            exit(1);
       }   
      glEnable(GL_TEXTURE_CUBE_MAP);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);
      init();
      glutDisplayFunc(display);
      glutMainLoop();
}

顶点着色器

 #version 430

layout(location = 0)in vec4 VertPosition;

uniform mat4 MVPMat;

void main()
{
    gl_Position = MVPMat * VertPosition;
}

片元着色器

 #version 430

out vec4 FragColor;

void main()
{

    FragColor = vec4(vec3(gl_FragCoord.z), 1.0f);
}

将display函数中的glBindFramebuffer(GL_FRAMEBUFFER, FBOs[0])注释掉,就能够在DepthPixel中看到正确的深度结果,但是只要绑定了fbo,其深度结果就全都是0.也就是说,在屏渲染的时候,我能够获取到正确的深度值,但是离屏渲染的时候,深度值总是0.

  • 写回答

1条回答 默认 最新

  • NightRainXiaoxiang 2016-06-06 07:31
    关注

    已经解决,需要在
    glBindFramebuffer(GL_FRAMEBUFFER, FBOs[0]);//绑定帧缓存对象
    之后加上这样几条语句
    glClearDepth(1.0f);
    glClear(GL_DEPTH_BUFFER_BIT);

    // Enable polygon offset to resolve depth-fighting isuses
    glEnable(GL_POLYGON_OFFSET_FILL);
    glPolygonOffset(2.0f, 4.0f);
    

    因为不clear一下的话,深度缓存中的数据初始都是0,渲染是所有的深度都会大于等于0,所以不可能再去更新深度缓存。望以后遇到同样问题的同学引以为戒。

    评论

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!