渲染到CubeMap纹理

时间:2017-08-17 13:11:49

标签: opengl

似乎每次传递都会使用相同的像素数据渲染cubeMap的所有六个面!

这是代码(我猜我的问题在这里): 调用顺序在函数init()中表示。

只需设置数据!这里不会有任何错误

void initRenderData( GLuint& m_sceneVAO, GLuint& m_sceneVBO, GLuint& m_sceneEBO, rcMeshLoaderObj** m_ppObjModel, float( bound )[6], std::string s = "fffzzz.obj" )
{
    *m_ppObjModel = new rcMeshLoaderObj;
    (*m_ppObjModel)->load(s);
    (*m_ppObjModel)->getBoundBox(bound);

    glGenVertexArrays ( 1, &m_sceneVAO );
    glBindVertexArray ( m_sceneVAO );

    glGenBuffers ( 1, &m_sceneVBO );
    glBindBuffer ( GL_ARRAY_BUFFER, m_sceneVBO );
    glBufferData ( GL_ARRAY_BUFFER, sizeof ( GLfloat )*(*m_ppObjModel)->getVertCount()*3, (*m_ppObjModel)->getVerts(), GL_STATIC_DRAW);
    glVertexAttribPointer ( 0, 3, GL_FLOAT, GL_TRUE, 0, BUFFER_OFFSET ( 0 ) );
    glEnableVertexAttribArray ( 0 );

    //default value for normal attribute and color attribute
    glVertexAttrib3f( 1, 0.0f, .0f, .0f );
    glVertexAttrib4f( 2, 0.5f, 0.5f, 0.5f, 1.0f );

    glGenBuffers ( 1, &m_sceneEBO );
    glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, m_sceneEBO );
    glBufferData ( GL_ELEMENT_ARRAY_BUFFER, sizeof ( unsigned int ) * 3 * (*m_ppObjModel)->getTriCount ( ), (*m_ppObjModel)->getTris ( ), GL_STATIC_DRAW );
}
//just draw the scene, could't be any error here eithor.
void drawModel( rcMeshLoaderObj* m_pObjModel, GLuint& m_sceneVAO, GLuint& m_sceneEBO)
{
    glBindVertexArray(m_sceneVAO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_sceneEBO);

    glDrawElements(
        GL_TRIANGLES,
        m_pObjModel->getTriCount() * 3,
        GL_UNSIGNED_INT,
        NULL);
}

生成cubeMap纹理和2d纹理

void genCubeTexture( GLuint& cubeMapTex, GLint internalFormat, GLenum format, GLenum type, GLsizei width, GLsizei height, GLint level = 0, const GLvoid * data = NULL )
{
    glGenTextures( 1, &cubeMapTex );
    glBindTexture( GL_TEXTURE_CUBE_MAP, cubeMapTex );

    for ( GLuint face = 0; face < 6; face++) {
        glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, internalFormat,
                      width, height, 0, format, type, data );
    }

    glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
    glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
    glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
    glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );
    glGenerateMipmap( GL_TEXTURE_CUBE_MAP );

    glBindTexture( GL_TEXTURE_CUBE_MAP, 0 );
}

void genTexture2D( GLuint& texture2D, GLint internalFormat, GLenum format, GLenum type, GLsizei width, GLsizei height, GLint level = 0, const GLvoid * data = NULL )
{
    glGenTextures( 1, &texture2D );
    glBindTexture( GL_TEXTURE_2D, texture2D );
    glTexImage2D( GL_TEXTURE_2D, level, internalFormat,
                  width, height, 0,
                  format, type, data );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL );
}
// no error would be here
void initShadowMapProgram ( GLuint & shadow_program)
{
    ShaderInfo shaders[] = {
        {GL_VERTEX_SHADER, "shadow.vert" },
        {GL_FRAGMENT_SHADER, "shadow.frag" },
        {GL_NONE, NULL }
    };
    shadow_program = LoadShaders ( shaders );
}

我猜错误来自下面的代码

