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

Last change on this file since 118 was 118, checked in by epyon, 12 years ago
  • cached_buffer - size caching, partial updates
  • cached_buffer - you can now freely change the size of locked vector, the cache will update accordingly
  • nv_cachebuf_test - added test for complexity change
File size: 8.1 KB
RevLine 
[102]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
21struct vertex
22{
23        nv::ivec2 coord;
24        nv::vec4  color;
25        vertex() {}
26        vertex( const nv::ivec2& coord, const nv::vec4& color )
27                : coord( coord ), color( color ) {}
28};
29
30struct quad
31{
32        vertex vtx[6];
33        quad( const nv::ivec2& coorda, const nv::ivec2& coordb, const nv::vec4& color )
34        {
35                vtx[0].color = color;
36                vtx[1].color = color;
37                vtx[2].color = color;
38                vtx[3].color = color;
39                vtx[4].color = color;
40                vtx[5].color = color;
41                vtx[0].coord = coorda;
42                vtx[1].coord = nv::ivec2( coorda.x, coordb.y );
43                vtx[2].coord = coordb;
44                vtx[3].coord = coordb;
45                vtx[4].coord = nv::ivec2( coordb.x, coorda.y );
46                vtx[5].coord = coorda;
47        }
48        quad( const nv::ivec2& coorda, const nv::ivec2& coordb, const nv::ivec2& coordc, const nv::ivec2& coordd, const nv::vec4& color )
49        {
50                vtx[0].color = color;
51                vtx[1].color = color;
52                vtx[2].color = color;
53                vtx[3].color = color;
54                vtx[4].color = color;
55                vtx[5].color = color;
56                vtx[0].coord = coorda;
57                vtx[1].coord = coordb;
58                vtx[2].coord = coordc;
59                vtx[3].coord = coordc;
60                vtx[4].coord = coordd;
61                vtx[5].coord = coorda;
62        }
63
64};
65
66struct app_window
67{
68        app_window( nv::cached_buffer<quad>* cache, const glm::ivec2& a, const glm::ivec2& b, const glm::vec4& color )
[118]69                : m_slice( cache ), m_a( a ), m_b( b ), m_c( color )
[102]70        {
[118]71                create_complex();
[102]72        }
73
74        void change_color( const glm::vec4& color )
75        {
[118]76                m_c = color;
[102]77                glm::vec4 dcolor( color.x * 0.5, color.y * 0.5, color.z * 0.5, 1.0 );
78                std::vector<quad>& v = m_slice.lock();
79                vertex* vtx = (vertex*)v.data();
[118]80                if ( v.size() > 1 )
81                {
82                        for (size_t i = 0; i < (v.size() - 1) * 6; ++i )
83                                vtx[i].color = dcolor;
84                        for (size_t i = (v.size() - 1) * 6; i < (v.size()) * 6; ++i )
85                                vtx[i].color = color;
86                }
87                else
88                {
89                        for (size_t i = 0; i < 6; ++i )
90                                vtx[i].color = color;
91                }
[102]92        }
93
[118]94        void simplify_toggle()
95        {
96                if ( m_slice.data().size() > 1 )
97                {
98                        NV_LOG( nv::LOG_INFO, "Simplifing" );
99                        create_simple();
100                }
101                else
102                {
103                        NV_LOG( nv::LOG_INFO, "Complexifing" );
104                        create_complex();
105                }
106        }
107
108        void create_simple()
109        {
110                std::vector<quad>& v = m_slice.lock();
111                v.clear();
112                v.emplace_back( m_a, m_b, m_c );
113        }
114
115        void create_complex()
116        {
117                glm::vec4 dcolor( m_c.x * 0.5, m_c.y * 0.5, m_c.z * 0.5, 1.0 );
118                std::vector<quad>& v = m_slice.lock();
119                v.clear();
120                nv::ivec2 a2( m_a.x, m_b.y );
121                nv::ivec2 b2( m_b.x, m_a.y );
122                nv::ivec2 t1( 10, 10 );
123                nv::ivec2 t2( -10, 10 );
124                v.emplace_back( m_a - t1, m_a,       b2, b2 - t2, dcolor );
125                v.emplace_back( m_a - t1, a2 + t2, a2, m_a,       dcolor );
126                v.emplace_back( a2 + t2, m_b + t1, m_b, a2, dcolor );
127                v.emplace_back( m_b + t1, b2 - t2, b2, m_b, dcolor );
128                v.emplace_back( m_a, m_b, m_c );
129        }
130
[102]131        void draw()
132        {
133                m_slice.commit();
134        }
135
136        nv::buffer_slice<quad> m_slice;
[118]137        nv::ivec2 m_a;
138        nv::ivec2 m_b;
139        nv::vec4 m_c;
[102]140};
141
142class application
143{
144public:
145        application();
146        bool initialize();
147        bool run();
148        void kill_window();
149        void spawn_window();
[118]150        void simplify_window();
[102]151        void recolor_window();
152        ~application();
153protected:
154        nv::device* m_device;
155        nv::window* m_window;
156        nv::clear_state m_clear_state;
157        nv::render_state m_render_state;
158       
159        nv::cached_buffer<quad>* m_quad_cache;
160        std::vector<app_window>  m_windows;
161
162        nv::program* m_program;
163        nv::vertex_array* m_va;
164        unsigned int m_count;
165        int m_coord_loc;
166        int m_color_loc;
167};
168
169application::application()
170{
171        m_device = new nv::gl_device();
172        m_window = m_device->create_window( 800, 600 );
173
174        m_clear_state.buffers = nv::clear_state::COLOR_AND_DEPTH_BUFFER;
175        m_render_state.depth_test.enabled = false;
176        m_render_state.culling.enabled    = false;
177        m_render_state.blending.enabled   = false;
178        m_render_state.blending.src_rgb_factor   = nv::blending::SRC_ALPHA;
179        m_render_state.blending.dst_rgb_factor   = nv::blending::ONE_MINUS_SRC_ALPHA;
180        m_render_state.blending.src_alpha_factor = nv::blending::SRC_ALPHA;
181        m_render_state.blending.dst_alpha_factor = nv::blending::ONE_MINUS_SRC_ALPHA;
182}
183
184bool application::initialize()
185{
186        {
187                m_program = m_device->create_program( nv::slurp( "cachebuf.vert" ), nv::slurp( "cachebuf.frag" ) );
188                m_va      = m_device->create_vertex_array();
189
190                m_quad_cache = new nv::cached_buffer<quad>( m_device, nv::DYNAMIC_DRAW, 20, true );
191                m_coord_loc  = m_program->get_attribute("coord")->get_location();
192                m_color_loc  = m_program->get_attribute("color")->get_location();
193
194                m_va->add_vertex_buffer( m_coord_loc, (nv::vertex_buffer*)m_quad_cache->get_buffer(), nv::INT,   2, 0, sizeof( vertex ), false );
195                m_va->add_vertex_buffer( m_color_loc, (nv::vertex_buffer*)m_quad_cache->get_buffer(), nv::FLOAT, 4, offset_of( &vertex::color ), sizeof( vertex ), false );
196        }
197        return true;
198}
199
200bool application::run()
201{
202        int keypress = 0;
203        m_program->bind();
204        glm::mat4 projection = glm::ortho( 0.0f, 800.0f, 600.0f, 0.0f, -1.0f, 1.0f );
205        m_program->set_uniform( "projection", glm::mat4(projection) );
206
207        while(!keypress)
208        {
209                for ( auto& w : m_windows )
210                {
211                        w.draw();
212                }
[106]213                if (m_quad_cache->commit() )
214                {
215                        m_va->update_vertex_buffer( m_coord_loc, (nv::vertex_buffer*)m_quad_cache->get_buffer(), false );
216                        m_va->update_vertex_buffer( m_color_loc, (nv::vertex_buffer*)m_quad_cache->get_buffer(), false );
217                }
[102]218
219                m_window->get_context()->clear( m_clear_state );
220                m_program->bind();
221//              m_program->set_uniform( "tex", 0 );
[118]222                m_window->get_context()->draw( nv::TRIANGLES, m_render_state, m_program, m_va, m_quad_cache->get_size() * 6 );
[102]223                m_window->swap_buffers();
224
225                nv::io_event event;
226                while(m_window->poll_event(event))
227                {     
228                        switch (event.type)
229                        {
230                        case nv::EV_QUIT:
231                                keypress = 1;
232                                break;
233                        case nv::EV_KEY:
234                                if (event.key.pressed)
235                                {
236                                        switch (event.key.code)
237                                        {
238                                        case nv::KEY_N      : spawn_window(); break;
[118]239                                        case nv::KEY_S      : simplify_window(); break;
[102]240                                        case nv::KEY_C      : recolor_window(); break;
241                                        case nv::KEY_K      : kill_window(); break;
242                                        case nv::KEY_ESCAPE : keypress = 1; break;
243                                        }
244                                }
245                                break;
246                        }
247                }
248        }
249        return true;
250}
251
252void application::spawn_window()
253{
254        glm::ivec2 a( std::rand() % 600, std::rand() % 400 );
255        glm::ivec2 b( std::rand() % 200, std::rand() % 200 );
256        NV_LOG( nv::LOG_INFO, "Spawn (" << a.x << "," << a.y << "x" << b.x << "," << b.y << ")" );
257        m_windows.emplace_back( m_quad_cache, a, a + b, glm::vec4( 0, 0, 1, 1 ) );
258}
259
260void application::kill_window()
261{
262        if ( m_windows.size() == 0 ) return;
263        size_t index = rand() % m_windows.size();
264        m_windows.erase( m_windows.begin() + index );
265}
[118]266
[102]267void application::recolor_window()
268{
269        if ( m_windows.size() == 0 ) return;
270        size_t index = rand() % m_windows.size();
271        m_windows[ index ].change_color( nv::vec4( (float)rand() / float(RAND_MAX), (float)rand() / float(RAND_MAX), (float)rand() / float(RAND_MAX), 1.0 ) );
272}
273
[118]274void application::simplify_window()
275{
276        if ( m_windows.size() == 0 ) return;
277        size_t index = rand() % m_windows.size();
278        NV_LOG( nv::LOG_INFO, "Simplify " << index );
279        m_windows[ index ].simplify_toggle();
280}
281
[102]282application::~application()
283{
284        m_windows.clear();
285        delete m_quad_cache;
286
287        delete m_program;
288        delete m_va;
289        delete m_window;
290        delete m_device;
291}
292
293
294int main(int, char* [])
295{
296        std::srand((unsigned int) std::time(0) );
297        nv::logger log(nv::LOG_TRACE);
298        log.add_sink( new nv::log_file_sink("log.txt"), nv::LOG_TRACE );
299        log.add_sink( new nv::log_console_sink(), nv::LOG_TRACE );
300       
301        NV_LOG( nv::LOG_NOTICE, "Logging started" );
302        application app;
303        if ( app.initialize() )
304        {
305                app.run();
306        }
307        NV_LOG( nv::LOG_NOTICE, "Logging stopped" );
308
309        return 0;
310}
311
Note: See TracBrowser for help on using the repository browser.