[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