void setDepthTexture (GLuint& shadow_program, GLuint& m_depthFBO, GLuint& m_shadowTexture, glm::vec3& lightPosition, rcMeshLoaderObj* model, GLuint& vao, GLuint& ebo )
{

    //generate  CubeMap textures separately used for framebuffer's color attachment0 and color attachment1.
    glActiveTexture( GL_TEXTURE1 );
    genCubeTexture( m_frame_buffer_color, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, 1024, 1024 );
    glActiveTexture( GL_TEXTURE2 );
    genCubeTexture( m_shadowTexture, GL_R32F, GL_RED, GL_FLOAT, 1024, 1024 );

    //generate a 2D texture used for framebuffer's depth attachment.
    glActiveTexture( GL_TEXTURE3 );
    genTexture2D( m_depthTexture, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, 1024, 1024 );

    glm::vec3 d, up;
    glm::mat4 light_mvp_matrix;
    GLint mvp_matrix_location = glGetUniformLocation ( shadow_program, "mvp_matrix" );
    glUseProgram ( shadow_program );

    glGenFramebuffers ( 1, &m_depthFBO );
    glBindFramebuffer( GL_FRAMEBUFFER, m_depthFBO );
    glFramebufferTexture( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_depthTexture, 0 );


    for( GLuint face = 0; face < 6; face++ )
    {
        glBindFramebuffer ( GL_FRAMEBUFFER, m_depthFBO );
        glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, m_shadowTexture, 0 );
        glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, m_frame_buffer_color, 0 );

        switch( face )
        {
            case 0://X+
                d = { 1.0f, 0.0f, 0.0f };
                up = { 0.0f, 1.0f, 0.0f };
                break;
            case 1://X-
                d = { -1.0f, 0.0f, 0.0f };
                up = { 0.0f, 1.0f, 0.0f };
                break;
            case 2://Y+
                d = { 0.0f, 1.0f, 0.0f };
                up = { 0.0f, 0.0f, -1.0f };
                break;
            case 3://Y-
                d = { 0.0f, -1.0f, 0.0f };
                up = { 0.0f, 0.0f, 1.0f };
                break;
            case 4://Z+
                d = { 0.0f, 0.0f, 1.0f };
                up = { 0.0f, 1.0f, 0.0f };
                break;
            case 5://Z-
                d = { 0.0f, 0.0f, -1.0f };
                up = { 0.0f, 1.0f, 0.0f };
                break;
            default:
                break;
        }
        GLenum status = glCheckFramebufferStatus( GL_FRAMEBUFFER );
        if( status != GL_FRAMEBUFFER_COMPLETE )
            printErrorMessage( status );
        camera.setPDU( lightPosition, d, up );
        light_mvp_matrix = lightPerspectiveMatrix*glm::lookAt( lightPosition, lightPosition + d, up );

        glUniformMatrix4fv ( mvp_matrix_location, 1, GL_FALSE, glm::value_ptr ( light_mvp_matrix ) );

        glClearDepth ( 1.0f );
        glClearColor ( 0.0f, 0.0f, 0.0f, 1.0f );
        glClear ( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
        glEnable ( GL_DEPTH_TEST );
        glEnable ( GL_POLYGON_OFFSET_FILL );

        glViewport ( 0, 0, 1024, 1024 );

        //glPolygonOffset ( 2.0f, 4.0f );
        drawModel( model, vao, ebo );
        //glPolygonOffset ( 0.0f, 0.0f );

        glDisable ( GL_POLYGON_OFFSET_FILL );
    }
    glBindFramebuffer ( GL_FRAMEBUFFER, 0 );
    glUseProgram( 0 );
}
//could't be here
void initRenderProgram(GLint& program, GLuint& m_shadowTexture, glm::vec3& lightPosition, Camera& camera)
{ 
    ShaderInfo shaders[] = {
        {GL_VERTEX_SHADER, "ObjModel.vert" },
        {GL_GEOMETRY_SHADER, "ObjModel.geom" },
        {GL_FRAGMENT_SHADER, "ObjModel.frag" },
        {GL_NONE, NULL }
    };
    program = LoadShaders ( shaders );
    glUseProgram ( program );

    shadowTexture_location = glGetUniformLocation( program, "shadowTex" );
    depthTexture_location = glGetUniformLocation( program, "depthTex" );

    model_matrix_location = glGetUniformLocation ( program, "model_matrix" );
    view_matrix_location = glGetUniformLocation ( program, "view_matrix" );
    projection_matrix_location = glGetUniformLocation ( program, "projection_matrix" );

    light_position_location = glGetUniformLocation( program, "light_position" );
    material_ambient_location = glGetUniformLocation( program, "material_ambient" );
    material_diffuse_location = glGetUniformLocation( program, "material_diffuse" );
    material_specular_location = glGetUniformLocation( program, "material_specular" );
    material_specular_power_location = glGetUniformLocation( program, "material_specular_power" );
    eye_position_location = glGetUniformLocation( program, "eye_position" );



    glActiveTexture( GL_TEXTURE1 );
    glBindTexture( GL_TEXTURE_CUBE_MAP, m_shadowTexture );
    glUniform1i ( shadowTexture_location, 1 );

    glUniformMatrix4fv( model_matrix_location, 1, GL_FALSE, glm::value_ptr( glm::mat4( 1.0f ) ) );
    glUniformMatrix4fv( view_matrix_location, 1, GL_FALSE, glm::value_ptr( camera.getViewMatrix( ) ) );
    glUniformMatrix4fv( projection_matrix_location, 1, GL_FALSE, glm::value_ptr( camera.getProjectionMatrix( ) ) );

    glUniform3f( light_position_location, lightPosition.x, lightPosition.y, lightPosition.z );
    glUniform3f( material_ambient_location, 0.3f, 0.3f, 0.3f );
    glUniform3f( material_diffuse_location, 0.4f, 0.4f, 0.4f );
    glUniform3f( material_specular_location, 0.3f, 0.3f, 0.3f );
    glUniform1f( material_specular_power_location, 20.0f );
    glUniform3f( eye_position_location, camera.getPosition( ).x, camera.getPosition( ).y, camera.getPosition( ).z );

    glUseProgram ( 0 );

    glClearColor(0, 0, 0, 1);
    glEnable(GL_DOUBLEBUFFER);
    glEnable(GL_DEPTH_TEST);

}

