source: trunk/tests/cachebuf_test/nv_cachebuf_test.cc @ 319

Last change on this file since 319 was 319, checked in by epyon, 11 years ago
  • created core module and moved all free source files there
  • took the opportunity to update all copyright lines and minor cleanup
  • minor fixes
  • not all examples are up to date
File size: 10.2 KB
RevLine 
[102]1#include <nv/gl/gl_device.hh>
2#include <nv/gfx/image.hh>
3#include <nv/interface/context.hh>
4#include <nv/interface/window.hh>
[319]5#include <nv/core/logging.hh>
6#include <nv/core/logger.hh>
[102]7#include <glm/glm.hpp>
8#include <glm/gtc/matrix_transform.hpp>
9#include <glm/gtc/type_ptr.hpp>
[319]10#include <nv/core/string.hh>
[102]11#include <cstdlib> // rand
12#include <ctime> // time
13
[152]14#include <nv/gfx/sliced_buffer.hh>
[102]15
[119]16#define INDEXED_TEST
17
[102]18struct vertex
19{
20        nv::ivec2 coord;
21        nv::vec4  color;
22        vertex() {}
23        vertex( const nv::ivec2& coord, const nv::vec4& color )
24                : coord( coord ), color( color ) {}
25};
26
[119]27#ifndef INDEXED_TEST
[102]28struct quad
29{
30        vertex vtx[6];
31        quad( const nv::ivec2& coorda, const nv::ivec2& coordb, const nv::vec4& color )
32        {
33                vtx[0].color = color;
34                vtx[1].color = color;
35                vtx[2].color = color;
36                vtx[3].color = color;
37                vtx[4].color = color;
38                vtx[5].color = color;
39                vtx[0].coord = coorda;
40                vtx[1].coord = nv::ivec2( coorda.x, coordb.y );
41                vtx[2].coord = coordb;
42                vtx[3].coord = coordb;
43                vtx[4].coord = nv::ivec2( coordb.x, coorda.y );
44                vtx[5].coord = coorda;
45        }
46        quad( const nv::ivec2& coorda, const nv::ivec2& coordb, const nv::ivec2& coordc, const nv::ivec2& coordd, const nv::vec4& color )
47        {
48                vtx[0].color = color;
49                vtx[1].color = color;
50                vtx[2].color = color;
51                vtx[3].color = color;
52                vtx[4].color = color;
53                vtx[5].color = color;
54                vtx[0].coord = coorda;
55                vtx[1].coord = coordb;
56                vtx[2].coord = coordc;
57                vtx[3].coord = coordc;
58                vtx[4].coord = coordd;
59                vtx[5].coord = coorda;
60        }
61
62};
[119]63#endif
[102]64
[119]65#ifdef INDEXED_TEST
[152]66typedef nv::indexed_sliced_buffer<vertex> gcache;
[119]67typedef nv::indexed_buffer_slice<vertex> gslice;
68#else
[152]69typedef nv::sliced_buffer<quad> gcache;
[119]70typedef nv::buffer_slice<quad> gslice;
71#endif
72
[102]73struct app_window
74{
[119]75        app_window( gcache* cache, const glm::ivec2& a, const glm::ivec2& b, const glm::vec4& color )
76                : m_slice( cache ), m_simple( false ), m_a( a ), m_b( b ), m_c( color )
[102]77        {
[118]78                create_complex();
[102]79        }
80
81        void change_color( const glm::vec4& color )
82        {
[118]83                m_c = color;
[102]84                glm::vec4 dcolor( color.x * 0.5, color.y * 0.5, color.z * 0.5, 1.0 );
[119]85                #ifdef INDEXED_TEST
86                std::vector<vertex>& v = m_slice.lock_vertices();
87                size_t size   = v.size();
88                size_t dcount = 8;
89                size_t dmin   = 8;
90                size_t count  = size;
91                #else
[102]92                std::vector<quad>& v = m_slice.lock();
[119]93                size_t size   = v.size();
94                size_t dcount = (size - 1) * 6;
95                size_t dmin   = 1;
96                size_t count  = size * 6;
97                #endif
[102]98                vertex* vtx = (vertex*)v.data();
[119]99                if ( size > dmin )
[118]100                {
[119]101                        for (size_t i = 0; i < dcount; ++i )
[118]102                                vtx[i].color = dcolor;
[119]103                        for (size_t i = dcount; i < count; ++i )
[118]104                                vtx[i].color = color;
105                }
106                else
107                {
[119]108                        for (size_t i = 0; i < count; ++i )
[118]109                                vtx[i].color = color;
110                }
[102]111        }
112
[118]113        void simplify_toggle()
114        {
[119]115                if ( !m_simple )
[118]116                {
117                        NV_LOG( nv::LOG_INFO, "Simplifing" );
118                        create_simple();
119                }
120                else
121                {
122                        NV_LOG( nv::LOG_INFO, "Complexifing" );
123                        create_complex();
124                }
125        }
126
127        void create_simple()
128        {
[119]129                #ifdef INDEXED_TEST
130                std::vector<vertex>& v     = m_slice.lock_vertices();
131                std::vector<nv::uint16>& i = m_slice.lock_indices();
132                v.clear();
133                i.clear();
134                v.emplace_back( m_a, m_c );
135                v.emplace_back( nv::ivec2( m_a.x, m_b.y ), m_c );
136                v.emplace_back( m_b, m_c );
137                v.emplace_back( nv::ivec2( m_b.x, m_a.y ), m_c );
138                nv::uint16 tmp[] = { 0, 1, 2, 2, 3, 0 };
139                i.insert( i.end(), tmp, std::end( tmp ) );
140                #else
[118]141                std::vector<quad>& v = m_slice.lock();
142                v.clear();
143                v.emplace_back( m_a, m_b, m_c );
[119]144                #endif
145                m_simple = true;
[118]146        }
147
148        void create_complex()
149        {
150                glm::vec4 dcolor( m_c.x * 0.5, m_c.y * 0.5, m_c.z * 0.5, 1.0 );
151                nv::ivec2 a2( m_a.x, m_b.y );
152                nv::ivec2 b2( m_b.x, m_a.y );
153                nv::ivec2 t1( 10, 10 );
154                nv::ivec2 t2( -10, 10 );
[119]155                #ifdef INDEXED_TEST
156                std::vector<vertex>& v     = m_slice.lock_vertices();
157                std::vector<nv::uint16>& i = m_slice.lock_indices();
158                v.clear();
159                i.clear();
160                v.emplace_back( m_a- t1, dcolor ); // 0
161                v.emplace_back( a2 + t2, dcolor ); // 1
162                v.emplace_back( m_b+ t1, dcolor ); // 2
163                v.emplace_back( b2 - t2, dcolor ); // 3
164
165                v.emplace_back( m_a, dcolor ); // 4
166                v.emplace_back( a2, dcolor );  // 5
167                v.emplace_back( m_b, dcolor ); // 6
168                v.emplace_back( b2, dcolor );  // 7
169                nv::uint16 tmp[] = {
170                        0, 4, 7, 7, 3, 0,
171                        0, 1, 5, 5, 4, 0,
172                        1, 2, 6, 6, 5, 1,
173                        2, 3, 7, 7, 6, 2,
174                };
175                i.insert( i.end(), tmp, std::end( tmp ) );
176
177                v.emplace_back( m_a, m_c );    // 8
178                v.emplace_back( a2, m_c );     // 9
179                v.emplace_back( m_b, m_c );    // 10
180                v.emplace_back( b2, m_c );     // 11
181                nv::uint16 tmp2[] = { 8, 9, 10, 10, 11, 8 };
182                i.insert( i.end(), tmp2, std::end( tmp2 ) );
183
184                #else
185                std::vector<quad>& v = m_slice.lock();
186                v.clear();
[118]187                v.emplace_back( m_a - t1, m_a,       b2, b2 - t2, dcolor );
188                v.emplace_back( m_a - t1, a2 + t2, a2, m_a,       dcolor );
189                v.emplace_back( a2 + t2, m_b + t1, m_b, a2, dcolor );
190                v.emplace_back( m_b + t1, b2 - t2, b2, m_b, dcolor );
191                v.emplace_back( m_a, m_b, m_c );
[119]192                #endif
193                m_simple = false;
[118]194        }
195
[102]196        void draw()
197        {
198                m_slice.commit();
199        }
200
[119]201        gslice m_slice;
202        bool m_simple;
[118]203        nv::ivec2 m_a;
204        nv::ivec2 m_b;
205        nv::vec4 m_c;
[102]206};
207
208class application
209{
210public:
211        application();
212        bool initialize();
213        bool run();
214        void kill_window();
215        void spawn_window();
[118]216        void simplify_window();
[102]217        void recolor_window();
218        ~application();
219protected:
[319]220        nv::device*  m_device;
221        nv::context* m_context;
222        nv::window*  m_window;
[102]223        nv::clear_state m_clear_state;
224        nv::render_state m_render_state;
225       
[119]226        gcache* m_quad_cache;
[102]227        std::vector<app_window>  m_windows;
228
[319]229        nv::program       m_program;
230        nv::vertex_array  m_va;
[102]231        unsigned int m_count;
232};
233
234application::application()
235{
[319]236        m_device  = new nv::gl_device();
237        m_window  = m_device->create_window( 800, 600, false );
238        m_context = m_window->get_context();
[102]239
240        m_clear_state.buffers = nv::clear_state::COLOR_AND_DEPTH_BUFFER;
241        m_render_state.depth_test.enabled = false;
242        m_render_state.culling.enabled    = false;
243        m_render_state.blending.enabled   = false;
244        m_render_state.blending.src_rgb_factor   = nv::blending::SRC_ALPHA;
245        m_render_state.blending.dst_rgb_factor   = nv::blending::ONE_MINUS_SRC_ALPHA;
246        m_render_state.blending.src_alpha_factor = nv::blending::SRC_ALPHA;
247        m_render_state.blending.dst_alpha_factor = nv::blending::ONE_MINUS_SRC_ALPHA;
248}
249
250bool application::initialize()
251{
252        {
[119]253                m_program   = m_device->create_program( nv::slurp( "cachebuf.vert" ), nv::slurp( "cachebuf.frag" ) );
[319]254                m_va        = m_context->create_vertex_array();
[102]255
[119]256                #ifdef INDEXED_TEST
[319]257                m_quad_cache = new gcache( m_context, nv::DYNAMIC_DRAW, 200, 200 );
258                m_context->set_index_buffer( m_va, m_quad_cache->get_index_buffer(), nv::USHORT, false );
259                nv::buffer buffer = m_quad_cache->get_vertex_buffer();
[119]260                #else
[319]261                m_quad_cache = new gcache( m_context, nv::DYNAMIC_DRAW, 20, true );
262                nv::buffer buffer = m_quad_cache->get_buffer();
[119]263                #endif
[102]264
[319]265                m_context->add_vertex_buffer( m_va, nv::slot::POSITION, buffer, nv::INT,   2, 0, sizeof( vertex ), false );
266                m_context->add_vertex_buffer( m_va, nv::slot::COLOR,    buffer, nv::FLOAT, 4, offset_of( &vertex::color ), sizeof( vertex ), false );
[102]267        }
268        return true;
269}
270
271bool application::run()
272{
273        int keypress = 0;
274        glm::mat4 projection = glm::ortho( 0.0f, 800.0f, 600.0f, 0.0f, -1.0f, 1.0f );
[319]275        m_device->set_uniform( m_program, "nv_projection", glm::mat4(projection) );
[102]276
277        while(!keypress)
278        {
279                for ( auto& w : m_windows )
280                {
281                        w.draw();
282                }
[106]283                if (m_quad_cache->commit() )
284                {
[119]285                        #ifdef INDEXED_TEST
[319]286                        m_context->set_index_buffer( m_va, m_quad_cache->get_index_buffer(), nv::USHORT, false );
287                        nv::buffer buffer = m_quad_cache->get_vertex_buffer();
[119]288                        #else
[319]289                        nv::buffer buffer = m_quad_cache->get_buffer();
[119]290                        #endif
[106]291                }
[102]292
293                m_window->get_context()->clear( m_clear_state );
294//              m_program->set_uniform( "tex", 0 );
[119]295                #ifdef INDEXED_TEST
296                size_t draw_size = m_quad_cache->get_index_size();
297                #else
298                size_t draw_size = m_quad_cache->get_size() * 6;
299                #endif
300                m_window->get_context()->draw( nv::TRIANGLES, m_render_state, m_program, m_va, draw_size );
[102]301                m_window->swap_buffers();
302
303                nv::io_event event;
304                while(m_window->poll_event(event))
305                {     
306                        switch (event.type)
307                        {
308                        case nv::EV_QUIT:
309                                keypress = 1;
310                                break;
311                        case nv::EV_KEY:
312                                if (event.key.pressed)
313                                {
314                                        switch (event.key.code)
315                                        {
316                                        case nv::KEY_N      : spawn_window(); break;
[118]317                                        case nv::KEY_S      : simplify_window(); break;
[102]318                                        case nv::KEY_C      : recolor_window(); break;
319                                        case nv::KEY_K      : kill_window(); break;
320                                        case nv::KEY_ESCAPE : keypress = 1; break;
321                                        }
322                                }
323                                break;
324                        }
325                }
326        }
327        return true;
328}
329
330void application::spawn_window()
331{
332        glm::ivec2 a( std::rand() % 600, std::rand() % 400 );
333        glm::ivec2 b( std::rand() % 200, std::rand() % 200 );
334        NV_LOG( nv::LOG_INFO, "Spawn (" << a.x << "," << a.y << "x" << b.x << "," << b.y << ")" );
335        m_windows.emplace_back( m_quad_cache, a, a + b, glm::vec4( 0, 0, 1, 1 ) );
336}
337
338void application::kill_window()
339{
340        if ( m_windows.size() == 0 ) return;
341        size_t index = rand() % m_windows.size();
342        m_windows.erase( m_windows.begin() + index );
343}
[118]344
[102]345void application::recolor_window()
346{
347        if ( m_windows.size() == 0 ) return;
348        size_t index = rand() % m_windows.size();
349        m_windows[ index ].change_color( nv::vec4( (float)rand() / float(RAND_MAX), (float)rand() / float(RAND_MAX), (float)rand() / float(RAND_MAX), 1.0 ) );
350}
351
[118]352void application::simplify_window()
353{
354        if ( m_windows.size() == 0 ) return;
355        size_t index = rand() % m_windows.size();
356        NV_LOG( nv::LOG_INFO, "Simplify " << index );
357        m_windows[ index ].simplify_toggle();
358}
359
[102]360application::~application()
361{
362        m_windows.clear();
363        delete m_quad_cache;
364
[319]365        m_device->release( m_program );
366        m_context->release( m_va );
[102]367        delete m_window;
368        delete m_device;
369}
370
371
372int main(int, char* [])
373{
374        std::srand((unsigned int) std::time(0) );
375        nv::logger log(nv::LOG_TRACE);
376        log.add_sink( new nv::log_file_sink("log.txt"), nv::LOG_TRACE );
377        log.add_sink( new nv::log_console_sink(), nv::LOG_TRACE );
378       
379        NV_LOG( nv::LOG_NOTICE, "Logging started" );
380        application app;
381        if ( app.initialize() )
382        {
383                app.run();
384        }
385        NV_LOG( nv::LOG_NOTICE, "Logging stopped" );
386
387        return 0;
388}
389
Note: See TracBrowser for help on using the repository browser.