source: trunk/src/rocket/rocket_interface.cc @ 352

Last change on this file since 352 was 352, checked in by epyon, 10 years ago
  • rocket utility classes
  • wx utility classes
  • various utilities
  • handle_test
  • various more changes
File size: 16.6 KB
RevLine 
[352]1#include "nv/rocket/rocket_interface.hh"
2
3#include <nv/interface/context.hh>
4#include <nv/gl/gl_device.hh>
5#include <nv/core/time.hh>
6#include <Rocket/Core.h>
7#include <Rocket/Debugger/Debugger.h>
8
9
10class rocket_c_file_interface : public Rocket::Core::FileInterface
11{
12public:
13        rocket_c_file_interface( const Rocket::Core::String& root ) : root( root ) {}
14        virtual ~rocket_c_file_interface() {}
15        virtual Rocket::Core::FileHandle Open( const Rocket::Core::String& path );
16        virtual void Close( Rocket::Core::FileHandle file );
17        virtual size_t Read( void* buffer, size_t size, Rocket::Core::FileHandle file );
18        virtual bool Seek( Rocket::Core::FileHandle file, long offset, int origin );
19        virtual size_t Tell( Rocket::Core::FileHandle file );
20private:
21        Rocket::Core::String root;
22};
23
24class rocket_sdl2_system_interface : public Rocket::Core::SystemInterface
25{
26public:
27        float GetElapsedTime();
28        bool LogMessage( Rocket::Core::Log::Type type, const Rocket::Core::String& message );
29};
30
31class rocket_sdl2_render_interface : public Rocket::Core::RenderInterface
32{
33public:
34        rocket_sdl2_render_interface( nv::context* context );
35
36        /// Called by Rocket when it wants to render geometry that it does not wish to optimise.
37        virtual void RenderGeometry( Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, Rocket::Core::TextureHandle texture, const Rocket::Core::Vector2f& translation );
38        /// Called by Rocket when it wants to enable or disable scissoring to clip content.
39        virtual void EnableScissorRegion( bool enable );
40        /// Called by Rocket when it wants to change the scissor region.
41        virtual void SetScissorRegion( int x, int y, int width, int height );
42
43        /// Called by Rocket when a texture is required by the library.
44        virtual bool LoadTexture( Rocket::Core::TextureHandle& texture_handle, Rocket::Core::Vector2i& texture_dimensions, const Rocket::Core::String& source );
45        /// Called by Rocket when a texture is required to be built from an internally-generated sequence of pixels.
46        virtual bool GenerateTexture( Rocket::Core::TextureHandle& texture_handle, const Rocket::Core::byte* source, const Rocket::Core::Vector2i& source_dimensions );
47        /// Called by Rocket when a loaded texture is no longer required.
48        virtual void ReleaseTexture( Rocket::Core::TextureHandle texture_handle );
49private:
50        nv::device*      m_device;
51        nv::context*     m_context;
52        nv::program      m_program;
53        nv::scene_state  m_state;
54        nv::render_state m_rstate;
55};
56
57
58static const char *rocket_vertex_shader = R"(
59#version 120
60attribute vec2 nv_position;
61attribute vec2 nv_texcoord;
62attribute vec4 nv_color;
63varying vec4 v_color;
64varying vec2 v_texcoord;
65uniform mat4 nv_m_projection;
66uniform mat4 nv_m_model;
67uniform vec2 texsize;
68void main(void)
69{
70        gl_Position = nv_m_projection * nv_m_model * vec4(nv_position.x, nv_position.y, 0.0, 1.0);
71        v_texcoord  = nv_texcoord; // / texsize;
72        v_color     = nv_color / 256;
73}
74)";
75
76static const char *rocket_fragment_shader = R"(
77#version 120
78varying vec4 v_color;
79varying vec2 v_texcoord;
80uniform sampler2D nv_t_diffuse;
81void main(void)
82{
83        vec4 tex_color = texture2D( nv_t_diffuse, v_texcoord );
84
85        gl_FragColor   = tex_color * v_color;
86}
87)";
88
89Rocket::Core::FileHandle rocket_c_file_interface::Open( const Rocket::Core::String& path )
90{
91        // Attempt to open the file relative to the application's root.
92        FILE* fp = fopen( ( root + path ).CString(), "rb" );
93        if ( fp != NULL )
94                return ( Rocket::Core::FileHandle ) fp;
95
96        // Attempt to open the file relative to the current working directory.
97        fp = fopen( path.CString(), "rb" );
98        return ( Rocket::Core::FileHandle ) fp;
99}
100
101void rocket_c_file_interface::Close( Rocket::Core::FileHandle file )
102{
103        fclose( (FILE*)file );
104}
105
106size_t rocket_c_file_interface::Read( void* buffer, size_t size, Rocket::Core::FileHandle file )
107{
108        return fread( buffer, 1, size, (FILE*)file );
109}
110
111bool rocket_c_file_interface::Seek( Rocket::Core::FileHandle file, long offset, int origin )
112{
113        return fseek( (FILE*)file, offset, origin ) == 0;
114}
115
116size_t rocket_c_file_interface::Tell( Rocket::Core::FileHandle file )
117{
118        return ftell( (FILE*)file );
119}
120
121float rocket_sdl2_system_interface::GetElapsedTime()
122{
123        return nv::get_ticks() / 1000;
124}
125
126bool rocket_sdl2_system_interface::LogMessage( Rocket::Core::Log::Type type, const Rocket::Core::String& message )
127{
128        switch ( type )
129        {
130        case Rocket::Core::Log::LT_ALWAYS: NV_LOG( nv::LOG_NOTICE, message.CString() ); break;
131        case Rocket::Core::Log::LT_ERROR: NV_LOG( nv::LOG_ERROR, message.CString() ); break;
132        case Rocket::Core::Log::LT_ASSERT: NV_LOG( nv::LOG_CRITICAL, message.CString() ); break;
133        case Rocket::Core::Log::LT_WARNING: NV_LOG( nv::LOG_WARNING, message.CString() ); break;
134        case Rocket::Core::Log::LT_INFO: NV_LOG( nv::LOG_INFO, message.CString() ); break;
135        case Rocket::Core::Log::LT_DEBUG: NV_LOG( nv::LOG_DEBUG, message.CString() ); break;
136        case Rocket::Core::Log::LT_MAX: break;
137        };
138
139        return true;
140}
141
142struct rocket_vertex
143{
144        nv::vec2   position;
145        nv::u8vec4 color;
146        nv::vec2   texcoord;
147};
148
149
150union texture_handle_convert
151{
152        Rocket::Core::TextureHandle th;
153        struct
154        {
155                nv::uint16 index;
156                nv::uint16 counter;
157        };
158};
159
160rocket_sdl2_render_interface::rocket_sdl2_render_interface( nv::context* context )
161{
162        m_context = context;
163        m_device = m_context->get_device();
164        m_rstate.depth_test.enabled = false;
165        m_rstate.culling.enabled = false;
166        m_rstate.blending.enabled = true;
167        m_rstate.blending.src_rgb_factor = nv::blending::SRC_ALPHA;
168        m_rstate.blending.dst_rgb_factor = nv::blending::ONE_MINUS_SRC_ALPHA;
169        m_rstate.blending.src_alpha_factor = nv::blending::SRC_ALPHA;
170        m_rstate.blending.dst_alpha_factor = nv::blending::ONE_MINUS_SRC_ALPHA;
171
172        m_program = m_device->create_program( rocket_vertex_shader, rocket_fragment_shader );
173
174        m_state.get_camera().set_ortho( 0.0f, float( 1024 ), float( 728 ), 0.0f );
175}
176
177void rocket_sdl2_render_interface::EnableScissorRegion( bool enable )
178{
179        m_rstate.scissor_test.enabled = enable;
180}
181
182void rocket_sdl2_render_interface::SetScissorRegion( int x, int y, int width, int height )
183{
184        m_rstate.scissor_test.pos.x = x;
185        m_rstate.scissor_test.pos.y = y;
186        m_rstate.scissor_test.dim.x = width;
187        m_rstate.scissor_test.pos.y = height;
188}
189
190bool rocket_sdl2_render_interface::LoadTexture( Rocket::Core::TextureHandle& texture_handle, Rocket::Core::Vector2i& texture_dimensions, const Rocket::Core::String& source )
191{
192        Rocket::Core::FileInterface* file_interface = Rocket::Core::GetFileInterface();
193        Rocket::Core::FileHandle file_handle = file_interface->Open( source );
194        if ( !file_handle )
195                return false;
196
197        file_interface->Seek( file_handle, 0, SEEK_END );
198        size_t buffer_size = file_interface->Tell( file_handle );
199        file_interface->Seek( file_handle, 0, SEEK_SET );
200
201        nv::uint8* buffer = new nv::uint8[buffer_size];
202        file_interface->Read( buffer, buffer_size, file_handle );
203        file_interface->Close( file_handle );
204
205        Rocket::Core::String ext = source.Substring( source.Length() - 3, 3 ).ToLower();
206
207        nv::sampler sampler( nv::sampler::LINEAR, nv::sampler::REPEAT );
208        nv::image_data* data = m_device->create_image_data( buffer, buffer_size );
209        nv::image_format iformat( nv::RGBA, nv::UBYTE );
210        if ( ext == "tga" ) iformat.format = nv::BGRA;
211
212        nv::texture tex = m_device->create_texture( data->get_size(), iformat, sampler, (void*)data->get_data() );
213        texture_dimensions.x = data->get_size().x;
214        texture_dimensions.y = data->get_size().y;
215        delete data;
216
217        typedef nv::handle_operator< nv::texture > op;
218        texture_handle_convert thc;
219        thc.index = op::get_index( tex );
220        thc.counter = op::get_counter( tex );
221        texture_handle = thc.th;
222        NV_LOG( nv::LOG_DEBUG, "load " << source.CString() << " as " << thc.index << "," << thc.counter );
223        return true;
224}
225
226bool rocket_sdl2_render_interface::GenerateTexture( Rocket::Core::TextureHandle& texture_handle, const Rocket::Core::byte* source, const Rocket::Core::Vector2i& source_dimensions )
227{
228        nv::sampler sampler( nv::sampler::LINEAR, nv::sampler::REPEAT );
229        nv::texture tex = m_device->create_texture( nv::ivec2( source_dimensions.x, source_dimensions.y ), nv::image_format( nv::RGBA, nv::UBYTE ), sampler, (void*)source );
230        typedef nv::handle_operator< nv::texture > op;
231        texture_handle_convert thc;
232        thc.index = op::get_index( tex );
233        thc.counter = op::get_counter( tex );
234        texture_handle = thc.th;
235        return true;
236}
237
238void rocket_sdl2_render_interface::ReleaseTexture( Rocket::Core::TextureHandle texture_handle )
239{
240        texture_handle_convert thc;
241        thc.th = texture_handle;
242        typedef nv::handle_operator< nv::texture > op;
243        m_device->release( op::create( thc.index, thc.counter ) );
244}
245
246
247void rocket_sdl2_render_interface::RenderGeometry( Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, Rocket::Core::TextureHandle texture, const Rocket::Core::Vector2f& translation )
248{
249        const nv::texture_info* info = nullptr;
250        if ( texture != 0 )
251        {
252                texture_handle_convert thc;
253                thc.th = texture;
254                typedef nv::handle_operator< nv::texture > op;
255                nv::texture tex( op::create( thc.index, thc.counter ) );
256                m_context->bind( tex, nv::TEX_DIFFUSE );
257                info = m_device->get_texture_info( tex );
258        }
259        else
260        {
261                m_context->bind( nv::texture(), nv::TEX_DIFFUSE );
262                return;
263        }
264
265        rocket_vertex* rv = (rocket_vertex*)vertices;
266
267        nv::vertex_array m_va = m_context->create_vertex_array( rv, num_vertices, (unsigned*)indices, num_indices, nv::STATIC_DRAW );
268        //if ( info )   m_device->set_uniform( m_program, "texsize", nv::vec2( info->size ) );
269        m_state.set_model( glm::translate( glm::mat4(), nv::vec3( translation.x, translation.y, 0.0f ) ) );
270        m_context->draw( nv::TRIANGLES, m_rstate, m_state, m_program, m_va, num_indices );
271        m_context->release( m_va );
272
273}
274
275/*
276int RocketSDL2SystemInterface::TranslateMouseButton( Uint8 button )
277{
278        switch ( button )
279        {
280        case SDL_BUTTON_LEFT:
281                return 0;
282        case SDL_BUTTON_RIGHT:
283                return 1;
284        case SDL_BUTTON_MIDDLE:
285                return 2;
286        default:
287                return 3;
288        }
289}
290
291int RocketSDL2SystemInterface::GetKeyModifiers()
292{
293        SDL_Keymod sdlMods = SDL_GetModState();
294
295        int retval = 0;
296
297        if ( sdlMods & KMOD_CTRL )
298                retval |= Rocket::Core::Input::KM_CTRL;
299
300        if ( sdlMods & KMOD_SHIFT )
301                retval |= Rocket::Core::Input::KM_SHIFT;
302
303        if ( sdlMods & KMOD_ALT )
304                retval |= Rocket::Core::Input::KM_ALT;
305
306        return retval;
307}
308
309*/
310
311int rocket_get_key_modifiers()
312{
313        return 0;
314}
315
316int rocket_get_mouse_buttons( const nv::mouse_button_event& button )
317{
318        return 0;
319}
320
321Rocket::Core::Input::KeyIdentifier rocket_translate_key( const nv::key_event& key )
322{
323        using namespace Rocket::Core::Input;
324
325        switch ( key.code )
326        {
327        case nv::KEY_NONE  : return KI_UNKNOWN;
328        case nv::KEY_SPACE : return KI_SPACE;
329        case nv::KEY_0: return KI_0;
330        case nv::KEY_1: return KI_1;
331        case nv::KEY_2: return KI_2;
332        case nv::KEY_3: return KI_3;
333        case nv::KEY_4: return KI_4;
334        case nv::KEY_5: return KI_5;
335        case nv::KEY_6: return KI_6;
336        case nv::KEY_7: return KI_7;
337        case nv::KEY_8: return KI_8;
338        case nv::KEY_9: return KI_9;
339        case nv::KEY_A: return KI_A;
340        case nv::KEY_B: return KI_B;
341        case nv::KEY_C: return KI_C;
342        case nv::KEY_D: return KI_D;
343        case nv::KEY_E: return KI_E;
344        case nv::KEY_F: return KI_F;
345        case nv::KEY_G: return KI_G;
346        case nv::KEY_H: return KI_H;
347        case nv::KEY_I: return KI_I;
348        case nv::KEY_J: return KI_J;
349        case nv::KEY_K: return KI_K;
350        case nv::KEY_L: return KI_L;
351        case nv::KEY_M: return KI_M;
352        case nv::KEY_N: return KI_N;
353        case nv::KEY_O: return KI_O;
354        case nv::KEY_P: return KI_P;
355        case nv::KEY_Q: return KI_Q;
356        case nv::KEY_R: return KI_R;
357        case nv::KEY_S: return KI_S;
358        case nv::KEY_T: return KI_T;
359        case nv::KEY_U: return KI_U;
360        case nv::KEY_V: return KI_V;
361        case nv::KEY_W: return KI_W;
362        case nv::KEY_X: return KI_X;
363        case nv::KEY_Y: return KI_Y;
364        case nv::KEY_Z: return KI_Z;
365        case nv::KEY_SCOLON:return KI_OEM_1;
366//      case nv::KEY_PLUS:return KI_OEM_PLUS;
367        case nv::KEY_COMMA:return KI_OEM_COMMA;
368        case nv::KEY_MINUS:return KI_OEM_MINUS;
369        case nv::KEY_PERIOD:return KI_OEM_PERIOD;
370        case nv::KEY_SLASH:return KI_OEM_2;
371        case nv::KEY_BQUOTE:return KI_OEM_3;
372        case nv::KEY_LBRACKET:return KI_OEM_4;
373        case nv::KEY_BSLASH:return KI_OEM_5;
374        case nv::KEY_RBRACKET:return KI_OEM_6;
375//      case nv::KEY_QUOTEDBL:return KI_OEM_7;
376//      case nv::KEY_KP_0:return KI_NUMPAD0;
377//      case nv::KEY_KP_1:return KI_NUMPAD1;
378//      case nv::KEY_KP_2:return KI_NUMPAD2;
379//      case nv::KEY_KP_3:return KI_NUMPAD3;
380//      case nv::KEY_KP_4:return KI_NUMPAD4;
381//      case nv::KEY_KP_5:return KI_NUMPAD5;
382//      case nv::KEY_KP_6:return KI_NUMPAD6;
383//      case nv::KEY_KP_7:return KI_NUMPAD7;
384//      case nv::KEY_KP_8:return KI_NUMPAD8;
385//      case nv::KEY_KP_9:return KI_NUMPAD9;
386//      case nv::KEY_KP_ENTER:return KI_NUMPADENTER;
387//      case nv::KEY_KP_MULTIPLY:return KI_MULTIPLY;
388//      case nv::KEY_KP_PLUS:return KI_ADD;
389//      case nv::KEY_KP_MINUS: return KI_SUBTRACT;
390//      case nv::KEY_KP_PERIOD: return KI_DECIMAL;
391//      case nv::KEY_KP_DIVIDE: return KI_DIVIDE;
392//      case nv::KEY_KP_EQUALS: return KI_OEM_NEC_EQUAL;
393        case nv::KEY_BACK    : return KI_BACK;
394        case nv::KEY_TAB     : return KI_TAB;
395//      case nv::KEY_CLEAR   : return KI_CLEAR;
396        case nv::KEY_ENTER   : return KI_RETURN;
397//      case nv::KEY_PAUSE   : return KI_PAUSE;
398//      case nv::KEY_CAPSLOCK: return KI_CAPITAL;
399        case nv::KEY_PGUP  : return KI_PRIOR;
400        case nv::KEY_PGDOWN: return KI_NEXT;
401        case nv::KEY_END   : return KI_END;
402        case nv::KEY_HOME  : return KI_HOME;
403        case nv::KEY_LEFT  : return KI_LEFT;
404        case nv::KEY_UP    : return KI_UP;
405        case nv::KEY_RIGHT : return KI_RIGHT;
406        case nv::KEY_DOWN  : return KI_DOWN;
407        case nv::KEY_INSERT: return KI_INSERT;
408        case nv::KEY_DELETE: return KI_DELETE;
409        case nv::KEY_F1    : return KI_F1;
410        case nv::KEY_F2    : return KI_F2;
411        case nv::KEY_F3    : return KI_F3;
412        case nv::KEY_F4    : return KI_F4;
413        case nv::KEY_F5    : return KI_F5;
414        case nv::KEY_F6    : return KI_F6;
415        case nv::KEY_F7    : return KI_F7;
416        case nv::KEY_F8    : return KI_F8;
417        case nv::KEY_F9    : return KI_F9;
418        case nv::KEY_F10   : return KI_F10;
419        case nv::KEY_F11   : return KI_F11;
420        case nv::KEY_F12   : return KI_F12;
421//      case nv::KEY_F13 : return KI_F13;
422//      case nv::KEY_F14 : return KI_F14;
423//      case nv::KEY_F15 : return KI_F15;
424//      case nv::KEY_NUMLOCKCLEAR : return KI_NUMLOCK;
425//      case nv::KEY_SCROLLLOCK : return KI_SCROLL;
426//      case nv::KEY_LSHIFT  : return KI_LSHIFT;
427//      case nv::KEY_RSHIFT  : return KI_RSHIFT;
428//      case nv::KEY_LCTRL   : return KI_LCONTROL;
429//      case nv::KEY_RCTRL   : return KI_RCONTROL;
430//      case nv::KEY_LALT    : return KI_LMENU;
431//      case nv::KEY_RALT    : return KI_RMENU;
432//      case nv::KEY_LGUI    : return KI_LMETA;
433//      case nv::KEY_RGUI    : return KI_RMETA;
434//      case nv::KEY_LSUPER  : return KI_LWIN;
435//  case nv::KEY_RSUPER  : return KI_RWIN;
436        default: return KI_UNKNOWN;
437        }
438
439        return KI_UNKNOWN;
440}
441
442static rocket_sdl2_render_interface* s_render_interface = nullptr;
443static rocket_sdl2_system_interface* s_system_interface = nullptr;
444static rocket_c_file_interface*      s_file_interface   = nullptr;
445
446bool nv::rocket_event( void* context, nv::io_event& event )
447{
448        Rocket::Core::Context *Context = ( Rocket::Core::Context * )context;
449        switch ( event.type )
450        {
451        case nv::EV_MOUSE_MOVE :
452                Context->ProcessMouseMove( event.mmove.x, event.mmove.y, rocket_get_key_modifiers() );
453                break;
454        case nv::EV_MOUSE_BUTTON :
455                if ( event.mbutton.pressed )
456                        Context->ProcessMouseButtonDown( rocket_get_mouse_buttons( event.mbutton ), rocket_get_key_modifiers() );
457                else
458                        Context->ProcessMouseButtonUp( rocket_get_mouse_buttons( event.mbutton ), rocket_get_key_modifiers() );
459                break;
460        case nv::EV_MOUSE_WHEEL:
461                return Context->ProcessMouseWheel( event.mwheel.y, rocket_get_key_modifiers() );
462        case nv::EV_KEY:
463                if (event.key.pressed)
464                {
465                        if ( event.key.code == KEY_BQUOTE )
466                        {
467                                Rocket::Debugger::SetVisible( !Rocket::Debugger::IsVisible() );
468                                return true;
469                        }
470
471                        return Context->ProcessKeyDown( rocket_translate_key( event.key ) , rocket_get_key_modifiers() );
472                }
473                break;
474        default:
475                break;
476        }
477        return false;
478}
479
480bool nv::rocket_initialize( nv::window* w, const char* assets_root )
481{
482        s_render_interface = new rocket_sdl2_render_interface( w->get_context() );
483        s_system_interface = new rocket_sdl2_system_interface();
484        s_file_interface   = new rocket_c_file_interface( assets_root );
485
486        Rocket::Core::SetFileInterface( s_file_interface );
487        Rocket::Core::SetRenderInterface( s_render_interface );
488        Rocket::Core::SetSystemInterface( s_system_interface );
489
490        return Rocket::Core::Initialise();
491}
492
493void nv::rocket_shutdown()
494{
495        Rocket::Core::Shutdown();
496        delete s_render_interface;
497        delete s_system_interface;
498        delete s_file_interface;
499}
Note: See TracBrowser for help on using the repository browser.