[Scummvm-git-logs] scummvm master -> 12535f4bb9b4dcafd5983ba7fa6922e3feedfb6a

aquadran noreply at scummvm.org
Tue Nov 19 20:08:40 UTC 2024


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
12535f4bb9 WINTERMUTE: Initial greyscale and sepia filter implementation in classic GL renderer for blackandwhite plugin


Commit: 12535f4bb9b4dcafd5983ba7fa6922e3feedfb6a
    https://github.com/scummvm/scummvm/commit/12535f4bb9b4dcafd5983ba7fa6922e3feedfb6a
Author: Paweł Kołodziejski (aquadran at gmail.com)
Date: 2024-11-19T21:08:35+01:00

Commit Message:
WINTERMUTE: Initial greyscale and sepia filter implementation in classic GL renderer for blackandwhite plugin

Changed paths:
    engines/wintermute/base/gfx/base_renderer3d.h
    engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp
    engines/wintermute/base/gfx/opengl/base_render_opengl3d.h
    engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
    engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h
    engines/wintermute/ext/wme_blackandwhite.cpp
    engines/wintermute/ext/wme_blackandwhite.h


diff --git a/engines/wintermute/base/gfx/base_renderer3d.h b/engines/wintermute/base/gfx/base_renderer3d.h
index f201da33903..3690bec3831 100644
--- a/engines/wintermute/base/gfx/base_renderer3d.h
+++ b/engines/wintermute/base/gfx/base_renderer3d.h
@@ -56,6 +56,12 @@ class ShadowVolume;
 #define DEFAULT_NEAR_PLANE 90.0f
 #define DEFAULT_FAR_PLANE  10000.0f
 
+enum PostFilter {
+	kPostFilterOff,
+	kPostFilterBlackAndWhite,
+	kPostFilterSepia
+};
+
 class BaseRenderer3D : public BaseRenderer {
 public:
 	BaseRenderer3D(BaseGame *inGame = nullptr);
@@ -160,6 +166,8 @@ public:
 	                                 const BaseArray<AdGeneric *> &generics, const BaseArray<Light3D *> &lights, Camera3D *camera) = 0;
 	virtual void renderShadowGeometry(const BaseArray<AdWalkplane *> &planes, const BaseArray<AdBlock *> &blocks, const BaseArray<AdGeneric *> &generics, Camera3D *camera) = 0;
 
+	virtual void postfilter() = 0;
+	virtual void setPostfilter(PostFilter postFilter) = 0;
 	bool flip() override;
 	bool indicatorFlip() override;
 	bool forcedFlip() override;
@@ -180,6 +188,7 @@ protected:
 	Graphics::TSpriteBlendMode _batchBlendMode;
 	bool _batchAlphaDisable;
 	BaseSurfaceOpenGL3D *_batchTexture;
+	PostFilter _postFilterMode;
 
 	// NOT declared in sub class: HRESULT CreateShaderQuad();
 	virtual void setAmbientLightRenderState() = 0;
