Changeset 119 for trunk


Ignore:
Timestamp:
06/12/13 09:38:06 (12 years ago)
Author:
epyon
Message:
  • vertex_buffer - fixes to index buffered vertex_arrays
  • cached_buffer - added indexed_buffer_slice and indexed_cached_buffer
  • nv_cachebuf_test - compile define for indexed or regular arrays
Location:
trunk
Files:
3 edited

Legend:

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

    r118 r119  
    1616namespace nv
    1717{
     18
    1819        template< typename T > class cached_buffer;
    1920
     
    3031                        m_cache->reset();
    3132                }
    32                 void commit()
    33                 {
    34                         m_cache->commit( this );
     33                bool commit( bool force_changed = false )
     34                {
     35                        bool resized = force_changed || ( m_cached_size != m_data.size() );
     36                        bool result  = m_cache->commit( m_data, m_locked, resized, m_offset );
    3537                        m_cached_size = m_data.size();
    3638                        m_locked      = false;
    37                 }
     39                        return result;
     40                }
     41               
     42                template < typename V >
     43                bool commit_offset( bool force_changed, V value )
     44                {
     45                        bool locked = m_locked;
     46                        bool result = commit( force_changed );
     47                        if ( locked || result )
     48                        {
     49                                m_cache->add_offset<T>( m_data.size(), m_offset, static_cast<T>(value) );
     50                        }
     51                        return result;
     52                }
     53
     54                bool is_locked() const
     55                {
     56                        return m_locked;
     57                }
     58
     59                size_t get_offset() const
     60                {
     61                        return m_offset;
     62                }
     63
    3864                vector& lock()
    3965                {
     
    4975                        m_cache->reset();
    5076                }
    51         private:
    52                 friend class cached_buffer<T>;
    53 
     77        public:
    5478                vector m_data;
    5579                cache* m_cache;
     
    6387        {
    6488        public:
    65                 typedef buffer_slice<T> slice;
    6689                typedef std::vector<T>  vector;
    6790                typedef T               value_type;
    68                 static const int value_type_size = sizeof(T);
    69 
    70                 cached_buffer( device* dev, buffer_hint hint, int initial_size, bool is_vertex = true )
     91                static const size_t value_type_size = sizeof(T);
     92
     93                cached_buffer( device* dev, buffer_hint hint, size_t initial_size, bool is_vertex = true )
    7194                        : m_device( dev )
    7295                        , m_buffer( nullptr )
     
    81104                }
    82105
    83                 void commit( slice* bslice )
    84                 {
     106                bool commit( const vector& bv, bool updated, bool resized, size_t& offset )
     107                {
     108                        if ( !m_full_update && resized )
     109                        {
     110                                m_data.erase( m_data.begin() + offset, m_data.end() );
     111                                m_min = glm::min<int>( m_min, offset );
     112                                m_full_update = true;
     113                        }
    85114                        if ( m_full_update )
    86115                        {
    87                                 const vector& bv = bslice->data();
    88                                 bslice->m_offset = m_data.size();
     116                                offset = m_data.size();
    89117                                m_data.insert( m_data.end(), bv.cbegin(), bv.cend() );
    90118                        }
    91                         else if ( bslice->m_locked )
    92                         {
    93                                 const vector& bv = bslice->data();
    94                                 if ( bslice->m_cached_size != bv.size() )
    95                                 {
    96                                         m_data.erase( m_data.begin() + bslice->m_offset, m_data.end() );
    97                                         m_full_update = true;
    98                                         m_data.insert( m_data.end(), bv.cbegin(), bv.cend() );
    99                                         m_min = glm::min<int>( m_min, bslice->m_offset );
    100                                 }
    101                                 else
    102                                 {
    103                                         std::copy( bv.cbegin(), bv.cend(), m_data.begin() + bslice->m_offset );
    104                                         m_min = glm::min<int>( m_min, bslice->m_offset );
    105                                         m_max = glm::max<int>( m_max, bslice->m_offset + bv.size() );
    106                                 }
     119                        else if ( updated )
     120                        {
     121                                std::copy( bv.cbegin(), bv.cend(), m_data.begin() + offset );
     122                                m_min = glm::min<size_t>( m_min, offset );
     123                                m_max = glm::max<size_t>( m_max, offset + bv.size() );
     124                        }
     125                        return m_full_update;
     126                }
     127
     128                template < typename V >
     129                void add_offset( size_t size, size_t offset, V value )
     130                {
     131                        if ( size == 0 ) return;
     132                        T* ptr  = m_data.data() + offset;
     133                        T* pend = ptr + size;
     134                        for ( ; ptr != pend; ptr++ )
     135                        {
     136                                *ptr += value;
    107137                        }
    108138                }
     
    128158                                create_buffer( bsize );
    129159                                m_full_update = true;
     160                                m_min  = 0;
    130161                                result = true;
    131162                        }
    132                         m_buffer->bind();
    133                         if ( m_full_update )
    134                         {
    135                                 if ( m_min > 0 )
    136                                 {
    137                                         int offset = m_min * value_type_size;
    138                                         int size   = m_data.size() * value_type_size - offset;
    139                                         m_buffer->update( m_data.data() + m_min, offset, size );
    140                                 }
    141                                 else
    142                                 {
    143                                         m_buffer->update( m_data.data(), 0, m_data.size() * value_type_size );
    144                                 }
    145                         }
    146                         else if ( m_max > 0 )
    147                         {
     163                        if ( m_full_update ) m_max = m_data.size();
     164                        if ( m_max > 0 )
     165                        {
     166                                m_buffer->bind();
    148167                                int offset = m_min * value_type_size;
    149168                                int size   = (m_max-m_min) * value_type_size;
    150169                                m_buffer->update( m_data.data() + m_min, offset, size );
    151                         }
    152                         m_buffer->unbind();
     170                                m_buffer->unbind();
     171                        }
    153172                        m_full_update = false;
    154173                        m_min = get_max_size();
     
    193212                vector      m_data;
    194213
    195                 int         m_min;
    196                 int         m_max;
     214                size_t      m_min;
     215                size_t      m_max;
    197216        };
    198217
     218        template< typename T, typename I = uint16 > class indexed_cached_buffer;
     219
     220        template< typename T, typename I = uint16 >
     221        class indexed_buffer_slice
     222        {
     223        public:
     224                typedef indexed_cached_buffer<T,I> cache;
     225                typedef buffer_slice<T> vertex_slice;
     226                typedef buffer_slice<I> index_slice;
     227                typedef typename vertex_slice::vector vertex_vector;
     228                typedef typename index_slice::vector  index_vector;
     229
     230                indexed_buffer_slice( cache* c )
     231                        : m_vertex_slice( &c->get_vertex_cache() )
     232                        , m_index_slice( &c->get_index_cache() )
     233                        , m_cache( c )
     234                {
     235                }
     236
     237                void commit()
     238                {
     239                        bool changed = m_vertex_slice.commit();
     240                        m_index_slice.commit_offset( changed, m_vertex_slice.get_offset() );
     241                }
     242                vertex_vector& lock_vertices()
     243                {
     244                        return m_vertex_slice.lock();
     245                }
     246                index_vector& lock_indices()
     247                {
     248                        return m_index_slice.lock();
     249                }
     250                const vertex_vector& vertex_data()
     251                {
     252                        return m_vertex_slice.data();
     253                }
     254                const index_vector& index_data()
     255                {
     256                        return m_index_slice.data();
     257                }
     258
     259        private:
     260                vertex_slice m_vertex_slice;
     261                index_slice  m_index_slice;
     262                cache*       m_cache;
     263        };
     264
     265        template< typename T, typename I >
     266        class indexed_cached_buffer
     267        {
     268        public:
     269                typedef cached_buffer<T> cached_vertex_buffer;
     270                typedef cached_buffer<I> cached_index_buffer;
     271                static const int value_type_size = sizeof(T);
     272
     273                indexed_cached_buffer( device* dev, buffer_hint hint, int initial_size, int initial_index_size )
     274                        : m_vertex_buffer( dev, hint, initial_size, true )
     275                        , m_index_buffer( dev, hint, initial_index_size, false )
     276                {
     277
     278                }
     279
     280                void reset()
     281                {
     282                        m_vertex_buffer.reset();
     283                        m_index_buffer.reset();
     284                }
     285
     286                bool commit()
     287                {
     288                        bool vresult = m_vertex_buffer.commit();
     289                        bool iresult = m_index_buffer.commit();
     290                        return vresult || iresult;
     291                }
     292
     293                int get_max_vertex_size() const { return m_vertex_buffer.get_max_size(); }
     294                int get_max_index_size()  const { return m_index_buffer.get_max_size(); }
     295                int get_vertex_size()     const { return m_vertex_buffer.get_size(); }
     296                int get_index_size()      const { return m_index_buffer.get_size(); }
     297                vertex_buffer* get_vertex_buffer() { return static_cast<vertex_buffer*>( m_vertex_buffer.get_buffer() ); }
     298                index_buffer*  get_index_buffer()  { return static_cast<index_buffer*>( m_index_buffer.get_buffer() ); }
     299                cached_vertex_buffer& get_vertex_cache() { return m_vertex_buffer; }
     300                cached_index_buffer&  get_index_cache()  { return m_index_buffer; }
     301
     302        private:
     303                cached_vertex_buffer m_vertex_buffer;
     304                cached_index_buffer  m_index_buffer;
     305        };
     306
     307
    199308} // namespace nv
    200309
  • trunk/nv/interface/vertex_buffer.hh

    r116 r119  
    9393        {
    9494        public:
    95                 vertex_array() : m_map(), m_index( nullptr ), m_index_owner( false ), m_index_type(INT) {}
     95                vertex_array() : m_map(), m_index( nullptr ), m_index_owner( false ), m_index_type(USHORT) {}
    9696                void add_vertex_buffer( int location, vertex_buffer* buffer, datatype datatype, int components, int offset = 0, int stride = 0, bool owner = true )
    9797                {
     
    109109                void set_index_buffer( index_buffer* buffer, datatype datatype, bool owner )
    110110                {
     111                        if (m_index && m_index_owner) delete m_index;
    111112                        m_index       = buffer;
    112113                        m_index_owner = owner;
    113114                        m_index_type  = datatype;
     115                }
     116                void set_index_buffer( index_buffer* buffer )
     117                {
     118                        if (m_index && m_index_owner) delete m_index;
     119                        m_index       = buffer;
    114120                }
    115121                bool has_index_buffer() const { return m_index != nullptr; }
  • trunk/tests/cachebuf_test/nv_cachebuf_test.cc

    r118 r119  
    1919#include <nv/gfx/cached_buffer.hh>
    2020
     21#define INDEXED_TEST
     22
    2123struct vertex
    2224{
     
    2830};
    2931
     32#ifndef INDEXED_TEST
    3033struct quad
    3134{
     
    6366
    6467};
     68#endif
     69
     70#ifdef INDEXED_TEST
     71typedef nv::indexed_cached_buffer<vertex> gcache;
     72typedef nv::indexed_buffer_slice<vertex> gslice;
     73#else
     74typedef nv::cached_buffer<quad> gcache;
     75typedef nv::buffer_slice<quad> gslice;
     76#endif
    6577
    6678struct app_window
    6779{
    68         app_window( nv::cached_buffer<quad>* cache, const glm::ivec2& a, const glm::ivec2& b, const glm::vec4& color )
    69                 : m_slice( cache ), m_a( a ), m_b( b ), m_c( color )
     80        app_window( gcache* cache, const glm::ivec2& a, const glm::ivec2& b, const glm::vec4& color )
     81                : m_slice( cache ), m_simple( false ), m_a( a ), m_b( b ), m_c( color )
    7082        {
    7183                create_complex();
     
    7688                m_c = color;
    7789                glm::vec4 dcolor( color.x * 0.5, color.y * 0.5, color.z * 0.5, 1.0 );
     90                #ifdef INDEXED_TEST
     91                std::vector<vertex>& v = m_slice.lock_vertices();
     92                size_t size   = v.size();
     93                size_t dcount = 8;
     94                size_t dmin   = 8;
     95                size_t count  = size;
     96                #else
    7897                std::vector<quad>& v = m_slice.lock();
     98                size_t size   = v.size();
     99                size_t dcount = (size - 1) * 6;
     100                size_t dmin   = 1;
     101                size_t count  = size * 6;
     102                #endif
    79103                vertex* vtx = (vertex*)v.data();
    80                 if ( v.size() > 1 )
    81                 {
    82                         for (size_t i = 0; i < (v.size() - 1) * 6; ++i )
     104                if ( size > dmin )
     105                {
     106                        for (size_t i = 0; i < dcount; ++i )
    83107                                vtx[i].color = dcolor;
    84                         for (size_t i = (v.size() - 1) * 6; i < (v.size()) * 6; ++i )
     108                        for (size_t i = dcount; i < count; ++i )
    85109                                vtx[i].color = color;
    86110                }
    87111                else
    88112                {
    89                         for (size_t i = 0; i < 6; ++i )
     113                        for (size_t i = 0; i < count; ++i )
    90114                                vtx[i].color = color;
    91115                }
     
    94118        void simplify_toggle()
    95119        {
    96                 if ( m_slice.data().size() > 1 )
     120                if ( !m_simple )
    97121                {
    98122                        NV_LOG( nv::LOG_INFO, "Simplifing" );
     
    108132        void create_simple()
    109133        {
     134                #ifdef INDEXED_TEST
     135                std::vector<vertex>& v     = m_slice.lock_vertices();
     136                std::vector<nv::uint16>& i = m_slice.lock_indices();
     137                v.clear();
     138                i.clear();
     139                v.emplace_back( m_a, m_c );
     140                v.emplace_back( nv::ivec2( m_a.x, m_b.y ), m_c );
     141                v.emplace_back( m_b, m_c );
     142                v.emplace_back( nv::ivec2( m_b.x, m_a.y ), m_c );
     143                nv::uint16 tmp[] = { 0, 1, 2, 2, 3, 0 };
     144                i.insert( i.end(), tmp, std::end( tmp ) );
     145                #else
    110146                std::vector<quad>& v = m_slice.lock();
    111147                v.clear();
    112148                v.emplace_back( m_a, m_b, m_c );
     149                #endif
     150                m_simple = true;
    113151        }
    114152
     
    116154        {
    117155                glm::vec4 dcolor( m_c.x * 0.5, m_c.y * 0.5, m_c.z * 0.5, 1.0 );
    118                 std::vector<quad>& v = m_slice.lock();
    119                 v.clear();
    120156                nv::ivec2 a2( m_a.x, m_b.y );
    121157                nv::ivec2 b2( m_b.x, m_a.y );
    122158                nv::ivec2 t1( 10, 10 );
    123159                nv::ivec2 t2( -10, 10 );
     160                #ifdef INDEXED_TEST
     161                std::vector<vertex>& v     = m_slice.lock_vertices();
     162                std::vector<nv::uint16>& i = m_slice.lock_indices();
     163                v.clear();
     164                i.clear();
     165                v.emplace_back( m_a- t1, dcolor ); // 0
     166                v.emplace_back( a2 + t2, dcolor ); // 1
     167                v.emplace_back( m_b+ t1, dcolor ); // 2
     168                v.emplace_back( b2 - t2, dcolor ); // 3
     169
     170                v.emplace_back( m_a, dcolor ); // 4
     171                v.emplace_back( a2, dcolor );  // 5
     172                v.emplace_back( m_b, dcolor ); // 6
     173                v.emplace_back( b2, dcolor );  // 7
     174                nv::uint16 tmp[] = {
     175                        0, 4, 7, 7, 3, 0,
     176                        0, 1, 5, 5, 4, 0,
     177                        1, 2, 6, 6, 5, 1,
     178                        2, 3, 7, 7, 6, 2,
     179                };
     180                i.insert( i.end(), tmp, std::end( tmp ) );
     181
     182                v.emplace_back( m_a, m_c );    // 8
     183                v.emplace_back( a2, m_c );     // 9
     184                v.emplace_back( m_b, m_c );    // 10
     185                v.emplace_back( b2, m_c );     // 11
     186                nv::uint16 tmp2[] = { 8, 9, 10, 10, 11, 8 };
     187                i.insert( i.end(), tmp2, std::end( tmp2 ) );
     188
     189                #else
     190                std::vector<quad>& v = m_slice.lock();
     191                v.clear();
    124192                v.emplace_back( m_a - t1, m_a,       b2, b2 - t2, dcolor );
    125193                v.emplace_back( m_a - t1, a2 + t2, a2, m_a,       dcolor );
     
    127195                v.emplace_back( m_b + t1, b2 - t2, b2, m_b, dcolor );
    128196                v.emplace_back( m_a, m_b, m_c );
     197                #endif
     198                m_simple = false;
    129199        }
    130200
     
    134204        }
    135205
    136         nv::buffer_slice<quad> m_slice;
     206        gslice m_slice;
     207        bool m_simple;
    137208        nv::ivec2 m_a;
    138209        nv::ivec2 m_b;
     
    157228        nv::render_state m_render_state;
    158229       
    159         nv::cached_buffer<quad>* m_quad_cache;
     230        gcache* m_quad_cache;
    160231        std::vector<app_window>  m_windows;
    161232
     
    185256{
    186257        {
    187                 m_program = m_device->create_program( nv::slurp( "cachebuf.vert" ), nv::slurp( "cachebuf.frag" ) );
    188                 m_va      = m_device->create_vertex_array();
    189 
    190                 m_quad_cache = new nv::cached_buffer<quad>( m_device, nv::DYNAMIC_DRAW, 20, true );
    191                 m_coord_loc  = m_program->get_attribute("coord")->get_location();
    192                 m_color_loc  = m_program->get_attribute("color")->get_location();
    193 
    194                 m_va->add_vertex_buffer( m_coord_loc, (nv::vertex_buffer*)m_quad_cache->get_buffer(), nv::INT,   2, 0, sizeof( vertex ), false );
    195                 m_va->add_vertex_buffer( m_color_loc, (nv::vertex_buffer*)m_quad_cache->get_buffer(), nv::FLOAT, 4, offset_of( &vertex::color ), sizeof( vertex ), false );
     258                m_program   = m_device->create_program( nv::slurp( "cachebuf.vert" ), nv::slurp( "cachebuf.frag" ) );
     259                m_coord_loc = m_program->get_attribute("coord")->get_location();
     260                m_color_loc = m_program->get_attribute("color")->get_location();
     261                m_va        = m_device->create_vertex_array();
     262
     263                #ifdef INDEXED_TEST
     264                m_quad_cache = new gcache( m_device, nv::DYNAMIC_DRAW, 200, 200 );
     265                m_va->set_index_buffer( m_quad_cache->get_index_buffer(), nv::USHORT, false );
     266                nv::vertex_buffer* buffer = m_quad_cache->get_vertex_buffer();
     267                #else
     268                m_quad_cache = new gcache( m_device, nv::DYNAMIC_DRAW, 20, true );
     269                nv::vertex_buffer* buffer = (nv::vertex_buffer*)m_quad_cache->get_buffer();
     270                #endif
     271
     272                m_va->add_vertex_buffer( m_coord_loc, buffer, nv::INT,   2, 0, sizeof( vertex ), false );
     273                m_va->add_vertex_buffer( m_color_loc, buffer, nv::FLOAT, 4, offset_of( &vertex::color ), sizeof( vertex ), false );
    196274        }
    197275        return true;
     
    213291                if (m_quad_cache->commit() )
    214292                {
    215                         m_va->update_vertex_buffer( m_coord_loc, (nv::vertex_buffer*)m_quad_cache->get_buffer(), false );
    216                         m_va->update_vertex_buffer( m_color_loc, (nv::vertex_buffer*)m_quad_cache->get_buffer(), false );
     293                        #ifdef INDEXED_TEST
     294                        m_va->set_index_buffer( m_quad_cache->get_index_buffer() );
     295                        nv::vertex_buffer* buffer = m_quad_cache->get_vertex_buffer();
     296                        #else
     297                        nv::vertex_buffer* buffer = (nv::vertex_buffer*)m_quad_cache->get_buffer();
     298                        #endif
     299                        m_va->update_vertex_buffer( m_coord_loc, buffer, false );
     300                        m_va->update_vertex_buffer( m_color_loc, buffer, false );
    217301                }
    218302
     
    220304                m_program->bind();
    221305//              m_program->set_uniform( "tex", 0 );
    222                 m_window->get_context()->draw( nv::TRIANGLES, m_render_state, m_program, m_va, m_quad_cache->get_size() * 6 );
     306                #ifdef INDEXED_TEST
     307                size_t draw_size = m_quad_cache->get_index_size();
     308                #else
     309                size_t draw_size = m_quad_cache->get_size() * 6;
     310                #endif
     311                m_window->get_context()->draw( nv::TRIANGLES, m_render_state, m_program, m_va, draw_size );
    223312                m_window->swap_buffers();
    224313
Note: See TracChangeset for help on using the changeset viewer.