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;
181 m_enableTransparency =
true;
195 m_textureImage = img;
197 m_enableTransparency =
false;
211 m_textureImage = std::move(img);
212 m_textureImageAlpha = std::move(imgAlpha);
214 m_enableTransparency =
true;
227 m_textureImage = std::move(img);
229 m_enableTransparency =
false;
237 const size_t len, vector<unsigned char>&
data)
239 #ifdef TEXTUREOBJ_USE_MEMPOOL 243 CRenderizableShaderTexturedTriangles_MemPoolParams mem_params;
244 mem_params.len = len;
257 void* ptr = &
data[0];
259 return reinterpret_cast<unsigned char*
>(
260 std::align(16, 1 , ptr, space));
265 #if MRPT_HAS_OPENGL_GLUT 266 unsigned char* dataAligned =
nullptr;
267 vector<unsigned char>
data;
269 #ifdef TEXTUREOBJ_PROFILE_MEM_ALLOC 274 if (m_textureImage.isEmpty())
return;
278 if (m_texture_is_loaded)
281 glActiveTexture(GL_TEXTURE0);
282 glBindTexture(GL_TEXTURE_2D, m_glTextureName);
283 CHECK_OPENGL_ERROR();
291 m_glTextureName = getNewTextureNumber();
294 glActiveTexture(GL_TEXTURE0);
296 glBindTexture(GL_TEXTURE_2D, m_glTextureName);
297 CHECK_OPENGL_ERROR();
304 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
305 CHECK_OPENGL_ERROR();
312 GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
313 m_textureInterpolate ? GL_LINEAR : GL_NEAREST);
314 CHECK_OPENGL_ERROR();
318 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
319 CHECK_OPENGL_ERROR();
321 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
322 CHECK_OPENGL_ERROR();
328 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize);
329 while (m_textureImage.getHeight() > (
unsigned int)texSize ||
330 m_textureImage.getWidth() > (
unsigned int)texSize)
334 m_textureImageAlpha =
338 const int width = m_textureImage.getWidth();
339 const int height = m_textureImage.getHeight();
341 #ifdef TEXTUREOBJ_PROFILE_MEM_ALLOC 344 "opengl_texture: load %ix%i %s %stransp", width, height,
345 m_textureImage.isColor() ?
"RGB" :
"BW",
346 m_enableTransparency ?
"" :
"no ");
347 tim.
enter(sSec.c_str());
351 if (m_enableTransparency)
353 ASSERT_(!m_textureImageAlpha.isColor());
355 m_textureImageAlpha.getWidth(), m_textureImage.getWidth());
357 m_textureImageAlpha.getHeight(), m_textureImage.getHeight());
362 if (!m_textureImage.isColor())
363 m_textureImage = m_textureImage.colorImage();
366 if (m_enableTransparency)
370 #ifdef TEXTUREOBJ_PROFILE_MEM_ALLOC 372 "opengl_texture_alloc %ix%i (color,trans)", width, height);
373 tim.
enter(sSec.c_str());
378 #ifdef TEXTUREOBJ_PROFILE_MEM_ALLOC 379 tim.
leave(sSec.c_str());
382 for (
int y = 0; y < height; y++)
384 unsigned char* ptrSrcCol = m_textureImage(0, y, 0);
385 unsigned char* ptrSrcAlfa = m_textureImageAlpha(0, y);
386 unsigned char* ptr = dataAligned + y * width * 4;
388 for (
int x = 0; x < width; x++)
390 *ptr++ = *ptrSrcCol++;
391 *ptr++ = *ptrSrcCol++;
392 *ptr++ = *ptrSrcCol++;
393 *ptr++ = *ptrSrcAlfa++;
398 const GLenum img_type = GL_UNSIGNED_BYTE;
400 const bool is_RGB_order =
401 (m_textureImage.getChannelsOrder() == std::string(
"RGB"));
402 const GLenum img_format = (is_RGB_order ? GL_RGBA : GL_BGRA);
405 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
406 glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
408 GL_TEXTURE_2D, 0 , GL_RGBA8 ,
409 width, height, 0 , img_format, img_type, dataAligned);
410 CHECK_OPENGL_ERROR();
411 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
412 CHECK_OPENGL_ERROR();
420 const GLenum img_type = GL_UNSIGNED_BYTE;
421 const int nBytesPerPixel = m_textureImage.isColor() ? 3 : 1;
423 const bool is_RGB_order =
424 (m_textureImage.getChannelsOrder() == std::string(
"RGB"));
425 const GLenum img_format = nBytesPerPixel == 3
426 ? (is_RGB_order ? GL_RGB : GL_BGR)
430 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
431 CHECK_OPENGL_ERROR();
433 GL_UNPACK_ROW_LENGTH,
434 m_textureImage.getRowStride() / nBytesPerPixel);
435 CHECK_OPENGL_ERROR();
437 GL_TEXTURE_2D, 0 , GL_RGB8 , width,
438 height, 0 , img_format, img_type,
439 m_textureImage.ptrLine<uint8_t>(0));
440 CHECK_OPENGL_ERROR();
441 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
442 CHECK_OPENGL_ERROR();
446 m_texture_is_loaded =
true;
448 #ifdef TEXTUREOBJ_PROFILE_MEM_ALLOC 451 "opengl_texture: load %ix%i %s %stransp", width, height,
452 m_textureImage.isColor() ?
"RGB" :
"BW",
453 m_enableTransparency ?
"" :
"no ");
454 tim.
leave(sSec.c_str());
458 #ifdef TEXTUREOBJ_USE_MEMPOOL 465 CRenderizableShaderTexturedTriangles_MemPoolParams mem_params;
466 mem_params.len =
data.size();
470 data.swap(mem_block->data);
480 format(
"m_glTextureName=%i\n%s", m_glTextureName, e.what()));
495 catch (
const std::exception& e)
498 <<
"[~CRenderizableShaderTexturedTriangles] Ignoring exception: " 504 if (m_texture_is_loaded)
506 m_texture_is_loaded =
false;
507 releaseTextureName(m_glTextureName);
518 out << m_enableTransparency << m_textureInterpolate;
519 out << m_textureImage;
520 if (m_enableTransparency)
out << m_textureImageAlpha;
535 in >> m_enableTransparency >> m_textureInterpolate;
536 in >> m_textureImage;
537 if (m_enableTransparency)
539 in >> m_textureImageAlpha;
540 assignImage(m_textureImage, m_textureImageAlpha);
544 assignImage(m_textureImage);
559 #if MRPT_HAS_OPENGL_GLUT 562 glGenTextures(1, &textureID);
575 #if MRPT_HAS_OPENGL_GLUT 580 if (std::this_thread::get_id() == it->second)
583 glDeleteTextures(1, &t);
584 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