From 58ccf0ba82212bfe923f001057d02c2331a2f10a Mon Sep 17 00:00:00 2001 From: sfan5 Date: Fri, 8 Nov 2024 13:15:20 +0100 Subject: [PATCH] Fix some smaller issues with texture/image handling --- irr/include/ITexture.h | 2 +- src/client/minimap.cpp | 10 +++---- src/client/render/interlaced.cpp | 4 +-- src/client/sky.cpp | 46 +++++++++++++++++++---------- src/client/sky.h | 9 +++--- src/irrlicht_changes/CGUITTFont.cpp | 1 + 6 files changed, 44 insertions(+), 28 deletions(-) diff --git a/irr/include/ITexture.h b/irr/include/ITexture.h index 64b42ee54..6cbf64bd3 100644 --- a/irr/include/ITexture.h +++ b/irr/include/ITexture.h @@ -182,7 +182,7 @@ public: //! Lock function. /** Locks the Texture and returns a pointer to access the pixels. After lock() has been called and all operations on the pixels - are done, you must call unlock(). + are done, you must call unlock(). Afterwards the pointer becomes invalid. Locks are not accumulating, hence one unlock will do for an arbitrary number of previous locks. You should avoid locking different levels without unlocking in between, though, because only the last level locked will be diff --git a/src/client/minimap.cpp b/src/client/minimap.cpp index f28f6a39a..b11d8b345 100644 --- a/src/client/minimap.cpp +++ b/src/client/minimap.cpp @@ -474,17 +474,15 @@ video::ITexture *Minimap::getMinimapTexture() blitMinimapPixelsToImageRadar(map_image); break; case MINIMAP_TYPE_TEXTURE: - // Want to use texture source, to : 1 find texture, 2 cache it + // FIXME: this is a pointless roundtrip through the gpu video::ITexture* texture = m_tsrc->getTexture(data->mode.texture); video::IImage* image = driver->createImageFromData( - texture->getColorFormat(), texture->getSize(), - texture->lock(video::ETLM_READ_ONLY), true, false); - texture->unlock(); + texture->getColorFormat(), texture->getSize(), + texture->lock(video::ETLM_READ_ONLY), true, false); auto dim = image->getDimension(); map_image->fill(video::SColor(255, 0, 0, 0)); - image->copyTo(map_image, irr::core::vector2d { ((data->mode.map_size - (static_cast(dim.Width))) >> 1) @@ -492,7 +490,9 @@ video::ITexture *Minimap::getMinimapTexture() ((data->mode.map_size - (static_cast(dim.Height))) >> 1) + data->pos.Z / data->mode.scale }); + image->drop(); + texture->unlock(); } map_image->copyToScaling(minimap_image); diff --git a/src/client/render/interlaced.cpp b/src/client/render/interlaced.cpp index 7399d9242..f56d8a3d9 100644 --- a/src/client/render/interlaced.cpp +++ b/src/client/render/interlaced.cpp @@ -24,7 +24,7 @@ void InitInterlacedMaskStep::run(PipelineContext &context) last_mask = mask; auto size = mask->getSize(); - u8 *data = reinterpret_cast(mask->lock()); + u8 *data = reinterpret_cast(mask->lock(video::ETLM_WRITE_ONLY)); for (u32 j = 0; j < size.Height; j++) { u8 val = j % 2 ? 0xff : 0x00; memset(data, val, 4 * size.Width); @@ -74,4 +74,4 @@ void populateInterlacedPipeline(RenderPipeline *pipeline, Client *client) merge->setRenderSource(buffer); merge->setRenderTarget(pipeline->createOwned()); pipeline->addStep(); -} \ No newline at end of file +} diff --git a/src/client/sky.cpp b/src/client/sky.cpp index cfce57ef3..8da7fc68e 100644 --- a/src/client/sky.cpp +++ b/src/client/sky.cpp @@ -145,21 +145,15 @@ void Sky::render() float offset = (1.0 - fabs(sin((m_time_of_day - 0.5) * irr::core::PI))) * 511; if (m_sun_tonemap) { - u8 * texels = (u8 *)m_sun_tonemap->lock(); - video::SColor* texel = (video::SColor *)(texels + (u32)offset * 4); - video::SColor texel_color (255, texel->getRed(), - texel->getGreen(), texel->getBlue()); - m_sun_tonemap->unlock(); + auto texel_color = m_sun_tonemap->getPixel(offset, 0); + texel_color.setAlpha(255); // Only accessed by our code later, not used by a shader m_materials[3].ColorParam = texel_color; } if (m_moon_tonemap) { - u8 * texels = (u8 *)m_moon_tonemap->lock(); - video::SColor* texel = (video::SColor *)(texels + (u32)offset * 4); - video::SColor texel_color (255, texel->getRed(), - texel->getGreen(), texel->getBlue()); - m_moon_tonemap->unlock(); + auto texel_color = m_moon_tonemap->getPixel(offset, 0); + texel_color.setAlpha(255); // Only accessed by our code later, not used by a shader m_materials[4].ColorParam = texel_color; } @@ -711,14 +705,33 @@ void Sky::place_sky_body( } } +// FIXME: stupid helper that does a pointless texture upload/download +static void getTextureAsImage(video::IImage *&dst, const std::string &name, ITextureSource *tsrc) +{ + if (dst) { + dst->drop(); + dst = nullptr; + } + if (tsrc->isKnownSourceImage(name)) { + auto *texture = tsrc->getTexture(name); + assert(texture); + auto *driver = RenderingEngine::get_video_driver(); + dst = driver->createImageFromData( + texture->getColorFormat(), texture->getSize(), + texture->lock(video::ETLM_READ_ONLY)); + texture->unlock(); + } +} + void Sky::setSunTexture(const std::string &sun_texture, const std::string &sun_tonemap, ITextureSource *tsrc) { // Ignore matching textures (with modifiers) entirely, // but lets at least update the tonemap before hand. - m_sun_params.tonemap = sun_tonemap; - m_sun_tonemap = tsrc->isKnownSourceImage(sun_tonemap) ? - tsrc->getTexture(sun_tonemap) : nullptr; + if (m_sun_params.tonemap != sun_tonemap) { + m_sun_params.tonemap = sun_tonemap; + getTextureAsImage(m_sun_tonemap, sun_tonemap, tsrc); + } if (m_sun_params.texture == sun_texture && !m_first_update) return; @@ -758,9 +771,10 @@ void Sky::setMoonTexture(const std::string &moon_texture, { // Ignore matching textures (with modifiers) entirely, // but lets at least update the tonemap before hand. - m_moon_params.tonemap = moon_tonemap; - m_moon_tonemap = tsrc->isKnownSourceImage(moon_tonemap) ? - tsrc->getTexture(moon_tonemap) : nullptr; + if (m_moon_params.tonemap != moon_tonemap) { + m_moon_params.tonemap = moon_tonemap; + getTextureAsImage(m_moon_tonemap, moon_tonemap, tsrc); + } if (m_moon_params.texture == moon_texture && !m_first_update) return; diff --git a/src/client/sky.h b/src/client/sky.h index 73f377ae2..0ba3ee62c 100644 --- a/src/client/sky.h +++ b/src/client/sky.h @@ -17,6 +17,7 @@ namespace irr::video { class IVideoDriver; + class IImage; } class IShaderSource; @@ -200,10 +201,10 @@ private: u64 m_seed = 0; irr_ptr m_stars; - video::ITexture *m_sun_texture; - video::ITexture *m_moon_texture; - video::ITexture *m_sun_tonemap; - video::ITexture *m_moon_tonemap; + video::ITexture *m_sun_texture = nullptr; + video::ITexture *m_moon_texture = nullptr; + video::IImage *m_sun_tonemap = nullptr; + video::IImage *m_moon_tonemap = nullptr; void updateStars(); diff --git a/src/irrlicht_changes/CGUITTFont.cpp b/src/irrlicht_changes/CGUITTFont.cpp index ee5ec6b35..8337390c1 100644 --- a/src/irrlicht_changes/CGUITTFont.cpp +++ b/src/irrlicht_changes/CGUITTFont.cpp @@ -1020,6 +1020,7 @@ video::IImage* CGUITTFont::createTextureFromChar(const char32_t& ch) pageholder->copyTo(image, core::position2di(0, 0), glyph.source_rect); tex->unlock(); + pageholder->drop(); return image; }