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

Last change on this file since 127 was 119, checked in by epyon, 12 years ago
  • 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
File size: 10.5 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/types.hh>
15#include <nv/interface/mesh.hh>
16#include <cstdlib> // rand
17#include <ctime> // time
18
19#include <nv/gfx/cached_buffer.hh>
20
21#define INDEXED_TEST
22
23struct vertex
24{
25        nv::ivec2 coord;
26        nv::vec4  color;
27        vertex() {}
28        vertex( const nv::ivec2& coord, const nv::vec4& color )
29                : coord( coord ), color( color ) {}
30};
31
32#ifndef INDEXED_TEST
33struct quad
34{
35        vertex vtx[6];
36        quad( const nv::ivec2& coorda, const nv::ivec2& coordb, const nv::vec4& color )
37        {
38                vtx[0].color = color;
39                vtx[1].color = color;
40                vtx[2].color = color;
41                vtx[3].color = color;
42                vtx[4].color = color;
43                vtx[5].color = color;
44                vtx[0].coord = coorda;
45                vtx[1].coord = nv::ivec2( coorda.x, coordb.y );
46                vtx[2].coord = coordb;
47                vtx[3].coord = coordb;
48                vtx[4].coord = nv::ivec2( coordb.x, coorda.y );
49                vtx[5].coord = coorda;
50        }
51        quad( const nv::ivec2& coorda, const nv::ivec2& coordb, const nv::ivec2& coordc, const nv::ivec2& coordd, const nv::vec4& color )
52        {
53                vtx[0].color = color;
54                vtx[1].color = color;
55                vtx[2].color = color;
56                vtx[3].color = color;
57                vtx[4].color = color;
58                vtx[5].color = color;
59                vtx[0].coord = coorda;
60                vtx[1].coord = coordb;
61                vtx[2].coord = coordc;
62                vtx[3].coord = coordc;
63                vtx[4].coord = coordd;
64                vtx[5].coord = coorda;
65        }
66
67};
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
77
78struct app_window
79{
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 )
82        {
83                create_complex();
84        }
85
86        void change_color( const glm::vec4& color )
87        {
88                m_c = color;
89                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
97                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
103                vertex* vtx = (vertex*)v.data();
104                if ( size > dmin )
105                {
106                        for (size_t i = 0; i < dcount; ++i )
107                                vtx[i].color = dcolor;
108                        for (size_t i = dcount; i < count; ++i )
109                                vtx[i].color = color;
110                }
111                else
112                {
113                        for (size_t i = 0; i < count; ++i )
114                                vtx[i].color = color;
115                }
116        }
117
118        void simplify_toggle()
119        {
120                if ( !m_simple )
121                {
122                        NV_LOG( nv::LOG_INFO, "Simplifing" );
123                        create_simple();
124                }
125                else
126                {
127                        NV_LOG( nv::LOG_INFO, "Complexifing" );
128                        create_complex();
129                }
130        }
131
132        void create_simple()
133        {
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
146                std::vector<quad>& v = m_slice.lock();
147                v.clear();
148                v.emplace_back( m_a, m_b, m_c );
149                #endif
150                m_simple = true;
151        }
152
153        void create_complex()
154        {
155                glm::vec4 dcolor( m_c.x * 0.5, m_c.y * 0.5, m_c.z * 0.5, 1.0 );
156                nv::ivec2 a2( m_a.x, m_b.y );
157                nv::ivec2 b2( m_b.x, m_a.y );
158                nv::ivec2 t1( 10, 10 );
159                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();
192                v.emplace_back( m_a - t1, m_a,       b2, b2 - t2, dcolor );
193                v.emplace_back( m_a - t1, a2 + t2, a2, m_a,       dcolor );
194                v.emplace_back( a2 + t2, m_b + t1, m_b, a2, dcolor );
195                v.emplace_back( m_b + t1, b2 - t2, b2, m_b, dcolor );
196                v.emplace_back( m_a, m_b, m_c );
197                #endif
198                m_simple = false;
199        }
200
201        void draw()
202        {
203                m_slice.commit();
204        }
205
206        gslice m_slice;
207        bool m_simple;
208        nv::ivec2 m_a;
209        nv::ivec2 m_b;
210        nv::vec4 m_c;
211};
212
213class application
214{
215public:
216        application();
217        bool initialize();
218        bool run();
219        void kill_window();
220        void spawn_window();
221        void simplify_window();
222        void recolor_window();
223        ~application();
224protected:
225        nv::device* m_device;
226        nv::window* m_window;
227        nv::clear_state m_clear_state;
228        nv::render_state m_render_state;
229       
230        gcache* m_quad_cache;
231        std::vector<app_window>  m_windows;
232
233        nv::program* m_program;
234        nv::vertex_array* m_va;
235        unsigned int m_count;
236        int m_coord_loc;
237        int m_color_loc;
238};
239
240application::application()
241{
242        m_device = new nv::gl_device();
243        m_window = m_device->create_window( 800, 600 );
244
245        m_clear_state.buffers = nv::clear_state::COLOR_AND_DEPTH_BUFFER;
246        m_render_state.depth_test.enabled = false;
247        m_render_state.culling.enabled    = false;
248        m_render_state.blending.enabled   = false;
249        m_render_state.blending.src_rgb_factor   = nv::blending::SRC_ALPHA;
250        m_render_state.blending.dst_rgb_factor   = nv::blending::ONE_MINUS_SRC_ALPHA;
251        m_render_state.blending.src_alpha_factor = nv::blending::SRC_ALPHA;
252        m_render_state.blending.dst_alpha_factor = nv::blending::ONE_MINUS_SRC_ALPHA;
253}
254
255bool application::initialize()
256{
257        {
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 );
274        }
275        return true;
276}
277
278bool application::run()
279{
280        int keypress = 0;
281        m_program->bind();
282        glm::mat4 projection = glm::ortho( 0.0f, 800.0f, 600.0f, 0.0f, -1.0f, 1.0f );
283        m_program->set_uniform( "projection", glm::mat4(projection) );
284
285        while(!keypress)
286        {
287                for ( auto& w : m_windows )
288                {
289                        w.draw();
290                }
291                if (m_quad_cache->commit() )
292                {
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 );
301                }
302
303                m_window->get_context()->clear( m_clear_state );
304                m_program->bind();
305//              m_program->set_uniform( "tex", 0 );
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 );
312                m_window->swap_buffers();
313
314                nv::io_event event;
315                while(m_window->poll_event(event))
316                {     
317                        switch (event.type)
318                        {
319                        case nv::EV_QUIT:
320                                keypress = 1;
321                                break;
322                        case nv::EV_KEY:
323                                if (event.key.pressed)
324                                {
325                                        switch (event.key.code)
326                                        {
327                                        case nv::KEY_N      : spawn_window(); break;
328                                        case nv::KEY_S      : simplify_window(); break;
329                                        case nv::KEY_C      : recolor_window(); break;
330                                        case nv::KEY_K      : kill_window(); break;
331                                        case nv::KEY_ESCAPE : keypress = 1; break;
332                                        }
333                                }
334                                break;
335                        }
336                }
337        }
338        return true;
339}
340
341void application::spawn_window()
342{
343        glm::ivec2 a( std::rand() % 600, std::rand() % 400 );
344        glm::ivec2 b( std::rand() % 200, std::rand() % 200 );
345        NV_LOG( nv::LOG_INFO, "Spawn (" << a.x << "," << a.y << "x" << b.x << "," << b.y << ")" );
346        m_windows.emplace_back( m_quad_cache, a, a + b, glm::vec4( 0, 0, 1, 1 ) );
347}
348
349void application::kill_window()
350{
351        if ( m_windows.size() == 0 ) return;
352        size_t index = rand() % m_windows.size();
353        m_windows.erase( m_windows.begin() + index );
354}
355
356void application::recolor_window()
357{
358        if ( m_windows.size() == 0 ) return;
359        size_t index = rand() % m_windows.size();
360        m_windows[ index ].change_color( nv::vec4( (float)rand() / float(RAND_MAX), (float)rand() / float(RAND_MAX), (float)rand() / float(RAND_MAX), 1.0 ) );
361}
362
363void application::simplify_window()
364{
365        if ( m_windows.size() == 0 ) return;
366        size_t index = rand() % m_windows.size();
367        NV_LOG( nv::LOG_INFO, "Simplify " << index );
368        m_windows[ index ].simplify_toggle();
369}
370
371application::~application()
372{
373        m_windows.clear();
374        delete m_quad_cache;
375
376        delete m_program;
377        delete m_va;
378        delete m_window;
379        delete m_device;
380}
381
382
383int main(int, char* [])
384{
385        std::srand((unsigned int) std::time(0) );
386        nv::logger log(nv::LOG_TRACE);
387        log.add_sink( new nv::log_file_sink("log.txt"), nv::LOG_TRACE );
388        log.add_sink( new nv::log_console_sink(), nv::LOG_TRACE );
389       
390        NV_LOG( nv::LOG_NOTICE, "Logging started" );
391        application app;
392        if ( app.initialize() )
393        {
394                app.run();
395        }
396        NV_LOG( nv::LOG_NOTICE, "Logging stopped" );
397
398        return 0;
399}
400
Note: See TracBrowser for help on using the repository browser.