各位老师好,在下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.