[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