[Scummvm-git-logs] scummvm master -> 0bb4ba58512495f5f9362c0b801fe5fe980c5d95
aquadran
noreply at scummvm.org
Fri Sep 26 18:22:12 UTC 2025
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
0bb4ba5851 WINTERMUTE: Implement deferred image loading in 3D renderer in sync with 2D renderer
Commit: 0bb4ba58512495f5f9362c0b801fe5fe980c5d95
https://github.com/scummvm/scummvm/commit/0bb4ba58512495f5f9362c0b801fe5fe980c5d95
Author: PaweÅ KoÅodziejski (aquadran at gmail.com)
Date: 2025-09-26T20:22:06+02:00
Commit Message:
WINTERMUTE: Implement deferred image loading in 3D renderer in sync with 2D renderer
Changed paths:
engines/wintermute/base/gfx/opengl/base_surface_opengl3d.cpp
engines/wintermute/base/gfx/opengl/base_surface_opengl3d.h
engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
engines/wintermute/base/gfx/osystem/base_surface_osystem.h
diff --git a/engines/wintermute/base/gfx/opengl/base_surface_opengl3d.cpp b/engines/wintermute/base/gfx/opengl/base_surface_opengl3d.cpp
index 791af9a1663..128b1b47ca9 100644
--- a/engines/wintermute/base/gfx/opengl/base_surface_opengl3d.cpp
+++ b/engines/wintermute/base/gfx/opengl/base_surface_opengl3d.cpp
@@ -23,6 +23,7 @@
#include "graphics/transform_tools.h"
+#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_engine.h"
#include "engines/wintermute/base/gfx/base_image.h"
@@ -72,6 +73,16 @@ bool BaseSurfaceOpenGL3D::invalidate() {
return true;
}
+bool BaseSurfaceOpenGL3D::prepareToDraw() {
+ _lastUsedTime = _game->_liveTimer;
+
+ if (!_valid) {
+ loadImage();
+ }
+
+ return true;
+}
+
bool BaseSurfaceOpenGL3D::displayTransZoom(int x, int y, Common::Rect32 rect, float zoomX, float zoomY, uint32 alpha, Graphics::TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY) {
prepareToDraw();
@@ -133,85 +144,6 @@ bool BaseSurfaceOpenGL3D::create(const char *filename, bool defaultCK, byte ckRe
if (lifeTime != -1 && _lifeTime == 0) {
_valid = false;
- } else {
- if (!img.loadFile(surfacefilename)) {
- return false;
- }
-
- if (img.getSurface()->format.bytesPerPixel == 1 && img.getPalette() == nullptr) {
- return false;
- }
-
- bool needsColorKey = false;
- bool replaceAlpha = true;
-
- if (_imageData) {
- _imageData->free();
- delete _imageData;
- _imageData = nullptr;
- }
-
- _imageData = img.getSurface()->convertTo(Graphics::PixelFormat::createFormatRGBA32(), img.getPalette(), img.getPaletteCount());
-
- if (surfacefilename.matchString("savegame:*g", true)) {
- uint8 r, g, b, a;
- for (int x = 0; x < _imageData->w; x++) {
- for (int y = 0; y < _imageData->h; y++) {
- _imageData->format.colorToARGB(_imageData->getPixel(x, y), a, r, g, b);
- uint8 grey = (uint8)((0.2126f * r + 0.7152f * g + 0.0722f * b) + 0.5f);
- _imageData->setPixel(x, y, _imageData->format.ARGBToColor(a, grey, grey, grey));
- }
- }
- }
-
- if (surfacefilename.hasSuffix(".bmp")) {
- // Ignores alpha channel for BMPs
- needsColorKey = true;
- } else if (surfacefilename.hasSuffix(".jpg")) {
- // Ignores alpha channel for JPEGs
- needsColorKey = true;
- } else if (BaseEngine::instance().getTargetExecutable() < WME_LITE) {
- // WME 1.x always use colorkey, even for images with transparency
- needsColorKey = true;
- replaceAlpha = false;
- } else if (BaseEngine::instance().isFoxTail()) {
- // FoxTail does not use colorkey
- needsColorKey = false;
- } else if (img.getSurface()->format.aBits() == 0) {
- // generic WME Lite does not use colorkey for non-BMPs with transparency
- needsColorKey = true;
- }
-
- if (needsColorKey) {
- // We set the pixel color to transparent black,
- // like D3DX, if it matches the color key.
- _imageData->applyColorKey(ckRed, ckGreen, ckBlue, replaceAlpha, 0, 0, 0);
- }
-
- // Bug #6572 WME: Rosemary - Sprite flaw on going upwards
- // Some Rosemary sprites have non-fully transparent pixels
- // In original WME it wasn't seen because sprites were downscaled
- // Let's set alpha to 0 if it is smaller then some treshold
- if (BaseEngine::instance().getGameId() == "rosemary" && surfacefilename.hasPrefix("actors") && _imageData->format.bytesPerPixel == 4) {
- uint32 mask = _imageData->format.ARGBToColor(255, 0, 0, 0);
- uint32 treshold = _imageData->format.ARGBToColor(16, 0, 0, 0);
- uint32 blank = _imageData->format.ARGBToColor(0, 0, 0, 0);
-
- for (int x = 0; x < _imageData->w; x++) {
- for (int y = 0; y < _imageData->h; y++) {
- uint32 pixel = _imageData->getPixel(x, y);
- if ((pixel & mask) > blank && (pixel & mask) < treshold) {
- _imageData->setPixel(x, y, blank);
- }
- }
- }
- }
-
- putSurface(*_imageData);
-
- /* TODO: Delete _imageData if we no longer need to access the pixel data? */
-
- _valid = true;
}
_ckDefault = defaultCK;
@@ -235,6 +167,95 @@ bool BaseSurfaceOpenGL3D::create(const char *filename, bool defaultCK, byte ckRe
return true;
}
+bool BaseSurfaceOpenGL3D::loadImage() {
+ if (!_filename) {
+ return false;
+ }
+ Common::String filename = _filename;
+
+ BaseImage img = BaseImage();
+ if (!img.loadFile(filename)) {
+ return false;
+ }
+
+ if (img.getSurface()->format.bytesPerPixel == 1 && img.getPalette() == nullptr) {
+ return false;
+ }
+
+ bool needsColorKey = false;
+ bool replaceAlpha = true;
+
+ if (_imageData) {
+ _imageData->free();
+ delete _imageData;
+ _imageData = nullptr;
+ }
+
+ _imageData = img.getSurface()->convertTo(Graphics::PixelFormat::createFormatRGBA32(), img.getPalette(), img.getPaletteCount());
+
+ if (filename.matchString("savegame:*g", true)) {
+ uint8 r, g, b, a;
+ for (int x = 0; x < _imageData->w; x++) {
+ for (int y = 0; y < _imageData->h; y++) {
+ _imageData->format.colorToARGB(_imageData->getPixel(x, y), a, r, g, b);
+ uint8 grey = (uint8)((0.2126f * r + 0.7152f * g + 0.0722f * b) + 0.5f);
+ _imageData->setPixel(x, y, _imageData->format.ARGBToColor(a, grey, grey, grey));
+ }
+ }
+ }
+
+ if (filename.hasSuffix(".bmp")) {
+ // Ignores alpha channel for BMPs
+ needsColorKey = true;
+ } else if (filename.hasSuffix(".jpg")) {
+ // Ignores alpha channel for JPEGs
+ needsColorKey = true;
+ } else if (BaseEngine::instance().getTargetExecutable() < WME_LITE) {
+ // WME 1.x always use colorkey, even for images with transparency
+ needsColorKey = true;
+ replaceAlpha = false;
+ } else if (BaseEngine::instance().isFoxTail()) {
+ // FoxTail does not use colorkey
+ needsColorKey = false;
+ } else if (img.getSurface()->format.aBits() == 0) {
+ // generic WME Lite does not use colorkey for non-BMPs with transparency
+ needsColorKey = true;
+ }
+
+ if (needsColorKey) {
+ // We set the pixel color to transparent black,
+ // like D3DX, if it matches the color key.
+ _imageData->applyColorKey(_ckRed, _ckGreen, _ckBlue, replaceAlpha, 0, 0, 0);
+ }
+
+ // Bug #6572 WME: Rosemary - Sprite flaw on going upwards
+ // Some Rosemary sprites have non-fully transparent pixels
+ // In original WME it wasn't seen because sprites were downscaled
+ // Let's set alpha to 0 if it is smaller then some treshold
+ if (BaseEngine::instance().getGameId() == "rosemary" && filename.hasPrefix("actors") && _imageData->format.bytesPerPixel == 4) {
+ uint32 mask = _imageData->format.ARGBToColor(255, 0, 0, 0);
+ uint32 treshold = _imageData->format.ARGBToColor(16, 0, 0, 0);
+ uint32 blank = _imageData->format.ARGBToColor(0, 0, 0, 0);
+
+ for (int x = 0; x < _imageData->w; x++) {
+ for (int y = 0; y < _imageData->h; y++) {
+ uint32 pixel = _imageData->getPixel(x, y);
+ if ((pixel & mask) > blank && (pixel & mask) < treshold) {
+ _imageData->setPixel(x, y, blank);
+ }
+ }
+ }
+ }
+
+ putSurface(*_imageData);
+
+ /* TODO: Delete _imageData if we no longer need to access the pixel data? */
+
+ _valid = true;
+
+ return true;
+}
+
bool BaseSurfaceOpenGL3D::create(int width, int height) {
_width = width;
_height = height;
diff --git a/engines/wintermute/base/gfx/opengl/base_surface_opengl3d.h b/engines/wintermute/base/gfx/opengl/base_surface_opengl3d.h
index b55f16af3cb..97f87ee0d97 100644
--- a/engines/wintermute/base/gfx/opengl/base_surface_opengl3d.h
+++ b/engines/wintermute/base/gfx/opengl/base_surface_opengl3d.h
@@ -39,6 +39,7 @@ public:
~BaseSurfaceOpenGL3D();
bool invalidate() override;
+ bool prepareToDraw() override;
bool displayTransRotate(int x, int y, float rotate, int32 hotspotX, int32 hotspotY, Common::Rect32 rect, float zoomX, float zoomY, uint32 alpha = 0xFFFFFFFF, Graphics::TSpriteBlendMode blendMode = Graphics::BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) override;
bool displayTransZoom(int x, int y, Common::Rect32 rect, float zoomX, float zoomY, uint32 alpha = 0xFFFFFFFF, Graphics::TSpriteBlendMode blendMode = Graphics::BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) override;
@@ -57,6 +58,14 @@ public:
void setTexture();
+ int getWidth() override {
+ return _width;
+ }
+
+ int getHeight() override {
+ return _height;
+ }
+
GLuint getTextureName() {
return _tex;
}
@@ -79,6 +88,7 @@ private:
bool _pixelOpReady;
bool _surfaceModified;
+ bool loadImage();
void writeAlpha(Graphics::Surface *surface, const Graphics::Surface *mask);
};
diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
index 7d7187413a7..4c8b7cbb467 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
@@ -115,8 +115,12 @@ bool BaseSurfaceOSystem::create(const char *filename, bool defaultCK, byte ckRed
return STATUS_OK;
}
-bool BaseSurfaceOSystem::finishLoad() {
+bool BaseSurfaceOSystem::loadImage() {
+ if (!_filename) {
+ return false;
+ }
Common::String filename = _filename;
+
BaseImage *image = new BaseImage();
if (!image->loadFile(filename)) {
delete image;
@@ -274,7 +278,7 @@ bool BaseSurfaceOSystem::isTransparentAtLite(int x, int y) const {
//////////////////////////////////////////////////////////////////////////
bool BaseSurfaceOSystem::startPixelOp() {
if (!_valid) {
- if (DID_FAIL(finishLoad())) {
+ if (DID_FAIL(loadImage())) {
return STATUS_FAILED;
}
}
@@ -347,7 +351,7 @@ bool BaseSurfaceOSystem::drawSprite(int x, int y, Common::Rect32 *rect, Common::
// TODO: Skip this check if we can reuse an existing ticket?
if (!_valid) {
- finishLoad();
+ loadImage();
}
if (renderer->_forceAlphaColor != 0) {
diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.h b/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
index 6afbbb1b16a..7e96ca73525 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
@@ -60,15 +60,9 @@ public:
bool displayTiled(int x, int y, Common::Rect32 rect, int numTimesX, int numTimesY) override;
bool putSurface(const Graphics::Surface &surface, bool hasAlpha = false) override;
int getWidth() override {
- if (_width == 0) {
- finishLoad();
- }
return _width;
}
int getHeight() override {
- if (_height == 0) {
- finishLoad();
- }
return _height;
}
bool putPixel(int x, int y, byte r, byte g, byte b, byte a) override {
@@ -96,7 +90,7 @@ public:
Graphics::AlphaType getAlphaType() const { return _alphaType; }
private:
Graphics::Surface *_surface;
- bool finishLoad();
+ bool loadImage();
bool drawSprite(int x, int y, Common::Rect32 *rect, Common::Rect32 *newRect, Graphics::TransformStruct transformStruct);
void writeAlpha(Graphics::Surface *surface, const Graphics::Surface *mask);
More information about the Scummvm-git-logs
mailing list