Main MRPT website > C++ reference for MRPT 1.5.7
CTexturedObject.cpp
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 
10 #include "opengl-precomp.h" // Precompiled header
11 
13 #include <mrpt/utils/CTimeLogger.h>
14 #include <mrpt/utils/CStream.h>
15 #include "opengl_internals.h"
16 
17 using namespace mrpt;
18 using namespace mrpt::opengl;
19 using namespace mrpt::poses;
20 using namespace mrpt::utils;
21 using namespace mrpt::math;
22 using namespace std;
23 
25 
26 // Whether to profile memory allocations:
27 //#define TEXTUREOBJ_PROFILE_MEM_ALLOC
28 
29 // Whether to use a memory pool for the texture buffer:
30 #define TEXTUREOBJ_USE_MEMPOOL
31 
32 // Data types for memory pooling CTexturedObject:
33 #ifdef TEXTUREOBJ_USE_MEMPOOL
34 
36 
38  {
39  size_t len; //!< size of the vector<unsigned char>
40 
41  inline bool isSuitable(const CTexturedObject_MemPoolParams &req) const {
42  return len==req.len;
43  }
44  };
46  {
47  vector<unsigned char> data;
48  };
49 
51 #endif
52 
53 
54 /*---------------------------------------------------------------
55  CTexturedObject
56  ---------------------------------------------------------------*/
58  m_glTextureName(0),
59  m_texture_is_loaded(false),
60  m_enableTransparency(false)
61 {
62 }
63 
64 /*---------------------------------------------------------------
65  assignImage
66  ---------------------------------------------------------------*/
68  const CImage& img,
69  const CImage& imgAlpha )
70 {
72 
74 
75  unloadTexture();
76 
77  // Make a copy:
79  m_textureImageAlpha = imgAlpha;
80 
81  m_enableTransparency = true;
82 
83  MRPT_END
84 }
85 
86 
87 /*---------------------------------------------------------------
88  assignImage
89  ---------------------------------------------------------------*/
91  const CImage& img )
92 {
94 
96 
97  unloadTexture();
98 
99  // Make a copy:
101 
102  m_enableTransparency = false;
103 
104  MRPT_END
105 }
106 
107 /*---------------------------------------------------------------
108  assignImage
109  ---------------------------------------------------------------*/
111  CImage& img,
112  CImage& imgAlpha )
113 {
114  MRPT_START
115 
117 
118  unloadTexture();
119 
120  // Make a copy:
123 
124  m_enableTransparency = true;
125 
126  MRPT_END
127 }
128 
129 /*---------------------------------------------------------------
130  assignImage
131  ---------------------------------------------------------------*/
133  CImage& img )
134 {
135  MRPT_START
136 
138 
139  unloadTexture();
140 
141  // Make a copy:
143 
144  m_enableTransparency = false;
145 
146  MRPT_END
147 }
148 
149 
150 // Auxiliary function for loadTextureInOpenGL(): reserve memory and return 16byte aligned starting point within it:
151 unsigned char *reserveDataBuffer(const size_t len, vector<unsigned char> &data)
152 {
153 #ifdef TEXTUREOBJ_USE_MEMPOOL
155  if (pool)
156  {
158  mem_params.len = len;
159 
160  CTexturedObject_MemPoolData *mem_block = pool->request_memory(mem_params);
161  if (mem_block)
162  {
163  // Recover the memory block via a swap:
164  data.swap(mem_block->data);
165  delete mem_block;
166  }
167  }
168 #endif
169  data.resize(len);
170  return ((unsigned char*)(((POINTER_TYPE)&data[0]) & (~((POINTER_TYPE)0x0F)) )) + 0x10;
171 }
172 
173 
174 /*---------------------------------------------------------------
175  loadTextureInOpenGL
176  ---------------------------------------------------------------*/
178 {
179 #if MRPT_HAS_OPENGL_GLUT
180  unsigned char *dataAligned=NULL;
181  vector<unsigned char> data;
182 
183 # ifdef TEXTUREOBJ_PROFILE_MEM_ALLOC
184  static mrpt::utils::CTimeLogger tim;
185 # endif
186 
187 
188  try
189  {
191  {
194  return;
195  }
196 
197 
198  // Reserve the new one --------------------------
199 
200  // allocate texture names:
202 
203  // select our current texture
206 
207  // when texture area is small, linear interpolation. Default is GL_LINEAR_MIPMAP_NEAREST but we
208  // are not building mipmaps.
209  // See also: http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=133116&page=1
212 
213  // when texture area is large, NEAREST: this is mainly thinking of rendering
214  // occupancy grid maps, such as we want those "big pixels" to be clearly visible ;-)
217 
218  // if wrap is true, the texture wraps over at the edges (repeat)
219  // ... false, the texture ends at the edges (clamp)
222 
225 
226  // Assure that the images do not overpass the maximum dimensions allowed by OpenGL:
227  // ------------------------------------------------------------------------------------
228  GLint texSize;
230  while ( m_textureImage.getHeight()>(unsigned int)texSize || m_textureImage.getWidth()>(unsigned int)texSize )
231  {
234  }
235 
236  const int width = m_textureImage.getWidth();
237  const int height = m_textureImage.getHeight();
238 
239 # ifdef TEXTUREOBJ_PROFILE_MEM_ALLOC
240  {
241  const std::string sSec = mrpt::format("opengl_texture: load %ix%i %s %stransp",width,height, m_textureImage.isColor() ? "RGB":"BW", m_enableTransparency ? "":"no ");
242  tim.enter(sSec.c_str());
243  }
244 # endif
245 
246  r_width = width; //round2up( width );
247  r_height = height; // round2up( height );
248 
249  // Padding pixels:
252 
253 
255  {
259  }
260 
261  if (m_textureImage.isColor())
262  {
263  // Color texture:
265  {
266  // Color texture WITH trans.
267  // --------------------------------------
268 #ifdef TEXTUREOBJ_PROFILE_MEM_ALLOC
269  const std::string sSec = mrpt::format("opengl_texture_alloc %ix%i (color,trans)",width,height);
270  tim.enter(sSec.c_str());
271 #endif
272 
273  dataAligned = reserveDataBuffer(height*width*4 + 512, data );
274 
275 #ifdef TEXTUREOBJ_PROFILE_MEM_ALLOC
276  tim.leave(sSec.c_str());
277 #endif
278 
279  for (int y=0;y<height;y++)
280  {
281  unsigned char *ptrSrcCol = m_textureImage(0,y,0);
282  unsigned char *ptrSrcAlfa = m_textureImageAlpha(0,y);
283  unsigned char *ptr = dataAligned + y*width*4;
284 
285  for (int x=0;x<width;x++)
286  {
287  *ptr++ = *ptrSrcCol++;
288  *ptr++ = *ptrSrcCol++;
289  *ptr++ = *ptrSrcCol++;
290  *ptr++ = *ptrSrcAlfa++;
291  }
292  }
293 
294  // Prepare image data types:
295  const GLenum img_type = GL_UNSIGNED_BYTE;
296  const bool is_RGB_order = (!::strcmp(m_textureImage.getChannelsOrder(),"RGB")); // Reverse RGB <-> BGR order?
297  const GLenum img_format = (is_RGB_order ? GL_RGBA : GL_BGRA);
298 
299  // Send image data to OpenGL:
302  glTexImage2D(GL_TEXTURE_2D, 0 /*level*/, 4 /* RGB components */, width, height,0 /*border*/, img_format, img_type, dataAligned );
305 
306  // No need to hide a fill border:
307  m_pad_x_right = 0;
308  m_pad_y_bottom = 0;
309 
310  } // End of color texture WITH trans.
311  else
312  {
313  // Color texture WITHOUT trans.
314  // --------------------------------------
315  // Prepare image data types:
316  const GLenum img_type = GL_UNSIGNED_BYTE;
317  const int nBytesPerPixel = m_textureImage.isColor() ? 3 : 1;
318  const bool is_RGB_order = (!::strcmp(m_textureImage.getChannelsOrder(),"RGB")); // Reverse RGB <-> BGR order?
319  const GLenum img_format = nBytesPerPixel==3 ? (is_RGB_order ? GL_RGB : GL_BGR): GL_LUMINANCE;
320 
321  // Send image data to OpenGL:
324  glTexImage2D(GL_TEXTURE_2D, 0 /*level*/, 3 /* RGB components */, width, height,0 /*border*/, img_format, img_type, m_textureImage.get_unsafe(0,0) );
326 
327  // No need to hide a fill border:
328  m_pad_x_right = 0;
329  m_pad_y_bottom = 0;
330 
331  } // End of color texture WITHOUT trans.
332  }
333  else
334  {
335  // Gray-scale texture:
337  {
338 # ifdef TEXTUREOBJ_PROFILE_MEM_ALLOC
339  const std::string sSec = mrpt::format("opengl_texture_alloc %ix%i (gray,transp)",width,height);
340  tim.enter(sSec.c_str());
341 # endif
342 
343  dataAligned = reserveDataBuffer(height*width*2 + 1024, data );
344 
345 # ifdef TEXTUREOBJ_PROFILE_MEM_ALLOC
346  tim.leave(sSec.c_str());
347 # endif
348 
349  for (int y=0;y<height;y++)
350  {
351  unsigned char *ptrSrcCol = m_textureImage(0,y);
352  unsigned char *ptrSrcAlfa = m_textureImageAlpha(0,y);
353  unsigned char *ptr = dataAligned + y*width*2;
354  for (int x=0;x<width;x++)
355  {
356  *ptr++ = *ptrSrcCol++;
357  *ptr++ = *ptrSrcAlfa++;
358  }
359  }
360 
361  // Prepare image data types:
362  const GLenum img_type = GL_UNSIGNED_BYTE;
363  const GLenum img_format = GL_LUMINANCE_ALPHA;
364 
365  // Send image data to OpenGL:
368  glTexImage2D(GL_TEXTURE_2D, 0 /*level*/, 2 /* RGB components */, width, height,0 /*border*/, img_format, img_type, dataAligned );
371 
372  // No need to hide a fill border:
373  m_pad_x_right = 0;
374  m_pad_y_bottom = 0;
375 
376  }// End of gray-scale texture WITH trans.
377  else
378  {
379  // Prepare image data types:
380  const GLenum img_type = GL_UNSIGNED_BYTE;
381  const GLenum img_format = GL_LUMINANCE;
382 
383  // Send image data to OpenGL:
386  glTexImage2D(GL_TEXTURE_2D, 0 /*level*/, 1 /* RGB components */, width, height,0 /*border*/, img_format, img_type, m_textureImage(0,0) );
389 
390  // No need to hide a fill border:
391  m_pad_x_right = 0;
392  m_pad_y_bottom = 0;
393 
394  }// End of gray-scale texture WITHOUT trans.
395 
396  }
397 
398  m_texture_is_loaded = true;
399 
400 # ifdef TEXTUREOBJ_PROFILE_MEM_ALLOC
401  {
402  const std::string sSec = mrpt::format("opengl_texture: load %ix%i %s %stransp",width,height, m_textureImage.isColor() ? "RGB":"BW", m_enableTransparency ? "":"no ");
403  tim.leave(sSec.c_str());
404  }
405 # endif
406 
407 
408 #ifdef TEXTUREOBJ_USE_MEMPOOL
409  // Before freeing the buffer in "data", donate my memory to the pool:
410  if (!data.empty())
411  {
413  if (pool)
414  {
416  mem_params.len = data.size();
417 
419  data.swap(mem_block->data);
420 
421  pool->dump_to_pool(mem_params, mem_block);
422  }
423  }
424 #endif
425 
426  }
427  catch(exception &e)
428  {
429  THROW_EXCEPTION(format("m_glTextureName=%i\n%s",m_glTextureName,e.what()));
430  }
431  catch(...)
432  {
433  THROW_EXCEPTION("Runtime error!");
434  }
435 #endif
436 }
437 
438 /*---------------------------------------------------------------
439  ~CTexturedObject
440  ---------------------------------------------------------------*/
442 {
443  unloadTexture();
444 }
445 
446 /*---------------------------------------------------------------
447  unloadTexture
448  ---------------------------------------------------------------*/
450 {
452  {
453  m_texture_is_loaded = false;
455  m_glTextureName = 0;
456  }
457 }
458 
459 /*---------------------------------------------------------------
460  Implements the writing to a CStream capability of
461  CSerializable objects
462  ---------------------------------------------------------------*/
464 {
465  uint8_t ver = 0;
466 
467  out << ver;
468  out << m_enableTransparency;
469  out << m_textureImage;
471 }
472 
474 {
475 #if MRPT_HAS_OPENGL_GLUT
476  render_pre();
477  if (glGetError()!= GL_NO_ERROR)
478  std::cerr << "render_pre: Error" << std::endl;
480  if (glGetError()!= GL_NO_ERROR)
481  std::cerr << "render_texturedobj: Error" << std::endl;
482  render_post();
483  if (glGetError()!= GL_NO_ERROR)
484  std::cerr << "render_post: Error" << std::endl;
485 #endif
486 }
487 
488 
490 {
491 #if MRPT_HAS_OPENGL_GLUT
492  MRPT_START
495 
496  if (m_enableTransparency || m_color.A!=255)
497  {
501  }
502  else
503  {
506  }
507 
508  // This will load and/or select our texture, only if "m_texture_is_loaded" is false
510  MRPT_END
511 #endif
512 }
513 
515 {
516 #if MRPT_HAS_OPENGL_GLUT
517  MRPT_START
518 
519  if (m_enableTransparency || m_color.A!=255)
520  {
523 
525 
528  }
529 
532 
533  MRPT_END
534 #endif
535 }
536 
537 /*---------------------------------------------------------------
538  Implements the reading from a CStream capability of
539  CSerializable objects
540  ---------------------------------------------------------------*/
542 {
544  in >> version;
545 
547 
548  switch(version)
549  {
550  case 0:
551  {
553  in >> m_textureImage;
555  {
558  }
559  else
560  {
562  }
563  } break;
564  default:
566  };
568 }
#define IMPLEMENTS_VIRTUAL_SERIALIZABLE(class_name, base_class_name, NameSpace)
This must be inserted as implementation of some required members for virtual CSerializable classes:
mrpt::system::CGenericMemoryPool< CTexturedObject_MemPoolParams, CTexturedObject_MemPoolData > TMyMemPool
unsigned char * reserveDataBuffer(const size_t len, vector< unsigned char > &data)
A renderizable object suitable for rendering with OpenGL's display lists.
EIGEN_STRONG_INLINE void notifyChange() const
Must be called to notify that the object has changed (so, the display list must be updated)
static void releaseTextureName(unsigned int i)
static unsigned int getNewTextureNumber()
Returns the lowest next free texture name (avoid using OpenGL's own function since we may call them f...
static void checkOpenGLError()
Checks glGetError and throws an exception if an error situation is found.
mrpt::utils::TColor m_color
Color components in the range [0,255].
Definition: CRenderizable.h:54
A base class for all OpenGL objects with loadable textures.
void loadTextureInOpenGL() const
VERY IMPORTANT: If you use a multi-thread application, you MUST call this from the same thread that w...
virtual void render_pre() const
void readFromStreamTexturedObject(mrpt::utils::CStream &in)
virtual void render_dl() const MRPT_OVERRIDE
Derived classes must implement this method to the render the object.
mrpt::utils::CImage m_textureImage
void assignImage_fast(mrpt::utils::CImage &img, mrpt::utils::CImage &imgAlpha)
Similar to assignImage, but the passed images will be returned as empty: it avoids making a copy of t...
void writeToStreamTexturedObject(mrpt::utils::CStream &out) const
virtual void render_texturedobj() const =0
Must be implemented by derived classes.
int m_pad_y_bottom
The size of the fill in pixels in the textured image, w.r.t the image passed by the user.
int r_height
Size of the texture image, rounded up to next power of 2.
void assignImage(const mrpt::utils::CImage &img, const mrpt::utils::CImage &imgAlpha)
Assigns a texture and a transparency image, and enables transparency (If the images are not 2^N x 2^M...
mrpt::utils::CImage m_textureImageAlpha
bool m_enableTransparency
Of the texture using "m_textureImageAlpha".
virtual void render_post() const
A generic system for versatile memory pooling.
POOLABLE_DATA * request_memory(const DATA_PARAMS &params)
Request a block of data which fulfils the size requirements stated in params.
static CGenericMemoryPool< DATA_PARAMS, POOLABLE_DATA > * getInstance(const size_t max_pool_entries=5)
Construct-on-first-use (~singleton) pattern: Return the unique instance of this class for a given tem...
void dump_to_pool(const DATA_PARAMS &params, POOLABLE_DATA *block)
Saves the passed data block (characterized by params) to the pool.
A class for storing images as grayscale or RGB bitmaps.
Definition: CImage.h:102
unsigned char * get_unsafe(unsigned int col, unsigned int row, unsigned int channel=0) const
Access to pixels without checking boundaries - Use normally the () operator better,...
Definition: CImage.cpp:491
CImage scaleHalf() const
Returns a new image scaled down to half its original size.
Definition: CImage.h:282
size_t getRowStride() const
Returns the row stride of the image: this is the number of bytes between two consecutive rows.
Definition: CImage.cpp:869
bool isColor() const
Returns true if the image is RGB, false if it is grayscale.
Definition: CImage.cpp:898
size_t getHeight() const MRPT_OVERRIDE
Returns the height of the image in pixels.
Definition: CImage.cpp:884
size_t getWidth() const MRPT_OVERRIDE
Returns the width of the image in pixels.
Definition: CImage.cpp:855
void copyFastFrom(CImage &o)
Moves an image from another object, erasing the origin image in the process (this is much faster than...
Definition: CImage.cpp:167
const char * getChannelsOrder() const
Returns a string of the form "BGR","RGB" or "GRAY" indicating the channels ordering.
Definition: CImage.cpp:1180
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:39
A versatile "profiler" that logs the time spent within each pair of calls to enter(X)-leave(X),...
Definition: CTimeLogger.h:42
void enter(const char *func_name)
Start of a named section.
Definition: CTimeLogger.h:97
double leave(const char *func_name)
End of a named section.
Definition: CTimeLogger.h:102
#define GL_MAX_TEXTURE_SIZE
Definition: glew.h:506
#define GL_TEXTURE_MIN_FILTER
Definition: glew.h:662
GLAPI void GLAPIENTRY glEnable(GLenum cap)
#define GL_TEXTURE_WRAP_S
Definition: glew.h:663
#define GL_BGR
Definition: glew.h:1144
#define GL_LUMINANCE_ALPHA
Definition: glew.h:622
#define GL_DEPTH_TEST
Definition: glew.h:397
#define GL_LINEAR
Definition: glew.h:656
#define GL_SRC_ALPHA
Definition: glew.h:282
#define GL_BGRA
Definition: glew.h:6993
#define GL_LUMINANCE
Definition: glew.h:621
#define GL_RGB
Definition: glew.h:619
#define GL_ZERO
Definition: glew.h:278
#define GL_NEAREST
Definition: glew.h:655
unsigned int GLenum
Definition: glew.h:202
#define GL_UNSIGNED_BYTE
Definition: glew.h:298
#define GL_NO_ERROR
Definition: glew.h:322
GLAPI void GLAPIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
#define GL_UNPACK_ALIGNMENT
Definition: glew.h:480
GLAPI void GLAPIENTRY glBindTexture(GLenum target, GLuint texture)
GLAPI GLenum GLAPIENTRY glGetError(void)
#define GL_RGBA
Definition: glew.h:620
#define GL_BLEND
Definition: glew.h:428
#define GL_ONE_MINUS_SRC_ALPHA
Definition: glew.h:283
#define GL_REPEAT
Definition: glew.h:666
#define GL_ONE
Definition: glew.h:279
GLAPI void GLAPIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
#define GL_TEXTURE_WRAP_T
Definition: glew.h:664
#define GL_TEXTURE_MAG_FILTER
Definition: glew.h:661
int GLint
Definition: glew.h:205
GLAPI void GLAPIENTRY glDisable(GLenum cap)
#define GL_TEXTURE_2D
Definition: glew.h:6074
GLAPI void GLAPIENTRY glPixelStorei(GLenum pname, GLint param)
GLAPI void GLAPIENTRY glGetIntegerv(GLenum pname, GLint *params)
GLAPI void GLAPIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
#define GL_UNPACK_ROW_LENGTH
Definition: glew.h:477
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: glext.h:3520
GLenum GLsizei len
Definition: glext.h:4349
GLenum GLint GLint y
Definition: glext.h:3516
GLenum GLsizei width
Definition: glext.h:3513
GLuint in
Definition: glext.h:6301
GLint GLvoid * img
Definition: glext.h:3645
GLenum GLint x
Definition: glext.h:3516
GLenum GLsizei GLsizei height
Definition: glext.h:3523
GLsizei const GLchar ** string
Definition: glext.h:3919
unsigned long POINTER_TYPE
For performing type casting from a pointer to its numeric value.
Definition: types_simple.h:42
int version
Definition: mrpt_jpeglib.h:898
#define MRPT_START
Definition: mrpt_macros.h:366
#define ASSERT_(f)
Definition: mrpt_macros.h:278
#define MRPT_END
Definition: mrpt_macros.h:370
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
Definition: mrpt_macros.h:217
#define THROW_EXCEPTION(msg)
Definition: mrpt_macros.h:154
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:20
The namespace for 3D scene representation and rendering.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Definition: CPoint.h:18
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values,...
Definition: zip.h:16
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:21
unsigned char uint8_t
Definition: rptypes.h:43
vector< unsigned char > data
bool isSuitable(const CTexturedObject_MemPoolParams &req) const
size_t len
size of the vector<unsigned char>



Page generated by Doxygen 1.9.1 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at mar 26 may 2026 13:12:03 CEST