diff --git a/engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp b/engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp
index 79ca6f9b5cf..623678216b3 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp
@@ -96,6 +96,12 @@ bool BaseRenderOpenGL3D::initRenderer(int width, int height, bool windowed) {
 	_simpleShadow[3].u = 1.0f;
 	_simpleShadow[3].v = 0.0f;
 
+	// filter post process: greyscale, sepia
+	glGenTextures(1, &_filterTexture);
+	glBindTexture(GL_TEXTURE_2D, _filterTexture);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
 
 
 	_windowed = !ConfMan.getBool("fullscreen");
@@ -113,6 +119,7 @@ bool BaseRenderOpenGL3D::initRenderer(int width, int height, bool windowed) {
 
 bool BaseRenderOpenGL3D::flip() {
 	_lastTexture = nullptr;
+	postfilter();
 	// Disable blend mode to prevent interfere with backend renderer
 	bool prevStateBlend = glIsEnabled(GL_BLEND);
 	glDisable(GL_BLEND);
@@ -1013,7 +1020,116 @@ bool BaseRenderOpenGL3D::setProjectionTransform(const DXMatrix &transform) {
 	return true;
 }
 
-BaseSurface *Wintermute::BaseRenderOpenGL3D::createSurface() {
+void BaseRenderOpenGL3D::postfilter() {
+	if (_postFilterMode == kPostFilterOff)
+		return;
+
+	setup2D();
+	_state = RSTATE_NONE;
+	glViewport(0, 0, _width, _height);
+
+	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
+
+	glMatrixMode(GL_TEXTURE);
+	glLoadIdentity();
+
+	glMatrixMode(GL_MODELVIEW);
+	glLoadIdentity();
+
+	if (_postFilterMode == kPostFilterBlackAndWhite ||
+		_postFilterMode == kPostFilterSepia) {
+		glDisable(GL_BLEND);
+		glDisable(GL_ALPHA_TEST);
+		glDisable(GL_CULL_FACE);
+
+
+		glEnable(GL_TEXTURE_2D);
+		glBindTexture(GL_TEXTURE_2D, _filterTexture);
+
+
+		glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, _width, _height, 0);
+
+		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB);
+		GLfloat grayscaleWeights[] = {0.333f, 0.333f, 0.333f};
+		glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, grayscaleWeights);
+		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
+		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT);
+		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+
+		glBegin(GL_QUADS);
+		glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
+		glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);
+		glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f,  1.0f);
+		glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f,  1.0f);
+		glEnd();
+
+
+		glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, _width, _height, 0);
+
+		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_SUBTRACT);
+		GLfloat whiteColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
+		glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, whiteColor);
+		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_CONSTANT);
+		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE);
+		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+
+		glBegin(GL_QUADS);
+		glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
+		glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);
+		glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f,  1.0f);
+		glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f,  1.0f);
+		glEnd();
+
+		glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, _width, _height, 0);
+		
+		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+		glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
+		GLfloat luminanceWeights[] = { 0.65f, 0.65f, 0.65f };
+		glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, luminanceWeights);
+		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
+		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT);
+		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+
+		glBegin(GL_QUADS);
+		glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
+		glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);
+		glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f,  1.0f);
+		glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f,  1.0f);
+		glEnd();
+
+		if (_postFilterMode == kPostFilterSepia) {
+			glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, _width, _height, 0);
+
+			glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+			glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
+			GLfloat sepiaWeights[] = { 1.0f, 0.88f, 0.71f, 1.0f };
+			glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, sepiaWeights);
+			glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
+			glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+			glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT);
+			glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+
+			glBegin(GL_QUADS);
+			glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
+			glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);
+			glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f,  1.0f);
+			glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f,  1.0f);
+			glEnd();
+
+		}
+
+		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+		glDisable(GL_TEXTURE_2D);
+	}
+}
+
+BaseSurface *BaseRenderOpenGL3D::createSurface() {
 	return new BaseSurfaceOpenGL3D(_gameRef, this);
 }
 
diff --git a/engines/wintermute/base/gfx/opengl/base_render_opengl3d.h b/engines/wintermute/base/gfx/opengl/base_render_opengl3d.h
index a241dd5b849..201e44eb306 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d.h
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d.h
@@ -151,10 +151,14 @@ public:
 
 	bool setViewport3D(DXViewport *viewport) override;
 
+	void postfilter() override;
+	void setPostfilter(PostFilter postFilter) override { _postFilterMode = postFilter; };
+
 private:
 	SimpleShadowVertex _simpleShadow[4]{};
 	Common::Array<DXVector4> _lightPositions;
 	Common::Array<DXVector3> _lightDirections;
+	GLuint _filterTexture;
 };
 
 } // wintermute namespace
diff --git a/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp b/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
index 1e63d1da89d..d3bb326e647 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
@@ -899,7 +899,10 @@ bool BaseRenderOpenGL3DShader::setProjectionTransform(const DXMatrix &transform)
 	return true;
 }
 
