text_drawable.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2010-2025, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7  * Redistributions of source code must retain the above copyright
8  notice, this list of conditions and the following disclaimer.
9  * Redistributions in binary form must reproduce the above copyright
10  notice, this list of conditions and the following disclaimer in the
11  documentation and/or other materials provided with the distribution.
12  * Neither the name of the Universite de Sherbrooke nor the
13  names of its contributors may be used to endorse or promote products
14  derived from this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 
28 #ifdef __ANDROID__
29 #include <jni.h>
30 #endif
31 
32 #include <tango-gl/util.h>
33 #include <vector>
34 #include <rtabmap/core/Transform.h>
35 #include "util.h"
36 #include "text_drawable.h"
37 #include "text_atlas_png.h"
39 
40 const std::string kTextVertexShader =
41  "uniform mat4 uMVPMatrix;"
42  "attribute vec4 vPosition;"
43  "attribute vec2 a_texCoord;"
44  "varying vec2 v_texCoord;"
45  "void main() {"
46  " gl_Position = uMVPMatrix * vPosition;"
47  " v_texCoord = a_texCoord;"
48  "}";
49 const std::string kTextFragmentShader =
50  "precision mediump float;"
51  "uniform vec3 uColor;"
52  "varying vec2 v_texCoord;"
53  "uniform sampler2D s_texture;"
54  "void main() {"
55  " gl_FragColor = texture2D( s_texture, v_texCoord );"
56  " gl_FragColor.rgb = uColor;"
57  "}";
58 
59 const int RI_TEXT_TEXTURE_SIZE = 512; // 512
60 const float RI_TEXT_HEIGHT_BASE = 32.0f;
61 const char RI_TEXT_START = ' ';
62 const char RI_TEXT_STOP = '~'+1;
63 
69 std::vector<float> TextDrawable::textCharacterWidths_;
70 
72 {
74 
75  // hard-coded with text_atlas.png resource
76  textCharacterWidths_.resize(95);
78  textCharacterWidths_[1]=9.000000;
79  textCharacterWidths_[2]=10.000000;
80  textCharacterWidths_[3]=19.000000;
81  textCharacterWidths_[4]=18.000000;
82  textCharacterWidths_[5]=24.000000;
83  textCharacterWidths_[6]=21.000000;
84  textCharacterWidths_[7]=5.000000;
85  textCharacterWidths_[8]=11.000000;
86  textCharacterWidths_[9]=11.000000;
87  textCharacterWidths_[10]=15.000000;
88  textCharacterWidths_[11]=17.000000;
89  textCharacterWidths_[12]=8.000000;
90  textCharacterWidths_[13]=12.000000;
91  textCharacterWidths_[14]=9.000000;
92  textCharacterWidths_[15]=12.000000;
93  textCharacterWidths_[16]=18.000000;
94  textCharacterWidths_[17]=18.000000;
95  textCharacterWidths_[18]=18.000000;
96  textCharacterWidths_[19]=18.000000;
97  textCharacterWidths_[20]=18.000000;
98  textCharacterWidths_[21]=18.000000;
99  textCharacterWidths_[22]=18.000000;
100  textCharacterWidths_[23]=18.000000;
101  textCharacterWidths_[24]=18.000000;
102  textCharacterWidths_[25]=18.000000;
103  textCharacterWidths_[26]=9.000000;
104  textCharacterWidths_[27]=8.000000;
105  textCharacterWidths_[28]=16.000000;
106  textCharacterWidths_[29]=18.000000;
107  textCharacterWidths_[30]=17.000000;
108  textCharacterWidths_[31]=16.000000;
109  textCharacterWidths_[32]=29.000000;
110  textCharacterWidths_[33]=22.000000;
111  textCharacterWidths_[34]=20.000000;
112  textCharacterWidths_[35]=21.000000;
113  textCharacterWidths_[36]=21.000000;
114  textCharacterWidths_[37]=18.000000;
115  textCharacterWidths_[38]=18.000000;
116  textCharacterWidths_[39]=22.000000;
117  textCharacterWidths_[40]=23.000000;
118  textCharacterWidths_[41]=9.000000;
119  textCharacterWidths_[42]=18.000000;
120  textCharacterWidths_[43]=20.000000;
121  textCharacterWidths_[44]=17.000000;
122  textCharacterWidths_[45]=28.000000;
123  textCharacterWidths_[46]=23.000000;
124  textCharacterWidths_[47]=22.000000;
125  textCharacterWidths_[48]=21.000000;
126  textCharacterWidths_[49]=22.000000;
127  textCharacterWidths_[50]=20.000000;
128  textCharacterWidths_[51]=20.000000;
129  textCharacterWidths_[52]=20.000000;
130  textCharacterWidths_[53]=21.000000;
131  textCharacterWidths_[54]=21.000000;
132  textCharacterWidths_[55]=28.000000;
133  textCharacterWidths_[56]=20.000000;
134  textCharacterWidths_[57]=20.000000;
135  textCharacterWidths_[58]=19.000000;
136  textCharacterWidths_[59]=9.000000;
137  textCharacterWidths_[60]=14.000000;
138  textCharacterWidths_[61]=9.000000;
139  textCharacterWidths_[62]=14.000000;
140  textCharacterWidths_[63]=14.000000;
141  textCharacterWidths_[64]=11.000000;
142  textCharacterWidths_[65]=17.000000;
143  textCharacterWidths_[66]=18.000000;
144  textCharacterWidths_[67]=17.000000;
145  textCharacterWidths_[68]=18.000000;
146  textCharacterWidths_[69]=17.000000;
147  textCharacterWidths_[70]=11.000000;
148  textCharacterWidths_[71]=18.000000;
149  textCharacterWidths_[72]=18.000000;
150  textCharacterWidths_[73]=8.000000;
151  textCharacterWidths_[74]=8.000000;
152  textCharacterWidths_[75]=17.000000;
153  textCharacterWidths_[76]=8.000000;
154  textCharacterWidths_[77]=28.000000;
155  textCharacterWidths_[78]=18.000000;
156  textCharacterWidths_[79]=18.000000;
157  textCharacterWidths_[80]=18.000000;
158  textCharacterWidths_[81]=18.000000;
159  textCharacterWidths_[82]=12.000000;
160  textCharacterWidths_[83]=16.000000;
161  textCharacterWidths_[84]=11.000000;
162  textCharacterWidths_[85]=18.000000;
163  textCharacterWidths_[86]=16.000000;
164  textCharacterWidths_[87]=24.000000;
165  textCharacterWidths_[88]=16.000000;
166  textCharacterWidths_[89]=16.000000;
167  textCharacterWidths_[90]=16.000000;
168  textCharacterWidths_[91]=11.000000;
169  textCharacterWidths_[92]=8.000000;
170  textCharacterWidths_[93]=11.000000;
171  textCharacterWidths_[94]=21.000000;
172  textUVWidth_=0.062500;
173  textUVHeight_=0.082031;
174  textHeight_=42.000000;
175 
177  UASSERT(textProgram_ != 0);
178 
179  glGenTextures(1, &textTextureId_);
181 
182  // gen texture from image
183  glBindTexture(GL_TEXTURE_2D, textTextureId_);
184  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
185  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
186  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
187  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
188 
189  std::vector<char> data = uHex2Bytes(rtabmap::TEXT_ATLAS_PNG);
190 
191  cv::Mat rgbImage = cv::imdecode(data, cv::IMREAD_UNCHANGED);
192 
193  glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
194  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rgbImage.cols, rgbImage.rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbImage.data);
195 
196  GLint error = glGetError();
197  UASSERT(error == GL_NO_ERROR);
198 }
199 
201 {
202  if(textProgram_)
203  {
204  glDeleteShader(textProgram_);
205  textProgram_ = 0;
206  }
207 }
208 
210  const std::string & text,
211  const rtabmap::Transform & pose,
212  float textSize, // meters
213  const tango_gl::Color & color) :
214  poseGl_(glmFromTransform(pose)),
215  color_(color)
216 {
217  if(textProgram_ > 0)
218  {
219  vertexBuffer_ = std::vector<float>(text.size() * 12);
220  textureBuffer_ = std::vector<float>(text.size() * 8);
221  drawListBuffer_ = std::vector<unsigned short>(text.size() * 6);
222 
223  int index_vecs = 0;
224  int index_indices = 0;
225  int index_uvs = 0;
226  float x=0.0f;
227  float y=0.0f;
228  float uniformscale = textSize/textHeight_;
229  for(unsigned int i=0; i<text.size(); ++i)
230  {
231  // get ascii value
232  char c = text[i];
233  int c_val = (int)c;
234 
235  int indx = c_val-RI_TEXT_START;
236 
237  if(indx<0 || indx>=textCharacterWidths_.size()) {
238  // unknown character, we will add a space for it to be save.
239  indx = 0;
240  }
241 
243 
244  // Calculate the uv parts
245  int row = indx / colCount;
246  int col = indx % colCount;
247 
248  float v = row * textUVHeight_;
249  float v2 = v + textUVHeight_;
250  float u = col * textUVWidth_;
252 
253  // Creating the triangle information
254  std::vector<float> vec(12);
255  std::vector<float> uv(8);
256 
257  vec[0] = x;
258  vec[1] = y + (textHeight_ * uniformscale);
259  vec[2] = 0;
260  vec[3] = x;
261  vec[4] = y;
262  vec[5] = 0;
263  vec[6] = x + (textCharacterWidths_[indx] * uniformscale);
264  vec[7] = y;
265  vec[8] = 0;
266  vec[9] = x + (textCharacterWidths_[indx] * uniformscale);
267  vec[10] = y + (textHeight_ * uniformscale);
268  vec[11] = 0;
269 
270  // 0.001f = texture bleeding hack/fix
271  uv[0] = u+0.001f;
272  uv[1] = v+0.001f;
273  uv[2] = u+0.001f;
274  uv[3] = v2-0.001f;
275  uv[4] = u2-0.001f;
276  uv[5] = v2-0.001f;
277  uv[6] = u2-0.001f;
278  uv[7] = v+0.001f;
279 
280  unsigned short inds[6] = {0, 1, 2, 0, 2, 3};
281 
282  // We need a base value because the object has indices related to
283  // that object and not to this collection so basicly we need to
284  // translate the indices to align with the vertexlocation in ou
285  // vecs array of vectors.
286  short base = (short) (index_vecs / 3);
287 
288  // We should add the vec, translating the indices to our saved vector
289  for(int i=0;i<vec.size();i++)
290  {
291  vertexBuffer_[index_vecs] = vec[i];
292  index_vecs++;
293  }
294 
295  // We should add the uvs
296  for(int i=0;i<uv.size();i++)
297  {
298  textureBuffer_[index_uvs] = uv[i];
299  index_uvs++;
300  }
301 
302  // We handle the indices
303  for(int j=0;j<6;j++)
304  {
305  drawListBuffer_[index_indices] = (unsigned short) (base + inds[j]);
306  index_indices++;
307  }
308 
309  // Calculate the new position
310  x += (textCharacterWidths_[indx] * uniformscale);
311  }
312  }
313 }
314 
316  const glm::mat4 & projectionMatrix,
317  const glm::mat4 & viewMatrix,
318  const glm::mat4 & viewMatrixRotInv) const
319 {
320  glUseProgram(textProgram_);
321 
322  // get handle to vertex shader's vPosition member
323  int mPositionHandle = glGetAttribLocation(textProgram_, "vPosition");
324 
325  // Enable a handle to the triangle vertices
326  glEnableVertexAttribArray(mPositionHandle);
327 
328  // Prepare the background coordinate data
329  glVertexAttribPointer(mPositionHandle, 3, GL_FLOAT, false, 0, &vertexBuffer_[0]);
330 
331  int mTexCoordLoc = glGetAttribLocation(textProgram_, "a_texCoord" );
332 
333  // Prepare the texturecoordinates
334  glVertexAttribPointer ( mTexCoordLoc, 2, GL_FLOAT, false, 0, &textureBuffer_[0]);
335 
336  glEnableVertexAttribArray ( mPositionHandle );
337  glEnableVertexAttribArray ( mTexCoordLoc );
338 
339  // get handle to shape's transformation matrix
340  int mtrxhandle = glGetUniformLocation(textProgram_, "uMVPMatrix");
341 
342  // Apply the projection and view transformation
343  //glUniformMatrix4fv(mtrxhandle, 1, false, m, 0);
344  glm::mat4 mvp_mat = projectionMatrix * viewMatrix * poseGl_ * viewMatrixRotInv;//glm::toMat4(gesture_camera_->GetParent()->GetRotation());
345  glUniformMatrix4fv(mtrxhandle, 1, GL_FALSE, glm::value_ptr(mvp_mat));
346 
347  // get handle to color value
348  int colorhandle = glGetUniformLocation(textProgram_, "uColor");
349  glUniform3f(colorhandle, color_.r, color_.g, color_.b);
350 
351  int mSamplerLoc = glGetUniformLocation (textProgram_, "s_texture" );
352 
353  // Texture activate unit 0
354  glActiveTexture(GL_TEXTURE0);
355  // Bind the texture to this unit.
356  glBindTexture(GL_TEXTURE_2D, textTextureId_);
357  // Set the sampler texture unit to our selected id
358  glUniform1i ( mSamplerLoc, 0);
359 
360  // Draw the triangle
361  glDrawElements(GL_TRIANGLES, drawListBuffer_.size(), GL_UNSIGNED_SHORT, &drawListBuffer_[0]);
362 
363  // Disable vertex array
364  glDisableVertexAttribArray(mPositionHandle);
365  glDisableVertexAttribArray(mTexCoordLoc);
366 }
int
int
base
TextDrawable::textHeight_
static float textHeight_
Definition: text_drawable.h:42
c
Scalar Scalar * c
TextDrawable::textTextureId_
static GLuint textTextureId_
Definition: text_drawable.h:39
TextDrawable::vertexBuffer_
std::vector< float > vertexBuffer_
Definition: text_drawable.h:64
TextDrawable::color_
tango_gl::Color color_
Definition: text_drawable.h:68
Transform.h
col
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ColXpr col(Index i) const
util.h
glm::value_ptr
GLM_FUNC_DECL const genType::value_type * value_ptr(genType const &vec)
y
Matrix3f y
kTextFragmentShader
const std::string kTextFragmentShader
Definition: text_drawable.cpp:49
tango_gl::Color::g
float g
Definition: color.h:29
glm::detail::tmat4x4
Definition: type_mat.hpp:47
tango_gl::Color::r
float r
Definition: color.h:28
rtabmap::TEXT_ATLAS_PNG
static const char * TEXT_ATLAS_PNG
Definition: text_atlas_png.h:9
RI_TEXT_START
const char RI_TEXT_START
Definition: text_drawable.cpp:61
TextDrawable::Render
void Render(const glm::mat4 &projectionMatrix, const glm::mat4 &viewMatrix, const glm::mat4 &viewMatrixRotInv) const
Definition: text_drawable.cpp:315
GL_FALSE
#define GL_FALSE
Definition: dummy.cpp:79
TextDrawable::textUVHeight_
static float textUVHeight_
Definition: text_drawable.h:41
TextDrawable::textCharacterWidths_
static std::vector< float > textCharacterWidths_
Definition: text_drawable.h:43
data
int data[]
GLuint
unsigned int GLuint
Definition: dummy.cpp:78
j
std::ptrdiff_t j
UConversion.h
Some conversion functions.
tango_gl::util::CreateProgram
GLuint CreateProgram(const char *vertex_source, const char *fragment_source)
Definition: util.cpp:75
RI_TEXT_HEIGHT_BASE
const float RI_TEXT_HEIGHT_BASE
Definition: text_drawable.cpp:60
TextDrawable::createShaderProgram
static void createShaderProgram()
Definition: text_drawable.cpp:71
text_drawable.h
TextDrawable::textUVWidth_
static float textUVWidth_
Definition: text_drawable.h:40
TextDrawable::textureBuffer_
std::vector< float > textureBuffer_
Definition: text_drawable.h:65
text_atlas_png.h
glm::row
GLM_FUNC_DECL genType::row_type row(genType const &m, length_t const &index)
u2
Vector u2
TextDrawable::drawListBuffer_
std::vector< unsigned short > drawListBuffer_
Definition: text_drawable.h:66
UASSERT
#define UASSERT(condition)
x
x
error
void error(const char *str)
TextDrawable::TextDrawable
TextDrawable(const std::string &text, const rtabmap::Transform &pose, float textSize=0.1f, const tango_gl::Color &color=tango_gl::Color(1, 0, 0))
Definition: text_drawable.cpp:209
RI_TEXT_TEXTURE_SIZE
const int RI_TEXT_TEXTURE_SIZE
Definition: text_drawable.cpp:59
TextDrawable::textProgram_
static GLuint textProgram_
Definition: text_drawable.h:38
TextDrawable::releaseShaderProgram
static void releaseShaderProgram()
Definition: text_drawable.cpp:200
rtabmap::Transform
Definition: Transform.h:41
tango_gl::Color
Definition: color.h:21
kTextVertexShader
const std::string kTextVertexShader
Definition: text_drawable.cpp:40
TextDrawable::poseGl_
glm::mat4 poseGl_
Definition: text_drawable.h:67
v
Array< int, Dynamic, 1 > v
float
float
glUniformMatrix4fv
void glUniformMatrix4fv(GLuint, int, int, float *)
Definition: dummy.cpp:80
RI_TEXT_STOP
const char RI_TEXT_STOP
Definition: text_drawable.cpp:62
tango_gl::Color::b
float b
Definition: color.h:30
rtabmap::glmFromTransform
glm::mat4 glmFromTransform(const rtabmap::Transform &transform)
Definition: util.h:124
i
int i
text
text
uHex2Bytes
std::vector< char > UTILITE_EXPORT uHex2Bytes(const std::string &hex)
Definition: UConversion.cpp:223
v2
v2


rtabmap
Author(s): Mathieu Labbe
autogenerated on Mon Apr 28 2025 02:46:05