OpenGL Frambuffers,渲染到深度纹理

时间:2014-08-28 21:34:20

标签: c++ opengl shader

问题:

代码应该渲染场景并将结果写入深度纹理。当我在渲染后检查纹理的内容时,它包含所有0值。

我尝试了什么:

我尝试输出到屏幕而不是纹理,它按预期绘制场景,因此正确读取顶点和矩阵值。我已经尝试了多个教程,他们基本上都说将帧缓冲区绑定到纹理,这正是我所做的。我相信麻烦可能是某种版本问题或者我忽略的东西,如参数或其他东西。我已经在这里待了几个小时,我无法发现它。希望有人可以。

详细信息:

  • OpenGL 3.1
  • GLSL 140

注意:这样做的目的是允许阴影映射工作。因此有2组着色器和绘图功能。一个绘制到深度缓冲区,另一个绘制对象。

代码:

着色器初始化代码:

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");

}

对象初始化代码

void Engine::load(MObject* object)
{
    unload(object);

    // |Physics|
    object->mesh = memoryManager.alloc<btTriangleIndexVertexArray>(
                                        object->elements.length()/3,
                                        (int*)&object->elements[0],
                                        3*sizeof(GLuint),
                                        object->attributes.length(),
                                        (btScalar*)&object->attributes[0],
                                        sizeof(MObject::Attribute));

    btCollisionShape* shape;
    btScalar mass = 0;
    btVector3 inertia(0, 0, 0);
    if(object->dynamic)
    {
        shape = memoryManager.alloc<btGImpactMeshShape>(object->mesh);
        ((btGImpactMeshShape*)shape)->updateBound();
        mass = 1;
        shape->calculateLocalInertia(mass, inertia);
    }else{
        shape = memoryManager.alloc<btBvhTriangleMeshShape>(object->mesh, true);
    }

    object->rigidBody = (btRigidBody*)memoryManager.galloc(sizeof(btRigidBody), memoryManager.alignment<btRigidBody>());
    new (object->rigidBody) btRigidBody(mass, object, shape, inertia); // 16-byte aligned param work around...
    physicsWorld->addRigidBody(object->rigidBody);

    // |Graphics|

    // Vertex array object

    glGenVertexArrays(1, &object->objectvao);
    glBindVertexArray(object->objectvao);

    // Vertex buffer object

    glGenBuffers(1, &object->vbo);
    glBindBuffer(GL_ARRAY_BUFFER, object->vbo);
    glBufferData(GL_ARRAY_BUFFER, object->attributes.length()*sizeof(MObject::Attribute), object->attributes.data, GL_STATIC_DRAW);

    // Vertex attributes

    glEnableVertexAttribArray(object->objectPositionLoc);
    glVertexAttribPointer(object->objectPositionLoc, 3, GL_FLOAT, GL_FALSE, sizeof(MObject::Attribute), (void*)0);
    glEnableVertexAttribArray(object->objectTexCoordLoc);
    glVertexAttribPointer(object->objectTexCoordLoc, 2, GL_FLOAT, GL_FALSE, sizeof(MObject::Attribute), (void*)offsetof(class MObject::Attribute, texCoord));
    glEnableVertexAttribArray(object->objectNormalLoc);
    glVertexAttribPointer(object->objectNormalLoc, 3, GL_SHORT, GL_TRUE, sizeof(MObject::Attribute), (void*)offsetof(class MObject::Attribute, normal));

    // Element buffer object

    object->eboNumElements = object->elements.length();
    glGenBuffers(1, &object->ebo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object->ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, object->elements.length()*sizeof(GLuint), object->elements.data, GL_STATIC_DRAW);

    glBindVertexArray(0);

    // Shadow vao

    glGenVertexArrays(1, &object->shadowvao);
    glBindVertexArray(object->shadowvao);

    glBindBuffer(GL_ARRAY_BUFFER, object->vbo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object->ebo);

    glEnableVertexAttribArray(object->shadowPositionLoc);
    glVertexAttribPointer(object->shadowPositionLoc, 3, GL_FLOAT, GL_FALSE, sizeof(MObject::Attribute), (void*)0);

    glBindVertexArray(0);


    mObjectList.pushBack(object);
}

绘制代码:

/ * START - 主要更新圈的部分* /     // |绘制更新|

// 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);

/ *结束 - 主要更新圈的部分* /

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);
}*/

1 个答案:

答案 0 :(得分:-1)

我明白了。显然,如果你重新排列opengl调用它有点工作。我相信我所做的是将glBindFramebuffer放在glUseProgram之前并且它有效。