OpenGL的Frambuffers,渲染到深度纹理
问题描述:
的代码应该渲染场景并将结果写入到一个深度纹理。当我在渲染之后检查纹理的内容时,它包含全部0个值。
我曾尝试:
我试图输出到屏幕上,而不是质地和它绘制的场景如预期,因此被正确读取顶点和矩阵值。我已经尝试了多个教程,他们都基本上说要将帧缓冲区绑定到纹理,这正是我所做的。我相信这个问题可能是某种版本问题,或者是我忽略了一些参数或其他内容。我已经在这里待了几个小时,但我无法发现它。希望有人能。
详情:
- 的OpenGL 3.1
- GLSL 140
注:这样做的目的是为了让阴影映射工作。所以有两套着色器和绘图函数。一个绘制到深度缓冲区,另一个绘制对象。
代码:
着色器的初始化代码:
void Engine::loadMObject()
{
glGenFramebuffers(1, &MObject::fbo);
glGenTextures(1, &MObject::shadowMap);
glBindFramebuffer(GL_FRAMEBUFFER, MObject::fbo);
glBindTexture(GL_TEXTURE_2D, MObject::shadowMap);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, windowWidth, windowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, MObject::shadowMap, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
assi(status == GL_FRAMEBUFFER_COMPLETE, "FBO error!");
glBindFramebuffer(GL_FRAMEBUFFER, 0);
MObject::shadowProgram = Shader::compile((char*)MObject::shadowVertexShaderFile, (char*)MObject::shadowFramentShaderFile);
MObject::shadowPositionLoc = glGetAttribLocation(MObject::shadowProgram, "position");
MObject::shadowModelProjectionMatrixLoc = glGetUniformLocation(MObject::shadowProgram, "modelProjectionMatrix");
MObject::objectProgram = Shader::compile((char*)MObject::objectVertexShaderFile, (char*)MObject::objectFragmentShaderFile);
MObject::objectPositionLoc = glGetAttribLocation(MObject::objectProgram, "position");
MObject::objectTexCoordLoc = glGetAttribLocation(MObject::objectProgram, "texCoord");
MObject::objectNormalLoc = glGetAttribLocation(MObject::objectProgram, "normal");
MObject::objectWorldMatrixLoc = glGetUniformLocation(MObject::objectProgram, "worldMatrix");
MObject::objectViewMatrixLoc = glGetUniformLocation(MObject::objectProgram, "viewMatrix");
MObject::objectProjectionMatrixLoc = glGetUniformLocation(MObject::objectProgram, "projectionMatrix");
MObject::objectTextureLoc = glGetUniformLocation(MObject::objectProgram, "texture");
MObject::objectDepthModelProjectionMatrixLoc = glGetUniformLocation(MObject::objectProgram, "depthModelProjectionMatrix");
}
对象的初始化代码
抽奖代码:
/*开始 - 主要更新循环部分*/ // |绘制更新|
// Shadow Pass
// testing...
if(isKeyDown(SDL_SCANCODE_0)){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(MObject::shadowProgram);
glBindFramebuffer(GL_FRAMEBUFFER, MObject::fbo);
glBindTexture(GL_TEXTURE_2D, MObject::shadowMap);
for(U32 i=0;i<mObjectList.length();++i)
{
drawShadow(mObjectList[i]);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, MObject::shadowMap);
GLfloat* pixels = new GLfloat[windowWidth*windowHeight];
glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_FLOAT, pixels);
for(U32 i=0;i<windowHeight*windowHeight;++i)
{
if(pixels[i] != 0.0f)
printd("I GOT IT!");
}
delete[] pixels;
}else{
// Object Pass
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(MObject::objectProgram);
for(U32 i=0;i<mObjectList.length();++i)
{
drawObject(mObjectList[i]);
}
}
// Swapping buffers
SDL_GL_SwapWindow(mainWindow);
/* END - 部分主OF UPDATE LOOP */
void Engine::drawObject(MObject* object)
{
TransformMatrix matrix;
getOrthographicMatrix(matrix, -10, 10, 10, -10, -10, 20);
glBindVertexArray(object->objectvao);
glUniformMatrix4fv(MObject::objectWorldMatrixLoc, 1, GL_FALSE, (GLfloat*)&object->worldMatrix);
glUniformMatrix4fv(MObject::objectViewMatrixLoc, 1, GL_FALSE, (GLfloat*)&getViewMatrix());
glUniformMatrix4fv(MObject::objectProjectionMatrixLoc, 1, GL_FALSE, (GLfloat*)&getProjectionMatrix());
glUniformMatrix4fv(MObject::objectDepthModelProjectionMatrixLoc, 1, GL_FALSE, (GLfloat*)&getProjectionMatrix());
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, object->tbo);
glUniform1i(MObject::objectTextureLoc, 0);
glDrawElements(GL_TRIANGLES, object->eboNumElements, GL_UNSIGNED_INT, 0);
}
void Engine::drawShadow(MObject* object)
{
TransformMatrix matrix;
//getOrthographicMatrix(matrix, -10, 10, 10, -10, -10, 20);
matrix = getProjectionMatrix() * getViewMatrix() * object->worldMatrix;
glBindVertexArray(object->shadowvao);
glUniformMatrix4fv(MObject::shadowModelProjectionMatrixLoc, 1, GL_FALSE, (GLfloat*)&matrix);
glDrawElements(GL_TRIANGLES, object->eboNumElements, GL_UNSIGNED_INT, 0);
}
顶点着色器:
#version 140
in vec3 position;
uniform mat4 modelProjectionMatrix;
void main(){
gl_Position = modelProjectionMatrix * vec4(position, 1.0f);
}
片段着色器:
#version 140
out float fragmentdepth;
void main(){
fragmentdepth = gl_FragCoord.z;
}
/*
out vec4 color;
void main(){
color = vec4(clamp(gl_FragCoord.z, 0.0f, 1.0f), 0.0f, 0.0f, 1.0f);
}*/
答
我想通了。显然,如果你重新排列opengl调用一点点它的作品。我相信我所做的就是在glUseProgram之前放入glBindFramebuffer并且它工作正常。
你尝试添加'glEnable(GL_DEPTH_TEST);' – programmerjake 2014-08-28 22:08:54