source: trunk/tests/md5_test/md5_test.cc @ 239

Last change on this file since 239 was 239, checked in by epyon, 11 years ago
  • massive update of mesh handling
  • universal mesh handling routines
  • removed a lot of legacy code
  • significantly streamlined MD5 loading
  • all tests updated to new features
File size: 6.5 KB
Line 
1#include <nv/common.hh>
2#include <iomanip>
3#include <nv/gfx/keyframed_mesh.hh>
4#include <nv/interface/vertex_buffer.hh>
5#include <nv/gl/gl_device.hh>
6#include <nv/gfx/image.hh>
7#include <nv/interface/context.hh>
8#include <nv/interface/window.hh>
9#include <nv/interface/program.hh>
10#include <nv/interface/texture2d.hh>
11#include <nv/interface/mesh_loader.hh>
12#include <nv/io/c_file_system.hh>
13#include <nv/formats/md5_loader.hh>
14#include <nv/profiler.hh>
15#include <nv/logging.hh>
16#include <nv/logger.hh>
17#include <nv/math.hh>
18#include <nv/time.hh>
19#include <nv/string.hh>
20#include <nv/gfx/skeletal_mesh.hh>
21#include <glm/gtx/rotate_vector.hpp>
22#include <glm/gtc/matrix_access.hpp>
23#include <glm/gtx/matrix_interpolation.hpp>
24
25class application
26{
27public:
28        application();
29        bool initialize();
30        bool run();
31        ~application();
32protected:
33        void load_animation( const std::string& path );
34protected:
35
36
37        nv::device*       m_device;
38        nv::window*       m_window;
39        nv::texture2d*    m_diffuse;
40        nv::texture2d*    m_specular;
41        nv::texture2d*    m_normal;
42        nv::clear_state   m_clear_state;
43        nv::render_state  m_render_state;
44        nv::scene_state   m_scene_state;
45
46        nv::skeletal_mesh* m_mesh;
47        nv::program*       m_program;
48        nv::md5_mesh_data* m_mesh_data;
49        nv::md5_animation* m_animation;
50
51};
52
53application::application()
54{
55        NV_PROFILE( "app_construct" );
56        m_device = new nv::gl_device();
57        m_window = m_device->create_window( 800, 600, false );
58        m_animation = nullptr;
59
60        nv::sampler sampler( nv::sampler::LINEAR, nv::sampler::REPEAT );
61        nv::image_data* data = m_device->create_image_data( "data/qshambler_d.png" );
62        m_diffuse  = m_device->create_texture2d( data->get_size(), nv::RGBA, nv::UBYTE, sampler, (void*)data->get_data() );
63        delete data;
64        data = m_device->create_image_data( "data/qshambler_s.png" );
65        m_specular = m_device->create_texture2d( data->get_size(), nv::RGBA, nv::UBYTE, sampler, (void*)data->get_data() );
66        delete data;
67
68        data = m_device->create_image_data( "data/qshambler_local.png" );
69        m_normal = m_device->create_texture2d( data->get_size(), nv::RGBA, nv::UBYTE, sampler, (void*)data->get_data() );
70        delete data;
71
72        m_clear_state.buffers = nv::clear_state::COLOR_AND_DEPTH_BUFFER;
73        m_render_state.depth_test.enabled = true;
74        m_render_state.culling.enabled    = true;
75        m_render_state.culling.order      = nv::culling::CCW;
76        m_render_state.blending.enabled   = false;
77        m_render_state.blending.src_rgb_factor   = nv::blending::SRC_ALPHA;
78        m_render_state.blending.dst_rgb_factor   = nv::blending::ONE_MINUS_SRC_ALPHA;
79        m_render_state.blending.src_alpha_factor = nv::blending::SRC_ALPHA;
80        m_render_state.blending.dst_alpha_factor = nv::blending::ONE_MINUS_SRC_ALPHA;
81}
82
83bool application::initialize()
84{
85        NV_PROFILE( "app_initialize" );
86        m_program = m_device->create_program( nv::slurp( "md5.vert" ), nv::slurp( "md5.frag" ) );
87
88        nv::md5_loader* loader = nullptr;
89        {
90                NV_PROFILE("loader->load");
91                nv::c_file_system fs;
92                nv::stream* mesh_file = fs.open( "data/qshambler.md5mesh" );
93                loader = new nv::md5_loader();
94                loader->load( *mesh_file );
95                delete mesh_file;
96        }
97
98        {
99                NV_PROFILE("create_mesh");
100                m_mesh_data = (nv::md5_mesh_data*)loader->release_mesh_data();
101                m_mesh = new nv::skeletal_mesh( m_window->get_context(), m_mesh_data );
102                delete loader;
103        }
104
105        load_animation( "data/idle02.md5anim" );
106        return true;
107}
108
109bool application::run()
110{
111        nv::profiler::pointer()->log_report();
112        NV_PROFILE( "app_run" );
113        int keypress = 0;
114
115        glm::vec3 move( 0, 50.f, 0 );
116
117        nv::uint32 ticks   = m_device->get_ticks();
118        nv::uint32 last_ticks;
119        nv::fps_counter_class< nv::system_us_timer > fps_counter;
120
121        //m_mesh->setup_animation( 0, m_mesh->get_max_frames(), 2, true );
122
123        while(!keypress)
124        {
125                last_ticks = ticks;
126                ticks      = m_device->get_ticks();
127                nv::uint32 elapsed = ticks - last_ticks;
128                m_mesh->update( elapsed );
129                {
130                        NV_PROFILE( "clear" );
131                        m_window->get_context()->clear( m_clear_state );
132                }
133
134                {
135                        NV_PROFILE( "update_sh" );
136
137                        glm::vec3 source( 150.0f, 0.0f, 0.0f );
138                        glm::vec3 eye = glm::rotate( source, (ticks / 20.f), glm::vec3( 0.0,1.0,0.0 ) );
139
140                        m_scene_state.get_camera().set_lookat(eye + move, glm::vec3(0.0f, 0.0f, 0.0f) + move, glm::vec3(0.0, 1.0, 0.0));
141                        m_scene_state.get_camera().set_perspective(60.0f, 1.0f*800.0f/600.0f, 0.1f, 1000.0f);
142
143                        m_diffuse ->bind( 0 );
144                        m_specular->bind( 1 );
145                        m_normal  ->bind( 2 );
146                        m_program->set_opt_uniform( "light_position", glm::vec3(180.0, 180.0, 0) );
147                        m_program->set_opt_uniform( "light_diffuse",  glm::vec4(0.7,0.7,0.7,1.0) );
148                        m_program->set_opt_uniform( "light_specular", glm::vec4(1.0,1.0,1.0,1.0) );
149                }
150
151                {
152                        NV_PROFILE( "draw" );
153                        m_scene_state.set_model(nv::mat4(
154                                1.f,0.f,0.f,0.f,
155                                0.f,0.f,1.f,0.f,
156                                0.f,1.f,0.f,0.f,
157                                0.f,0.f,0.f,1.f
158                        ) );
159
160                        m_window->get_context()->draw( m_render_state, m_scene_state, m_program, m_mesh );
161                }
162
163                {
164                        NV_PROFILE( "swap" );
165                        m_window->swap_buffers();
166                }
167
168                {
169                        NV_PROFILE( "pollevent" );
170                        nv::io_event event;
171                        while(m_window->poll_event(event))
172                        {     
173                                switch (event.type)
174                                {
175                                case nv::EV_QUIT:
176                                        keypress = 1;
177                                        break;
178                                case nv::EV_KEY:
179                                        if (event.key.pressed)
180                                        {
181                                                switch (event.key.code)
182                                                {
183                                                case nv::KEY_ESCAPE : keypress = 1; break;
184                                                case nv::KEY_F1 : nv::profiler::pointer()->log_report(); break;
185                                                default: break;
186                                                }
187                                        }
188                                        break;
189                                default: break;
190                                }
191                        }
192                }
193                fps_counter.tick();
194        }
195        return true;
196}
197
198void application::load_animation( const std::string& path )
199{
200        delete m_animation;
201        m_animation = nullptr;
202        NV_PROFILE("load_animation");
203        nv::c_file_system fs;
204        nv::stream* anim_file = fs.open( path.c_str() );
205
206        if ( anim_file != nullptr )
207        {
208                m_animation = new nv::md5_animation();
209                if ( !m_animation->load_animation(*anim_file) )
210                {
211                        delete m_animation;
212                        m_animation = nullptr;
213                }
214                m_mesh->setup_animation( m_animation );
215                delete anim_file;
216        }
217}
218
219
220application::~application()
221{
222        delete m_program;
223        delete m_mesh;
224        delete m_diffuse;
225        delete m_window;
226        delete m_device;
227}
228
229
230int main(int, char* [])
231{
232        nv::logger log(nv::LOG_TRACE);
233        log.add_sink( new nv::log_file_sink("log.txt"), nv::LOG_TRACE );
234        log.add_sink( new nv::log_console_sink(), nv::LOG_TRACE );
235       
236        NV_LOG( nv::LOG_NOTICE, "Logging started" );
237        application app;
238        if ( app.initialize() )
239        {
240                app.run();
241        }
242        NV_LOG( nv::LOG_NOTICE, "Logging stopped" );
243
244        return 0;
245}
246
Note: See TracBrowser for help on using the repository browser.