Fix some smaller issues with texture/image handling

This commit is contained in:
sfan5 2024-11-08 13:15:20 +01:00
parent 4aae31ad5e
commit 58ccf0ba82
6 changed files with 44 additions and 28 deletions

@ -182,7 +182,7 @@ public:
//! Lock function. //! Lock function.
/** Locks the Texture and returns a pointer to access the /** Locks the Texture and returns a pointer to access the
pixels. After lock() has been called and all operations on the pixels 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 Locks are not accumulating, hence one unlock will do for an arbitrary
number of previous locks. You should avoid locking different levels without number of previous locks. You should avoid locking different levels without
unlocking in between, though, because only the last level locked will be unlocking in between, though, because only the last level locked will be

@ -474,17 +474,15 @@ video::ITexture *Minimap::getMinimapTexture()
blitMinimapPixelsToImageRadar(map_image); blitMinimapPixelsToImageRadar(map_image);
break; break;
case MINIMAP_TYPE_TEXTURE: 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::ITexture* texture = m_tsrc->getTexture(data->mode.texture);
video::IImage* image = driver->createImageFromData( video::IImage* image = driver->createImageFromData(
texture->getColorFormat(), texture->getSize(), texture->getColorFormat(), texture->getSize(),
texture->lock(video::ETLM_READ_ONLY), true, false); texture->lock(video::ETLM_READ_ONLY), true, false);
texture->unlock();
auto dim = image->getDimension(); auto dim = image->getDimension();
map_image->fill(video::SColor(255, 0, 0, 0)); map_image->fill(video::SColor(255, 0, 0, 0));
image->copyTo(map_image, image->copyTo(map_image,
irr::core::vector2d<int> { irr::core::vector2d<int> {
((data->mode.map_size - (static_cast<int>(dim.Width))) >> 1) ((data->mode.map_size - (static_cast<int>(dim.Width))) >> 1)
@ -492,7 +490,9 @@ video::ITexture *Minimap::getMinimapTexture()
((data->mode.map_size - (static_cast<int>(dim.Height))) >> 1) ((data->mode.map_size - (static_cast<int>(dim.Height))) >> 1)
+ data->pos.Z / data->mode.scale + data->pos.Z / data->mode.scale
}); });
image->drop(); image->drop();
texture->unlock();
} }
map_image->copyToScaling(minimap_image); map_image->copyToScaling(minimap_image);

@ -24,7 +24,7 @@ void InitInterlacedMaskStep::run(PipelineContext &context)
last_mask = mask; last_mask = mask;
auto size = mask->getSize(); auto size = mask->getSize();
u8 *data = reinterpret_cast<u8 *>(mask->lock()); u8 *data = reinterpret_cast<u8 *>(mask->lock(video::ETLM_WRITE_ONLY));
for (u32 j = 0; j < size.Height; j++) { for (u32 j = 0; j < size.Height; j++) {
u8 val = j % 2 ? 0xff : 0x00; u8 val = j % 2 ? 0xff : 0x00;
memset(data, val, 4 * size.Width); memset(data, val, 4 * size.Width);
@ -74,4 +74,4 @@ void populateInterlacedPipeline(RenderPipeline *pipeline, Client *client)
merge->setRenderSource(buffer); merge->setRenderSource(buffer);
merge->setRenderTarget(pipeline->createOwned<ScreenTarget>()); merge->setRenderTarget(pipeline->createOwned<ScreenTarget>());
pipeline->addStep<DrawHUD>(); pipeline->addStep<DrawHUD>();
} }

@ -145,21 +145,15 @@ void Sky::render()
float offset = (1.0 - fabs(sin((m_time_of_day - 0.5) * irr::core::PI))) * 511; float offset = (1.0 - fabs(sin((m_time_of_day - 0.5) * irr::core::PI))) * 511;
if (m_sun_tonemap) { if (m_sun_tonemap) {
u8 * texels = (u8 *)m_sun_tonemap->lock(); auto texel_color = m_sun_tonemap->getPixel(offset, 0);
video::SColor* texel = (video::SColor *)(texels + (u32)offset * 4); texel_color.setAlpha(255);
video::SColor texel_color (255, texel->getRed(),
texel->getGreen(), texel->getBlue());
m_sun_tonemap->unlock();
// Only accessed by our code later, not used by a shader // Only accessed by our code later, not used by a shader
m_materials[3].ColorParam = texel_color; m_materials[3].ColorParam = texel_color;
} }
if (m_moon_tonemap) { if (m_moon_tonemap) {
u8 * texels = (u8 *)m_moon_tonemap->lock(); auto texel_color = m_moon_tonemap->getPixel(offset, 0);
video::SColor* texel = (video::SColor *)(texels + (u32)offset * 4); texel_color.setAlpha(255);
video::SColor texel_color (255, texel->getRed(),
texel->getGreen(), texel->getBlue());
m_moon_tonemap->unlock();
// Only accessed by our code later, not used by a shader // Only accessed by our code later, not used by a shader
m_materials[4].ColorParam = texel_color; 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, void Sky::setSunTexture(const std::string &sun_texture,
const std::string &sun_tonemap, ITextureSource *tsrc) const std::string &sun_tonemap, ITextureSource *tsrc)
{ {
// Ignore matching textures (with modifiers) entirely, // Ignore matching textures (with modifiers) entirely,
// but lets at least update the tonemap before hand. // but lets at least update the tonemap before hand.
m_sun_params.tonemap = sun_tonemap; if (m_sun_params.tonemap != sun_tonemap) {
m_sun_tonemap = tsrc->isKnownSourceImage(sun_tonemap) ? m_sun_params.tonemap = sun_tonemap;
tsrc->getTexture(sun_tonemap) : nullptr; getTextureAsImage(m_sun_tonemap, sun_tonemap, tsrc);
}
if (m_sun_params.texture == sun_texture && !m_first_update) if (m_sun_params.texture == sun_texture && !m_first_update)
return; return;
@ -758,9 +771,10 @@ void Sky::setMoonTexture(const std::string &moon_texture,
{ {
// Ignore matching textures (with modifiers) entirely, // Ignore matching textures (with modifiers) entirely,
// but lets at least update the tonemap before hand. // but lets at least update the tonemap before hand.
m_moon_params.tonemap = moon_tonemap; if (m_moon_params.tonemap != moon_tonemap) {
m_moon_tonemap = tsrc->isKnownSourceImage(moon_tonemap) ? m_moon_params.tonemap = moon_tonemap;
tsrc->getTexture(moon_tonemap) : nullptr; getTextureAsImage(m_moon_tonemap, moon_tonemap, tsrc);
}
if (m_moon_params.texture == moon_texture && !m_first_update) if (m_moon_params.texture == moon_texture && !m_first_update)
return; return;

@ -17,6 +17,7 @@
namespace irr::video namespace irr::video
{ {
class IVideoDriver; class IVideoDriver;
class IImage;
} }
class IShaderSource; class IShaderSource;
@ -200,10 +201,10 @@ private:
u64 m_seed = 0; u64 m_seed = 0;
irr_ptr<scene::SMeshBuffer> m_stars; irr_ptr<scene::SMeshBuffer> m_stars;
video::ITexture *m_sun_texture; video::ITexture *m_sun_texture = nullptr;
video::ITexture *m_moon_texture; video::ITexture *m_moon_texture = nullptr;
video::ITexture *m_sun_tonemap; video::IImage *m_sun_tonemap = nullptr;
video::ITexture *m_moon_tonemap; video::IImage *m_moon_tonemap = nullptr;
void updateStars(); void updateStars();

@ -1020,6 +1020,7 @@ video::IImage* CGUITTFont::createTextureFromChar(const char32_t& ch)
pageholder->copyTo(image, core::position2di(0, 0), glyph.source_rect); pageholder->copyTo(image, core::position2di(0, 0), glyph.source_rect);
tex->unlock(); tex->unlock();
pageholder->drop();
return image; return image;
} }