Changeset 303


Ignore:
Timestamp:
08/08/14 13:18:41 (11 years ago)
Author:
epyon
Message:
  • program is now handle-based
  • all device constructs are now handle-based and do not dynamically allocate
Location:
trunk
Files:
3 deleted
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/nv/gfx/debug_draw.hh

    r302 r303  
    1010#include <nv/common.hh>
    1111#include <nv/math.hh>
    12 #include <nv/interface/program.hh>
    1312#include <nv/interface/context.hh>
    1413
     
    3029                void update();
    3130                void reset();
    32                 program*      get_program()      { return m_program; }
     31                program       get_program()      { return m_program; }
    3332                vertex_array  get_vertex_array() { return m_va; }
    3433                uint32        get_count()        { return m_data.size(); }
     
    3938        private:
    4039                device*                  m_device;
    41                 program*                 m_program;
     40                program                  m_program;
    4241                vertex_array             m_va;
    4342                std::vector< debug_vtx > m_data;
  • trunk/nv/gfx/keyframed_mesh.hh

    r302 r303  
    2727                virtual mat4 get_node_matrix( uint32 node_id ) const;
    2828                virtual void update_animation( animation_entry*, uint32 a_anim_time );
    29                 virtual void update( program* a_program );
     29                virtual void update( program a_program );
    3030                virtual ~keyframed_mesh();
    3131        protected:
     
    7474                keyframed_mesh_gpu( context* a_context, const mesh_data* a_data, const mesh_nodes_data* a_tag_map );
    7575                void update( uint32 ms );
    76                 virtual void update( program* a_program );
     76                virtual void update( program a_program );
    7777        private:
    7878                int m_loc_next_position;
  • trunk/nv/gfx/skeletal_mesh.hh

    r302 r303  
    101101                skeletal_mesh_gpu( context* a_context, const mesh_data* a_mesh, const mesh_nodes_data* a_bone_data );
    102102                virtual size_t get_index_count() const { return m_index_count; }
    103                 virtual void update( program* a_program );
     103                virtual void update( program a_program );
    104104                virtual void update_animation( animation_entry* a_anim, uint32
    105105                        a_anim_time );
  • trunk/nv/gl/gl_context.hh

    r302 r303  
    2424                ~gl_context();
    2525                virtual void bind( texture t, texture_slot slot );
    26                 virtual void bind( program* p );
     26                virtual void bind( program p );
    2727                virtual void bind( buffer b );
    2828                virtual void bind( vertex_array va );
    29                 virtual void unbind( program* p );
     29                virtual void unbind( program p );
    3030                virtual void unbind( buffer b );
    3131                virtual void unbind( vertex_array va );
     
    3636                virtual void clear( const clear_state& cs );
    3737                // temporary
    38                 virtual void draw( primitive prim, const render_state& rs, program* p, vertex_array va, size_t count );
     38                virtual void draw( primitive prim, const render_state& rs, program p, vertex_array va, size_t count );
    3939                virtual const ivec4& get_viewport();
    4040                virtual void set_viewport( const ivec4& viewport );
    4141                virtual void apply_render_state( const render_state& state );
     42                virtual void apply_engine_uniforms( program p, const scene_state& s );
     43
    4244        protected:
    4345                void force_apply_render_state( const render_state& state );
  • trunk/nv/gl/gl_device.hh

    r302 r303  
    2727        };
    2828
     29        struct gl_program_info : public program_info
     30        {
     31                unsigned glid;
     32                unsigned glidv;
     33                unsigned glidf;
     34        };
     35
    2936        class gl_device : public device
    3037        {
    3138        public:
     39                friend class gl_context;
     40
    3241                gl_device();
    3342                virtual window* create_window( uint16 width, uint16 height, bool fullscreen );
     
    3544                virtual image_data* create_image_data( const std::string& filename ); // temporary
    3645
    37                 virtual program* create_program( const string& vs_source, const string& fs_source );
     46                virtual program create_program( const string& vs_source, const string& fs_source );
     47                virtual vertex_array create_vertex_array();
    3848                virtual buffer create_buffer( buffer_type type, buffer_hint hint, size_t size, const void* source = nullptr );
    3949                virtual texture create_texture( ivec2 size, image_format aformat, sampler asampler, void* data = nullptr );
     
    4353                virtual void release( buffer b );
    4454                virtual void release( texture t );
    45                 virtual const texture_info* get_texture_info( texture t );
    46                 virtual const buffer_info* get_buffer_info( buffer t );
     55                virtual void release( vertex_array va );
     56                virtual void release( program p );
     57                virtual const texture_info* get_texture_info( texture t ) const;
     58                virtual const buffer_info* get_buffer_info( buffer t ) const;
     59                virtual const vertex_array_info* get_vertex_array_info( vertex_array va ) const;
    4760
     61                virtual int get_attribute_location( program p, const string& name, bool fatal = true ) const;
     62                virtual void prepare_program( program p );
    4863                virtual ~gl_device();
     64        protected:
     65                uniform_base* get_uniform( program p, const string& name, bool fatal = true ) const;
     66
     67                // TODO: remove
     68                virtual vertex_array_info* get_vertex_array_info_mutable( vertex_array );
     69       
    4970        private:
     71                bool compile( gl_program_info* p, const string& vertex_program, const string& fragment_program );
     72                void update_uniforms( gl_program_info* p );
     73                void load_attributes( gl_program_info* p );
     74                void load_uniforms( gl_program_info* p );
     75                bool compile( uint32 sh_type, const std::string& shader_code, unsigned& glid );
     76
     77
     78
    5079                const void* m_info;
    51                 entity_store< gl_texture_info, texture > m_textures;
    52                 entity_store< gl_buffer_info,  buffer >  m_buffers;
     80                entity_store< gl_texture_info, texture >        m_textures;
     81                entity_store< gl_buffer_info,  buffer >         m_buffers;
     82                entity_store< vertex_array_info, vertex_array > m_vertex_arrays;
     83                entity_store< gl_program_info, program >        m_programs;
    5384        };
    5485
  • trunk/nv/interface/context.hh

    r302 r303  
    1616#include <nv/interface/device.hh>
    1717#include <nv/interface/camera.hh>
    18 #include <nv/interface/program.hh>
    1918#include <nv/interface/vertex_buffer.hh>
    2019#include <nv/interface/clear_state.hh>
     
    3938                mesh_interface() {}
    4039                virtual void update( uint32 ) {}
    41                 virtual void update( program* ) {}
     40                virtual void update( program ) {}
    4241                virtual nv::vertex_array get_vertex_array() const = 0;
    4342                virtual size_t get_index_count() const = 0;
     
    5150                context( device* a_device )     
    5251                {
    53                         // TODO: this will pose a problem in case of multiple contexts
    54                         program::initialize_engine_uniforms();
    5552                        m_device = a_device;
    5653                }
    5754                virtual void bind( texture, texture_slot ) = 0;
    5855                virtual void bind( buffer ) = 0;
    59                 virtual void bind( program* ) = 0;
     56                virtual void bind( program ) = 0;
    6057                virtual void bind( vertex_array ) = 0;
    6158                virtual void unbind( buffer ) = 0;
    62                 virtual void unbind( program* ) = 0;
    63                 virtual void unbind( vertex_array ) = 0;
     59                virtual void unbind( program ) = 0;
    6460                virtual void update( texture, void* ) = 0;
    6561                virtual void update( buffer, const void*, size_t /*offset*/, size_t /*size*/ ) = 0;
     
    6763                virtual void clear( const clear_state& cs ) = 0;
    6864                // temporary
    69                 virtual void draw( primitive prim, const render_state& rs, program* p, vertex_array va, size_t count ) = 0;
     65                virtual void draw( primitive prim, const render_state& rs, program p, vertex_array va, size_t count ) = 0;
    7066
    71                 virtual void draw( const render_state& rs, program* p, const mesh_interface* mesh )
     67                void draw( const render_state& rs, program p, const mesh_interface* mesh )
    7268                {
    7369                        draw( mesh->get_primitive_type(), rs, p, mesh->get_vertex_array(), mesh->get_index_count() );
    7470                }
    75                 virtual void draw( const render_state& rs, const scene_state& s, program* p, const mesh_interface* mesh )
     71                void draw( const render_state& rs, const scene_state& s, program p, const mesh_interface* mesh )
    7672                {
    77                         p->apply_engine_uniforms( this, &s );
     73                        apply_engine_uniforms(p,s);
    7874                        draw( rs, p, mesh );
    7975                }
    80                 virtual void draw( primitive prim, const render_state& rs, const scene_state& s, program* p, vertex_array va, size_t count )
     76                void draw( primitive prim, const render_state& rs, const scene_state& s, program p, vertex_array va, size_t count )
    8177                {
    82                         p->apply_engine_uniforms( this, &s );
     78                        apply_engine_uniforms(p,s);
    8379                        draw( prim, rs, p, va, count );
    8480                }
     81                virtual void apply_engine_uniforms( program p, const scene_state& s ) = 0;
    8582
    8683                virtual void apply_render_state( const render_state& state ) = 0;
     
    9087                virtual ~context()
    9188                {
    92                         // TODO: this will pose a problem in case of multiple contexts
    93                         program::destroy_engine_uniforms();
    9489                }
    9590        protected:
    96                 vertex_array_info* get_vertex_array_info( vertex_array va )
    97                 {
    98                         return m_device->m_vertex_arrays.get( va );
    99                 }
    10091
    10192                device*      m_device;
  • trunk/nv/interface/device.hh

    r302 r303  
    1616#include <nv/string.hh>
    1717#include <nv/handle.hh>
     18#include <nv/interface/uniform.hh>
    1819#include <nv/interface/mesh_data.hh>
    1920#include <nv/interface/vertex_buffer.hh>
     
    2324{
    2425        class window;
    25         class program;
     26
     27        enum texture_slot
     28        {
     29                TEX_DIFFUSE  = 0,
     30                TEX_SPECULAR = 1,
     31                TEX_NORMAL   = 2,
     32                TEXTURE_0    = 0,
     33                TEXTURE_1    = 1,
     34                TEXTURE_2    = 2,
     35                TEXTURE_3    = 3,
     36                TEXTURE_4    = 4,
     37                TEXTURE_5    = 5,
     38                TEXTURE_6    = 6,
     39                TEXTURE_7    = 7,
     40        };
     41
     42
     43        struct attribute
     44        {
     45                string   name;
     46                int      location;
     47                datatype type;
     48                int      length;
     49        };
     50
     51        typedef std::unordered_map< string, attribute >    attribute_map;
    2652
    2753        struct texture_tag {};
    2854        struct vertex_array_tag {};
    2955        struct buffer_tag {};
     56        struct program_tag {};
    3057        typedef handle< uint32, 16, 16, buffer_tag >       buffer;
    3158        typedef handle< uint32, 16, 16, texture_tag >      texture;
    3259        typedef handle< uint32, 16, 16, vertex_array_tag > vertex_array;
    33 
     60        typedef handle< uint32, 16, 16, program_tag >      program;
    3461
    3562        struct sampler
     
    102129        };
    103130
     131        struct program_info
     132        {
     133                attribute_map       m_attribute_map;
     134                uniform_map             m_uniform_map;
     135                engine_uniform_list m_engine_uniforms;
     136        };
     137
    104138        class device
    105139        {
    106140                friend class context;
    107141        public:
     142                device()
     143                {
     144                        initialize_engine_uniforms();
     145                }
    108146                virtual window* create_window( uint16 width, uint16 height, bool fullscreen ) = 0;
    109147                virtual window* adopt_window( void* sys_w_handle, void* sys_dc ) = 0;
    110                 virtual program* create_program( const string& vs_source, const string& fs_source ) = 0;
     148                virtual program create_program( const string& vs_source, const string& fs_source ) = 0;
    111149                virtual buffer create_buffer( buffer_type type, buffer_hint hint, size_t size, const void* source = nullptr ) = 0;
    112150                virtual image_data* create_image_data( const std::string& filename ) = 0; // temporary
    113151                virtual texture create_texture( ivec2 size, image_format aformat, sampler asampler, void* data = nullptr ) = 0;
     152                virtual vertex_array create_vertex_array() = 0;
    114153                virtual void release( texture ) = 0;
    115154                virtual void release( buffer ) = 0;
    116                 virtual const texture_info* get_texture_info( texture ) = 0;
    117                 virtual const buffer_info* get_buffer_info( buffer ) = 0;
     155                virtual void release( vertex_array ) = 0;
     156                virtual void release( program ) = 0;
     157                virtual const texture_info* get_texture_info( texture ) const = 0;
     158                virtual const buffer_info* get_buffer_info( buffer ) const = 0;
     159                virtual const vertex_array_info* get_vertex_array_info( vertex_array ) const = 0;
    118160                virtual uint32 get_ticks() = 0;
    119161                virtual void delay( uint32 ms ) = 0;
     162
    120163                virtual texture create_texture( image_data* data, sampler asampler )
    121164                {
    122165                        return create_texture( data->get_size(), data->get_format(), asampler, (void*)data->get_data() );
    123166                }
    124 
    125                 virtual vertex_array create_vertex_array()
    126                 {
    127                         vertex_array result = m_vertex_arrays.create();
    128                         vertex_array_info* info = m_vertex_arrays.get( result );
    129                         info->count       = 0;
    130                         info->index       = buffer();
    131                         info->index_owner = false;
    132                         info->index_type  = USHORT;
    133                         return result;
    134                 }
    135 
    136                 virtual void release( vertex_array va )
    137                 {
    138                         vertex_array_info* info = m_vertex_arrays.get( va );
    139                         if ( info )
    140                         {
    141                                 for ( uint32 i = 0; i < info->count; ++i )
    142                                 {
    143                                         if ( info->attr[i].owner ) release( info->attr[i].vbuffer );
    144                                 }
    145                                 if ( info->index.is_valid() && info->index_owner) release( info->index );
    146                                 m_vertex_arrays.destroy( va );
    147                         }
    148                 };
    149167
    150168                template < typename VTX, slot SLOT >
     
    222240                void replace_vertex_buffer( vertex_array va, buffer vb, bool owner )
    223241                {
    224                         vertex_array_info* info = m_vertex_arrays.get( va );
     242                        vertex_array_info* info = get_vertex_array_info_mutable( va );
    225243                        if ( info )
    226244                        {
     
    237255                void replace_vertex_buffer( vertex_array va, buffer vb, slot location, bool owner )
    238256                {
    239                         vertex_array_info* info = m_vertex_arrays.get( va );
     257                        vertex_array_info* info = get_vertex_array_info_mutable( va );
    240258                        if ( info )
    241259                        {
     
    255273                void update_attribute_offset( vertex_array va, slot location, size_t offset )
    256274                {
    257                         vertex_array_info* info = m_vertex_arrays.get( va );
     275                        vertex_array_info* info = get_vertex_array_info_mutable( va );
    258276                        if ( info )
    259277                        {
     
    270288                void set_index_buffer( vertex_array va, buffer b, datatype datatype, bool owner )
    271289                {
    272                         vertex_array_info* info = m_vertex_arrays.get( va );
     290                        vertex_array_info* info = get_vertex_array_info_mutable( va );
    273291                        if ( info )
    274292                        {
     
    284302                }
    285303
    286                 void add_vertex_buffer( vertex_array va, slot location, buffer buf, datatype datatype, size_t components, size_t offset = 0, size_t stride = 0, bool owner = true )
    287                 {
    288                         vertex_array_info* info = m_vertex_arrays.get( va );
     304                virtual void add_vertex_buffer( vertex_array va, slot location, buffer buf, datatype datatype, size_t components, size_t offset = 0, size_t stride = 0, bool owner = true )
     305                {
     306                        vertex_array_info* info = get_vertex_array_info_mutable( va );
    289307                        if ( info )
    290308                        {
     
    304322                buffer find_buffer( vertex_array va, slot location )
    305323                {
    306                         vertex_array_info* info = m_vertex_arrays.get( va );
     324                        const vertex_array_info* info = get_vertex_array_info( va );
    307325                        if ( info )
    308326                        {
     
    344362                }
    345363
     364                int try_get_attribute_location( program p, const string& name ) const
     365                {
     366                        return get_attribute_location( p, name, false );
     367                }
     368
     369                virtual int get_attribute_location( program p, const string& name, bool fatal = true ) const = 0;
     370
     371                template < typename T >
     372                void set_uniform_array( program p, const string& name, const T* value, uint32 count, bool fatal = true )
     373                {
     374                        uniform_base* base = get_uniform( p, name, fatal );
     375                        if ( base != nullptr )
     376                        {
     377                                if ( base->type_check( type_to_enum<T>::type ) )
     378                                {
     379                                        // TODO: nicer check
     380                                        NV_ASSERT( (int)count <= base->get_length(), "LENGTH CHECK FAIL" );
     381                                        ((uniform<T>*)( base ))->set_value( value, count );
     382                                }
     383                        }
     384                }
     385
     386                template < typename T >
     387                void set_uniform_array( const string& name, const std::vector<T>& value )
     388                {
     389                        set_uniform_array( program p, name, (const T*)value.data(), value.size() );
     390                }
     391
     392                template < typename T >
     393                void set_opt_uniform_array( program p, const string& name, const T* value, uint32 count )
     394                {
     395                        set_uniform_array( p, name, value, count, false );
     396                }
     397
     398                template < typename T >
     399                void set_opt_uniform_array( program p, const string& name, const std::vector<T>& value )
     400                {
     401                        set_uniform_array( p, name, (const T*)value.data(), value.size(), false );
     402                }
     403
     404
     405                template < typename T >
     406                void set_uniform( program p, const string& name, const T& value, bool fatal = true )
     407                {
     408                        uniform_base* base = get_uniform( p, name, fatal );
     409                        if ( base != nullptr )
     410                        {
     411                                if ( base->type_check( type_to_enum<T>::type ) )
     412                                {
     413                                        ((uniform<T>*)( base ))->set_value( value );
     414                                }
     415                        }
     416                }
     417
     418                template < typename T >
     419                void set_opt_uniform( program p, const string& name, const T& value )
     420                {
     421                        set_uniform( p, name, value, false );
     422                }
    346423
    347424                virtual ~device()
    348425                {
    349                         // TODO: releases buffers via gl_context which is destoryed!
    350                         while ( m_vertex_arrays.size() > 0 )
    351                                 release( m_vertex_arrays.get_handle(0) );
    352                 }
     426                        destroy_engine_uniforms();
     427                }
     428
     429                // This is done this way to avoid compilation unit creation
     430                static engine_uniform_factory_map& get_uniform_factory()
     431                {
     432                        static engine_uniform_factory_map s_engine_uniform_factory_map;
     433                        return s_engine_uniform_factory_map;
     434                }
     435
     436                // This is done this way to avoid compilation unit creation
     437                static engine_link_uniform_factory_map& get_link_uniform_factory()
     438                {
     439                        static engine_link_uniform_factory_map s_engine_link_uniform_factory_map;
     440                        return s_engine_link_uniform_factory_map;
     441                }
     442
     443                virtual void prepare_program( program p ) = 0;
     444
    353445        protected:
    354                 entity_store< vertex_array_info, vertex_array > m_vertex_arrays;
     446                virtual uniform_base* get_uniform( program p, const string& name, bool fatal = true ) const = 0;
     447
     448                // TODO: remove
     449                virtual vertex_array_info* get_vertex_array_info_mutable( vertex_array ) = 0;
     450
     451                void initialize_engine_uniforms()
     452                {
     453                        engine_uniform_factory_map& factory_map = get_uniform_factory();
     454                        factory_map[ "nv_m_view" ]       = new engine_uniform_factory< engine_uniform_m_view >();
     455                        factory_map[ "nv_m_view_inv" ]   = new engine_uniform_factory< engine_uniform_m_view_inv >();
     456                        factory_map[ "nv_m_model" ]      = new engine_uniform_factory< engine_uniform_m_model >();
     457                        factory_map[ "nv_m_model_inv" ]  = new engine_uniform_factory< engine_uniform_m_model_inv >();
     458                        factory_map[ "nv_m_modelview" ]  = new engine_uniform_factory< engine_uniform_m_modelview >();
     459                        factory_map[ "nv_m_projection" ] = new engine_uniform_factory< engine_uniform_m_projection >();
     460                        factory_map[ "nv_m_normal" ]     = new engine_uniform_factory< engine_uniform_m_normal >();
     461                        factory_map[ "nv_m_mvp" ]        = new engine_uniform_factory< engine_uniform_m_mvp >();
     462                        factory_map[ "nv_v_camera_position" ]  = new engine_uniform_factory< engine_uniform_v_camera_position >();
     463                        factory_map[ "nv_v_camera_direction" ] = new engine_uniform_factory< engine_uniform_v_camera_direction >();
     464
     465                        engine_link_uniform_factory_map& factory_link_map = get_link_uniform_factory();
     466                        factory_link_map[ "nv_texture_0" ] = new engine_link_uniform_int<0>();
     467                        factory_link_map[ "nv_texture_1" ] = new engine_link_uniform_int<1>();
     468                        factory_link_map[ "nv_texture_2" ] = new engine_link_uniform_int<2>();
     469                        factory_link_map[ "nv_texture_3" ] = new engine_link_uniform_int<3>();
     470                        factory_link_map[ "nv_texture_4" ] = new engine_link_uniform_int<4>();
     471                        factory_link_map[ "nv_texture_5" ] = new engine_link_uniform_int<5>();
     472                        factory_link_map[ "nv_texture_6" ] = new engine_link_uniform_int<6>();
     473                        factory_link_map[ "nv_texture_7" ] = new engine_link_uniform_int<7>();
     474                        factory_link_map[ "nv_t_diffuse" ] = new engine_link_uniform_int<0>();
     475                        factory_link_map[ "nv_t_specular"] = new engine_link_uniform_int<1>();
     476                        factory_link_map[ "nv_t_normal"  ] = new engine_link_uniform_int<2>();
     477                }
     478                void destroy_engine_uniforms()
     479                {
     480                        for ( auto& i : get_uniform_factory() ) delete i.second;
     481                        for ( auto& i : get_link_uniform_factory() ) delete i.second;
     482                        get_uniform_factory().clear();
     483                        get_link_uniform_factory().clear();
     484                }
     485
    355486        };
    356487
  • trunk/nv/interface/uniform.hh

    r255 r303  
    2727                uniform_base( const string& name, datatype type, int location, int length )
    2828                        : m_name( name ), m_type( type ), m_location(location), m_length( length ), m_dirty( true ) {}
     29                bool try_type_check( datatype )
     30                {
     31                        // TODO: proper typecheck with type decay
     32                        return true;
     33                }
     34                bool type_check( datatype otype )
     35                {
     36                        if ( try_type_check(otype) ) return true;
     37                        // TODO: report error
     38                        return false;
     39                }
    2940                datatype get_type() const { return m_type; }
    3041                int get_location() const { return m_location; }
     
    3243                bool is_dirty() const { return m_dirty; }
    3344                void clean() { m_dirty = false; }
     45                static uniform_base* create( datatype utype, const string& name, int location, int length );
    3446                virtual ~uniform_base() {}
    3547        protected:
     
    217229        };
    218230
     231        inline uniform_base* uniform_base::create( datatype utype, const string& name, int location, int length )
     232        {
     233                switch( utype )
     234                {
     235                case FLOAT          : return new uniform< enum_to_type< FLOAT          >::type >( name, location, length );
     236                case INT            : return new uniform< enum_to_type< INT            >::type >( name, location, length );
     237                case FLOAT_VECTOR_2 : return new uniform< enum_to_type< FLOAT_VECTOR_2 >::type >( name, location, length );
     238                case FLOAT_VECTOR_3 : return new uniform< enum_to_type< FLOAT_VECTOR_3 >::type >( name, location, length );
     239                case FLOAT_VECTOR_4 : return new uniform< enum_to_type< FLOAT_VECTOR_4 >::type >( name, location, length );
     240                case INT_VECTOR_2   : return new uniform< enum_to_type< INT_VECTOR_2   >::type >( name, location, length );
     241                case INT_VECTOR_3   : return new uniform< enum_to_type< INT_VECTOR_3   >::type >( name, location, length );
     242                case INT_VECTOR_4   : return new uniform< enum_to_type< INT_VECTOR_4   >::type >( name, location, length );
     243                case FLOAT_MATRIX_2 : return new uniform< enum_to_type< FLOAT_MATRIX_2 >::type >( name, location, length );
     244                case FLOAT_MATRIX_3 : return new uniform< enum_to_type< FLOAT_MATRIX_3 >::type >( name, location, length );
     245                case FLOAT_MATRIX_4 : return new uniform< enum_to_type< FLOAT_MATRIX_4 >::type >( name, location, length );
     246                default     : return nullptr;
     247                }
     248        }
    219249
    220250
  • trunk/src/gfx/debug_draw.cc

    r302 r303  
    2929
    3030nv::debug_data::debug_data( device* a_device )
    31         : m_device( a_device ), m_program( nullptr ), m_va()
     31        : m_device( a_device ), m_program(), m_va()
    3232{
    3333        m_program = m_device->create_program( nv_debug_draw_vertex_shader, nv_debug_draw_fragment_shader );
     
    7676{
    7777        m_device->release( m_va );
    78         delete m_program;
     78        m_device->release( m_program );
    7979}
  • trunk/src/gfx/keyframed_mesh.cc

    r302 r303  
    9898
    9999
    100 void nv::keyframed_mesh::update( program* a_program )
    101 {
    102         a_program->set_opt_uniform( "nv_interpolate", m_interpolation );
     100void nv::keyframed_mesh::update( program a_program )
     101{
     102        m_context->get_device()->set_opt_uniform( a_program, "nv_interpolate", m_interpolation );
    103103}
    104104
     
    165165}
    166166
    167 void nv::keyframed_mesh_gpu::update( program* a_program )
     167void nv::keyframed_mesh_gpu::update( program a_program )
    168168{
    169169        if ( m_loc_next_position == -1 )
    170170        {
    171                 m_loc_next_position = a_program->get_attribute( "nv_next_position" )->get_location();
    172                 m_loc_next_normal   = a_program->get_attribute( "nv_next_normal" )->get_location();
     171                device* dev = m_context->get_device();
     172                m_loc_next_position = dev->get_attribute_location( a_program, "nv_next_position" );
     173                m_loc_next_normal   = dev->get_attribute_location( a_program, "nv_next_normal" );
    173174                if ( m_has_tangent )
    174                         m_loc_next_tangent  = a_program->get_attribute( "nv_next_tangent" )->get_location();
    175 
    176                 device* dev = m_context->get_device();
     175                        m_loc_next_tangent  = dev->get_attribute_location( a_program, "nv_next_tangent" );
     176
    177177                dev->add_vertex_buffer( m_va, (slot)m_loc_next_position, m_pbuffer, FLOAT, 3, 0, m_vsize, false );
    178178                dev->add_vertex_buffer( m_va, (slot)m_loc_next_normal,   m_pbuffer, FLOAT, 3, sizeof( vec3 ), m_vsize, false );
  • trunk/src/gfx/skeletal_mesh.cc

    r302 r303  
    213213}
    214214
    215 void nv::skeletal_mesh_gpu::update( program* a_program )
     215void nv::skeletal_mesh_gpu::update( program a_program )
    216216{
    217217        if ( m_bone_data )
    218                 a_program->set_opt_uniform_array( "nv_m_bones", m_transform, m_bone_data->get_count() );
     218                m_context->get_device()->set_opt_uniform_array( a_program, "nv_m_bones", m_transform, m_bone_data->get_count() );
    219219}
    220220
  • trunk/src/gl/gl_context.cc

    r302 r303  
    99#include "nv/lib/sdl.hh"
    1010#include "nv/gl/gl_device.hh"
    11 #include "nv/gl/gl_program.hh"
    1211
    1312using namespace nv;
     
    2322}
    2423
    25 void nv::gl_context::bind( program* p )
    26 {
    27         gl_program* glp = static_cast< gl_program* >( p );
    28         glUseProgram( glp->glid );
    29         glp->update_uniforms();
     24void nv::gl_context::bind( program p )
     25{
     26        gl_program_info* info = ((gl_device*)m_device)->m_programs.get( p );
     27        if ( info )
     28        {
     29                glUseProgram( info->glid );
     30                ((gl_device*)m_device)->update_uniforms( info );
     31        }
    3032}
    3133
     
    4143void nv::gl_context::bind( vertex_array va )
    4244{
    43         vertex_array_info* info = get_vertex_array_info( va );
     45        const vertex_array_info* info = m_device->get_vertex_array_info( va );
    4446        if ( info )
    4547        {
     
    6870}
    6971
    70 void nv::gl_context::unbind( program* )
     72void nv::gl_context::unbind( program )
    7173{
    7274        glUseProgram( 0 );
     
    8486void nv::gl_context::unbind( vertex_array va )
    8587{
    86         vertex_array_info* info = get_vertex_array_info( va );
     88        const vertex_array_info* info = m_device->get_vertex_array_info( va );
    8789        if ( info )
    8890        {
     
    483485}
    484486
    485 void gl_context::draw( primitive prim, const render_state& rs, program* p, vertex_array va, size_t count )
     487void nv::gl_context::apply_engine_uniforms( program p, const scene_state& s )
     488{
     489        gl_program_info* info = ((gl_device*)m_device)->m_programs.get( p );
     490        if ( info )
     491        {
     492                for ( auto u : info->m_engine_uniforms )
     493                {
     494                        u->set( this, &s );
     495                }
     496        }
     497}
     498
     499void gl_context::draw( primitive prim, const render_state& rs, program p, vertex_array va, size_t count )
    486500{
    487501        apply_render_state( rs );
    488         vertex_array_info* info = get_vertex_array_info( va );
     502        const vertex_array_info* info = m_device->get_vertex_array_info( va );
    489503        if ( count > 0 && info )
    490504        {
  • trunk/src/gl/gl_device.cc

    r302 r303  
    66
    77#include "nv/gl/gl_window.hh"
    8 #include "nv/gl/gl_program.hh"
    98#include "nv/logging.hh"
    109#include "nv/lib/sdl.hh"
     
    5049}
    5150
    52 program* gl_device::create_program( const string& vs_source, const string& fs_source )
    53 {
    54         return new gl_program( vs_source, fs_source );
     51program gl_device::create_program( const string& vs_source, const string& fs_source )
     52{
     53        program result = m_programs.create();
     54        gl_program_info* info = m_programs.get( result );
     55
     56        info->glid = glCreateProgram();
     57        compile( info, vs_source, fs_source );
     58        prepare_program( result );
     59        return result;
    5560}
    5661
     
    8590gl_device::~gl_device()
    8691{
     92        while ( m_vertex_arrays.size() > 0 )
     93                release( m_vertex_arrays.get_handle(0) );
    8794        while ( m_textures.size() > 0 )
    8895                release( m_textures.get_handle(0) );
    8996        while ( m_buffers.size() > 0 )
    9097                release( m_buffers.get_handle(0) );
     98        while ( m_programs.size() > 0 )
     99                release( m_programs.get_handle(0) );
    91100
    92101        SDL_Quit();
     
    154163}
    155164
    156 const texture_info* nv::gl_device::get_texture_info( texture t )
     165const texture_info* nv::gl_device::get_texture_info( texture t ) const
    157166{
    158167        return m_textures.get( t );
     
    178187}
    179188
    180 const buffer_info* nv::gl_device::get_buffer_info( buffer t )
     189const buffer_info* nv::gl_device::get_buffer_info( buffer t ) const
    181190{
    182191        return m_buffers.get( t );
    183192}
     193
     194nv::vertex_array nv::gl_device::create_vertex_array()
     195{
     196        vertex_array result = m_vertex_arrays.create();
     197        vertex_array_info* info = m_vertex_arrays.get( result );
     198        info->count       = 0;
     199        info->index       = buffer();
     200        info->index_owner = false;
     201        info->index_type  = USHORT;
     202        return result;
     203}
     204
     205void nv::gl_device::release( vertex_array va )
     206{
     207        vertex_array_info* info = m_vertex_arrays.get( va );
     208        if ( info )
     209        {
     210                for ( uint32 i = 0; i < info->count; ++i )
     211                {
     212                        if ( info->attr[i].owner ) release( info->attr[i].vbuffer );
     213                }
     214                if ( info->index.is_valid() && info->index_owner) release( info->index );
     215                m_vertex_arrays.destroy( va );
     216        }
     217}
     218
     219void nv::gl_device::release( program p )
     220{
     221        gl_program_info* info = m_programs.get( p );
     222        if ( info )
     223        {
     224                for ( auto& i : info->m_uniform_map )
     225                        delete i.second;
     226
     227                glDetachShader( info->glid, info->glidv );
     228                glDetachShader( info->glid, info->glidf );
     229                glDeleteShader( info->glidv );
     230                glDeleteShader( info->glidf );
     231                glDeleteProgram( info->glid );
     232
     233                m_programs.destroy( p );
     234        }
     235}
     236
     237const vertex_array_info* nv::gl_device::get_vertex_array_info( vertex_array va ) const
     238{
     239        return m_vertex_arrays.get( va );
     240}
     241
     242vertex_array_info* nv::gl_device::get_vertex_array_info_mutable( vertex_array va )
     243{
     244        return m_vertex_arrays.get( va );
     245}
     246
     247void nv::gl_device::prepare_program( program p )
     248{
     249        gl_program_info* info = m_programs.get( p );
     250        if ( info )
     251        {
     252                auto& map  = get_uniform_factory();
     253                auto& lmap = get_link_uniform_factory();
     254
     255                for ( auto& i : info->m_uniform_map )
     256                {
     257                        auto j = lmap.find( i.first );
     258                        if ( j != lmap.end() )
     259                        {
     260                                j->second->set( i.second );
     261                        }                       
     262
     263                        auto k = map.find( i.first );
     264                        if ( k != map.end() )
     265                        {
     266                                info->m_engine_uniforms.push_back( k->second->create( i.second ) );
     267                        }                               
     268                }
     269        }
     270}
     271
     272uniform_base* nv::gl_device::get_uniform( program p, const string& name, bool fatal /*= true */ ) const
     273{
     274        const gl_program_info* info = m_programs.get( p );
     275        {
     276                uniform_map::const_iterator i = info->m_uniform_map.find( name );
     277                if ( i != info->m_uniform_map.end() )
     278                {
     279                        return i->second;
     280                }
     281                if ( fatal )
     282                {
     283                        NV_LOG( LOG_ERROR, "Uniform '" << name << "' not found in program!" );
     284                        NV_THROW( runtime_error, ( "Uniform '"+name+"' not found!" ) );
     285                }
     286        }
     287        return nullptr;
     288}
     289
     290int nv::gl_device::get_attribute_location( program p, const string& name, bool fatal /*= true */ ) const
     291{
     292        const gl_program_info* info = m_programs.get( p );
     293        if ( info )
     294        {
     295                attribute_map::const_iterator i = info->m_attribute_map.find( name );
     296                if ( i != info->m_attribute_map.end() )
     297                {
     298                        return i->second.location;
     299                }
     300                if ( fatal )
     301                {
     302                        NV_LOG( LOG_ERROR, "Attribute '" << name << "' not found in program!" );
     303                        NV_THROW( runtime_error, ( "Attribute '"+name+"' not found!" ) );
     304                }
     305        }
     306        return -1;
     307}
     308
     309bool nv::gl_device::compile( gl_program_info* p, const string& vertex_program, const string& fragment_program )
     310{
     311        if (!compile( GL_VERTEX_SHADER,   vertex_program, p->glidv ))   { return false; }
     312        if (!compile( GL_FRAGMENT_SHADER, fragment_program, p->glidf )) { return false; }
     313
     314        glBindAttribLocation( p->glid, static_cast<GLuint>( slot::POSITION   ), "nv_position"  );
     315        glBindAttribLocation( p->glid, static_cast<GLuint>( slot::TEXCOORD   ), "nv_texcoord"  );
     316        glBindAttribLocation( p->glid, static_cast<GLuint>( slot::NORMAL     ), "nv_normal"    );
     317        glBindAttribLocation( p->glid, static_cast<GLuint>( slot::COLOR      ), "nv_color"     );
     318        glBindAttribLocation( p->glid, static_cast<GLuint>( slot::TANGENT    ), "nv_tangent"   );
     319        glBindAttribLocation( p->glid, static_cast<GLuint>( slot::BONEINDEX  ), "nv_boneindex" );
     320        glBindAttribLocation( p->glid, static_cast<GLuint>( slot::BONEWEIGHT ), "nv_boneweight");
     321
     322        glAttachShader( p->glid, p->glidf );
     323        glAttachShader( p->glid, p->glidv );
     324        glLinkProgram( p->glid );
     325
     326        const uint32 buffer_size = 2048;
     327        char buffer[ buffer_size ] = { 0 };
     328        int length;
     329        int status;
     330
     331        glGetProgramiv( p->glid, GL_LINK_STATUS, &status );
     332        glGetProgramInfoLog( p->glid, buffer_size, &length, buffer );
     333
     334        NV_LOG( LOG_INFO, "Program #" << p->glid << (status == GL_FALSE ? " failed to compile!" : " compiled successfully.") );
     335
     336        if ( length > 0 )
     337        {
     338                NV_LOG( LOG_INFO, "Program #" << p->glid << " log: " << buffer );
     339        }
     340
     341        if ( status == GL_FALSE )
     342        {
     343                return false;
     344        }
     345
     346        glValidateProgram( p->glid );
     347        glGetProgramiv( p->glid, GL_VALIDATE_STATUS, &status );
     348
     349        if ( status == GL_FALSE )
     350        {
     351                glGetProgramInfoLog( p->glid, buffer_size, &length, buffer );
     352                NV_LOG( LOG_ERROR, "Program #" << p->glid << " validation error : " << buffer );
     353                return false;
     354        }
     355        load_attributes( p );
     356        load_uniforms( p );
     357        return true;
     358}
     359
     360void nv::gl_device::update_uniforms( gl_program_info* p )
     361{
     362        for ( uniform_map::iterator i = p->m_uniform_map.begin();       i != p->m_uniform_map.end(); ++i )
     363        {
     364                uniform_base* ubase = i->second;
     365                if ( ubase->is_dirty() )
     366                {
     367                        int uloc = ubase->get_location();
     368                        switch( ubase->get_type() )
     369                        {
     370                        case FLOAT          : glUniform1fv( uloc, ubase->get_length(), ((uniform< enum_to_type< FLOAT >::type >*)( ubase ))->get_value() ); break;
     371                        case INT            : glUniform1iv( uloc, ubase->get_length(), ((uniform< enum_to_type< INT >::type >*)( ubase ))->get_value() ); break;
     372                        case FLOAT_VECTOR_2 : glUniform2fv( uloc, ubase->get_length(), (GLfloat*)((uniform< enum_to_type< FLOAT_VECTOR_2 >::type >*)( ubase ))->get_value()); break;
     373                        case FLOAT_VECTOR_3 : glUniform3fv( uloc, ubase->get_length(), (GLfloat*)((uniform< enum_to_type< FLOAT_VECTOR_3 >::type >*)( ubase ))->get_value()); break;
     374                        case FLOAT_VECTOR_4 : glUniform4fv( uloc, ubase->get_length(), (GLfloat*)((uniform< enum_to_type< FLOAT_VECTOR_4 >::type >*)( ubase ))->get_value()); break;
     375                        case INT_VECTOR_2   : glUniform2iv( uloc, ubase->get_length(), (GLint*)((uniform< enum_to_type< INT_VECTOR_2 >::type >*)( ubase ))->get_value()); break;
     376                        case INT_VECTOR_3   : glUniform3iv( uloc, ubase->get_length(), (GLint*)((uniform< enum_to_type< INT_VECTOR_3 >::type >*)( ubase ))->get_value()); break;
     377                        case INT_VECTOR_4   : glUniform4iv( uloc, ubase->get_length(), (GLint*)((uniform< enum_to_type< INT_VECTOR_4 >::type >*)( ubase ))->get_value()); break;
     378                        case FLOAT_MATRIX_2 : glUniformMatrix2fv( uloc, ubase->get_length(), GL_FALSE, (GLfloat*)((uniform< enum_to_type< FLOAT_MATRIX_2 >::type >*)( ubase ))->get_value()); break;
     379                        case FLOAT_MATRIX_3 : glUniformMatrix3fv( uloc, ubase->get_length(), GL_FALSE, (GLfloat*)((uniform< enum_to_type< FLOAT_MATRIX_3 >::type >*)( ubase ))->get_value()); break;
     380                        case FLOAT_MATRIX_4 : glUniformMatrix4fv( uloc, ubase->get_length(), GL_FALSE, (GLfloat*)((uniform< enum_to_type< FLOAT_MATRIX_4 >::type >*)( ubase ))->get_value()); break;
     381                        default : break; // error?
     382                        }
     383                        ubase->clean();
     384                }
     385        }
     386}
     387
     388void nv::gl_device::load_attributes( gl_program_info* p )
     389{
     390        int params;
     391        glGetProgramiv( p->glid, GL_ACTIVE_ATTRIBUTES, &params );
     392
     393        for ( unsigned i = 0; i < (unsigned)params; ++i )
     394        {
     395                int attr_nlen;
     396                int attr_len;
     397                unsigned attr_type;
     398                char name_buffer[128];
     399
     400                glGetActiveAttrib( p->glid, i, 128, &attr_nlen, &attr_len, &attr_type, name_buffer );
     401
     402                string name( name_buffer, size_t(attr_nlen) );
     403
     404                // skip built-ins
     405                if ( name.substr(0,3) == "gl_" ) continue;
     406
     407                int attr_loc = glGetAttribLocation( p->glid, name.c_str() );
     408
     409                attribute& attr = p->m_attribute_map[ name ];
     410                attr.name     = name;
     411                attr.location = attr_loc;
     412                attr.type     = gl_enum_to_datatype( attr_type );
     413                attr.length   = attr_len;
     414        }
     415}
     416
     417void nv::gl_device::load_uniforms( gl_program_info* p )
     418{
     419        int params;
     420        glGetProgramiv( p->glid, GL_ACTIVE_UNIFORMS, &params );
     421
     422        for ( unsigned i = 0; i < size_t(params); ++i )
     423        {
     424                int uni_nlen;
     425                int uni_len;
     426                unsigned uni_type;
     427                char name_buffer[128];
     428
     429                glGetActiveUniform( p->glid, i, 128, &uni_nlen, &uni_len, &uni_type, name_buffer );
     430
     431                string name( name_buffer, size_t(uni_nlen) );
     432
     433                // skip built-ins
     434                if ( name.substr(0,3) == "gl_" ) continue;
     435
     436                int uni_loc = glGetUniformLocation( p->glid, name.c_str() );
     437                datatype utype = gl_enum_to_datatype( uni_type );
     438
     439                // check for array
     440                string::size_type arrchar = name.find('[');
     441                if ( arrchar != string::npos )
     442                {
     443                        name = name.substr( 0, arrchar );
     444                }
     445
     446                uniform_base* u = uniform_base::create( utype, name, uni_loc, uni_len );
     447                NV_ASSERT( u, "Unknown uniform type!" );
     448                p->m_uniform_map[ name ] = u;
     449        }
     450}
     451
     452bool nv::gl_device::compile( uint32 sh_type, const std::string& shader_code, unsigned& glid )
     453{
     454        glid = glCreateShader( sh_type );
     455
     456        const char* pc = shader_code.c_str();
     457
     458        glShaderSource( glid,   1, &pc, 0 );
     459        glCompileShader( glid );
     460
     461        const uint32 buffer_size = 1024;
     462        char buffer[ buffer_size ] = { 0 };
     463        int length;
     464        int compile_ok = GL_FALSE;
     465        glGetShaderiv(glid, GL_COMPILE_STATUS, &compile_ok);
     466        glGetShaderInfoLog( glid, buffer_size, &length, buffer );
     467
     468        if ( length > 0 )
     469        {
     470                if ( compile_ok == 0 )
     471                {
     472                        NV_LOG( LOG_ERROR, "Shader #" << glid << " error: " << buffer );
     473                }
     474                else
     475                {
     476                        NV_LOG( LOG_INFO, "Shader #" << glid << " compiled successfully: " << buffer );
     477                }
     478        }
     479        else
     480        {
     481                NV_LOG( LOG_INFO, "Shader #" << glid << " compiled successfully." );
     482        }
     483        return compile_ok != 0;
     484
     485}
     486
     487
  • trunk/src/gui/gui_renderer.cc

    r302 r303  
    6666public:
    6767        screen_render_data( context* actx, size_t initial_size )
    68                 : buffer( actx, VERTEX_BUFFER, DYNAMIC_DRAW, initial_size ), ctx( actx ), varray(), shader(nullptr)
     68                : buffer( actx, VERTEX_BUFFER, DYNAMIC_DRAW, initial_size ), ctx( actx ), varray(), shader()
    6969        {
    7070
     
    7272        ~screen_render_data()
    7373        {
    74                 delete shader;
     74                ctx->get_device()->release( shader );
    7575                ctx->get_device()->release( varray );
    7676        }
     
    8080        nv::texture       tex;
    8181        nv::vertex_array  varray;
    82         nv::program*      shader;
     82        nv::program       shader;
    8383};
    8484
Note: See TracChangeset for help on using the changeset viewer.