[Scummvm-git-logs] scummvm master -> 99e6b6e09f5883dc7677da8316a6fe22f87166bd
aquadran
noreply at scummvm.org
Tue May 20 22:22:01 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:
99e6b6e09f WINTERMUTE: Implemented flat shadow for shader renderer
Commit: 99e6b6e09f5883dc7677da8316a6fe22f87166bd
https://github.com/scummvm/scummvm/commit/99e6b6e09f5883dc7677da8316a6fe22f87166bd
Author: PaweÅ KoÅodziejski (aquadran at gmail.com)
Date: 2025-05-21T00:21:56+02:00
Commit Message:
WINTERMUTE: Implemented flat shadow for shader renderer
Changed paths:
R engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_mask.fragment
R engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_mask.vertex
dists/scummvm.rc
engines/wintermute/ad/ad_actor_3dx.cpp
engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h
engines/wintermute/base/gfx/opengl/meshx_opengl.cpp
engines/wintermute/base/gfx/opengl/meshx_opengl_shader.cpp
engines/wintermute/base/gfx/opengl/meshx_opengl_shader.h
engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_modelx.fragment
engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_modelx.vertex
engines/wintermute/base/gfx/opengl/shaders/wme_simple_shadow.vertex
engines/wintermute/base/gfx/opengl/shaders/wme_sprite.fragment
diff --git a/dists/scummvm.rc b/dists/scummvm.rc
index c6e2e25cd2a..d9e4f203642 100644
--- a/dists/scummvm.rc
+++ b/dists/scummvm.rc
@@ -102,8 +102,6 @@ shaders/stark_shadow.vertex FILE "engines/stark/shaders/stark_shadow
#if PLUGIN_ENABLED_STATIC(WINTERMUTE)
shaders/wme_fade.fragment FILE "engines/wintermute/base/gfx/opengl/shaders/wme_fade.fragment"
shaders/wme_fade.vertex FILE "engines/wintermute/base/gfx/opengl/shaders/wme_fade.vertex"
-shaders/wme_flat_shadow_mask.fragment FILE "engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_mask.fragment"
-shaders/wme_flat_shadow_mask.vertex FILE "engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_mask.vertex"
shaders/wme_flat_shadow_modelx.fragment FILE "engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_modelx.fragment"
shaders/wme_flat_shadow_modelx.vertex FILE "engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_modelx.vertex"
shaders/wme_geometry.fragment FILE "engines/wintermute/base/gfx/opengl/shaders/wme_geometry.fragment"
diff --git a/engines/wintermute/ad/ad_actor_3dx.cpp b/engines/wintermute/ad/ad_actor_3dx.cpp
index dc16a22a136..5c0780899b5 100644
--- a/engines/wintermute/ad/ad_actor_3dx.cpp
+++ b/engines/wintermute/ad/ad_actor_3dx.cpp
@@ -536,8 +536,8 @@ bool AdActor3DX::displayFlatShadow() {
}
DXVector3 lightPos = DXVector3(_shadowLightPos._x * _scale3D,
- _shadowLightPos._y * _scale3D,
- _shadowLightPos._z * _scale3D);
+ _shadowLightPos._y * _scale3D,
+ _shadowLightPos._z * _scale3D);
_gameRef->_renderer3D->getWorldTransform(&origWorld);
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 49d80448b15..8bc746b8869 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
@@ -120,6 +120,9 @@ bool BaseRenderOpenGL3DShader::initRenderer(int width, int height, bool windowed
_simpleShadowShader->enableVertexAttribute("normal", _simpleShadowVBO, 3, GL_FLOAT, false, sizeof(SimpleShadowVertex), 12);
_simpleShadowShader->enableVertexAttribute("texcoord", _simpleShadowVBO, 2, GL_FLOAT, false, sizeof(SimpleShadowVertex), 24);
+ static const char *flatShadowAttributes[] = { "position", nullptr };
+ _flatShadowShader = OpenGL::Shader::fromFiles("wme_flat_shadow_modelx", flatShadowAttributes);
+
static const char *shadowVolumeAttributes[] = { "position", nullptr };
_shadowVolumeShader = OpenGL::Shader::fromFiles("wme_shadow_volume", shadowVolumeAttributes);
@@ -303,6 +306,10 @@ bool BaseRenderOpenGL3DShader::setup3D(Camera3D *camera, bool force) {
_simpleShadowShader->setUniform1f("alphaRef", _alphaRef);
_simpleShadowShader->setUniform("alphaTest", true);
+ _flatShadowShader->use();
+ _flatShadowShader->setUniform("viewMatrix", viewMatrix);
+ _flatShadowShader->setUniform("projMatrix", projectionMatrix);
+
_shadowVolumeShader->use();
_shadowVolumeShader->setUniform("viewMatrix", viewMatrix);
_shadowVolumeShader->setUniform("projMatrix", projectionMatrix);
@@ -695,7 +702,7 @@ BaseImage *BaseRenderOpenGL3DShader::takeScreenshot() {
}
bool BaseRenderOpenGL3DShader::enableShadows() {
- _gameRef->_supportsRealTimeShadows = false;
+ _gameRef->_supportsRealTimeShadows = true;
return true;
}
@@ -962,7 +969,9 @@ bool BaseRenderOpenGL3DShader::setWorldTransform(const DXMatrix &transform) {
_simpleShadowShader->use();
_simpleShadowShader->setUniform("modelMatrix", modelMatrix);
- _simpleShadowShader->setUniform("normalMatrix", normalMatrix);
+
+ _flatShadowShader->use();
+ _flatShadowShader->setUniform("modelMatrix", modelMatrix);
_shadowVolumeShader->use();
_shadowVolumeShader->setUniform("modelMatrix", modelMatrix);
@@ -1003,7 +1012,7 @@ Mesh3DS *BaseRenderOpenGL3DShader::createMesh3DS() {
}
XMesh *BaseRenderOpenGL3DShader::createXMesh() {
- return new XMeshOpenGLShader(_gameRef, _xmodelShader);
+ return new XMeshOpenGLShader(_gameRef, _xmodelShader, _flatShadowShader);
}
ShadowVolume *BaseRenderOpenGL3DShader::createShadowVolume() {
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 34fc68a3042..d55f127d4fb 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h
@@ -184,6 +184,7 @@ private:
OpenGL::Shader *_xmodelShader{};
OpenGL::Shader *_geometryShader{};
OpenGL::Shader *_simpleShadowShader{};
+ OpenGL::Shader *_flatShadowShader{};
OpenGL::Shader *_shadowVolumeShader{};
OpenGL::Shader *_lineShader{};
};
diff --git a/engines/wintermute/base/gfx/opengl/meshx_opengl.cpp b/engines/wintermute/base/gfx/opengl/meshx_opengl.cpp
index cd606b4cd74..91bcaa62a9e 100644
--- a/engines/wintermute/base/gfx/opengl/meshx_opengl.cpp
+++ b/engines/wintermute/base/gfx/opengl/meshx_opengl.cpp
@@ -159,8 +159,7 @@ bool XMeshOpenGL::renderFlatShadowModel(uint32 shadowColor) {
if (!_gameRef->_renderer3D->_camera)
return false;
- auto fvf = _blendedMesh->getFVF();
- uint32 vertexSize = DXGetFVFVertexSize(fvf) / sizeof(float);
+ uint32 vertexSize = DXGetFVFVertexSize(_blendedMesh->getFVF()) / sizeof(float);
float *vertexData = (float *)_blendedMesh->getVertexBuffer().ptr();
if (vertexData == nullptr) {
return false;
diff --git a/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.cpp b/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.cpp
index 28618c3702e..825ec3670cc 100644
--- a/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.cpp
+++ b/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.cpp
@@ -43,8 +43,8 @@
namespace Wintermute {
//////////////////////////////////////////////////////////////////////////
-XMeshOpenGLShader::XMeshOpenGLShader(BaseGame *inGame, OpenGL::Shader *shader) :
- XMesh(inGame), _shader(shader) {
+XMeshOpenGLShader::XMeshOpenGLShader(BaseGame *inGame, OpenGL::Shader *shader, OpenGL::Shader *flatShadowShader) :
+ XMesh(inGame), _shader(shader), _flatShadowShader(flatShadowShader) {
glGenBuffers(1, &_vertexBuffer);
glGenBuffers(1, &_indexBuffer);
}
@@ -170,22 +170,87 @@ bool XMeshOpenGLShader::render(XModel *model) {
}
bool XMeshOpenGLShader::renderFlatShadowModel(uint32 shadowColor) {
- float *vertexData = (float *)_blendedMesh->getVertexBuffer().ptr();
+ if (!_blendedMesh)
+ return false;
+
+ // For WME DX, mesh model is not visible, possible it's clipped.
+ // For OpenGL, mesh is visible, skip draw it here instead in core.
+ if (!_gameRef->_renderer3D->_camera)
+ return false;
+
uint32 vertexSize = DXGetFVFVertexSize(_blendedMesh->getFVF()) / sizeof(float);
+ float *vertexData = (float *)_blendedMesh->getVertexBuffer().ptr();
if (vertexData == nullptr) {
return false;
}
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
+ bool noAttrs = false;
+ auto attrsTable = _blendedMesh->getAttributeTable();
+ uint32 numAttrs = attrsTable->_size;
+ DXAttributeRange *attrs;
+ if (numAttrs == 0) {
+ noAttrs = true;
+ numAttrs = 1;
+ attrs = new DXAttributeRange[numAttrs];
+ } else {
+ attrs = attrsTable->_ptr;
+ }
- _flatShadowShader->enableVertexAttribute("position", _vertexBuffer, 3, GL_FLOAT, false, 4 * vertexSize, 4);
+ if (noAttrs) {
+ attrs[0]._attribId = 0;
+ attrs[0]._vertexStart = attrs[0]._faceStart = 0;
+ attrs[0]._vertexCount = _blendedMesh->getNumVertices();
+ attrs[0]._faceCount = _blendedMesh->getNumFaces();
+ }
+
+ Math::Vector4d color;
+ color.x() = RGBCOLGetR(shadowColor) / 255.0f;
+ color.y() = RGBCOLGetG(shadowColor) / 255.0f;
+ color.z() = RGBCOLGetB(shadowColor) / 255.0f;
+ color.w() = RGBCOLGetA(shadowColor) / 255.0f;
+
+ _flatShadowShader->enableVertexAttribute("position", _vertexBuffer, 3, GL_FLOAT, false, 4 * vertexSize, 0);
_flatShadowShader->use(true);
- glDrawElements(GL_TRIANGLES, _blendedMesh->getNumFaces() * 3, GL_UNSIGNED_SHORT, 0);
+ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+ glDepthMask(GL_FALSE);
+
+ glEnable(GL_STENCIL_TEST);
+ glStencilFunc(GL_ALWAYS, 1, (GLuint)~0);
+ glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
+
+ for (uint32 i = 0; i < numAttrs; i++) {
+ size_t offsetFace = 4 * attrsTable->_ptr[i]._faceStart * 3;
+ glDrawElements(GL_TRIANGLES, attrsTable->_ptr[i]._faceCount * 3, GL_UNSIGNED_INT, (void *)offsetFace);
+ }
+
+ glStencilFunc(GL_EQUAL, 1, (GLuint)~0);
+ glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
+
+ _flatShadowShader->setUniform("shadowColor", color);
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glDepthMask(GL_TRUE);
+
+ for (uint32 i = 0; i < numAttrs; i++) {
+ size_t offsetFace = 4 * attrsTable->_ptr[i]._faceStart * 3;
+ glDrawElements(GL_TRIANGLES, attrsTable->_ptr[i]._faceCount * 3, GL_UNSIGNED_INT, (void *)offsetFace);
+ }
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ if (noAttrs) {
+ delete[] attrs;
+ }
+
+ glDisable(GL_BLEND);
+ glDisable(GL_STENCIL_TEST);
+
return true;
}
diff --git a/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.h b/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.h
index 419e062f137..5aa5dfc3d30 100644
--- a/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.h
+++ b/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.h
@@ -41,7 +41,7 @@ namespace Wintermute {
class XMeshOpenGLShader : public XMesh {
public:
- XMeshOpenGLShader(BaseGame *inGame, OpenGL::Shader *shader);
+ XMeshOpenGLShader(BaseGame *inGame, OpenGL::Shader *shader, OpenGL::Shader *flatShadowShader);
~XMeshOpenGLShader() override;
bool loadFromXData(const Common::String &filename, XFileData *xobj) override;
@@ -57,7 +57,7 @@ protected:
GLuint _indexBuffer;
OpenGL::Shader *_shader;
- OpenGL::Shader *_flatShadowShader{};
+ OpenGL::Shader *_flatShadowShader;
};
} // namespace Wintermute
diff --git a/engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_mask.fragment b/engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_mask.fragment
deleted file mode 100644
index a55e79ecfec..00000000000
--- a/engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_mask.fragment
+++ /dev/null
@@ -1,13 +0,0 @@
-in vec3 Texcoord;
-
-uniform sampler2D tex;
-uniform vec4 shadowColor;
-
-OUTPUT
-
-void main() {
- vec2 projectedTexcoord = Texcoord.xy / Texcoord.z;
-
- vec4 texColor = texture(tex, projectedTexcoord);
- outColor = shadowColor * texColor;
-}
diff --git a/engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_mask.vertex b/engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_mask.vertex
deleted file mode 100644
index e1cc2f8705c..00000000000
--- a/engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_mask.vertex
+++ /dev/null
@@ -1,22 +0,0 @@
-in vec3 position;
-
-uniform highp mat4 projMatrix;
-uniform highp mat4 viewMatrix;
-uniform highp mat4 worldMatrix;
-
-uniform highp mat4 lightProjMatrix;
-uniform highp mat4 lightViewMatrix;
-
-out vec3 Texcoord;
-
-void main() {
- vec4 worldCoords = worldMatrix * vec4(position, 1.0);
-
- vec4 textureCoords = lightProjMatrix * lightViewMatrix * worldCoords;
-
- Texcoord.x = 0.5 * (textureCoords.x) + 0.5 * textureCoords.w;
- Texcoord.y = 0.5 * (textureCoords.y) + 0.5 * textureCoords.w;
- Texcoord.z = textureCoords.w;
-
- gl_Position = projMatrix * viewMatrix * worldCoords;
-}
diff --git a/engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_modelx.fragment b/engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_modelx.fragment
index f480933ea8f..0296908835f 100644
--- a/engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_modelx.fragment
+++ b/engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_modelx.fragment
@@ -1,7 +1,8 @@
uniform vec4 shadowColor;
+uniform float alphaRef;
OUTPUT
void main() {
- outColor = vec4(shadowColor.rgb, 1.0);
+ outColor = shadowColor;
}
diff --git a/engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_modelx.vertex b/engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_modelx.vertex
index 977847e9a94..96172c58f79 100644
--- a/engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_modelx.vertex
+++ b/engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_modelx.vertex
@@ -5,6 +5,5 @@ uniform highp mat4 viewMatrix;
uniform highp mat4 projMatrix;
void main() {
- vec4 viewCoords = viewMatrix * modelMatrix * vec4(position, 1.0);
- gl_Position = projMatrix * viewCoords;
+ gl_Position = projMatrix * viewMatrix * modelMatrix * vec4(position, 1.0);
}
diff --git a/engines/wintermute/base/gfx/opengl/shaders/wme_simple_shadow.vertex b/engines/wintermute/base/gfx/opengl/shaders/wme_simple_shadow.vertex
index 12582fd9a1e..15d0496cbe6 100644
--- a/engines/wintermute/base/gfx/opengl/shaders/wme_simple_shadow.vertex
+++ b/engines/wintermute/base/gfx/opengl/shaders/wme_simple_shadow.vertex
@@ -5,7 +5,6 @@ in vec2 texcoord;
out vec2 Texcoord;
uniform highp mat4 modelMatrix;
-uniform highp mat4 normalMatrix;
uniform highp mat4 viewMatrix;
uniform highp mat4 projMatrix;
diff --git a/engines/wintermute/base/gfx/opengl/shaders/wme_sprite.fragment b/engines/wintermute/base/gfx/opengl/shaders/wme_sprite.fragment
index 5f602beebab..cfa69415b02 100644
--- a/engines/wintermute/base/gfx/opengl/shaders/wme_sprite.fragment
+++ b/engines/wintermute/base/gfx/opengl/shaders/wme_sprite.fragment
@@ -8,8 +8,7 @@ uniform UBOOL alphaTest;
OUTPUT
void main() {
- vec4 texColor = texture(tex, Texcoord);
- outColor = Color * texColor;
+ outColor = Color * texture(tex, Texcoord);
if (UBOOL_TEST(alphaTest) && outColor.a < alphaRef) {
discard;
More information about the Scummvm-git-logs
mailing list