OpenGL ES SDK for Android ARM Developer Center
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Text.cpp
Go to the documentation of this file.
1 /* Copyright (c) 2014-2017, ARM Limited and Contributors
2  *
3  * SPDX-License-Identifier: MIT
4  *
5  * Permission is hereby granted, free of charge,
6  * to any person obtaining a copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
14  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19  */
20 
21 #include "Text.h"
22 #include "AstcTextures.h"
23 
24 #include <cstdio>
25 #include <cstdlib>
26 #include <cstring>
27 
28 namespace AstcTextures
29 {
30  const char Text::textureFilename[] = "font.raw";
31 
32  const float Text::scale = 1.0f;
33 
34  const int Text::textureCharacterWidth = 8;
35  const int Text::textureCharacterHeight = 16;
36 
37  /* Please see header for specification. */
38  void loadData(const char* filename, unsigned char** textureData)
39  {
40  LOGI("Texture loadData started for %s...\n", filename);
41 
42  FILE* file = fopen(filename, "rb");
43 
44  if (file == NULL)
45  {
46  LOGE("Failed to open '%s'\n", filename);
47  exit(EXIT_FAILURE);
48  }
49 
50  fseek(file, 0, SEEK_END);
51 
52  unsigned int length = ftell(file);
53  unsigned char* loadedTexture = NULL;
54 
55  MALLOC_CHECK(unsigned char*, loadedTexture, length);
56 
57  fseek(file, 0, SEEK_SET);
58 
59  size_t read = fread(loadedTexture, sizeof(unsigned char), length, file);
60 
61  if (read != length)
62  {
63  LOGE("Failed to read in '%s'\n", filename);
64  exit(EXIT_FAILURE);
65  }
66 
67  fclose(file);
68 
69  *textureData = loadedTexture;
70  }
71 
72  /* Please see header for specification. */
74  {
75  vertexShaderID = 0;
76  fragmentShaderID = 0;
77  programID = 0;
79 
80  textVertex = NULL;
82  color = NULL;
83  textIndex = NULL;
84 
85  /* Create an orthographic projection. */
86  projectionMatrix = Matrix::matrixOrthographic(0, (float)windowWidth, 0, (float)windowHeight, 0, 1);
87 
88  /* Create program object and initialize it. */
90 
91  GL_CHECK(glUseProgram(programID));
92 
93  /* Vertex positions. */
95 
96  /* Text colors. */
98 
99  /* TexCoords. */
101 
102  /* Projection matrix. */
104 
105  GL_CHECK(glUniformMatrix4fv(m_iLocProjection, 1, GL_FALSE, projectionMatrix.getAsArray()));
106 
107  /* Set the sampler to point at the 0th texture unit. */
109 
110  GL_CHECK(glUniform1i(m_iLocTexture, 0));
111 
112  /* Load texture. */
113  GL_CHECK(glActiveTexture(GL_TEXTURE0));
114  GL_CHECK(glGenTextures(1, &textureID));
115  GL_CHECK(glBindTexture(GL_TEXTURE_2D, textureID));
116 
117  /* Set filtering. */
118  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
119  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
120  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
121  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
122 
123  const int textureLength = strlen(resourceDirectory) + strlen(textureFilename);
124  char* texture = NULL;
125 
126  MALLOC_CHECK(char*, texture, textureLength);
127  strcpy(texture, resourceDirectory);
128  strcat(texture, textureFilename);
129 
130  unsigned char* textureData = NULL;
131 
132  loadData(texture, &textureData);
133 
134  FREE_CHECK(texture);
135 
136  GL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 48, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData));
137 
138  FREE_CHECK(textureData);
139  }
140 
141  /* Please see header for specification. */
142  void Text::clear(void)
143  {
144  numberOfCharacters = 0;
145 
148  FREE_CHECK(color);
150  }
151 
152  /* Please see header for specification. */
153  void Text::addString(int xPosition, int yPosition, const char* string, int red, int green, int blue, int alpha)
154  {
155  int length = (int)strlen(string);
156  int iTexCoordPos = 4 * 2 * numberOfCharacters;
157  int iVertexPos = 4 * 3 * numberOfCharacters;
158  int iColorPos = 4 * 4 * numberOfCharacters;
159  int iIndex = 0;
160  int iIndexPos = 0;
161 
163 
164  /* Realloc memory. */
165  REALLOC_CHECK(float*, textVertex, numberOfCharacters * 4 * 3 * sizeof(float));
166  REALLOC_CHECK(float*, textTextureCoordinates, numberOfCharacters * 4 * 2 * sizeof(float));
167  REALLOC_CHECK(float*, color, numberOfCharacters * 4 * 4 * sizeof(float));
168  REALLOC_CHECK(GLshort*, textIndex, (numberOfCharacters * 6 - 2) * sizeof(GLshort));
169 
170  /* Re-init entire index array. */
171  textIndex[iIndex++] = 0;
172  textIndex[iIndex++] = 1;
173  textIndex[iIndex++] = 2;
174  textIndex[iIndex++] = 3;
175 
176  iIndexPos = 4;
177  for (int cIndex = 1; cIndex < numberOfCharacters; cIndex ++)
178  {
179  textIndex[iIndexPos++] = iIndex - 1;
180  textIndex[iIndexPos++] = iIndex;
181  textIndex[iIndexPos++] = iIndex++;
182  textIndex[iIndexPos++] = iIndex++;
183  textIndex[iIndexPos++] = iIndex++;
184  textIndex[iIndexPos++] = iIndex++;
185  }
186 
187  for (int iChar = 0; iChar < (signed int)strlen(string); iChar ++)
188  {
189  char cChar = string[iChar];
190  int iCharX = 0;
191  int iCharY = 0;
192  Vec2 sBottom_left;
193  Vec2 sBottom_right;
194  Vec2 sTop_left;
195  Vec2 sTop_right;
196 
197  /* Calculate tex coord for char here. */
198  cChar -= 32;
199  iCharX = cChar % 32;
200  iCharY = cChar / 32;
201  iCharX *= textureCharacterWidth;
202  iCharY *= textureCharacterHeight;
203  sBottom_left.x = iCharX;
204  sBottom_left.y = iCharY;
205  sBottom_right.x = iCharX + textureCharacterWidth;
206  sBottom_right.y = iCharY;
207  sTop_left.x = iCharX;
208  sTop_left.y = iCharY + textureCharacterHeight;
209  sTop_right.x = iCharX + textureCharacterWidth;
210  sTop_right.y = iCharY + textureCharacterHeight;
211 
212  /* Add vertex position data here. */
213  textVertex[iVertexPos++] = xPosition + iChar * textureCharacterWidth * scale;
214  textVertex[iVertexPos++] = (float)yPosition;
215  textVertex[iVertexPos++] = 0;
216 
217  textVertex[iVertexPos++] = xPosition + (iChar + 1) * textureCharacterWidth * scale;
218  textVertex[iVertexPos++] = (float)yPosition;
219  textVertex[iVertexPos++] = 0;
220 
221  textVertex[iVertexPos++] = xPosition + iChar * textureCharacterWidth * scale;
222  textVertex[iVertexPos++] = yPosition + textureCharacterHeight * scale;
223  textVertex[iVertexPos++] = 0;
224 
225  textVertex[iVertexPos++] = xPosition + (iChar + 1) * textureCharacterWidth * scale;
226  textVertex[iVertexPos++] = yPosition + textureCharacterHeight * scale;
227  textVertex[iVertexPos++] = 0;
228 
229  /* Texture coords here. Because textures are read in upside down, flip Y coords here. */
230  textTextureCoordinates[iTexCoordPos++] = sBottom_left.x / 256.0f;
231  textTextureCoordinates[iTexCoordPos++] = sTop_left.y / 48.0f;
232 
233  textTextureCoordinates[iTexCoordPos++] = sBottom_right.x / 256.0f;
234  textTextureCoordinates[iTexCoordPos++] = sTop_right.y / 48.0f;
235 
236  textTextureCoordinates[iTexCoordPos++] = sTop_left.x / 256.0f;
237  textTextureCoordinates[iTexCoordPos++] = sBottom_left.y / 48.0f;
238 
239  textTextureCoordinates[iTexCoordPos++] = sTop_right.x / 256.0f;
240  textTextureCoordinates[iTexCoordPos++] = sBottom_right.y / 48.0f;
241 
242  /* Color data. */
243  color[iColorPos++] = red / 255.0f;
244  color[iColorPos++] = green / 255.0f;
245  color[iColorPos++] = blue / 255.0f;
246  color[iColorPos++] = alpha / 255.0f;
247 
248  /* Copy to the other 3 vertices. */
249  memcpy(&color[iColorPos], &color[iColorPos - 4], 4 * sizeof(float));
250  memcpy(&color[iColorPos + 4], &color[iColorPos], 4 * sizeof(float));
251  memcpy(&color[iColorPos + 8], &color[iColorPos + 4], 4 * sizeof(float));
252  iColorPos += 3 * 4;
253  }
254  }
255 
256  /* Please see header for specification. */
257  void Text::draw(void)
258  {
259  /* Push currently bound vertex array object. */
260  GLint vertexArray = 0;
261 
262  GL_CHECK(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &vertexArray));
263  GL_CHECK(glBindVertexArray(0));
264  GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
265 
266  /* Push currently used program object. */
267  GLint currentProgram = 0;
268 
269  GL_CHECK(glGetIntegerv(GL_CURRENT_PROGRAM, &currentProgram));
270 
271  GL_CHECK(glUseProgram(programID));
272 
273  if (m_iLocPosition == -1 || m_iLocTextColor == -1 || m_iLocTexCoord == -1 || m_iLocProjection == -1)
274  {
275  LOGI("At least one of the attributes and/or uniforms is missing. Have you invoked Text(const char*, int, int) constructor?");
276  exit(EXIT_FAILURE);
277  }
278 
279  if (numberOfCharacters == 0)
280  {
281  return;
282  }
283 
284  GL_CHECK(glEnableVertexAttribArray(m_iLocPosition));
285  GL_CHECK(glEnableVertexAttribArray(m_iLocTextColor));
286  GL_CHECK(glEnableVertexAttribArray(m_iLocTexCoord));
287 
288  GL_CHECK(glVertexAttribPointer(m_iLocPosition, 3, GL_FLOAT, GL_FALSE, 0, textVertex));
289  GL_CHECK(glVertexAttribPointer(m_iLocTextColor, 4, GL_FLOAT, GL_FALSE, 0, color));
290  GL_CHECK(glVertexAttribPointer(m_iLocTexCoord, 2, GL_FLOAT, GL_FALSE, 0, textTextureCoordinates));
291  GL_CHECK(glUniformMatrix4fv(m_iLocProjection, 1, GL_FALSE, projectionMatrix.getAsArray()));
292 
293  GL_CHECK(glActiveTexture(GL_TEXTURE0));
294  GL_CHECK(glBindTexture(GL_TEXTURE_2D, textureID));
295 
296  GL_CHECK(glDrawElements(GL_TRIANGLE_STRIP, numberOfCharacters * 6 - 2, GL_UNSIGNED_SHORT, textIndex));
297 
298  GL_CHECK(glDisableVertexAttribArray(m_iLocTextColor));
299  GL_CHECK(glDisableVertexAttribArray(m_iLocTexCoord));
300  GL_CHECK(glDisableVertexAttribArray(m_iLocPosition));
301 
302  /* Pop previously used program object. */
303  GL_CHECK(glUseProgram(currentProgram));
304 
305  /* Pop previously bound vertex array object. */
306  GL_CHECK(glBindVertexArray(vertexArray));
307  }
308 
309  /* Please see header for specification. */
311  m_iLocPosition(-1),
312  m_iLocProjection(-1),
313  m_iLocTextColor(-1),
314  m_iLocTexCoord(-1),
315  m_iLocTexture(-1),
316  vertexShaderID(0),
317  fragmentShaderID(0),
318  programID(0),
319  textureID(0)
320  {
321  clear();
322  }
323 
324  /* Please see header for specification. */
326  {
327  clear();
328 
329  GL_CHECK(glDeleteTextures(1, &textureID));
330  }
331 }
GLuint create_program(const char *vertex_source, const char *fragment_source)
Create program object, attach vertex and fragment shader to it. Link program object and check whether...
const char fontFragmentShaderSource[]
Fragment shader source code for text rendering.
Definition: Text.h:52
void loadData(const char *filename, unsigned char **textureData)
Load texture data from a file into memory.
Definition: Text.cpp:38
float * textVertex
Definition: Text.h:106
#define MALLOC_CHECK(ptr_type, ptr, size)
Definition: AstcTextures.h:33
int windowWidth
Definition: Cube.cpp:56
GLuint textureID
#define LOGI(...)
Definition: AstcTextures.h:29
int m_iLocProjection
Definition: Text.h:111
GLint get_and_check_attrib_location(GLuint program, const GLchar *attrib_name)
Invoke glGetAttribLocation(), if it has returned a positive value. Otherwise, print a message and exi...
Definition: Text.cpp:73
const char fontVertexShaderSource[]
Vertex shader source code for text rendering.
Definition: Text.h:33
float * textTextureCoordinates
Definition: Text.h:107
Type representing texture coordinates.
Definition: Text.h:77
static const int textureCharacterHeight
The height (in pixels) of the characters in the text texture.
Definition: Text.h:131
void clear(void)
Removes the current string from the class.
Definition: Text.cpp:142
Matrix projectionMatrix
Definition: Text.h:104
Text(void)
Overloaded default constructor.
Definition: Text.cpp:310
float * color
Definition: Text.h:108
int m_iLocTexCoord
Definition: Text.h:113
GLint get_and_check_uniform_location(GLuint program, const GLchar *uniform_name)
Invoke glGetUniformLocation, if it has returned a positive value. Otherwise, print a message and exit...
Definition: Text.cpp:87
GLuint fragmentShaderID
precision highp int
Definition: hiz_cull.cs:38
static const char textureFilename[]
Definition: Text.h:92
int windowHeight
Definition: Cube.cpp:57
int m_iLocTexture
Definition: Text.h:114
int m_iLocPosition
Definition: Text.h:110
static Matrix matrixOrthographic(float left, float right, float bottom, float top, float zNear, float zFar)
Create and return an orthographic projection matrix.
Definition: Matrix.cpp:87
GLuint textureID
Definition: Text.h:118
static const int textureCharacterWidth
The width (in pixels) of the characters in the text texture.
Definition: Text.h:125
~Text(void)
Overloaded default destructor.
Definition: Text.cpp:325
GLuint fragmentShaderID
Definition: Text.h:116
int m_iLocTextColor
Definition: Text.h:112
GLuint programID
Definition: AntiAlias.cpp:60
#define GL_CHECK(x)
Definition: AstcTextures.h:59
unsigned char * textureData
Definition: ThreadSync.cpp:109
GLenum GLuint texture
Definition: gl2ext.h:385
string resourceDirectory
Definition: AntiAlias.cpp:55
float * getAsArray(void)
Get the matrix elements as a column major order array.
Definition: Matrix.cpp:52
#define REALLOC_CHECK(ptr_type, ptr, size)
Definition: AstcTextures.h:43
GLenum GLuint GLenum GLsizei length
Definition: gl2ext.h:134
GLuint vertexShaderID
#define LOGE(...)
Definition: AstcTextures.h:30
precision highp float
Definition: hiz_cull.cs:37
GLuint programID
Definition: Text.h:117
#define FREE_CHECK(ptr)
Definition: AstcTextures.h:53
static const float scale
Scaling factor to use when rendering the text.
Definition: Text.h:102
void draw(void)
Draw the text to the screen.
Definition: Text.cpp:257
GLshort * textIndex
Definition: Text.h:109
GLuint vertexShaderID
Definition: Text.h:115
void addString(int xPosition, int yPosition, const char *string, int red, int green, int blue, int alpha)
Add a std::string to be drawn to the screen.
Definition: Text.cpp:153
int numberOfCharacters
Definition: Text.h:105