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

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