Main MRPT website > C++ reference for MRPT 1.5.6
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;
470  if (m_enableTransparency) out << m_textureImageAlpha;
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  {
552  in >> m_enableTransparency;
553  in >> m_textureImage;
554  if (m_enableTransparency)
555  {
556  in >> m_textureImageAlpha;
557  assignImage( m_textureImage, m_textureImageAlpha );
558  }
559  else
560  {
561  assignImage( m_textureImage );
562  }
563  } break;
564  default:
566  };
568 }
virtual void render_dl() const MRPT_OVERRIDE
Derived classes must implement this method to the render the object.
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1166
#define GL_BGR
Definition: glew.h:1144
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...
#define GL_TEXTURE_WRAP_T
Definition: glew.h:664
#define GL_RGBA
Definition: glew.h:620
CImage scaleHalf() const
Returns a new image scaled down to half its original size.
Definition: CImage.h:282
A base class for all OpenGL objects with loadable textures.
GLAPI void GLAPIENTRY glEnable(GLenum cap)
#define GL_ZERO
Definition: glew.h:278
mrpt::system::CGenericMemoryPool< CTexturedObject_MemPoolParams, CTexturedObject_MemPoolData > TMyMemPool
A class for storing images as grayscale or RGB bitmaps.
Definition: CImage.h:101
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
#define THROW_EXCEPTION(msg)
void dump_to_pool(const DATA_PARAMS &params, POOLABLE_DATA *block)
Saves the passed data block (characterized by params) to the pool.
bool isColor() const
Returns true if the image is RGB, false if it is grayscale.
Definition: CImage.cpp:898
#define GL_BGRA
Definition: glew.h:6993
EIGEN_STRONG_INLINE void notifyChange() const
Must be called to notify that the object has changed (so, the display list must be updated) ...
#define GL_UNSIGNED_BYTE
Definition: glew.h:298
#define GL_LINEAR
Definition: glew.h:656
#define GL_ONE_MINUS_SRC_ALPHA
Definition: glew.h:283
#define GL_DEPTH_TEST
Definition: glew.h:397
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
POOLABLE_DATA * request_memory(const DATA_PARAMS &params)
Request a block of data which fulfils the size requirements stated in params.
unsigned int GLenum
Definition: glew.h:202
GLuint in
Definition: glew.h:7146
GLAPI void GLAPIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
unsigned char uint8_t
Definition: rptypes.h:43
A renderizable object suitable for rendering with OpenGL's display lists.
GLAPI void GLAPIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
A generic system for versatile memory pooling.
GLAPI void GLAPIENTRY glBindTexture(GLenum target, GLuint texture)
GLint GLvoid * img
Definition: glew.h:1290
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:38
vector< unsigned char > data
#define IMPLEMENTS_VIRTUAL_SERIALIZABLE(class_name, base_class_name, NameSpace)
This must be inserted as implementation of some required members for virtual CSerializable classes: ...
#define MRPT_END
virtual void render_pre() const
size_t len
size of the vector<unsigned char>
bool m_enableTransparency
Of the texture using "m_textureImageAlpha".
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
#define GL_ONE
Definition: glew.h:279
GLenum GLsizei len
Definition: glew.h:3955
GLint GLint GLint GLint GLint x
Definition: glew.h:1166
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:21
mrpt::utils::TColor m_color
Color components in the range [0,255].
Definition: CRenderizable.h:54
#define GL_RGB
Definition: glew.h:619
int version
Definition: mrpt_jpeglib.h:898
GLint GLenum GLsizei GLint GLsizei const GLvoid * data
Definition: glew.h:1284
#define GL_BLEND
Definition: glew.h:428
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
#define GL_REPEAT
Definition: glew.h:666
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
GLint GLint GLint GLint GLint GLint GLsizei GLsizei height
Definition: glew.h:1166
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...
unsigned char * reserveDataBuffer(const size_t len, vector< unsigned char > &data)
#define GL_NEAREST
Definition: glew.h:655
#define MRPT_START
#define GL_SRC_ALPHA
Definition: glew.h:282
static void checkOpenGLError()
Checks glGetError and throws an exception if an error situation is found.
#define GL_NO_ERROR
Definition: glew.h:322
#define GL_UNPACK_ROW_LENGTH
Definition: glew.h:477
#define GL_TEXTURE_MIN_FILTER
Definition: glew.h:662
void loadTextureInOpenGL() const
VERY IMPORTANT: If you use a multi-thread application, you MUST call this from the same thread that w...
GLsizei const GLcharARB ** string
Definition: glew.h:3293
#define GL_UNPACK_ALIGNMENT
Definition: glew.h:480
static unsigned int getNewTextureNumber()
Returns the lowest next free texture name (avoid using OpenGL's own function since we may call them f...
unsigned long POINTER_TYPE
For performing type casting from a pointer to its numeric value.
Definition: types_simple.h:42
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...
bool isSuitable(const CTexturedObject_MemPoolParams &req) const
#define GL_TEXTURE_MAG_FILTER
Definition: glew.h:661
mrpt::utils::CImage m_textureImage
virtual void render_post() const
GLAPI void GLAPIENTRY glGetIntegerv(GLenum pname, GLint *params)
GLAPI GLenum GLAPIENTRY glGetError(void)
#define ASSERT_(f)
A versatile "profiler" that logs the time spent within each pair of calls to enter(X)-leave(X), among other stats.
Definition: CTimeLogger.h:41
double leave(const char *func_name)
End of a named section.
Definition: CTimeLogger.h:102
int r_height
Size of the texture image, rounded up to next power of 2.
int GLint
Definition: glew.h:205
#define GL_MAX_TEXTURE_SIZE
Definition: glew.h:506
#define GL_LUMINANCE_ALPHA
Definition: glew.h:622
GLint GLint GLint GLint GLint GLint GLsizei width
Definition: glew.h:1166
void enter(const char *func_name)
Start of a named section.
Definition: CTimeLogger.h:97
GLAPI void GLAPIENTRY glDisable(GLenum cap)
const char * getChannelsOrder() const
Returns a string of the form "BGR","RGB" or "GRAY" indicating the channels ordering.
Definition: CImage.cpp:1180
GLAPI void GLAPIENTRY glPixelStorei(GLenum pname, GLint param)
size_t getWidth() const MRPT_OVERRIDE
Returns the width of the image in pixels.
Definition: CImage.cpp:855
#define GL_TEXTURE_WRAP_S
Definition: glew.h:663
#define GL_TEXTURE_2D
Definition: glew.h:6074
static void releaseTextureName(unsigned int i)
#define GL_LUMINANCE
Definition: glew.h:621
GLAPI void GLAPIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
mrpt::utils::CImage m_textureImageAlpha
size_t getHeight() const MRPT_OVERRIDE
Returns the height of the image in pixels.
Definition: CImage.cpp:884
void readFromStreamTexturedObject(mrpt::utils::CStream &in)
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, which checks the coordinates.
Definition: CImage.cpp:491



Page generated by Doxygen 1.8.6 for MRPT 1.5.6 Git: 4c65e84 Tue Apr 24 08:18:17 2018 +0200 at mar abr 24 08:26:17 CEST 2018