152 行
4.6 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. for (int j = 0; j < m_canvas_size.y; j++)
  32. for (int i = 0; i < m_canvas_size.x; i++)
  33. m_vertices << vec2(i, j);
  34. }
  35. void TextRender::Init()
  36. {
  37. m_font = new TileSet("neercs/video/resource/map.png",
  38. ivec2(256, 256), ivec2(1));
  39. m_shader = Shader::Create(lolfx_text);
  40. m_coord = m_shader->GetAttribLocation("in_Position",
  41. VertexUsage::Position, 0);
  42. m_color = m_shader->GetAttribLocation("in_Attr",
  43. VertexUsage::Color, 0);
  44. m_char = m_shader->GetAttribLocation("in_Char",
  45. VertexUsage::Color, 1);
  46. m_texture = m_shader->GetUniformLocation("in_Texture");
  47. m_transform = m_shader->GetUniformLocation("in_Transform");
  48. m_vdecl
  49. = new VertexDeclaration(VertexStream<vec2>(VertexUsage::Position),
  50. VertexStream<uint32_t>(VertexUsage::Color),
  51. VertexStream<uint32_t>(VertexUsage::Color));
  52. m_vbo1 = new VertexBuffer(m_vertices.Bytes());
  53. void *vertices = m_vbo1->Lock(0, 0);
  54. memcpy(vertices, &m_vertices[0], m_vertices.Bytes());
  55. m_vbo1->Unlock();
  56. m_vbo2 = new VertexBuffer(m_cells * sizeof(int32_t));
  57. m_vbo3 = new VertexBuffer(m_cells * sizeof(int32_t));
  58. m_fbo = new FrameBuffer(m_fbo_size);
  59. }
  60. void TextRender::Render()
  61. {
  62. /* Transform matrix for the scene:
  63. * - translate to the centre of the glyph
  64. * - scale by 2.f * font_size / fbo_size
  65. * - translate to the lower left corner */
  66. mat4 xform = mat4::translate(-1.f, -1.f + 2.0f * m_font_size.y
  67. * m_canvas_size.y / m_fbo_size.y, 0.f)
  68. * mat4::scale(vec3(2.f * m_font_size / m_fbo_size, 1.f)
  69. * vec3(1.f, -1.f, 1.f))
  70. * mat4::translate(0.5f, 0.5f, 0.f);
  71. /* Upload libcaca canvas contents to the vertex buffers */
  72. uint32_t *colors = (uint32_t *)m_vbo2->Lock(0, 0);
  73. for (int j = 0; j < m_canvas_size.y; j++)
  74. for (int i = 0; i < m_canvas_size.x; i++)
  75. {
  76. uint32_t attr = caca_get_attr(m_caca, i, j);
  77. uint16_t fg = caca_attr_to_rgb12_fg(attr);
  78. uint16_t bg = caca_attr_to_rgb12_bg(attr);
  79. caca_set_color_argb(m_caca, fg, bg);
  80. attr = caca_get_attr(m_caca, -1, -1);
  81. caca_put_attr(m_caca, i, j, attr);
  82. }
  83. memcpy(colors, caca_get_canvas_attrs(m_caca),
  84. m_cells * sizeof(uint32_t));
  85. m_vbo2->Unlock();
  86. uint32_t *chars = (uint32_t *)m_vbo3->Lock(0, 0);
  87. memcpy(chars, caca_get_canvas_chars(m_caca),
  88. m_cells * sizeof(uint32_t));
  89. m_vbo3->Unlock();
  90. m_fbo->Bind();
  91. glViewport(0, 0, m_fbo_size.x, m_fbo_size.y);
  92. glDisable(GL_DEPTH_TEST);
  93. glEnable(GL_POINT_SPRITE);
  94. //glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
  95. glDisable(GL_POINT_SMOOTH);
  96. glPointSize((float)max(m_font_size.x, m_font_size.y));
  97. m_shader->Bind();
  98. m_font->Bind();
  99. m_shader->SetUniform(m_texture, 0);
  100. m_shader->SetUniform(m_transform, xform);
  101. m_vdecl->SetStream(m_vbo1, m_coord);
  102. m_vdecl->SetStream(m_vbo2, m_color);
  103. m_vdecl->SetStream(m_vbo3, m_char);
  104. m_vdecl->Bind();
  105. m_vdecl->DrawElements(MeshPrimitive::Points, 0, m_cells);
  106. m_vdecl->Unbind();
  107. m_font->Unbind();
  108. m_shader->Unbind();
  109. glDisable(GL_POINT_SPRITE);
  110. m_fbo->Unbind();
  111. }
  112. void TextRender::Blit(ivec2 pos, ivec2 size)
  113. {
  114. glDisable(GL_BLEND);
  115. glEnable(GL_TEXTURE_2D);
  116. glBindTexture(GL_TEXTURE_2D, m_fbo->GetTexture());
  117. glColor3f(1.0f, 1.0f, 1.0f);
  118. vec2 tc = (vec2)m_canvas_size * m_font_size / m_fbo_size;
  119. glLoadIdentity();
  120. glBegin(GL_QUADS);
  121. glTexCoord2f(tc.x, tc.y);
  122. glVertex2i(pos.x + size.x, pos.y);
  123. glTexCoord2f(0.0f, tc.y);
  124. glVertex2i(pos.x, pos.y);
  125. glTexCoord2f(0.0f, 0.0f);
  126. glVertex2i(pos.x, pos.y + size.y);
  127. glTexCoord2f(tc.x, 0.0f);
  128. glVertex2i(pos.x + size.x, pos.y + size.y);
  129. glEnd();
  130. }