// Copyright (C) 2014-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/program_manager.hh" #include "nv/stl/range.hh" #include "nv/core/logging.hh" #include "nv/lua/lua_nova.hh" #include "nv/io/c_file_system.hh" nv::program_manager::program_manager( context* a_context ) : m_context( a_context ) { m_shader_head = a_context->get_device()->get_shader_header(); } bool nv::program_manager::load_resource( lua::table_guard& table, shash64 id ) { NV_LOG_DEBUG( table.get_string("id") ); string_buffer vsource; string_buffer fsource; string_buffer header( m_shader_head ); if ( table.is_table("common") ) { lua::table_guard common( table, "common" ); header.append( "\n" + load_source( common, "" ) + "\n" ); } { lua::table_guard vtable( table, "vertex" ); vsource = load_source( vtable, header ); } { lua::table_guard ftable( table, "fragment" ); fsource = load_source( ftable, header ); } add( m_context->get_device()->create_program( vsource, fsource ), id ); return true; } void nv::program_manager::release( program p ) { m_context->get_device()->release( p ); } nv::string_buffer nv::program_manager::load_source( lua::table_guard& table, const string_view& append ) { c_file_system fs; string_buffer out( append ); if ( table.is_string( "files" ) ) { out.append( fs.slurp( table.get_string( "files" ) ) ); } else if ( table.is_table( "files" ) ) { lua::table_guard inctable( table, "files" ); uint32 count = inctable.get_size(); for ( uint32 i = 1; i <= count; ++i ) { const_string include( inctable.get(i) ); if ( i == count ) out.append( "#line 1\n" ); out.append( fs.slurp( include ) ); } } if ( table.is_string( "file" ) ) { const_string data = fs.slurp( table.get_string( "file" ) ); out.append( "#line 1\n" + data ); } if ( table.is_string( "source" ) ) { out.append( table.get_string( "source" ) ); } return out; }