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
Line 
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>
5#include <nv/core/logging.hh>
6#include <nv/core/logger.hh>
7#include <glm/glm.hpp>
8#include <glm/gtc/matrix_transform.hpp>
9#include <glm/gtc/type_ptr.hpp>
10#include <nv/core/string.hh>
11#include <cstdlib> // rand
12#include <ctime> // time
13
14#include <nv/gfx/sliced_buffer.hh>
15
16#define INDEXED_TEST
17
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
27#ifndef INDEXED_TEST
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};
63#endif
64
65#ifdef INDEXED_TEST
66typedef nv::indexed_sliced_buffer<vertex> gcache;
67typedef nv::indexed_buffer_slice<vertex> gslice;
68#else
69typedef nv::sliced_buffer<quad> gcache;
70typedef nv::buffer_slice<quad> gslice;
71#endif
72
73struct app_window
74{
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 )
77        {
78                create_complex();
79        }
80
81        void change_color( const glm::vec4& color )
82        {
83                m_c = color;
84                glm::vec4 dcolor( color.x * 0.5, color.y * 0.5, color.z * 0.5, 1.0 );
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
92                std::vector<quad>& v = m_slice.lock();
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
98                vertex* vtx = (vertex*)v.data();
99                if ( size > dmin )
100                {
101                        for (size_t i = 0; i < dcount; ++i )
102                                vtx[i].color = dcolor;
103                        for (size_t i = dcount; i < count; ++i )
104                                vtx[i].color = color;
105                }
106                else
107                {
108                        for (size_t i = 0; i < count; ++i )
109                                vtx[i].color = color;
110                }
111        }
112
113        void simplify_toggle()
114        {
115                if ( !m_simple )
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        {
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
141                std::vector<quad>& v = m_slice.lock();
142                v.clear();
143                v.emplace_back( m_a, m_b, m_c );
144                #endif
145                m_simple = true;
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 );
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();
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 );
192                #endif
193                m_simple = false;
194        }
195
196        void draw()
197        {
198                m_slice.commit();
199        }
200
201        gslice m_slice;
202        bool m_simple;
203        nv::ivec2 m_a;
204        nv::ivec2 m_b;
205        nv::vec4 m_c;
206};
207
208class application
209{
210public:
211        application();
212        bool initialize();
213        bool run();
214        void kill_window();
215        void spawn_window();
216        void simplify_window();
217        void recolor_window();
218        ~application();
219protected:
220        nv::device*  m_device;
221        nv::context* m_context;
222        nv::window*  m_window;
223        nv::clear_state m_clear_state;
224        nv::render_state m_render_state;
225       
226        gcache* m_quad_cache;
227        std::vector<app_window>  m_windows;
228
229        nv::program       m_program;
230        nv::vertex_array  m_va;
231        unsigned int m_count;
232};
233
234application::application()
235{
236        m_device  = new nv::gl_device();
237        m_window  = m_device->create_window( 800, 600, false );
238        m_context = m_window->get_context();
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        {
253                m_program   = m_device->create_program( nv::slurp( "cachebuf.vert" ), nv::slurp( "cachebuf.frag" ) );
254                m_va        = m_context->create_vertex_array();
255
256                #ifdef INDEXED_TEST
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();
260                #else
261                m_quad_cache = new gcache( m_context, nv::DYNAMIC_DRAW, 20, true );
262                nv::buffer buffer = m_quad_cache->get_buffer();
263                #endif
264
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 );
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 );
275        m_device->set_uniform( m_program, "nv_projection", glm::mat4(projection) );
276
277        while(!keypress)
278        {
279                for ( auto& w : m_windows )
280                {
281                        w.draw();
282                }
283                if (m_quad_cache->commit() )
284                {
285                        #ifdef INDEXED_TEST
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();
288                        #else
289                        nv::buffer buffer = m_quad_cache->get_buffer();
290                        #endif
291                }
292
293                m_window->get_context()->clear( m_clear_state );
294//              m_program->set_uniform( "tex", 0 );
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 );
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;
317                                        case nv::KEY_S      : simplify_window(); break;
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}
344
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
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
360application::~application()
361{
362        m_windows.clear();
363        delete m_quad_cache;
364
365        m_device->release( m_program );
366        m_context->release( m_va );
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.