Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 

185 linhas
5.5 KiB

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