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

Last change on this file since 213 was 161, checked in by epyon, 12 years ago
  • unified naming of attributes in nv
  • predefined attribute bindings based on unified names
  • unified naming of attributes in all tests
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/types.hh>
15#include <nv/interface/mesh.hh>
16#include <cstdlib> // rand
17#include <ctime> // time
18
19#include <nv/gfx/sliced_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_sliced_buffer<vertex> gcache;
72typedef nv::indexed_buffer_slice<vertex> gslice;
73#else
74typedef nv::sliced_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};
237
238application::application()
239{
240        m_device = new nv::gl_device();
241        m_window = m_device->create_window( 800, 600 );
242
243        m_clear_state.buffers = nv::clear_state::COLOR_AND_DEPTH_BUFFER;
244        m_render_state.depth_test.enabled = false;
245        m_render_state.culling.enabled    = false;
246        m_render_state.blending.enabled   = false;
247        m_render_state.blending.src_rgb_factor   = nv::blending::SRC_ALPHA;
248        m_render_state.blending.dst_rgb_factor   = nv::blending::ONE_MINUS_SRC_ALPHA;
249        m_render_state.blending.src_alpha_factor = nv::blending::SRC_ALPHA;
250        m_render_state.blending.dst_alpha_factor = nv::blending::ONE_MINUS_SRC_ALPHA;
251}
252
253bool application::initialize()
254{
255        {
256                m_program   = m_device->create_program( nv::slurp( "cachebuf.vert" ), nv::slurp( "cachebuf.frag" ) );
257                m_va        = m_device->create_vertex_array();
258
259                #ifdef INDEXED_TEST
260                m_quad_cache = new gcache( m_device, nv::DYNAMIC_DRAW, 200, 200 );
261                m_va->set_index_buffer( m_quad_cache->get_index_buffer(), nv::USHORT, false );
262                nv::vertex_buffer* buffer = m_quad_cache->get_vertex_buffer();
263                #else
264                m_quad_cache = new gcache( m_device, nv::DYNAMIC_DRAW, 20, true );
265                nv::vertex_buffer* buffer = (nv::vertex_buffer*)m_quad_cache->get_buffer();
266                #endif
267
268                m_va->add_vertex_buffer( nv::slot::POSITION, buffer, nv::INT,   2, 0, sizeof( vertex ), false );
269                m_va->add_vertex_buffer( nv::slot::COLOR,    buffer, nv::FLOAT, 4, offset_of( &vertex::color ), sizeof( vertex ), false );
270        }
271        return true;
272}
273
274bool application::run()
275{
276        int keypress = 0;
277        m_program->bind();
278        glm::mat4 projection = glm::ortho( 0.0f, 800.0f, 600.0f, 0.0f, -1.0f, 1.0f );
279        m_program->set_uniform( "nv_projection", glm::mat4(projection) );
280
281        while(!keypress)
282        {
283                for ( auto& w : m_windows )
284                {
285                        w.draw();
286                }
287                if (m_quad_cache->commit() )
288                {
289                        #ifdef INDEXED_TEST
290                        m_va->set_index_buffer( m_quad_cache->get_index_buffer() );
291                        nv::vertex_buffer* buffer = m_quad_cache->get_vertex_buffer();
292                        #else
293                        nv::vertex_buffer* buffer = (nv::vertex_buffer*)m_quad_cache->get_buffer();
294                        #endif
295                        m_va->update_vertex_buffer( nv::slot::POSITION, buffer, false );
296                        m_va->update_vertex_buffer( nv::slot::COLOR,    buffer, false );
297                }
298
299                m_window->get_context()->clear( m_clear_state );
300                m_program->bind();
301//              m_program->set_uniform( "tex", 0 );
302                #ifdef INDEXED_TEST
303                size_t draw_size = m_quad_cache->get_index_size();
304                #else
305                size_t draw_size = m_quad_cache->get_size() * 6;
306                #endif
307                m_window->get_context()->draw( nv::TRIANGLES, m_render_state, m_program, m_va, draw_size );
308                m_window->swap_buffers();
309
310                nv::io_event event;
311                while(m_window->poll_event(event))
312                {     
313                        switch (event.type)
314                        {
315                        case nv::EV_QUIT:
316                                keypress = 1;
317                                break;
318                        case nv::EV_KEY:
319                                if (event.key.pressed)
320                                {
321                                        switch (event.key.code)
322                                        {
323                                        case nv::KEY_N      : spawn_window(); break;
324                                        case nv::KEY_S      : simplify_window(); break;
325                                        case nv::KEY_C      : recolor_window(); break;
326                                        case nv::KEY_K      : kill_window(); break;
327                                        case nv::KEY_ESCAPE : keypress = 1; break;
328                                        }
329                                }
330                                break;
331                        }
332                }
333        }
334        return true;
335}
336
337void application::spawn_window()
338{
339        glm::ivec2 a( std::rand() % 600, std::rand() % 400 );
340        glm::ivec2 b( std::rand() % 200, std::rand() % 200 );
341        NV_LOG( nv::LOG_INFO, "Spawn (" << a.x << "," << a.y << "x" << b.x << "," << b.y << ")" );
342        m_windows.emplace_back( m_quad_cache, a, a + b, glm::vec4( 0, 0, 1, 1 ) );
343}
344
345void application::kill_window()
346{
347        if ( m_windows.size() == 0 ) return;
348        size_t index = rand() % m_windows.size();
349        m_windows.erase( m_windows.begin() + index );
350}
351
352void application::recolor_window()
353{
354        if ( m_windows.size() == 0 ) return;
355        size_t index = rand() % m_windows.size();
356        m_windows[ index ].change_color( nv::vec4( (float)rand() / float(RAND_MAX), (float)rand() / float(RAND_MAX), (float)rand() / float(RAND_MAX), 1.0 ) );
357}
358
359void application::simplify_window()
360{
361        if ( m_windows.size() == 0 ) return;
362        size_t index = rand() % m_windows.size();
363        NV_LOG( nv::LOG_INFO, "Simplify " << index );
364        m_windows[ index ].simplify_toggle();
365}
366
367application::~application()
368{
369        m_windows.clear();
370        delete m_quad_cache;
371
372        delete m_program;
373        delete m_va;
374        delete m_window;
375        delete m_device;
376}
377
378
379int main(int, char* [])
380{
381        std::srand((unsigned int) std::time(0) );
382        nv::logger log(nv::LOG_TRACE);
383        log.add_sink( new nv::log_file_sink("log.txt"), nv::LOG_TRACE );
384        log.add_sink( new nv::log_console_sink(), nv::LOG_TRACE );
385       
386        NV_LOG( nv::LOG_NOTICE, "Logging started" );
387        application app;
388        if ( app.initialize() )
389        {
390                app.run();
391        }
392        NV_LOG( nv::LOG_NOTICE, "Logging stopped" );
393
394        return 0;
395}
396
Note: See TracBrowser for help on using the repository browser.