致电订单

void init ( )
{
    genSampler( m_shadowSampler );
    initRenderData ( m_sceneVAO, m_sceneVBO, m_sceneEBO, &m_pObjModel, bound );

    initShadowMapProgram( shadow_program );
    setDepthTexture( shadow_program, m_depthFBO, m_shadowTexture, lightPosition, m_pObjModel, m_sceneVAO, m_sceneEBO );
    initRenderProgram ( program, m_shadowTexture, lightPosition, camera );
}

可能在这里?

void display()
{

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


    //帧缓存附件之间的像素拷贝
    glBindFramebuffer ( GL_FRAMEBUFFER, 0 );
    glDrawBuffer ( GL_BACK );


    for( GLuint face = 0; face < 6; face++ )
    {
        glBindFramebuffer( GL_READ_FRAMEBUFFER, m_depthFBO );
        glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, m_frame_buffer_color, 0 );

        glReadBuffer( GL_COLOR_ATTACHMENT1 );

        GLfloat l, b;
        switch( face )
        {
            case 0:
                l = 0.5f;
                b = 1.0f / 3;
                break;
            case 1:
                l = 0.0f;
                b = 1.0f / 3;
                break;
            case 2:
                l = 0.25f;
                b = 2.0f / 3;
                break;
            case 3:
                l = 0.25f;
                b = 0.0f;
                break;
            case 4:
                l = 3.0f / 4;
                b = 1.0f / 3;
                break;
            case 5:
                l = 0.25f;
                b = 1.0f / 3;
                break;
            default:
                break;
        }

        glBlitFramebuffer( 0, 0, 1024, 1024,
                           0 + l * 400, viewPorts[0][3] - 300 + b * 300, l * 400 + 0.25f * 400, viewPorts[0][3] - 300 + b * 300 + 1.0f / 3 * 300 ,
                        GL_COLOR_BUFFER_BIT, GL_LINEAR );

    }


    glUseProgram ( program );

    glUniformMatrix4fv( model_matrix_location, 1, GL_FALSE, glm::value_ptr( glm::mat4( 1.0f ) ) );
    glUniformMatrix4fv( view_matrix_location, 1, GL_FALSE, glm::value_ptr( camera.getViewMatrix( ) ) );
    glUniformMatrix4fv( projection_matrix_location, 1, GL_FALSE, glm::value_ptr( camera.getProjectionMatrix( ) ) );
    glUniform3f( eye_position_location, camera.getPosition( ).x, camera.getPosition( ).y, camera.getPosition( ).z );

    glViewport(viewPorts[0][0], viewPorts[0][1], viewPorts[0][2], viewPorts[0][3]);

    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glShadeModel(GL_SMOOTH);

    drawModel( m_pObjModel, m_sceneVAO, m_sceneEBO );

    glUseProgram ( 0 );

    glViewport(viewPorts[0][0], viewPorts[0][1], viewPorts[0][2], viewPorts[0][3]);
    glMatrixMode(GL_PROJECTION);
    glLoadMatrixf ( glm::value_ptr ( camera.getViewProjectionMatrix ( ) ) );

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity ( );


    drawBoundBox ( bound );

 //   glEnable(GL_POLYGON_OFFSET_FILL);//激活多边形偏移
 //   glPolygonOffset(1, 1);//计算出一个偏移值,以后每个片段的深度值都加上这个值
    //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    //glLineWidth ( 1 );
    //glColor3f( 1.0f, 0.0f, 0.0f );
    //glDrawElements(
    //  GL_TRIANGLES,
    //  m_pObjModel->getTriCount() * 3,
    //  GL_UNSIGNED_INT,
    //  NULL);

    glUseProgram(0);

    camera.drawCompass3D(viewPorts[1]);

    glBindVertexArray(0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);


    glFinish();
    glutSwapBuffers();
}

这是图像:

it seems that every pass render all the six faces of the cubeMap with the same pixels data!

我该怎么做才能修好它?我的显卡是GF840,有没有可能因为我的NV卡不支持一些新的GL功能?

1 个答案:

答案 0 :(得分:-1)

这是错误的:

glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, f, m_frame_buffer_color, 0 );

第三个参数必须是从GL_TEXTURE_CUBE_MAP_POSITIVE_X开始的GLenum,因此请将其更改为:

glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, m_frame_buffer_color, 0 );