Changeset 354
- Timestamp:
- 04/15/15 15:37:04 (10 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/nv/gui/gui_environment.hh
r351 r354 30 30 { 31 31 public: 32 environment( window* w);32 environment( renderer* r ); 33 33 // temporary 34 34 void load_style( const std::string& filename ); … … 61 61 handle_store< element, handle > m_elements; 62 62 renderer* m_renderer; 63 window* m_window;64 63 handle m_screen; 65 rectangle m_area;66 64 position m_mouse_position; 67 65 handle m_selected; -
trunk/nv/gui/gui_renderer.hh
r351 r354 6 6 7 7 /** 8 * @file gui_ element.hh8 * @file gui_renderer.hh 9 9 * @author Kornel Kisielewicz 10 10 * @brief GUI Renderer … … 18 18 #include <nv/gui/gui_common.hh> 19 19 #include <nv/gui/gui_style.hh> 20 #include <nv/interface/window.hh>21 #include <nv/interface/device.hh>22 #include <nv/interface/context.hh>23 #include <nv/interface/camera.hh>24 #include <nv/gfx/sliced_buffer.hh>25 #include <nv/gfx/texture_atlas.hh>26 #include <nv/gfx/texture_font.hh>27 20 28 21 namespace nv … … 30 23 namespace gui 31 24 { 32 struct image_info33 {34 vec2 t1;35 vec2 t2;36 ivec2 size;37 38 image_info() {}39 image_info( const nv::vec2 tex1, const nv::vec2 tex2, const nv::ivec2 s )40 : t1( tex1 ), t2( tex2 ), size( s ) {}41 };42 43 25 class renderer 44 26 { 45 27 public: 46 renderer( window* w ); 47 texture_font* get_font( size_t name ) const; 48 const image_info* get_image( size_t name ) const; 49 void load_style( const std::string& filename ); 50 size_t load_font( const std::string& filename, size_t size ); 51 size_t load_image( const std::string& filename ); 52 void redraw( element* e, uint32 ); 53 void draw( element* e ); 54 void draw(); 55 void on_hover_change( element* e, bool hover ); 56 void on_select_change( element* e, bool select ); 57 virtual ~renderer(); 58 private: 59 typedef std::unordered_map< std::string, size_t > names; 60 typedef std::vector< texture_font* > font_vector; 61 typedef std::vector< image_info > image_vector; 62 63 context* m_context; 64 window* m_window; 65 style m_style; 66 rectangle m_area; 67 names m_image_names; 68 image_vector m_images; 69 names m_font_names; 70 font_vector m_fonts; 71 texture_atlas m_atlas; 72 bool m_reupload; 73 74 scene_state m_scene_state; 75 render_state m_render_state; 76 render_data* m_render_data; 28 renderer() {} 29 virtual void load_style( const std::string& filename ); 30 virtual void redraw( element* e, uint32 ) = 0; 31 virtual void draw( element* e ) = 0; 32 virtual void draw() = 0; 33 virtual void on_hover_change( element* e, bool hover ) = 0; 34 virtual void on_select_change( element* e, bool select ) = 0; 35 virtual rectangle get_area() const = 0; 36 virtual ~renderer() {} 37 protected: 38 style m_style; 77 39 }; 78 40 -
trunk/src/gui/gui_environment.cc
r351 r354 22 22 */ 23 23 24 #include "nv/gfx/sliced_buffer.hh" 25 #include "nv/gfx/texture_atlas.hh" 26 27 nv::gui::environment::environment( window* w ) 28 : m_renderer( nullptr ), m_window( w ) 29 { 30 m_area.dim( dimension( w->get_width(), w->get_height() ) ); 31 m_renderer = new renderer( w ); 32 m_screen = create_element( handle(), m_area ); 24 25 nv::gui::environment::environment( renderer* r ) 26 : m_renderer( r ) 27 { 28 m_screen = create_element( handle(), m_renderer->get_area() ); 33 29 } 34 30 … … 47 43 if ( parent.is_nil() ) parent = m_screen; 48 44 49 handle result = m_elements.create(); 50 element* e = m_elements.get( result ); 51 rectangle ar = r; 52 53 if ( ar.ul.x < 0 ) { ar.ul.x += m_area.lr.x; ar.lr.x += m_area.lr.x; } 54 if ( ar.ul.y < 0 ) { ar.ul.y += m_area.lr.y; ar.lr.y += m_area.lr.y; } 45 handle result = m_elements.create(); 46 element* e = m_elements.get( result ); 47 rectangle ar = r; 48 rectangle full = m_renderer->get_area(); 49 50 if ( ar.ul.x < 0 ) { ar.ul.x += full.lr.x; ar.lr.x += full.lr.x; } 51 if ( ar.ul.y < 0 ) { ar.ul.y += full.lr.y; ar.lr.y += full.lr.y; } 55 52 56 53 e->m_child_count = 0; -
trunk/src/gui/gui_renderer.cc
r351 r354 7 7 #include "nv/gui/gui_renderer.hh" 8 8 9 #include <glm/gtc/matrix_transform.hpp> 10 11 #include "nv/interface/device.hh" 12 #include "nv/interface/context.hh" 13 #include "nv/core/logging.hh" 14 15 static const char *nv_gui_vertex_shader = R"( 16 #version 120 17 attribute vec2 nv_position; 18 attribute vec2 nv_texcoord; 19 attribute vec4 nv_color; 20 varying vec4 v_color; 21 varying vec2 v_texcoord; 22 uniform mat4 nv_m_projection; 23 void main(void) 24 { 25 gl_Position = nv_m_projection * vec4(nv_position.x, nv_position.y, 0.0, 1.0); 26 v_texcoord = nv_texcoord; 27 v_color = nv_color; 28 } 29 )"; 30 31 static const char *nv_gui_fragment_shader = R"( 32 #version 120 33 varying vec4 v_color; 34 varying vec2 v_texcoord; 35 uniform sampler2D nv_t_diffuse; 36 void main(void) 37 { 38 vec4 tex_color = texture2D( nv_t_diffuse, v_texcoord ); 39 gl_FragColor = v_color * tex_color; 40 } 41 )"; 42 43 44 using namespace nv; 45 using namespace nv::gui; 46 47 struct vertex 48 { 49 ivec2 position; 50 vec2 texcoord; 51 vec4 color; 52 vertex() {} 53 vertex( const nv::ivec2& cr, const nv::vec2& tc, const nv::vec4& c ) 54 : position( cr ), texcoord( tc ), color( c ) 55 { 56 } 57 }; 58 59 const ivec2 atlas_size = ivec2( 1024, 1024 ); 60 61 struct gui_quad 62 { 63 vertex vtx[6]; 64 gui_quad( const nv::ivec2& coorda, const nv::ivec2& coordb, const nv::vec4& color ) 65 { 66 set_color( color ); 67 vtx[0].position = coorda; 68 vtx[1].position = nv::ivec2( coorda.x, coordb.y ); 69 vtx[2].position = coordb; 70 vtx[3].position = coordb; 71 vtx[4].position = nv::ivec2( coordb.x, coorda.y ); 72 vtx[5].position = coorda; 73 } 74 gui_quad( const nv::ivec2& coorda, const nv::ivec2& coordb, const nv::vec4& color, const nv::vec2& tcoorda, const nv::vec2& tcoordb ) 75 { 76 set_color( color ); 77 vtx[0].position = coorda; 78 vtx[1].position = nv::ivec2( coorda.x, coordb.y ); 79 vtx[2].position = coordb; 80 vtx[3].position = coordb; 81 vtx[4].position = nv::ivec2( coordb.x, coorda.y ); 82 vtx[5].position = coorda; 83 vtx[0].texcoord = tcoorda; 84 vtx[1].texcoord = nv::vec2( tcoorda.x, tcoordb.y ); 85 vtx[2].texcoord = tcoordb; 86 vtx[3].texcoord = tcoordb; 87 vtx[4].texcoord = nv::vec2( tcoordb.x, tcoorda.y ); 88 vtx[5].texcoord = tcoorda; 89 } 90 gui_quad( const nv::ivec2& coorda, const nv::ivec2& coordb, const nv::ivec2& coordc, const nv::ivec2& coordd, const nv::vec4& color ) 91 { 92 set_color( color ); 93 vtx[0].position = coorda; 94 vtx[1].position = coordb; 95 vtx[2].position = coordc; 96 vtx[3].position = coordc; 97 vtx[4].position = coordd; 98 vtx[5].position = coorda; 99 } 100 inline void set_color( const nv::vec4& color ) 101 { 102 vtx[0].color = color; vtx[1].color = color; vtx[2].color = color; 103 vtx[3].color = color; vtx[4].color = color; vtx[5].color = color; 104 } 105 }; 106 107 108 class screen_render_data : public render_data 109 { 110 public: 111 screen_render_data( context* actx, size_t initial_size ) 112 : buffer( actx, VERTEX_BUFFER, DYNAMIC_DRAW, initial_size ), ctx( actx ), varray(), shader() 113 { 114 115 } 116 ~screen_render_data() 117 { 118 ctx->get_device()->release( shader ); 119 ctx->release( varray ); 120 } 121 122 nv::sliced_buffer<gui_quad> buffer; 123 nv::context* ctx; 124 nv::texture tex; 125 nv::vertex_array varray; 126 nv::program shader; 127 }; 128 129 class element_render_data : public render_data 130 { 131 public: 132 element_render_data( nv::sliced_buffer<gui_quad>* cbuffer ) 133 : buffer( cbuffer ) {} 134 135 nv::buffer_slice< gui_quad > buffer; 136 }; 137 138 renderer::renderer( window* w ) 139 : m_window(w) 140 , m_style() 141 , m_atlas( atlas_size, 4 ) 142 , m_reupload( true ) 143 { 144 NV_LOG( LOG_TRACE, "Creating GUI renderer..." ); 145 m_context = w->get_context(); 146 m_area.dim( dimension( w->get_width(), w->get_height() ) ); 147 region white = m_atlas.get_region( ivec2(3,3) ); 148 size_t wsize = m_atlas.get_depth()*4*4; 149 uint8* wfill = new uint8[m_atlas.get_depth()*4*4]; 150 std::fill( wfill, wfill + wsize, 255 ); 151 white.pos = ivec2(); 152 m_atlas.set_region( white, wfill ); 153 delete[] wfill; 154 155 NV_LOG( LOG_TRACE, "Creating render data..." ); 156 screen_render_data* sr = new screen_render_data( w->get_context(), 1024 ); 157 m_render_data = sr; 158 sr->shader = m_window->get_device()->create_program( nv_gui_vertex_shader, nv_gui_fragment_shader ); 159 m_scene_state.get_camera().set_ortho( 0.0f, float( m_window->get_width() ), float( m_window->get_height() ), 0.0f ); 160 161 sr->varray = m_window->get_context()->create_vertex_array(); 162 buffer vb = sr->buffer.get_buffer(); 163 m_window->get_context()->add_vertex_buffers< vertex >( sr->varray, vb ); 164 165 nv::sampler sampler( nv::sampler::LINEAR, nv::sampler::CLAMP_TO_EDGE ); 166 sr->tex = m_window->get_device()->create_texture( m_atlas.get_size(), image_format( nv::RGBA, nv::UBYTE ), sampler, nullptr ); 167 168 m_render_state.depth_test.enabled = false; 169 m_render_state.culling.enabled = false; 170 m_render_state.blending.enabled = true; 171 m_render_state.blending.src_rgb_factor = blending::SRC_ALPHA; 172 m_render_state.blending.dst_rgb_factor = blending::ONE_MINUS_SRC_ALPHA; 173 m_render_state.blending.src_alpha_factor = blending::SRC_ALPHA; 174 m_render_state.blending.dst_alpha_factor = blending::ONE_MINUS_SRC_ALPHA; 175 NV_LOG( LOG_TRACE, "GUI Renderer created" ); 176 } 177 178 texture_font* renderer::get_font( size_t name ) const 179 { 180 if ( name >= m_fonts.size() ) return nullptr; 181 return m_fonts[ name ]; 182 } 183 184 const image_info* renderer::get_image( size_t name ) const 185 { 186 if ( name >= m_images.size() ) return nullptr; 187 return &m_images[ name ]; 188 } 189 190 size_t renderer::load_font( const std::string& filename, size_t size ) 191 { 192 std::string id_name( filename ); 193 id_name.append( to_string( size ) ); 194 auto i = m_font_names.find( id_name ); 195 if ( i != m_font_names.end() ) 196 { 197 return i->second; 198 } 199 size_t result = (size_t)m_fonts.size(); 200 texture_font* f = new texture_font( &m_atlas, filename.c_str(), (float)size ); 201 f->load_glyphs( "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ " ); 202 m_fonts.push_back( f ); 203 m_reupload = true; 204 m_font_names[ id_name ] = result; 205 return result; 206 } 207 208 size_t renderer::load_image( const std::string& filename ) 209 { 210 auto i = m_image_names.find( filename ); 211 if ( i != m_image_names.end() ) 212 { 213 return i->second; 214 } 215 size_t result = m_images.size(); 216 image_data* data = m_window->get_device()->create_image_data( filename ); 217 // TODO: Repitching 218 assert( data->get_depth() == 4 ); 219 region r = m_atlas.get_region( data->get_size() ); 220 m_atlas.set_region( r, data->get_data() ); 221 m_images.emplace_back( vec2( r.pos ) / vec2( atlas_size ), vec2( r.size + r.pos ) / vec2( atlas_size ), r.size ); 222 delete data; 223 m_reupload = true; 224 m_image_names[ filename ] = result; 225 return result; 226 } 227 228 void renderer::load_style( const std::string& filename ) 9 void nv::gui::renderer::load_style( const std::string& filename ) 229 10 { 230 11 m_style.load_style( filename ); 231 12 } 232 233 void renderer::redraw( element* e, uint32 )234 {235 screen_render_data* sr = (screen_render_data*)m_render_data;236 if ( e->m_render_data == nullptr )237 {238 e->m_render_data = new element_render_data( &sr->buffer );239 }240 element_render_data* er = (element_render_data*)(e->m_render_data);241 size_t size_before = er->buffer.data().size();242 243 std::vector< gui_quad >& qvec = er->buffer.lock();244 245 qvec.clear();246 rectangle abs = e->m_absolute;247 if ( e->m_absolute != m_area )248 {249 int border = 0;250 vec4 color;251 std::string path;252 std::string text;253 const char* stext[] = { nullptr, "selected", "hover" };254 const char* selector = stext[border];255 if ( e->m_flags[HOVER] ) selector = stext[2];256 if ( e->m_flags[SELECTED] ) selector = stext[1];257 258 if ( m_style.get( e, "skin", selector, path ) )259 {260 size_t image_id = load_image( path );261 const image_info* image = get_image( image_id );262 if ( image )263 {264 color = vec4( 2, 2, 2, 1 );265 ivec2 isize3 = image->size / 3;266 ivec2 isize3x = ivec2( isize3.x, 0 );267 ivec2 isize3y = ivec2( 0, isize3.y );268 vec2 tsize = ( image->t2 - image->t1 );269 vec2 tsize3 = ( image->t2 - image->t1 ) / 3.0f;270 vec2 tsize32 = ( image->t2 - image->t1 ) * ( 2.0f / 3.0f );271 vec2 tsizex = vec2( tsize.x, 0.0f );272 vec2 tsizey = vec2( 0.0f, tsize.y );273 vec2 tsize3x = vec2( tsize3.x, 0.0f );274 vec2 tsize3y = vec2( 0.0f, tsize3.y );275 vec2 tsize3x2 = vec2( tsize32.x, 0.0f );276 vec2 tsize3y2 = vec2( 0.0f, tsize32.y );277 278 rectangle inner = abs.shrinked( isize3 );279 qvec.emplace_back( abs.ul, inner.ul, color, image->t1, image->t1+tsize3 );280 qvec.emplace_back( abs.ul+isize3x, inner.ur(), color, image->t1+tsize3x, image->t1+tsize3x2+tsize3y);281 qvec.emplace_back( abs.ur()-isize3x, inner.ur()+isize3x, color, image->t1+tsize3x2, image->t1+tsizex+tsize3y );282 283 qvec.emplace_back( abs.ul+isize3y, inner.ll(), color, image->t1+tsize3y, image->t1+tsize3y2+tsize3x );284 qvec.emplace_back( inner.ul, inner.lr, color, image->t1+tsize3, image->t1+tsize32 );285 qvec.emplace_back( inner.ur(), inner.lr+isize3x, color, image->t1+tsize3+tsize3x, image->t1+tsize32+tsize3x );286 287 288 qvec.emplace_back( abs.ll()-isize3y, inner.ll()+isize3y, color, image->t1+tsize3y2, image->t1+tsize3y2+tsize3 );289 qvec.emplace_back( inner.ll(), abs.lr-isize3x, color, image->t1+tsize3y2+tsize3x, image->t1+tsize32+tsize3y );290 qvec.emplace_back( inner.lr, abs.lr, color, image->t1+tsize32, image->t1+tsize );291 292 293 // qvec.emplace_back( abs.ul, abs.ll(), inner.ll(), inner.ul, color );294 // qvec.emplace_back( inner.ur(), inner.lr, abs.lr, abs.ur(), color );295 // qvec.emplace_back( inner.ll(), abs.ll(), abs.lr, inner.lr, color );296 abs = inner;297 298 }299 300 }301 else302 {303 304 if ( m_style.get( e, "border", selector, border ) && m_style.get( e, "border_color", selector, color ) )305 {306 rectangle inner = abs.shrinked( border );307 qvec.emplace_back( abs.ul, inner.ul, inner.ur(), abs.ur(), color );308 qvec.emplace_back( abs.ul, abs.ll(), inner.ll(), inner.ul, color );309 qvec.emplace_back( inner.ur(), inner.lr, abs.lr, abs.ur(), color );310 qvec.emplace_back( inner.ll(), abs.ll(), abs.lr, inner.lr, color );311 abs = inner;312 }313 314 if ( m_style.get( e, "background_color", selector, color ) )315 {316 qvec.emplace_back( abs.ul, abs.lr, color );317 }318 }319 320 text = e->m_text;321 if ( !text.empty() )322 {323 if ( m_style.get( e, "text_color", selector, color ) && m_style.get( e, "text_font", selector, path ) && m_style.get( e, "text_size", selector, border ) )324 {325 size_t font_id = load_font( path, (uint16)border );326 texture_font* font = get_font( font_id );327 position p = abs.ul + position( 0, border );328 for ( char c : text )329 {330 const texture_glyph* g = font->get_glyph( static_cast<uint16>(c) );331 if (g)332 {333 position gp = position( g->offset.x, -g->offset.y );334 position p2 = p + g->size + gp;335 qvec.emplace_back( p + gp, p2, color, g->tl, g->br );336 p += g->advance;337 }338 }339 }340 }341 }342 343 if ( size_before != er->buffer.data().size() )344 {345 sr->buffer.reset();346 }347 }348 349 void renderer::on_hover_change( element* e, bool hover )350 {351 // TODO: FIX352 NV_LOG( nv::LOG_DEBUG, "on_hover_change" );353 e->m_flags[DIRTY] = true;354 }355 356 void renderer::on_select_change( element* e, bool select )357 {358 // TODO: FIX359 NV_LOG( nv::LOG_DEBUG, "on_select_change" );360 e->m_flags[DIRTY] = true;361 }362 363 364 void renderer::draw( element* e )365 {366 element_render_data* er = (element_render_data*)(e->m_render_data);367 er->buffer.commit();368 }369 370 void renderer::draw()371 {372 screen_render_data* sr = (screen_render_data*)m_render_data;373 374 if ( m_reupload )375 {376 m_context->update( sr->tex, (void*)m_atlas.get_data() );377 m_reupload = false;378 }379 380 if ( sr->buffer.commit() )381 {382 buffer vb = sr->buffer.get_buffer();383 m_context->replace_vertex_buffer( sr->varray, vb, false );384 }385 m_context->bind( sr->tex, TEX_DIFFUSE );386 m_context->draw( TRIANGLES, m_render_state, m_scene_state, sr->shader, sr->varray, sr->buffer.get_size() * 6 );387 }388 389 renderer::~renderer()390 {391 for ( auto p : m_fonts )392 {393 delete p;394 }395 if ( m_render_data )396 {397 m_context->get_device()->release( ((screen_render_data*)m_render_data)->tex );398 delete m_render_data;399 }400 }
Note: See TracChangeset
for help on using the changeset viewer.