36 #define TEXTUREOBJ_USE_MEMPOOL 40 #if MRPT_HAS_OPENGL_GLUT 45 const auto n = m_triangles.size();
48 m_vertexBuffer.createOnce();
49 m_vertexBuffer.bind();
50 m_vertexBuffer.allocate(m_triangles.data(),
sizeof(m_triangles[0]) * n);
60 #if MRPT_HAS_OPENGL_GLUT 69 glUniform1i(s.
uniformId(
"textureSampler"), 0);
75 GLint enabled = m_enableLight ? 1 : 0;
76 glUniform1i(s.
uniformId(
"enableLight"), enabled);
80 if (m_enableLight && rc.lights && rc.shader->hasUniform(
"light_diffuse"))
83 glUniform4fv(s.
uniformId(
"light_diffuse"), 1, &rc.lights->diffuse.R);
84 glUniform4fv(s.
uniformId(
"light_ambient"), 1, &rc.lights->ambient.R);
85 glUniform4fv(s.
uniformId(
"light_specular"), 1, &rc.lights->specular.R);
87 s.
uniformId(
"light_direction"), 1, &rc.lights->direction.x);
92 const GLuint attr_position = rc.shader->attributeId(
"position");
94 glEnableVertexAttribArray(attr_position);
95 m_vertexBuffer.bind();
96 glVertexAttribPointer(
103 CHECK_OPENGL_ERROR();
106 const GLuint attr_normals = rc.shader->attributeId(
"vertexNormal");
107 glEnableVertexAttribArray(attr_normals);
108 m_vertexBuffer.bind();
109 glVertexAttribPointer(
116 CHECK_OPENGL_ERROR();
119 const GLuint attr_uv = rc.shader->attributeId(
"vertexUV");
120 glEnableVertexAttribArray(attr_uv);
121 m_vertexBuffer.bind();
122 glVertexAttribPointer(
129 CHECK_OPENGL_ERROR();
132 glDrawArrays(GL_TRIANGLES, 0, 3 * m_triangles.size());
133 CHECK_OPENGL_ERROR();
135 glDisableVertexAttribArray(attr_position);
136 glDisableVertexAttribArray(attr_uv);
137 glDisableVertexAttribArray(attr_normals);
143 #ifdef TEXTUREOBJ_USE_MEMPOOL 147 struct CRenderizableShaderTexturedTriangles_MemPoolParams
152 inline bool isSuitable(
153 const CRenderizableShaderTexturedTriangles_MemPoolParams& req)
const 155 return len == req.len;
164 CRenderizableShaderTexturedTriangles_MemPoolParams,
178 m_textureImage = img;
179 m_textureImageAlpha = imgAlpha;
180 m_textureImageAssigned =
true;
182 m_enableTransparency =
true;
196 m_textureImage = img;
197 m_textureImageAssigned =
true;
199 m_enableTransparency =
false;
213 m_textureImage = std::move(img);
214 m_textureImageAlpha = std::move(imgAlpha);
215 m_textureImageAssigned =
true;
217 m_enableTransparency =
true;
230 m_textureImage = std::move(img);
231 m_textureImageAssigned =
true;
233 m_enableTransparency =
false;
241 const size_t len, vector<unsigned char>&
data)
243 #ifdef TEXTUREOBJ_USE_MEMPOOL 247 CRenderizableShaderTexturedTriangles_MemPoolParams mem_params;
248 mem_params.len = len;
261 void* ptr = &
data[0];
263 return reinterpret_cast<unsigned char*
>(
264 std::align(16, 1 , ptr, space));
269 #if MRPT_HAS_OPENGL_GLUT 270 unsigned char* dataAligned =
nullptr;
271 vector<unsigned char>
data;
273 #ifdef TEXTUREOBJ_PROFILE_MEM_ALLOC 278 if (m_textureImage.isEmpty())
return;
282 if (m_texture_is_loaded)
285 glActiveTexture(GL_TEXTURE0);
286 glBindTexture(GL_TEXTURE_2D, m_glTextureName);
287 CHECK_OPENGL_ERROR();
295 m_glTextureName = getNewTextureNumber();
298 glActiveTexture(GL_TEXTURE0);
300 glBindTexture(GL_TEXTURE_2D, m_glTextureName);
301 CHECK_OPENGL_ERROR();
308 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
309 CHECK_OPENGL_ERROR();
316 GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
317 m_textureInterpolate ? GL_LINEAR : GL_NEAREST);
318 CHECK_OPENGL_ERROR();
322 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
323 CHECK_OPENGL_ERROR();
325 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
326 CHECK_OPENGL_ERROR();
332 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize);
333 while (m_textureImage.getHeight() > (
unsigned int)texSize ||
334 m_textureImage.getWidth() > (
unsigned int)texSize)
338 m_textureImageAlpha =
342 const int width = m_textureImage.getWidth();
343 const int height = m_textureImage.getHeight();
345 #ifdef TEXTUREOBJ_PROFILE_MEM_ALLOC 348 "opengl_texture: load %ix%i %s %stransp", width, height,
349 m_textureImage.isColor() ?
"RGB" :
"BW",
350 m_enableTransparency ?
"" :
"no ");
351 tim.
enter(sSec.c_str());
355 if (m_enableTransparency)
357 ASSERT_(!m_textureImageAlpha.isColor());
359 m_textureImageAlpha.getWidth(), m_textureImage.getWidth());
361 m_textureImageAlpha.getHeight(), m_textureImage.getHeight());
366 if (!m_textureImage.isColor())
367 m_textureImage = m_textureImage.colorImage();
370 if (m_enableTransparency)
374 #ifdef TEXTUREOBJ_PROFILE_MEM_ALLOC 376 "opengl_texture_alloc %ix%i (color,trans)", width, height);
377 tim.
enter(sSec.c_str());
382 #ifdef TEXTUREOBJ_PROFILE_MEM_ALLOC 383 tim.
leave(sSec.c_str());
386 for (
int y = 0; y < height; y++)
388 unsigned char* ptrSrcCol = m_textureImage(0, y, 0);
389 unsigned char* ptrSrcAlfa = m_textureImageAlpha(0, y);
390 unsigned char* ptr = dataAligned + y * width * 4;
392 for (
int x = 0; x < width; x++)
394 *ptr++ = *ptrSrcCol++;
395 *ptr++ = *ptrSrcCol++;
396 *ptr++ = *ptrSrcCol++;
397 *ptr++ = *ptrSrcAlfa++;
402 const GLenum img_type = GL_UNSIGNED_BYTE;
404 const bool is_RGB_order =
405 (m_textureImage.getChannelsOrder() == std::string(
"RGB"));
406 const GLenum img_format = (is_RGB_order ? GL_RGBA : GL_BGRA);
409 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
410 glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
412 GL_TEXTURE_2D, 0 , GL_RGBA8 ,
413 width, height, 0 , img_format, img_type, dataAligned);
414 CHECK_OPENGL_ERROR();
415 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
416 CHECK_OPENGL_ERROR();
424 const GLenum img_type = GL_UNSIGNED_BYTE;
425 const int nBytesPerPixel = m_textureImage.isColor() ? 3 : 1;
427 const bool is_RGB_order =
428 (m_textureImage.getChannelsOrder() == std::string(
"RGB"));
429 const GLenum img_format = nBytesPerPixel == 3
430 ? (is_RGB_order ? GL_RGB : GL_BGR)
434 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
435 CHECK_OPENGL_ERROR();
437 GL_UNPACK_ROW_LENGTH,
438 m_textureImage.getRowStride() / nBytesPerPixel);
439 CHECK_OPENGL_ERROR();
441 GL_TEXTURE_2D, 0 , GL_RGB8 , width,
442 height, 0 , img_format, img_type,
443 m_textureImage.ptrLine<uint8_t>(0));
444 CHECK_OPENGL_ERROR();
445 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
446 CHECK_OPENGL_ERROR();
450 m_texture_is_loaded =
true;
452 #ifdef TEXTUREOBJ_PROFILE_MEM_ALLOC 455 "opengl_texture: load %ix%i %s %stransp", width, height,
456 m_textureImage.isColor() ?
"RGB" :
"BW",
457 m_enableTransparency ?
"" :
"no ");
458 tim.
leave(sSec.c_str());
462 #ifdef TEXTUREOBJ_USE_MEMPOOL 469 CRenderizableShaderTexturedTriangles_MemPoolParams mem_params;
470 mem_params.len =
data.size();
474 data.swap(mem_block->data);
484 format(
"m_glTextureName=%i\n%s", m_glTextureName, e.what()));
499 catch (
const std::exception& e)
502 <<
"[~CRenderizableShaderTexturedTriangles] Ignoring exception: " 508 if (m_texture_is_loaded)
510 m_texture_is_loaded =
false;
511 releaseTextureName(m_glTextureName);
522 out << m_enableTransparency << m_textureInterpolate;
523 out << m_textureImage;
524 if (m_enableTransparency)
out << m_textureImageAlpha;
525 out << m_textureImageAssigned;
541 in >> m_enableTransparency >> m_textureInterpolate;
542 in >> m_textureImage;
543 if (m_enableTransparency)
545 in >> m_textureImageAlpha;
546 assignImage(m_textureImage, m_textureImageAlpha);
550 assignImage(m_textureImage);
553 in >> m_textureImageAssigned;
555 m_textureImageAssigned =
true;
569 #if MRPT_HAS_OPENGL_GLUT 572 glGenTextures(1, &textureID);
585 #if MRPT_HAS_OPENGL_GLUT 590 if (std::this_thread::get_id() == it->second)
593 glDeleteTextures(1, &t);
594 CHECK_OPENGL_ERROR();
#define IMPLEMENTS_VIRTUAL_SERIALIZABLE(class_name, base_class, NS)
This must be inserted as implementation of some required members for virtual CSerializable classes: ...
void renderUpdateBuffers() const override
Called whenever m_outdatedBuffers is true: used to re-generate OpenGL vertex buffers, etc.
#define THROW_EXCEPTION(msg)
std::string std::string format(std::string_view fmt, ARGS &&... args)
void notifyChange() const
Call to enable calling renderUpdateBuffers() before the next render() rendering iteration.
void dump_to_pool(const DATA_PARAMS ¶ms, POOLABLE_DATA *block)
Saves the passed data block (characterized by params) to the pool.
The base class of 3D objects that can be directly rendered through OpenGL.
POOLABLE_DATA * request_memory(const DATA_PARAMS ¶ms)
Request a block of data which fulfils the size requirements stated in params.
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
A generic system for versatile memory pooling.
#define ASSERT_(f)
Defines an assertion mechanism.
static unsigned char * reserveDataBuffer(const size_t len, vector< unsigned char > &data)
This base provides a set of functions for maths stuff.
#define ASSERT_EQUAL_(__A, __B)
Assert comparing two values, reporting their actual values upon failure.
void render(const RenderContext &rc) const override
Implements the rendering of 3D objects in each class derived from CRenderizable.
void readFromStreamTexturedObject(mrpt::serialization::CArchive &in)
static void releaseTextureName(unsigned int i)
vector< unsigned char > data
virtual void onUpdateBuffers_TexturedTriangles()=0
Must be implemented in derived classes to update the geometric entities to be drawn in "m_*_buffer" f...
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
static unsigned int getNewTextureNumber()
void enter(const std::string_view &func_name) noexcept
Start of a named section.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Virtual base class for "archives": classes abstracting I/O streams.
static std::map< unsigned int, std::thread::id > textureReservedFrom
A versatile "profiler" that logs the time spent within each pair of calls to enter(X)-leave(X), among other stats.
mrpt::vision::TStereoCalibResults out
void writeToStreamTexturedObject(mrpt::serialization::CArchive &out) const
The namespace for 3D scene representation and rendering.
double leave(const std::string_view &func_name) noexcept
End of a named section.
std::string exception_to_str(const std::exception &e)
Builds a nice textual representation of a nested exception, which if generated using MRPT macros (THR...
int uniformId(const char *name) const
A resource handling helper for OpenGL Shader "programs".
virtual void initializeTextures() const override
VERY IMPORTANT: If you use a multi-thread application, you MUST call this from the same thread that w...
Renderizable generic renderer for objects using the triangles-with-a-texture shader.
virtual ~CRenderizableShaderTexturedTriangles() override
void assignImage(const mrpt::img::CImage &img, const mrpt::img::CImage &imgAlpha)
Assigns a texture and a transparency image, and enables transparency (If the images are not 2^N x 2^M...
A class for storing images as grayscale or RGB bitmaps.
#define BUFFER_OFFSET(offset)
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...
static struct FontData data