-BaseSurface *Wintermute::BaseRenderOpenGL3DShader::createSurface() {
+void BaseRenderOpenGL3DShader::postfilter() {
+}
+
+BaseSurface *BaseRenderOpenGL3DShader::createSurface() {
 	return new BaseSurfaceOpenGL3D(_gameRef, this);
 }
 
diff --git a/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h b/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h
index 986cdaf5411..b128ab13f01 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h
@@ -140,6 +140,9 @@ public:
 
 	bool setViewport3D(DXViewport *viewport) override;
 
+	void postfilter() override;
+	void setPostfilter(PostFilter postFilter) override { _postFilterMode = postFilter; };
+
 	OpenGL::Shader *_shadowMaskShader;
 
 private:
diff --git a/engines/wintermute/ext/wme_blackandwhite.cpp b/engines/wintermute/ext/wme_blackandwhite.cpp
index ab2a679228b..506b6a1a40d 100644
--- a/engines/wintermute/ext/wme_blackandwhite.cpp
+++ b/engines/wintermute/ext/wme_blackandwhite.cpp
@@ -38,6 +38,7 @@ BaseScriptable *makeSXBlackAndWhite(BaseGame *inGame, ScStack *stack) {
 //////////////////////////////////////////////////////////////////////////
 SXBlackAndWhite::SXBlackAndWhite(BaseGame *inGame, ScStack *stack) : BaseScriptable(inGame) {
 	stack->correctParams(0);
+	_postFilterMode = kPostFilterOff;
 }
 
 //////////////////////////////////////////////////////////////////////////
@@ -81,7 +82,8 @@ bool SXBlackAndWhite::scCallMethod(ScScript *script, ScStack *stack, ScStack *th
 	if (strcmp(name, "SetSepia") == 0) {
 		stack->correctParams(0);
 
-		setSepia();
+		_postFilterMode = kPostFilterSepia;
+		_gameRef->_renderer3D->setPostfilter(_postFilterMode);
 
 		stack->pushBool(true);
 		return STATUS_OK;
@@ -93,7 +95,8 @@ bool SXBlackAndWhite::scCallMethod(ScScript *script, ScStack *stack, ScStack *th
 	if (strcmp(name, "SetBlackAndWhite") == 0) {
 		stack->correctParams(0);
 
-		setBlackAndWhite();
+		_postFilterMode = kPostFilterBlackAndWhite;
+		_gameRef->_renderer3D->setPostfilter(_postFilterMode);
 
 		stack->pushBool(true);
 		return STATUS_OK;
@@ -105,7 +108,8 @@ bool SXBlackAndWhite::scCallMethod(ScScript *script, ScStack *stack, ScStack *th
 	if (strcmp(name, "SetNormalRender") == 0) {
 		stack->correctParams(0);
 
-		setNormalRender();
+		_postFilterMode = kPostFilterOff;
+		_gameRef->_renderer3D->setPostfilter(_postFilterMode);
 
 		stack->pushBool(true);
 		return STATUS_OK;
@@ -235,16 +239,12 @@ bool SXBlackAndWhite::scSetProperty(const char *name, ScValue *value) {
 bool SXBlackAndWhite::persist(BasePersistenceManager *persistMgr) {
 	BaseScriptable::persist(persistMgr);
 
-	return STATUS_OK;
-}
-
-void SXBlackAndWhite::setSepia() {
-}
-
-void SXBlackAndWhite::setBlackAndWhite() {
-}
+	persistMgr->transferSint32(TMEMBER_INT(_postFilterMode));
+	if (!persistMgr->getIsSaving()) {
+		_gameRef->_renderer3D->setPostfilter(_postFilterMode);
+	}
 
-void SXBlackAndWhite::setNormalRender() {
+	return STATUS_OK;
 }
 
 } // End of namespace Wintermute
diff --git a/engines/wintermute/ext/wme_blackandwhite.h b/engines/wintermute/ext/wme_blackandwhite.h
index 2c8c21cb6df..d33c16e50f1 100644
--- a/engines/wintermute/ext/wme_blackandwhite.h
+++ b/engines/wintermute/ext/wme_blackandwhite.h
@@ -25,6 +25,7 @@
 #include "common/str.h"
 
 #include "engines/wintermute/base/base_scriptable.h"
+#include "engines/wintermute/base/gfx/base_renderer3d.h"
 
 namespace Wintermute {
 
@@ -39,9 +40,7 @@ public:
 	~SXBlackAndWhite() override;
 
 private:
-	void setSepia();
-	void setBlackAndWhite();
-	void setNormalRender();
+	PostFilter _postFilterMode;
 };
 
 } // End of namespace Wintermute




More information about the Scummvm-git-logs mailing list