// 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["id"].get_string() ); string_buffer vsource; string_buffer fsource; string_buffer header( m_shader_head ); if ( table["common"].is_table() ) { 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( id, m_context->create_program( vsource, fsource ) ); return true; } void nv::program_manager::release( program p ) { m_context->release( p ); } nv::const_string nv::program_manager::file_to_string( const string_view& path ) { c_file_system fs; stream* fstream = open_stream( fs, path ); if ( !fstream ) return const_string(); uint32 size = static_cast< uint32 >( fstream->size() ); const_string result( nullptr, size ); fstream->read( const_cast( result.data() ), size, 1 ); delete fstream; return result; } 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["files"].is_string() ) { out.append( file_to_string( table["files"].get_string() ) ); } else if ( table["files"].is_table() ) { 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( file_to_string( include ) ); } } if ( table["file"].is_string() ) { const_string data = file_to_string( table["file"].get_string() ); out.append( "#line 1\n" + data ); } if ( table["source"].is_string() ) { out.append( table["source"].get_string() ); } return out; }