source: trunk/src/gfx/gfx_terminal.cc @ 515

Last change on this file since 515 was 514, checked in by epyon, 9 years ago
  • term_color implementation
  • support for background color
  • support for RGBA encoding
  • initial gfx_terminal implementation
File size: 5.2 KB
Line 
1// Copyright (C) 2016-2016 ChaosForge Ltd
2// http://chaosforge.org/
3//
4// This file is part of Nova libraries.
5// For conditions of distribution and use, see copying.txt file in root folder.
6
7#include "nv/gfx/gfx_terminal.hh"
8
9#include "nv/core/logging.hh"
10
11using namespace nv;
12
13static const char *nv_gfx_terminal_vs = R"(
14#version 330
15in vec2 nv_position;
16in vec2 nv_texcoord;
17out vec2 v_texcoord;
18void main(void)
19{
20        gl_Position = vec4(nv_position, 0.0, 1.0);
21        v_texcoord  = nv_texcoord;
22};
23)";
24static const char *nv_gfx_terminal_fs = R"(
25#version 330
26in  vec2 v_texcoord;
27out vec4 o_frag_color;
28
29uniform vec2 term_size;
30uniform vec2 dev_size;
31//uniform vec2 gylph_size;
32uniform sampler2D nv_t_diffuse;
33
34struct term_data
35{
36        uint fg;
37        uint bg;
38        uint gylph;
39        uint pad;
40};
41
42layout(std140) uniform terminal_block
43{
44        term_data term[80*50];
45};
46
47void main(void)
48{
49        vec2 coord   = v_texcoord * term_size;
50        ivec2 icoord = ivec2( coord );
51        vec2 tc      = coord - vec2( icoord );
52        tc.y = 1.0f - tc.y;
53
54        coord.y = term_size.y - coord.y;
55       
56        int index = int( coord.x ) + int( term_size.x ) * int( coord.y );
57        uint fg   = term[ index ].fg;
58        int gylph = int( term[ index ].gylph );
59        ivec2 gxy = ivec2( gylph % 16, gylph / 16 );
60        vec2 gpos = vec2( ( float(gxy.x) + tc.x ) / 16.0f, ( float(gxy.y) + tc.y ) / 16.0f );
61        vec4 tt   = texture( nv_t_diffuse, gpos );
62
63
64    vec4 color = vec4(
65        float( ( fg & uint(0x00FF0000) ) >> 16 ) / 255.0f,
66        float( ( fg & uint(0x0000FF00) ) >> 8 ) / 255.0f,
67        float(   fg & uint(0x000000FF) ) / 255.0f,
68        1.0 //fg & uint(0xFF000000)
69        );
70        o_frag_color = vec4( color.xyz * tt.xyz + vec3( 0.0, 0.2, 0.0 ) * ( 1.0 - tt.xyz ), 1.0 * tt.x );
71//      o_frag_color = vec4( fg, 0.0, 0.0, 1.0) ;
72}
73)";
74
75struct gfx_terminal_uniform_block
76{
77        uint32 fgcolor = 0;
78        uint32 bgcolor = 0;
79        uint32 gylph   = 0;
80        uint32 pad;
81
82        void set( term_color fg, term_color bg, char ch )
83        {
84                fgcolor = fg.get_argb32();
85                bgcolor = bg.get_argb32();
86                gylph   = uint32( ch );
87                NV_LOG_INFO( uint32(
88                        ( fgcolor & uint32( 0x00FF0000 ) ) >> 16 ), "-", uint32( ( fgcolor & uint32( 0x0000FF00 ) ) >> 8 ),"-" , uint32( fgcolor & uint32( 0x000000FF ) ) );
89        }
90};
91
92struct nv::gfx_terminal_data
93{
94        gfx_terminal_uniform_block* data;
95        dimension                   size;
96        buffer                      buffer;
97
98        gfx_terminal_data( dimension dim )
99        {
100                size = dim;
101                data = new gfx_terminal_uniform_block[dim.x * dim.y];
102        }
103
104        gfx_terminal_uniform_block& operator[]( position p )
105        {
106                int index = size.x * p.y + p.x;
107                return data[index];
108        }
109
110        ~gfx_terminal_data()
111        {
112                delete[] data;
113        }
114};
115
116gfx_terminal::gfx_terminal( context* ctx, texture t, dimension tsize, dimension psize )
117        : terminal( tsize ), m_context( ctx )
118{
119        m_data = new gfx_terminal_data( tsize );
120       
121        struct qvtx
122        {
123                vec2 position;
124                vec2 texcoord;
125        };
126
127        qvtx quad[] = {
128                qvtx{ vec2( -1.0f,-1.0f ), vec2( 0.0f, 0.0f ) },
129                qvtx{ vec2( 1.0f,-1.0f ),  vec2( 1.0f, 0.0f ) },
130                qvtx{ vec2( 1.0f,1.0f ),   vec2( 1.0f, 1.0f ) },
131                qvtx{ vec2( 1.0f,1.0f ),   vec2( 1.0f, 1.0f ) },
132                qvtx{ vec2( -1.0f,1.0f ),  vec2( 0.0f, 1.0f ) },
133                qvtx{ vec2( -1.0f,-1.0f ), vec2( 0.0f, 0.0f ) },
134        };
135        m_dc.va       = m_context->create_vertex_array( quad, 6, nv::STATIC_DRAW );
136        m_dc.va_count = 6;
137        m_dc.image    = t;
138
139        m_dc.p = m_context->create_program( nv_gfx_terminal_vs, nv_gfx_terminal_fs );
140
141        m_data->buffer = m_context->create_buffer( nv::UNIFORM_BUFFER, nv::DYNAMIC_DRAW, tsize.x * tsize.y * sizeof( gfx_terminal_uniform_block ), m_data->data );
142        m_context->bind( m_data->buffer, 7 );
143        m_context->get_device()->set_opt_uniform( m_dc.p, "term_size", vec2( tsize ) );
144//      m_context->get_device()->set_opt_uniform( m_dc.p, "dev_size", vec2( psize ) );
145        m_context->get_device()->set_opt_uniform( m_dc.p, "gylph_size", vec2( 8,8 ) );
146        m_context->get_device()->set_opt_uniform( m_dc.p, "nv_t_diffuse", int( nv::TEX_DIFFUSE ) );
147        m_context->get_device()->bind_block( m_dc.p, "terminal_block", 7 );
148        m_update_needed = false;
149}
150
151void gfx_terminal::update()
152{
153        m_context->bind( m_data->buffer, 7 );
154        m_context->update( m_data->buffer, m_data->data, 0, m_data->size.x * m_data->size.y * sizeof( gfx_terminal_uniform_block ) );
155        m_update_needed = false;
156}
157
158void gfx_terminal::print( position p, term_color fgcolor, term_color bgcolor, char ch )
159{
160        m_update_needed = true;
161        ( *m_data )[position( p.x - 1, p.y - 1)].set( fgcolor, bgcolor, ch );
162}
163
164void gfx_terminal::clear( rectangle r, term_color fgcolor, term_color bgcolor )
165{
166        m_update_needed = true;
167        for ( int x = r.ul.x - 1; x <= r.lr.x - 1; ++x )
168                for ( int y = r.ul.y - 1; y <= r.lr.y - 1; ++y )
169                        (*m_data)[ position( x, y ) ].set( fgcolor, bgcolor, ' ' );
170}
171
172void gfx_terminal::clear()
173{
174        m_update_needed = true;
175        for ( int i = 0; i < m_data->size.x * m_data->size.y; ++i )
176                m_data->data[i].set( term_color::LIGHTGRAY, term_color::TRANSPARENT, ' ' );
177}
178
179bool gfx_terminal::poll( io_event & kevent )
180{
181        return false;
182}
183
184void gfx_terminal::set_cursor( position p )
185{
186}
187
188void gfx_terminal::show_cursor()
189{
190}
191
192void gfx_terminal::hide_cursor()
193{
194}
195
196gfx_terminal::~gfx_terminal()
197{
198        delete m_data;
199}
200
Note: See TracBrowser for help on using the repository browser.