38#ifdef USE_ANDROID_GLES2
41#include "pi_shaders.h"
52TexFont::~TexFont() { Delete(); }
54void TexFont::Build(wxFont &font,
bool blur) {
56 if (font == m_font && blur == m_blur)
return;
68 for (
int i = MIN_GLYPH; i < MAX_GLYPH; i++) {
71 if (i == DEGREE_GLYPH)
72 text = wxString::Format(
"%c", 0x00B0);
74 text = wxString::Format(
"%c", i);
75 wxCoord descent, exlead;
76 sdc.GetTextExtent(text, &gw, &gh, &descent, &exlead,
84 m_maxglyphw = wxMax(tgi[i].width, m_maxglyphw);
85 m_maxglyphh = wxMax(tgi[i].height, m_maxglyphh);
93 int w = COLS_GLYPHS * m_maxglyphw;
94 int h = ROWS_GLYPHS * m_maxglyphh;
96 wxASSERT(w < 2048 && h < 2048);
99 for (tex_w = 1; tex_w < w; tex_w *= 2);
100 for (tex_h = 1; tex_h < h; tex_h *= 2);
102 wxBitmap tbmp(tex_w, tex_h);
104 dc.SelectObject(tbmp);
108 dc.SetBackground(wxBrush(wxColour(0, 0, 0)));
112 dc.SetTextForeground(wxColour(255, 255, 255));
119 int row = 0, col = 0;
120 for (
int i = MIN_GLYPH; i < MAX_GLYPH; i++) {
121 if (col == COLS_GLYPHS) {
126 tgi[i].x = col * m_maxglyphw;
127 tgi[i].y = row * m_maxglyphh;
130 if (i == DEGREE_GLYPH)
131 text = wxString::Format(
"%c", 0x00B0);
133 text = wxString::Format(
"%c", i);
135 dc.DrawText(text, tgi[i].x, tgi[i].y);
142 dc.SelectObject(wxNullBitmap);
144 wxImage image = tbmp.ConvertToImage();
146 GLuint format, internalformat;
150 internalformat = format;
153 if (m_blur) image = image.Blur(1);
155 unsigned char *imgdata = image.GetData();
158 unsigned char *teximage = (
unsigned char *)malloc(stride * tex_w * tex_h);
160 for (
int j = 0; j < tex_w * tex_h; j++)
161 for (
int k = 0; k < stride; k++)
162 teximage[j * stride + k] = imgdata[3 * j];
166 glGenTextures(1, &texobj);
167 glBindTexture(GL_TEXTURE_2D, texobj);
169 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
170 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
171 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
173 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
175 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, tex_w, tex_h, 0, format,
176 GL_UNSIGNED_BYTE, teximage);
184void TexFont::Delete() {
186 glDeleteTextures(1, &texobj);
191void TexFont::GetTextExtent(
const char *
string,
int *width,
int *height) {
194 for (
int i = 0;
string[i]; i++) {
195 unsigned char c =
string[i];
197 h += tgi[(int)
'A'].height;
200 if (c == 0xc2 && (
unsigned char)
string[i + 1] == 0xb0) {
204 if (c < MIN_GLYPH || c >= MAX_GLYPH)
continue;
208 if (tgisi.height > h) h = tgisi.height;
210 if (width) *width = w;
211 if (height) *height = h;
214void TexFont::GetTextExtent(
const wxString &
string,
int *width,
int *height) {
215 GetTextExtent((
const char *)
string.ToUTF8(), width, height);
218void TexFont::RenderGlyph(
int c) {
219 if (c < MIN_GLYPH || c >= MAX_GLYPH)
return;
223 int x = tgic.x, y = tgic.y;
224 float w = m_maxglyphw, h = m_maxglyphh;
225 float tx1 = (float)x / (
float)tex_w;
226 float tx2 = (float)(x + w) / (float)tex_w;
227 float ty1 = (float)y / (
float)tex_h;
228 float ty2 = (float)(y + h) / (float)tex_h;
230#ifndef USE_ANDROID_GLES2
234 glTexCoord2f(tx1, ty1);
236 glTexCoord2f(tx2, ty1);
238 glTexCoord2f(tx2, ty2);
240 glTexCoord2f(tx1, ty2);
244 glTranslatef(tgic.advance, 0.0, 0.0);
273 glUseProgram(pi_texture_2D_shader_program);
276 GLint mPosAttrib = glGetAttribLocation(pi_texture_2D_shader_program,
"aPos");
277 GLint mUvAttrib = glGetAttribLocation(pi_texture_2D_shader_program,
"aUV");
280 GLint texUni = glGetUniformLocation(pi_texture_2D_shader_program,
"uTex");
281 glUniform1i(texUni, 0);
284 glBindBuffer(GL_ARRAY_BUFFER, 0);
285 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
288 glVertexAttribPointer(mPosAttrib, 2, GL_FLOAT, GL_FALSE, 0, coords);
290 glEnableVertexAttribArray(mPosAttrib);
293 glVertexAttribPointer(mUvAttrib, 2, GL_FLOAT, GL_FALSE, 0, uv);
295 glEnableVertexAttribArray(mUvAttrib);
301 mat4x4_rotate_Z(Q, I, angle);
308 glGetUniformLocation(pi_texture_2D_shader_program,
"TransformMatrix");
309 glUniformMatrix4fv(matloc, 1, GL_FALSE, (
const GLfloat *)Q);
312 glActiveTexture(GL_TEXTURE0);
339 glVertexAttribPointer(mPosAttrib, 2, GL_FLOAT, GL_FALSE, 0, co1);
340 glVertexAttribPointer(mUvAttrib, 2, GL_FLOAT, GL_FALSE, 0, tco1);
342 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
346 m_dx += tgic.advance;
349void TexFont::RenderString(
const char *
string,
int x,
int y) {
350#ifndef USE_ANDROID_GLES2
353 glTranslatef(x, y, 0);
356 glBindTexture(GL_TEXTURE_2D, texobj);
358 for (
int i = 0;
string[i]; i++) {
359 if (
string[i] ==
'\n') {
361 glTranslatef(0, tgi[(
int)
'A'].height, 0);
366 if ((
unsigned char)
string[i] == 0xc2 &&
367 (
unsigned char)
string[i + 1] == 0xb0) {
368 RenderGlyph(DEGREE_GLYPH);
372 RenderGlyph(
string[i]);
381 glBindTexture(GL_TEXTURE_2D, texobj);
383 for (
int i = 0;
string[i]; i++) {
384 if (
string[i] ==
'\n') {
385 m_dy += tgi[(int)
'A'].height;
389 if ((
unsigned char)
string[i] == 0xc2 &&
390 (
unsigned char)
string[i + 1] == 0xb0) {
391 RenderGlyph(DEGREE_GLYPH);
395 RenderGlyph(
string[i]);
401void TexFont::RenderString(
const wxString &
string,
int x,
int y) {
402 RenderString((
const char *)
string.ToUTF8(), x, y);