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

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