// Initializes CCopyEntity::m_pMeshRenderMethod // - Initialize the mesh render method // - Initialize shader parameter loaders // - Create alpha entities // - Creates a shader void BaseEntity::InitEntityGraphics( CCopyEntity &entity, ShaderHandle& shader, ShaderTechniqueHandle& tech ) { if( shader.IsLoaded() && tech.GetTechniqueName() && 0 < strlen(tech.GetTechniqueName()) ) { CreateMeshRenderMethod( EntityHandle<>( entity.Self() ), shader, tech ); } else { InitMeshRenderMethod( entity ); } // create transparent parts of the model as separate entities if( m_EntityFlag & BETYPE_SUPPORT_TRANSPARENT_PARTS ) { // Remove any previous alpha entities int next_child_index = 0; while( next_child_index < entity.GetNumChildren() ) // for( int i=0; i<entity.GetNumChildren(); i++ ) { shared_ptr<CCopyEntity> pChild = entity.m_aChild[next_child_index].Get(); if( IsValidEntity(pChild.get()) && pChild->GetEntityTypeID() == CCopyEntityTypeID::ALPHA_ENTITY ) { CCopyEntity *pChildRawPtr = pChild.get(); m_pStage->TerminateEntity( pChildRawPtr ); } else next_child_index += 1; } CreateAlphaEntities( &entity ); } shared_ptr<BasicMesh> pMesh = entity.m_MeshHandle.GetMesh(); if( !pMesh ) return; BasicMesh& mesh = *pMesh; const int num_mesh_materials = mesh.GetNumMaterials(); std::vector<GenericShaderDesc> shader_descs; shader_descs.resize( num_mesh_materials ); std::vector<int> mirror_subsets_indices; // std::vector<int> non_mirror_subsets_indices; if( m_MeshProperty.m_MeshDesc.IsValid() ) // if( true ) { // The mesh is specified in the base entity } else { // base entity has no mesh // - entity's mesh is individual shader_descs.resize( num_mesh_materials ); for( int i=0; i<num_mesh_materials; i++ ) { // Fill out the shader desc based on the parameter values of the material // reflection bool registered_as_mirror = RegisterAsMirrorIfReflective( entity, mesh, i, shader_descs[i] ); if( registered_as_mirror ) mirror_subsets_indices.push_back( i ); // specularity if( 0.001f < mesh.GetMaterial(i).m_Mat.fSpecularity ) shader_descs[i].Specular = SpecularSource::UNIFORM; else shader_descs[i].Specular = SpecularSource::NONE; } vector< pair< GenericShaderDesc, vector<unsigned int> > > grouped_descs; group_elements( shader_descs, grouped_descs ); // Do a NULL check just in case // The mesh render method is initialized by InitMeshRenderMethod() above. if( !entity.m_pMeshRenderMethod ) entity.m_pMeshRenderMethod.reset( new MeshContainerRenderMethod ); bool shader_loaded = false; if( grouped_descs.size() == 1 ) { SubsetRenderMethod& render_method = entity.m_pMeshRenderMethod->PrimaryMeshRenderMethod(); render_method.m_Technique.SetTechniqueName( "Default" ); render_method.m_ShaderDesc.pShaderGenerator.reset( new GenericShaderGenerator( grouped_descs[0].first ) ); // shader_loaded = render_method.Load(); shader_loaded = render_method.m_Shader.Load( render_method.m_ShaderDesc ); } else { LOG_PRINT_WARNING( "Mesh materials need different shaders. This situation is not supported yet (the total number of materials: " + to_string(num_mesh_materials) + ")." ); } } }