source: trunk/tools/neercs/video/text-render.cpp @ 2277

Last change on this file since 2277 was 2277, checked in by sam, 8 years ago

build: hide LolFx external declarations behind macros.

  • Property svn:keywords set to Id
File size: 6.1 KB
Line 
1//
2// Neercs
3//
4
5#if defined HAVE_CONFIG_H
6#   include "config.h"
7#endif
8
9#include <cmath>
10#include <cstdio>
11#include <cstdlib>
12#include <ctime>
13#include <string>
14
15#include "core.h"
16#include "lolgl.h"
17
18using namespace std;
19using namespace lol;
20
21#include "../neercs.h"
22#include "render.h"
23#include "text-render.h"
24
25LOLFX_RESOURCE_DECLARE(text);
26
27#define HAVE_SHADER_4 1
28
29/*
30 * Text rendering interface
31 */
32
33TextRender::TextRender(caca_canvas_t *caca, ivec2 font_size)
34  : m_caca(caca),
35    m_font_size(font_size),
36    m_canvas_size(caca_get_canvas_width(m_caca),
37                  caca_get_canvas_height(m_caca)),
38    m_fbo_size(m_font_size * m_canvas_size),
39    m_cells(m_canvas_size.x * m_canvas_size.y),
40    m_vbo1(0), m_vbo2(0), m_vbo3(0), m_fbo(0)
41{
42}
43
44void TextRender::Init()
45{
46    m_font = new TileSet("video/resource/charset_amiga.png",
47                         ivec2(256, 256), ivec2(1));
48
49    m_shader = Shader::Create(LOLFX_RESOURCE_NAME(text));
50    m_color = m_shader->GetAttribLocation("in_Attr",
51                                          VertexUsage::Color, 0);
52    m_char = m_shader->GetAttribLocation("in_Char",
53                                         VertexUsage::Color, 1);
54#if !HAVE_SHADER_4
55    m_vertexid = m_shader->GetAttribLocation("in_VertexID",
56                                             VertexUsage::Position, 0);
57#endif
58    m_texture = m_shader->GetUniformLocation("u_Texture");
59    m_transform = m_shader->GetUniformLocation("u_Transform");
60    m_datasize = m_shader->GetUniformLocation("u_DataSize");
61    m_vdecl
62#if HAVE_SHADER_4
63      = new VertexDeclaration(VertexStream<uint32_t>(VertexUsage::Color),
64                              VertexStream<uint32_t>(VertexUsage::Color));
65#else
66      = new VertexDeclaration(VertexStream<u8vec4>(VertexUsage::Color),
67                              VertexStream<u8vec4>(VertexUsage::Color),
68                              VertexStream<float>(VertexUsage::Position));
69#endif
70
71    CreateBuffers();
72}
73
74void TextRender::CreateBuffers()
75{
76#if HAVE_SHADER_4
77    m_vbo1 = new VertexBuffer(m_cells * sizeof(uint32_t));
78    m_vbo2 = new VertexBuffer(m_cells * sizeof(uint32_t));
79#else
80    m_vbo1 = new VertexBuffer(m_cells * sizeof(u8vec4));
81    m_vbo2 = new VertexBuffer(m_cells * sizeof(u8vec4));
82    m_vbo3 = new VertexBuffer(4 * m_cells * sizeof(float));
83
84    float *idx = (float *)m_vbo3->Lock(0, 0);
85    for (int i = 0; i < m_cells; i++)
86        idx[i] = (float)i;
87    m_vbo3->Unlock();
88#endif
89
90    m_fbo = new FrameBuffer(m_fbo_size);
91}
92
93void TextRender::Render()
94{
95    /* Handle canvas size changes */
96    ivec2 current_size(caca_get_canvas_width(m_caca),
97                       caca_get_canvas_height(m_caca));
98    if (current_size != m_canvas_size)
99    {
100        delete m_vbo1;
101        delete m_vbo2;
102        delete m_vbo3;
103        delete m_fbo;
104
105        m_canvas_size = current_size;
106        m_fbo_size = m_font_size * m_canvas_size;
107        m_cells = m_canvas_size.x * m_canvas_size.y;
108
109        CreateBuffers();
110    }
111
112    /* Transform matrix for the scene:
113     *  - translate to the centre of the glyph
114     *  - scale by 2.f * font_size / fbo_size
115     *  - translate to the lower left corner */
116    mat4 xform = mat4::translate(-1.f, -1.f + 2.0f * m_font_size.y
117                                        * m_canvas_size.y / m_fbo_size.y, 0.f)
118               * mat4::scale(vec3(2.f * m_font_size / m_fbo_size, 1.f)
119                              * vec3(1.f, -1.f, 1.f))
120               * mat4::translate(0.5f, 0.5f, 0.f);
121
122    /* Upload libcaca canvas contents to the vertex buffers */
123    uint32_t *colors = (uint32_t *)m_vbo1->Lock(0, 0);
124    uint32_t savedattr = caca_get_attr(m_caca, -1, -1);
125    for (int j = 0; j < m_canvas_size.y; j++)
126    for (int i = 0; i < m_canvas_size.x; i++)
127    {
128        uint32_t attr = caca_get_attr(m_caca, i, j);
129        uint16_t fg = caca_attr_to_rgb12_fg(attr);
130        uint16_t bg = caca_attr_to_rgb12_bg(attr);
131        caca_set_color_argb(m_caca, fg, bg);
132        attr = caca_get_attr(m_caca, -1, -1);
133        caca_put_attr(m_caca, i, j, attr);
134    }
135    caca_set_attr(m_caca, savedattr);
136    memcpy(colors, caca_get_canvas_attrs(m_caca),
137           m_cells * sizeof(uint32_t));
138    m_vbo1->Unlock();
139
140    uint32_t *chars = (uint32_t *)m_vbo2->Lock(0, 0);
141    memcpy(chars, caca_get_canvas_chars(m_caca),
142           m_cells * sizeof(uint32_t));
143    m_vbo2->Unlock();
144
145    m_fbo->Bind();
146    glViewport(0, 0, m_fbo_size.x, m_fbo_size.y);
147    glDisable(GL_DEPTH_TEST);
148#if !defined HAVE_GLES_2X
149    glEnable(GL_POINT_SPRITE);
150    //glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
151    glDisable(GL_POINT_SMOOTH);
152    glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
153    glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
154#endif
155    m_shader->Bind();
156    m_font->Bind();
157    m_shader->SetUniform(m_texture, 0);
158    m_shader->SetUniform(m_transform, xform);
159    m_shader->SetUniform(m_datasize, vec2(m_canvas_size.x,
160                                          max(m_font_size.x, m_font_size.y)));
161    m_vdecl->SetStream(m_vbo1, m_color);
162    m_vdecl->SetStream(m_vbo2, m_char);
163#if !HAVE_SHADER_4
164    m_vdecl->SetStream(m_vbo3, m_vertexid);
165#endif
166    m_vdecl->Bind();
167    m_vdecl->DrawElements(MeshPrimitive::Points, 0, m_cells);
168    m_vdecl->Unbind();
169    m_font->Unbind();
170    m_shader->Unbind();
171#if !defined HAVE_GLES_2X
172    glDisable(GL_POINT_SPRITE);
173#endif
174    m_fbo->Unbind();
175}
176
177void TextRender::Blit(ivec2 pos, ivec2 size)
178{
179    /* FIXME: this is ugly! But we will get rid of it when we
180     * do the Direct3D port, so don't worry too much. */
181    ShaderTexture t = m_fbo->GetTexture();
182    uint64_t const &x = *(uint64_t const *)&t;
183
184    glDisable(GL_BLEND);
185    glEnable(GL_TEXTURE_2D);
186    glBindTexture(GL_TEXTURE_2D, (int)x);
187    glColor3f(1.0f, 1.0f, 1.0f);
188
189    vec2 tc = (vec2)m_canvas_size * m_font_size / m_fbo_size;
190
191    glLoadIdentity();
192    glBegin(GL_QUADS);
193        glTexCoord2f(tc.x, tc.y);
194        glVertex2i(pos.x + size.x, pos.y);
195        glTexCoord2f(0.0f, tc.y);
196        glVertex2i(pos.x, pos.y);
197        glTexCoord2f(0.0f, 0.0f);
198        glVertex2i(pos.x, pos.y + size.y);
199        glTexCoord2f(tc.x, 0.0f);
200        glVertex2i(pos.x + size.x, pos.y + size.y);
201    glEnd();
202}
203
Note: See TracBrowser for help on using the repository browser.