// Copyright (C) 2015-2015 ChaosForge Ltd // http://chaosforge.org/ // // This file is part of Nova libraries. // For conditions of distribution and use, see copying.txt file in root folder. #include "nv/engine/material_manager.hh" #include "nv/io/c_file_system.hh" #include "nv/image/png_loader.hh" using namespace nv; nv::gpu_material_manager::gpu_material_manager( context* context, material_manager* matmgr, image_manager* imgmgr ) : dependant_resource_manager( matmgr ), m_context( context ) , m_image_manager( imgmgr ) { uint8 data[2 * 2 * 4]; nv::raw_fill_n( data, 2 * 2 * 4, 0 ); m_default = m_context->create_texture( ivec2(2,2), nv::RGBA8, nv::sampler(), data ); } nv::resource< nv::gpu_material > nv::gpu_material_manager::create_resource( resource< material > m ) { resource_id id = m.id(); if ( auto mat = m.lock() ) { gpu_material* result = new gpu_material; sampler smp( sampler::LINEAR_MIPMAP_LINEAR, sampler::REPEAT ); for ( uint32 i = 0; i < size( mat->paths ); ++i ) if ( !mat->paths[i].empty() ) { if ( auto data = m_image_manager->get( mat->paths[i] ).lock() ) { result->textures[i] = m_context->create_texture( &*data, smp ); } } // HACK for ( uint32 i = 0; i < 5; ++i ) if ( result->textures[i].is_nil() ) result->textures[i] = m_default; return add( id, result ); } return resource< nv::gpu_material >(); } void gpu_material_manager::release( gpu_material* m ) { for ( const texture& t : m->textures ) { m_context->release( t ); } } bool material_manager::load_resource( nv::lua::table_guard& table, nv::shash64 id ) { c_file_system fs; material* m = new material; if ( table["path"].is_string() ) { m->id = table["id"].get_string128(); string128 path = table["path"].get_string128(); for ( uint32 i = 0; i < 5; ++i ) m->paths[i] = path; m->paths[TEX_DIFFUSE].append( "_diffuse.png" ); m->paths[TEX_NORMAL].append( "_normal.png" ); m->paths[TEX_METALLIC].append( "_metallic.png" ); m->paths[TEX_ROUGHNESS].append( "_roughness.png" ); m->paths[TEX_EMISSIVE].append( "_emissive.png" ); for ( uint32 i = 0; i < 5; ++i ) { if ( !fs.exists( m->paths[i] ) ) { if ( i != TEX_EMISSIVE ) NV_LOG_ERROR( "Texture file not found! : ", m->paths[i] ); if ( m_clear_paths ) m->paths[i].clear(); } } } else { m->paths[ TEX_DIFFUSE ] = table[ "diffuse" ].get_string128(); m->paths[ TEX_NORMAL ] = table[ "normal" ].get_string128(); m->paths[ TEX_METALLIC ] = table[ "metallic" ].get_string128(); m->paths[ TEX_ROUGHNESS] = table[ "roughness" ].get_string128(); m->paths[ TEX_EMISSIVE ] = table[ "emissive" ].get_string128(); } add( id, m ); return true; }