void C3D_MODEL_VIEWER::ogl_set_arrow_material()
{
    glEnable( GL_COLOR_MATERIAL );
    glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );

    const SFVEC4F specular = SFVEC4F( 0.1f, 0.1f, 0.1f, 1.0f );

    glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, &specular.r );
    glMaterialf(  GL_FRONT_AND_BACK, GL_SHININESS, 96.0f );
}
Example #2
0
C_OGL_3DMODEL::C_OGL_3DMODEL( const S3DMODEL &a3DModel,
                              MATERIAL_MODE aMaterialMode )
{
    m_ogl_idx_list_meshes = 0;
    m_ogl_idx_list_opaque = 0;
    m_ogl_idx_list_transparent = 0;
    m_nr_meshes = 0;
    m_meshs_bbox = NULL;

    // Validate a3DModel pointers
    wxASSERT( a3DModel.m_Materials != NULL );
    wxASSERT( a3DModel.m_Meshes != NULL );
    wxASSERT( a3DModel.m_MaterialsSize > 0 );
    wxASSERT( a3DModel.m_MeshesSize > 0 );

    if( (a3DModel.m_Materials != NULL) && (a3DModel.m_Meshes != NULL) &&
        (a3DModel.m_MaterialsSize > 0) && (a3DModel.m_MeshesSize > 0) )
    {
        m_nr_meshes = a3DModel.m_MeshesSize;

        m_meshs_bbox = new CBBOX[a3DModel.m_MeshesSize];

        // Generate m_MeshesSize auxiliar lists to render the meshes
        m_ogl_idx_list_meshes = glGenLists( a3DModel.m_MeshesSize );

        // Render each mesh of the model
        // /////////////////////////////////////////////////////////////////////
        for( unsigned int mesh_i = 0; mesh_i < a3DModel.m_MeshesSize; ++mesh_i )
        {
            if( glIsList( m_ogl_idx_list_meshes + mesh_i ) )
            {
                const SMESH &mesh = a3DModel.m_Meshes[mesh_i];

                // Validate the mesh pointers
                wxASSERT( mesh.m_Positions != NULL );
                wxASSERT( mesh.m_FaceIdx != NULL );
                wxASSERT( mesh.m_Normals != NULL );

                if( (mesh.m_Positions != NULL) &&
                    (mesh.m_Normals != NULL) &&
                    (mesh.m_FaceIdx != NULL) &&
                    (mesh.m_FaceIdxSize > 0) && (mesh.m_VertexSize > 0) )
                {
                    SFVEC4F *pColorRGBA = NULL;

                    // Create the bbox for this mesh
                    // /////////////////////////////////////////////////////////
                    m_meshs_bbox[mesh_i].Reset();

                    for( unsigned int vertex_i = 0;
                         vertex_i < mesh.m_VertexSize;
                         ++vertex_i )
                    {
                        m_meshs_bbox[mesh_i].Union( mesh.m_Positions[vertex_i] );
                    }

                    // Make sure we start with client state disabled
                    // /////////////////////////////////////////////////////////
                    glDisableClientState( GL_TEXTURE_COORD_ARRAY );
                    glDisableClientState( GL_COLOR_ARRAY );


                    // Enable arrays client states
                    // /////////////////////////////////////////////////////////
                    glEnableClientState( GL_VERTEX_ARRAY );
                    glEnableClientState( GL_NORMAL_ARRAY );

                    glVertexPointer( 3, GL_FLOAT, 0, mesh.m_Positions );
                    glNormalPointer( GL_FLOAT, 0, mesh.m_Normals );

                    if( mesh.m_Color != NULL )
                    {
                        glEnableClientState( GL_COLOR_ARRAY );

                        float transparency = 0.0f;

                        if( mesh.m_MaterialIdx < a3DModel.m_MaterialsSize )
                            transparency = a3DModel.m_Materials[mesh.m_MaterialIdx].m_Transparency;

                        if( (transparency > FLT_EPSILON) &&
                            (aMaterialMode ==  MATERIAL_MODE_NORMAL) )
                        {
                            // Create a new array of RGBA colors
                            pColorRGBA = new SFVEC4F[mesh.m_VertexSize];

                            // Copy RGB array and add the Alpha value
                            for( unsigned int i = 0; i < mesh.m_VertexSize; ++i )
                                pColorRGBA[i] = SFVEC4F( mesh.m_Color[i],
                                                         1.0f - transparency );

                            // Load an RGBA array
                            glColorPointer( 4, GL_FLOAT, 0, pColorRGBA );
                        }
                        else
                        {
                            switch( aMaterialMode )
                            {
                            case MATERIAL_MODE_NORMAL:
                            case MATERIAL_MODE_DIFFUSE_ONLY:
                                // load the original RGB color array
                                glColorPointer( 3, GL_FLOAT, 0, mesh.m_Color );
                                break;
                            case MATERIAL_MODE_CAD_MODE:
                                // Create a new array of RGBA colors
                                pColorRGBA = new SFVEC4F[mesh.m_VertexSize];

                                // Copy RGB array and add the Alpha value
                                for( unsigned int i = 0; i < mesh.m_VertexSize; ++i )
                                {
                                    pColorRGBA[i] =
                                            SFVEC4F( MaterialDiffuseToColorCAD( mesh.m_Color[i] ),
                                                     1.0f );
                                }

                                // Load an RGBA array
                                glColorPointer( 4, GL_FLOAT, 0, pColorRGBA );
                                break;
                            default:
                                break;
                            }
                        }
                    }

                    if( mesh.m_Texcoords != NULL )
                    {
                        glEnableClientState( GL_TEXTURE_COORD_ARRAY );
                        glTexCoordPointer( 2, GL_FLOAT, 0, mesh.m_Texcoords );
                    }

                    // Compile the display list to store triangles
                    // /////////////////////////////////////////////////////////
                    glNewList( m_ogl_idx_list_meshes + mesh_i, GL_COMPILE );

                    // Set material properties
                    // /////////////////////////////////////////////////////////

                    if( mesh.m_Color != NULL )
                    {
                        // This enables the use of the Color Pointer information
                        glEnable( GL_COLOR_MATERIAL );
                        glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
                    }
                    else
                    {
                        glDisable( GL_COLOR_MATERIAL );
                    }

                    if( mesh.m_MaterialIdx < a3DModel.m_MaterialsSize )
                    {
                        switch( aMaterialMode )
                        {
                        case MATERIAL_MODE_NORMAL:
                            OGL_SetMaterial( a3DModel.m_Materials[mesh.m_MaterialIdx] );
                            break;
                        case MATERIAL_MODE_DIFFUSE_ONLY:
                            OGL_SetDiffuseOnlyMaterial(
                                        a3DModel.m_Materials[mesh.m_MaterialIdx].m_Diffuse );
                            break;
                        case MATERIAL_MODE_CAD_MODE:
                            OGL_SetDiffuseOnlyMaterial(
                                        MaterialDiffuseToColorCAD(
                                            a3DModel.m_Materials[mesh.m_MaterialIdx].m_Diffuse ) );
                            break;
                        default:
                            break;
                        }
                    }

                    // Draw mesh
                    // /////////////////////////////////////////////////////////
                    glDrawElements( GL_TRIANGLES, mesh.m_FaceIdxSize,
                                    GL_UNSIGNED_INT, mesh.m_FaceIdx );

                    glDisable( GL_COLOR_MATERIAL );

                    glEndList();

                    // Disable arrays client states
                    // /////////////////////////////////////////////////////////
                    glDisableClientState( GL_TEXTURE_COORD_ARRAY );
                    glDisableClientState( GL_COLOR_ARRAY );
                    glDisableClientState( GL_NORMAL_ARRAY );
                    glDisableClientState( GL_VERTEX_ARRAY );

                    glFinish();

                    delete [] pColorRGBA;
                }
            }
        }// for each mesh


        m_ogl_idx_list_opaque = glGenLists( 1 );

        // Check if the generated list is valid
        if( glIsList( m_ogl_idx_list_opaque ) )
        {
            bool have_opaque_meshes = false;
            bool have_transparent_meshes = false;

            // Compile the model display list
            glNewList( m_ogl_idx_list_opaque, GL_COMPILE );

            // Render each mesh display list (opaque first)
            // /////////////////////////////////////////////////////////////////
            for( unsigned int mesh_i = 0; mesh_i < a3DModel.m_MeshesSize; ++mesh_i )
            {
                const SMESH &mesh = a3DModel.m_Meshes[mesh_i];

                if( mesh.m_MaterialIdx < a3DModel.m_MaterialsSize )
                {
                    const SMATERIAL &material = a3DModel.m_Materials[mesh.m_MaterialIdx];

                    if( material.m_Transparency == 0.0f )
                    {
                        have_opaque_meshes = true; // Flag that we have at least one opaque mesh
                        glCallList( m_ogl_idx_list_meshes + mesh_i );
                    }
                    else
                    {
                        have_transparent_meshes = true; // Flag that we found a transparent mesh
                    }
                }
            }

            glEndList();

            if( !have_opaque_meshes )
            {
                // If we dont have opaque meshes, we can free the list
                glDeleteLists( m_ogl_idx_list_opaque, 1 );
                m_ogl_idx_list_opaque = 0;
            }

            if( have_transparent_meshes )
            {
                m_ogl_idx_list_transparent = glGenLists( 1 );

                // Check if the generated list is valid
                if( glIsList( m_ogl_idx_list_transparent ) )
                {
                    // Compile the model display list
                    glNewList( m_ogl_idx_list_transparent, GL_COMPILE );

                    glEnable( GL_BLEND );
                    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

                    // Render each mesh display list
                    // /////////////////////////////////////////////////////////
                    for( unsigned mesh_i = 0; mesh_i < a3DModel.m_MeshesSize; ++mesh_i )
                    {
                        const SMESH &mesh = a3DModel.m_Meshes[mesh_i];

                        if( mesh.m_MaterialIdx < a3DModel.m_MaterialsSize )
                        {
                            const SMATERIAL &material = a3DModel.m_Materials[mesh.m_MaterialIdx];

                            // Render the transparent mesh if it have a transparency value
                            if( material.m_Transparency != 0.0f )
                                glCallList( m_ogl_idx_list_meshes + mesh_i );
                        }
                    }

                    glDisable( GL_BLEND );

                    glEndList();
                }
                else
                {
                    m_ogl_idx_list_transparent = 0;
                }
            }
        }
        else
        {
            m_ogl_idx_list_opaque = 0;
        }

        // Create the main bbox
        // /////////////////////////////////////////////////////////////////////
        m_model_bbox.Reset();

        for( unsigned int mesh_i = 0; mesh_i < a3DModel.m_MeshesSize; ++mesh_i )
            m_model_bbox.Union( m_meshs_bbox[mesh_i] );

        glFinish();
    }
}