You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

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