Changeset 303 for trunk/src


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/src
Files:
1 deleted
6 edited

Legend:

Unmodified
Added
Removed
  • 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.