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

关于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 STM32 INMP441无法读取数据
  • ¥100 求汇川机器人IRCB300控制器和示教器同版本升级固件文件升级包
  • ¥15 用visualstudio2022创建vue项目后无法启动
  • ¥15 x趋于0时tanx-sinx极限可以拆开算吗
  • ¥500 把面具戴到人脸上,请大家贡献智慧
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。
  • ¥15 各位 帮我看看如何写代码,打出来的图形要和如下图呈现的一样,急
  • ¥30 c#打开word开启修订并实时显示批注
  • ¥15 如何解决ldsc的这条报错/index error
  • ¥15 VS2022+WDK驱动开发环境