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

Last change on this file since 2090 was 2090, checked in by sam, 7 years ago

neercs: added a better check for forkpty(), and moved the GL_POINTS
size and texture logic to the vertex shader.

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