27#ifdef __OCPN__ANDROID__
31#include "pi_TexFont.h"
33#ifdef USE_ANDROID_GLES2
36#include "pi_shaders.h"
47TexFont::~TexFont() { Delete(); }
49void TexFont::Build(wxFont &font,
bool blur) {
51 if (font == m_font && blur == m_blur)
return;
63 for (
int i = MIN_GLYPH; i < MAX_GLYPH; i++) {
66 if (i == DEGREE_GLYPH)
67 text = wxString::Format(_T(
"%c"), 0x00B0);
69 text = wxString::Format(_T(
"%c"), i);
70 wxCoord descent, exlead;
71 sdc.GetTextExtent(text, &gw, &gh, &descent, &exlead,
79 m_maxglyphw = wxMax(tgi[i].width, m_maxglyphw);
80 m_maxglyphh = wxMax(tgi[i].height, m_maxglyphh);
88 int w = COLS_GLYPHS * m_maxglyphw;
89 int h = ROWS_GLYPHS * m_maxglyphh;
91 wxASSERT(w < 2048 && h < 2048);
94 for (tex_w = 1; tex_w < w; tex_w *= 2);
95 for (tex_h = 1; tex_h < h; tex_h *= 2);
97 wxBitmap tbmp(tex_w, tex_h);
99 dc.SelectObject(tbmp);
103 dc.SetBackground(wxBrush(wxColour(0, 0, 0)));
107 dc.SetTextForeground(wxColour(255, 255, 255));
114 int row = 0, col = 0;
115 for (
int i = MIN_GLYPH; i < MAX_GLYPH; i++) {
116 if (col == COLS_GLYPHS) {
121 tgi[i].x = col * m_maxglyphw;
122 tgi[i].y = row * m_maxglyphh;
125 if (i == DEGREE_GLYPH)
126 text = wxString::Format(_T(
"%c"), 0x00B0);
128 text = wxString::Format(_T(
"%c"), i);
130 dc.DrawText(text, tgi[i].x, tgi[i].y);
137 dc.SelectObject(wxNullBitmap);
139 wxImage image = tbmp.ConvertToImage();
141 GLuint format, internalformat;
145 internalformat = format;
148 if (m_blur) image = image.Blur(1);
150 unsigned char *imgdata = image.GetData();
153 unsigned char *teximage = (
unsigned char *)malloc(stride * tex_w * tex_h);
155 for (
int j = 0; j < tex_w * tex_h; j++)
156 for (
int k = 0; k < stride; k++)
157 teximage[j * stride + k] = imgdata[3 * j];
161 glGenTextures(1, &texobj);
162 glBindTexture(GL_TEXTURE_2D, texobj);
164 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
165 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
166 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
168 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
170 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, tex_w, tex_h, 0, format,
171 GL_UNSIGNED_BYTE, teximage);
179void TexFont::Delete() {
181 glDeleteTextures(1, &texobj);
186void TexFont::GetTextExtent(
const char *
string,
int *width,
int *height) {
189 for (
int i = 0;
string[i]; i++) {
190 unsigned char c =
string[i];
192 h += tgi[(int)
'A'].height;
195 if (c == 0xc2 && (
unsigned char)
string[i + 1] == 0xb0) {
199 if (c < MIN_GLYPH || c >= MAX_GLYPH)
continue;
203 if (tgisi.height > h) h = tgisi.height;
205 if (width) *width = w;
206 if (height) *height = h;
209void TexFont::GetTextExtent(
const wxString &
string,
int *width,
int *height) {
210 GetTextExtent((
const char *)
string.ToUTF8(), width, height);
213void TexFont::RenderGlyph(
int c) {
214 if (c < MIN_GLYPH || c >= MAX_GLYPH)
return;
218 int x = tgic.x, y = tgic.y;
219 float w = m_maxglyphw, h = m_maxglyphh;
220 float tx1 = (float)x / (
float)tex_w;
221 float tx2 = (float)(x + w) / (float)tex_w;
222 float ty1 = (float)y / (
float)tex_h;
223 float ty2 = (float)(y + h) / (float)tex_h;
225#ifndef USE_ANDROID_GLES2
229 glTexCoord2f(tx1, ty1);
231 glTexCoord2f(tx2, ty1);
233 glTexCoord2f(tx2, ty2);
235 glTexCoord2f(tx1, ty2);
239 glTranslatef(tgic.advance, 0.0, 0.0);
268 glUseProgram(pi_texture_2D_shader_program);
271 GLint mPosAttrib = glGetAttribLocation(pi_texture_2D_shader_program,
"aPos");
272 GLint mUvAttrib = glGetAttribLocation(pi_texture_2D_shader_program,
"aUV");
275 GLint texUni = glGetUniformLocation(pi_texture_2D_shader_program,
"uTex");
276 glUniform1i(texUni, 0);
279 glBindBuffer(GL_ARRAY_BUFFER, 0);
280 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
283 glVertexAttribPointer(mPosAttrib, 2, GL_FLOAT, GL_FALSE, 0, coords);
285 glEnableVertexAttribArray(mPosAttrib);
288 glVertexAttribPointer(mUvAttrib, 2, GL_FLOAT, GL_FALSE, 0, uv);
290 glEnableVertexAttribArray(mUvAttrib);
296 mat4x4_rotate_Z(Q, I, angle);
303 glGetUniformLocation(pi_texture_2D_shader_program,
"TransformMatrix");
304 glUniformMatrix4fv(matloc, 1, GL_FALSE, (
const GLfloat *)Q);
307 glActiveTexture(GL_TEXTURE0);
334 glVertexAttribPointer(mPosAttrib, 2, GL_FLOAT, GL_FALSE, 0, co1);
335 glVertexAttribPointer(mUvAttrib, 2, GL_FLOAT, GL_FALSE, 0, tco1);
337 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
341 m_dx += tgic.advance;
344void TexFont::RenderString(
const char *
string,
int x,
int y) {
345#ifndef USE_ANDROID_GLES2
348 glTranslatef(x, y, 0);
351 glBindTexture(GL_TEXTURE_2D, texobj);
353 for (
int i = 0;
string[i]; i++) {
354 if (
string[i] ==
'\n') {
356 glTranslatef(0, tgi[(
int)
'A'].height, 0);
361 if ((
unsigned char)
string[i] == 0xc2 &&
362 (
unsigned char)
string[i + 1] == 0xb0) {
363 RenderGlyph(DEGREE_GLYPH);
367 RenderGlyph(
string[i]);
376 glBindTexture(GL_TEXTURE_2D, texobj);
378 for (
int i = 0;
string[i]; i++) {
379 if (
string[i] ==
'\n') {
380 m_dy += tgi[(int)
'A'].height;
384 if ((
unsigned char)
string[i] == 0xc2 &&
385 (
unsigned char)
string[i + 1] == 0xb0) {
386 RenderGlyph(DEGREE_GLYPH);
390 RenderGlyph(
string[i]);
396void TexFont::RenderString(
const wxString &
string,
int x,
int y) {
397 RenderString((
const char *)
string.ToUTF8(), x, y);