[Scummvm-git-logs] scummvm master -> d205db38713c5a4874a59fd0c6292a2a880b149b

aquadran aquadran at gmail.com
Tue Nov 3 10:54:42 UTC 2020


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

Summary:
45cfe46681 WINTERMUTE: Add position data render function for .X models
a2b68b2d4e WINTERMUTE: Implement flat shadow rendering with gles 2 shaders
af9748344a WINTERMUTE: Enable flat shadows once an actor is created
d205db3871 WINTERMUTE: Only display flat shadow if this was requested


Commit: 45cfe46681080b1c9d03bc3b0b25f21dbcf9e851
    https://github.com/scummvm/scummvm/commit/45cfe46681080b1c9d03bc3b0b25f21dbcf9e851
Author: Gunnar Birke (gunnar.birke at online.de)
Date: 2020-11-03T11:54:36+01:00

Commit Message:
WINTERMUTE: Add position data render function for .X models

Changed paths:
  A engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_modelx.fragment
  A engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_modelx.vertex
    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.h
    engines/wintermute/base/gfx/opengl/meshx_opengl_shader.cpp
    engines/wintermute/base/gfx/opengl/meshx_opengl_shader.h
    engines/wintermute/base/gfx/x/frame_node.cpp
    engines/wintermute/base/gfx/x/frame_node.h
    engines/wintermute/base/gfx/x/meshx.h
    engines/wintermute/base/gfx/x/modelx.cpp
    engines/wintermute/base/gfx/x/modelx.h


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 0e3223ccb5..20cb173e7f 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
@@ -407,6 +407,9 @@ bool BaseRenderOpenGL3DShader::initRenderer(int width, int height, bool windowed
 	_lineShader = OpenGL::ShaderGL::fromFiles("wme_line", lineAttributes);
 	_lineShader->enableVertexAttribute("position", _lineVBO, 2, GL_FLOAT, false, 8, 0);
 
+	static const char *flatShadowModelXAttributes[] = { "position", nullptr };
+	_flatShadowModelXShader = OpenGL::ShaderGL::fromFiles("wme_flat_shadow_modelx", flatShadowModelXAttributes);
+
 	_active = true;
 	// setup a proper state
 	setup2D(true);
@@ -680,7 +683,7 @@ Mesh3DS *BaseRenderOpenGL3DShader::createMesh3DS() {
 }
 
 MeshX *BaseRenderOpenGL3DShader::createMeshX() {
-	return new MeshXOpenGLShader(_gameRef, _modelXShader);
+	return new MeshXOpenGLShader(_gameRef, _modelXShader, _flatShadowModelXShader);
 }
 
 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 ac7586a026..7ae581f8cd 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h
@@ -147,6 +147,7 @@ private:
 	OpenGL::ShaderGL *_shadowVolumeShader;
 	OpenGL::ShaderGL *_shadowMaskShader;
 	OpenGL::ShaderGL *_lineShader;
+	OpenGL::ShaderGL *_flatShadowModelXShader;
 };
 
 } // namespace Wintermute
diff --git a/engines/wintermute/base/gfx/opengl/meshx_opengl.cpp b/engines/wintermute/base/gfx/opengl/meshx_opengl.cpp
index 3dd2bc253d..88f908f4f5 100644
--- a/engines/wintermute/base/gfx/opengl/meshx_opengl.cpp
+++ b/engines/wintermute/base/gfx/opengl/meshx_opengl.cpp
@@ -87,6 +87,10 @@ bool MeshXOpenGL::render(ModelX *model) {
 	return true;
 }
 
+bool MeshXOpenGL::renderFlatShadowModel() {
+	return true;
+}
+
 } // namespace Wintermute
 
 #endif // defined(USE_OPENGL_GAME) && !defined(USE_GLES2)
diff --git a/engines/wintermute/base/gfx/opengl/meshx_opengl.h b/engines/wintermute/base/gfx/opengl/meshx_opengl.h
index c7fb0a4133..2f6ff31d71 100644
--- a/engines/wintermute/base/gfx/opengl/meshx_opengl.h
+++ b/engines/wintermute/base/gfx/opengl/meshx_opengl.h
@@ -41,6 +41,7 @@ public:
 	~MeshXOpenGL() override;
 
 	bool render(ModelX *model) override;
+	bool renderFlatShadowModel() override;
 };
 
 } // namespace Wintermute
diff --git a/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.cpp b/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.cpp
index a53ed5a941..a721614741 100644
--- a/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.cpp
+++ b/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.cpp
@@ -37,8 +37,8 @@
 namespace Wintermute {
 
 //////////////////////////////////////////////////////////////////////////
-MeshXOpenGLShader::MeshXOpenGLShader(BaseGame *inGame, OpenGL::ShaderGL *shader) :
-	MeshX(inGame), _shader(shader) {
+MeshXOpenGLShader::MeshXOpenGLShader(BaseGame *inGame, OpenGL::ShaderGL *shader, OpenGL::ShaderGL *flatShadowShader) :
+	MeshX(inGame), _shader(shader), _flatShadowShader(flatShadowShader) {
 	glGenBuffers(1, &_vertexBuffer);
 	glGenBuffers(1, &_indexBuffer);
 }
@@ -106,6 +106,24 @@ bool MeshXOpenGLShader::render(ModelX *model) {
 	return true;
 }
 
+bool MeshXOpenGLShader::renderFlatShadowModel() {
+	if (_vertexData == nullptr) {
+		return false;
+	}
+
+	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
+
+	_flatShadowShader->enableVertexAttribute("position", _vertexBuffer, 3, GL_FLOAT, false, 4 * kVertexComponentCount, 4 * kPositionOffset);
+	_flatShadowShader->use(true);
+
+	glDrawElements(GL_TRIANGLES, _indexRanges.back(), GL_UNSIGNED_SHORT, 0);
+
+	glBindBuffer(GL_ARRAY_BUFFER, 0);
+	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+	return true;
+}
+
 bool MeshXOpenGLShader::update(FrameNode *parentFrame) {
 	MeshX::update(parentFrame);
 
diff --git a/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.h b/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.h
index 5f9b2a5caf..ff99e938d0 100644
--- a/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.h
+++ b/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.h
@@ -39,11 +39,12 @@ namespace Wintermute {
 
 class MeshXOpenGLShader : public MeshX {
 public:
-	MeshXOpenGLShader(BaseGame *inGame, OpenGL::ShaderGL *shader);
+	MeshXOpenGLShader(BaseGame *inGame, OpenGL::ShaderGL *shader, OpenGL::ShaderGL *flatShadowShader);
 	~MeshXOpenGLShader() override;
 
 	bool loadFromX(const Common::String &filename, XFileLexer &lexer, Common::Array<MaterialReference> &materialReferences) override;
 	bool render(ModelX *model) override;
+	bool renderFlatShadowModel() override;
 	bool update(FrameNode *parentFrame) override;
 
 protected:
@@ -51,6 +52,7 @@ protected:
 	GLuint _indexBuffer;
 
 	OpenGL::ShaderGL *_shader;
+	OpenGL::ShaderGL *_flatShadowShader;
 };
 
 } // namespace Wintermute
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
new file mode 100644
index 0000000000..980969d66a
--- /dev/null
+++ b/engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_modelx.fragment
@@ -0,0 +1,8 @@
+uniform vec4 shadowColor;
+
+OUTPUT
+
+void main()
+{
+	outColor = vec4(shadowColor.rgb, 1.0);
+}
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
new file mode 100644
index 0000000000..f76d974b44
--- /dev/null
+++ b/engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_modelx.vertex
@@ -0,0 +1,11 @@
+in vec3 position;
+
+uniform highp mat4 modelMatrix;
+uniform highp mat4 viewMatrix;
+uniform highp mat4 projMatrix;
+
+void main()
+{
+	vec4 viewCoords = viewMatrix * modelMatrix * vec4(position, 1.0);
+	gl_Position = projMatrix * viewCoords;
+}
diff --git a/engines/wintermute/base/gfx/x/frame_node.cpp b/engines/wintermute/base/gfx/x/frame_node.cpp
index 838bc3afa0..e394f5cae7 100644
--- a/engines/wintermute/base/gfx/x/frame_node.cpp
+++ b/engines/wintermute/base/gfx/x/frame_node.cpp
@@ -383,6 +383,26 @@ bool FrameNode::render(ModelX *model) {
 	return true;
 }
 
+bool FrameNode::renderFlatShadowModel() {
+	bool res = true;
+
+	for (uint32 i = 0; i < _meshes.size(); i++) {
+		res = _meshes[i]->renderFlatShadowModel();
+		if (!res) {
+			return res;
+		}
+	}
+
+	for (uint32 i = 0; i < _frames.size(); i++) {
+		res = _frames[i]->renderFlatShadowModel();
+		if (!res) {
+			return res;
+		}
+	}
+
+	return res;
+}
+
 //////////////////////////////////////////////////////////////////////////
 bool FrameNode::pickPoly(Math::Vector3d *pickRayOrig, Math::Vector3d *pickRayDir) {
 	bool found = false;
diff --git a/engines/wintermute/base/gfx/x/frame_node.h b/engines/wintermute/base/gfx/x/frame_node.h
index 1935936fef..01108a5d42 100644
--- a/engines/wintermute/base/gfx/x/frame_node.h
+++ b/engines/wintermute/base/gfx/x/frame_node.h
@@ -52,6 +52,7 @@ public:
 	bool updateMeshes();
 	bool resetMatrices();
 	bool render(ModelX *model);
+	bool renderFlatShadowModel();
 	bool updateShadowVol(ShadowVolume *shadow, Math::Matrix4 &modelMat, const Math::Vector3d &light, float extrusionDepth);
 
 	bool loadFromX(const Common::String &filename, XFileLexer &lexer, ModelX *model, Common::Array<MaterialReference> &materialReferences);
diff --git a/engines/wintermute/base/gfx/x/meshx.h b/engines/wintermute/base/gfx/x/meshx.h
index 729ea0b26d..99276033fe 100644
--- a/engines/wintermute/base/gfx/x/meshx.h
+++ b/engines/wintermute/base/gfx/x/meshx.h
@@ -61,6 +61,7 @@ public:
 	bool findBones(FrameNode *rootFrame);
 	virtual bool update(FrameNode *parentFrame);
 	virtual bool render(ModelX *model) = 0;
+	virtual bool renderFlatShadowModel() = 0;
 	bool updateShadowVol(ShadowVolume *shadow, Math::Matrix4 &modelMat, const Math::Vector3d &light, float extrusionDepth);
 
 	bool pickPoly(Math::Vector3d *pickRayOrig, Math::Vector3d *pickRayDir);
diff --git a/engines/wintermute/base/gfx/x/modelx.cpp b/engines/wintermute/base/gfx/x/modelx.cpp
index b2aaccc900..9e9ffa2d05 100644
--- a/engines/wintermute/base/gfx/x/modelx.cpp
+++ b/engines/wintermute/base/gfx/x/modelx.cpp
@@ -501,6 +501,20 @@ bool ModelX::render() {
 	}
 }
 
+bool ModelX::renderFlatShadowModel() {
+	if (_rootFrame) {
+		if(_owner && !_owner->_drawBackfaces) {
+			_gameRef->_renderer3D->enableCulling();
+		} else {
+			_gameRef->_renderer3D->disableCulling();
+		}
+
+		return _rootFrame->renderFlatShadowModel();
+	} else {
+		return false;
+	}
+}
+
 //////////////////////////////////////////////////////////////////////////
 Math::Matrix4 *ModelX::getBoneMatrix(const char *boneName) {
 	FrameNode *bone = _rootFrame->findFrame(boneName);
diff --git a/engines/wintermute/base/gfx/x/modelx.h b/engines/wintermute/base/gfx/x/modelx.h
index 674ad8a4ea..b0956e3193 100644
--- a/engines/wintermute/base/gfx/x/modelx.h
+++ b/engines/wintermute/base/gfx/x/modelx.h
@@ -146,6 +146,7 @@ public:
 
 	bool update() override;
 	bool render();
+	bool renderFlatShadowModel();
 	bool reset();
 
 	bool updateShadowVol(ShadowVolume *shadow, Math::Matrix4 &modelMat, const Math::Vector3d &light, float extrusionDepth);


Commit: a2b68b2d4eee1da1778431944ade027d02934aa7
    https://github.com/scummvm/scummvm/commit/a2b68b2d4eee1da1778431944ade027d02934aa7
Author: Gunnar Birke (gunnar.birke at online.de)
Date: 2020-11-03T11:54:36+01:00

Commit Message:
WINTERMUTE: Implement flat shadow rendering with gles 2 shaders

Changed paths:
  A engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_mask.fragment
  A engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_mask.vertex
    engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
    engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h


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 20cb173e7f..e7c4961758 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
@@ -57,12 +57,15 @@ struct SpriteVertexShader {
 #include "common/pack-end.h"
 
 BaseRenderOpenGL3DShader::BaseRenderOpenGL3DShader(BaseGame *inGame)
-    : BaseRenderer3D(inGame), _spriteBatchMode(false) {
+	: BaseRenderer3D(inGame), _spriteBatchMode(false), _flatShadowMaskShader(nullptr) {
     (void)_spriteBatchMode; // silence warning
 }
 
 BaseRenderOpenGL3DShader::~BaseRenderOpenGL3DShader() {
 	glDeleteBuffers(1, &_spriteVBO);
+	glDeleteTextures(1, &_flatShadowRenderTexture);
+	glDeleteRenderbuffers(1, &_flatShadowDepthBuffer);
+	glDeleteFramebuffers(1, &_flatShadowFrameBuffer);
 }
 
 void BaseRenderOpenGL3DShader::setSpriteBlendMode(Graphics::TSpriteBlendMode blendMode) {
@@ -164,7 +167,79 @@ void BaseRenderOpenGL3DShader::disableCulling() {
 }
 
 bool BaseRenderOpenGL3DShader::enableShadows() {
-	warning("BaseRenderOpenGL3DShader::enableShadows not implemented yet");
+	if (_flatShadowMaskShader == nullptr) {
+		_flatShadowColor = Math::Vector4d(0.0f, 0.0f, 0.0f, 0.5f);
+
+		_shadowTextureWidth = 512;
+		_shadowTextureHeight = 512;
+
+		float nearPlane = 1.0f;
+		float farPlane = 10000.0f;
+		float fovy = M_PI / 4.0f;
+
+		float top = nearPlane *  tanf(fovy * 0.5f);
+		float bottom = -top;
+		float right = top;
+		float left = -right;
+
+		float deltaX = (-0.5f * (right - left)) / _shadowTextureWidth;
+		float deltaY = (0.5f * (top - bottom)) / _shadowTextureHeight;
+
+		Math::Matrix4 lightProjection = Math::makeFrustumMatrix(left + deltaX, right + deltaX, bottom + deltaY, top + deltaY, nearPlane, farPlane);
+
+		_flatShadowModelXShader->use();
+		_flatShadowModelXShader->setUniform("projMatrix", lightProjection);
+
+		glGenTextures(1, &_flatShadowRenderTexture);
+		glBindTexture(GL_TEXTURE_2D, _flatShadowRenderTexture);
+		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _shadowTextureWidth, _shadowTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+		glGenRenderbuffers(1, &_flatShadowDepthBuffer);
+		glBindRenderbuffer(GL_RENDERBUFFER, _flatShadowDepthBuffer);
+		glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, _shadowTextureWidth, _shadowTextureHeight);
+
+		glGenFramebuffers(1, &_flatShadowFrameBuffer);
+		glBindFramebuffer(GL_FRAMEBUFFER, _flatShadowFrameBuffer);
+		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _flatShadowRenderTexture, 0);
+		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _flatShadowDepthBuffer);
+
+		glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+		float flatShadowMaskVertices[12];
+		flatShadowMaskVertices[0] = -250.0f;
+		flatShadowMaskVertices[1] = 0.0f;
+		flatShadowMaskVertices[2] = -250.0f;
+
+		flatShadowMaskVertices[3] = -250.0f;
+		flatShadowMaskVertices[4] = 0.0f;
+		flatShadowMaskVertices[5] = 250.0f;
+
+		flatShadowMaskVertices[6] = 250.0f;
+		flatShadowMaskVertices[7] = 0.0f;
+		flatShadowMaskVertices[8] = -250.0f;
+
+		flatShadowMaskVertices[9] = 250.0f;
+		flatShadowMaskVertices[10] = 0.0f;
+		flatShadowMaskVertices[11] = 250.0f;
+
+		glGenBuffers(1, &_flatShadowMaskVBO);
+		glBindBuffer(GL_ARRAY_BUFFER, _flatShadowMaskVBO);
+		glBufferData(GL_ARRAY_BUFFER, 4 * 12, flatShadowMaskVertices, GL_STATIC_DRAW);
+
+		static const char *flatShadowMaskAttributes[] = { "position", nullptr };
+		_flatShadowMaskShader = OpenGL::ShaderGL::fromFiles("wme_flat_shadow_mask", flatShadowMaskAttributes);
+		_flatShadowMaskShader->enableVertexAttribute("position", _flatShadowMaskVBO, 3, GL_FLOAT, false, 12, 0);
+
+		_flatShadowMaskShader->use();
+		_flatShadowMaskShader->setUniform("lightProjMatrix", lightProjection);
+
+		_gameRef->_supportsRealTimeShadows = true;
+	}
+
 	return true;
 }
 
@@ -174,7 +249,76 @@ bool BaseRenderOpenGL3DShader::disableShadows() {
 }
 
 void BaseRenderOpenGL3DShader::displayShadow(BaseObject *object, const Math::Vector3d &lightPos, bool lightPosRelative) {
-	warning("BaseRenderOpenGL3DShader::displayShadow not implemented yet");
+	if (_flatShadowMaskShader) {
+		Math::Vector3d position = lightPos;
+		Math::Vector3d target = object->_posVector;
+
+		if (lightPosRelative) {
+			position = object->_posVector + lightPos;
+		}
+
+		Math::Matrix4 lightViewMatrix = Math::makeLookAtMatrix(position, target, Math::Vector3d(0.0f, 1.0f, 0.0f));
+		Math::Matrix4 translation;
+		translation.setPosition(-position);
+		translation.transpose();
+		lightViewMatrix = translation * lightViewMatrix;
+
+		_flatShadowModelXShader->use();
+		_flatShadowModelXShader->setUniform("viewMatrix", lightViewMatrix);
+
+		Math::Matrix4 tmp = object->_worldMatrix;
+		tmp.transpose();
+		_flatShadowModelXShader->setUniform("modelMatrix", tmp);
+
+		byte a = RGBCOLGetA(object->_shadowColor);
+		byte r = RGBCOLGetR(object->_shadowColor);
+		byte g = RGBCOLGetG(object->_shadowColor);
+		byte b = RGBCOLGetB(object->_shadowColor);
+
+		_flatShadowColor.x() = r / 255.0f;
+		_flatShadowColor.y() = g / 255.0f;
+		_flatShadowColor.z() = b / 255.0f;
+		_flatShadowColor.w() = a / 255.0f;
+		_flatShadowModelXShader->setUniform("shadowColor", _flatShadowColor);
+
+		glBindFramebuffer(GL_FRAMEBUFFER, _flatShadowFrameBuffer);
+
+		GLint currentViewport[4];
+		glGetIntegerv(GL_VIEWPORT, currentViewport);
+		glViewport(1, 1, _shadowTextureWidth - 2, _shadowTextureHeight - 2);
+
+		glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
+		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+		object->_modelX->renderFlatShadowModel();
+
+		glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+		glViewport(currentViewport[0], currentViewport[1], currentViewport[2], currentViewport[3]);
+
+		glDisable(GL_DEPTH_WRITEMASK);
+
+		Math::Matrix4 shadowPosition;
+		shadowPosition.setToIdentity();
+		shadowPosition.setPosition(object->_posVector);
+		shadowPosition.transpose();
+
+		_flatShadowMaskShader->use();
+		_flatShadowMaskShader->setUniform("lightViewMatrix", lightViewMatrix);
+		_flatShadowMaskShader->setUniform("worldMatrix", shadowPosition);
+		_flatShadowMaskShader->setUniform("viewMatrix", _lastViewMatrix);
+		_flatShadowMaskShader->setUniform("projMatrix", _projectionMatrix3d);
+		_flatShadowMaskShader->setUniform("shadowColor", _flatShadowColor);
+
+		glBindBuffer(GL_ARRAY_BUFFER, _flatShadowMaskVBO);
+		glBindTexture(GL_TEXTURE_2D, _flatShadowRenderTexture);
+
+		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+		glBindTexture(GL_TEXTURE_2D, 0);
+
+		glEnable(GL_DEPTH_WRITEMASK);
+	}
 }
 
 bool BaseRenderOpenGL3DShader::stencilSupported() {
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 7ae581f8cd..4990ab5183 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h
@@ -137,9 +137,17 @@ private:
 	TRendererState _renderState;
 	bool _spriteBatchMode;
 
+	Math::Vector4d _flatShadowColor;
+	int _shadowTextureWidth;
+	int _shadowTextureHeight;
+
 	GLuint _spriteVBO;
 	GLuint _fadeVBO;
 	GLuint _lineVBO;
+	GLuint _flatShadowMaskVBO;
+	GLuint _flatShadowFrameBuffer;
+	GLuint _flatShadowRenderTexture;
+	GLuint _flatShadowDepthBuffer;
 	OpenGL::ShaderGL *_spriteShader;
 	OpenGL::ShaderGL *_fadeShader;
 	OpenGL::ShaderGL *_modelXShader;
@@ -148,6 +156,7 @@ private:
 	OpenGL::ShaderGL *_shadowMaskShader;
 	OpenGL::ShaderGL *_lineShader;
 	OpenGL::ShaderGL *_flatShadowModelXShader;
+	OpenGL::ShaderGL *_flatShadowMaskShader;
 };
 
 } // 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
new file mode 100644
index 0000000000..dbced7035e
--- /dev/null
+++ b/engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_mask.fragment
@@ -0,0 +1,14 @@
+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
new file mode 100644
index 0000000000..83d94f92f4
--- /dev/null
+++ b/engines/wintermute/base/gfx/opengl/shaders/wme_flat_shadow_mask.vertex
@@ -0,0 +1,23 @@
+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;
+}


Commit: af9748344ab7a6c49f862940047e6b2aad7f17ec
    https://github.com/scummvm/scummvm/commit/af9748344ab7a6c49f862940047e6b2aad7f17ec
Author: Gunnar Birke (gunnar.birke at online.de)
Date: 2020-11-03T11:54:36+01:00

Commit Message:
WINTERMUTE: Enable flat shadows once an actor is created

Changed paths:
    engines/wintermute/ad/ad_actor_3dx.cpp


diff --git a/engines/wintermute/ad/ad_actor_3dx.cpp b/engines/wintermute/ad/ad_actor_3dx.cpp
index b167e4b2ad..1ecf07fa17 100644
--- a/engines/wintermute/ad/ad_actor_3dx.cpp
+++ b/engines/wintermute/ad/ad_actor_3dx.cpp
@@ -83,7 +83,7 @@ AdActor3DX::AdActor3DX(BaseGame *inGame) : AdObject3D(inGame),
                                            _targetAngle(0.0f),
                                            _path3D(new AdPath3D(inGame)),
                                            _path2D(new AdPath(inGame)) {
-	//	m_Renderer->EnableShadows();
+	_gameRef->_renderer3D->enableShadows();
 }
 
 //////////////////////////////////////////////////////////////////////////


Commit: d205db38713c5a4874a59fd0c6292a2a880b149b
    https://github.com/scummvm/scummvm/commit/d205db38713c5a4874a59fd0c6292a2a880b149b
Author: Gunnar Birke (gunnar.birke at online.de)
Date: 2020-11-03T11:54:36+01:00

Commit Message:
WINTERMUTE: Only display flat shadow if this was requested

Changed paths:
    engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp


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 e7c4961758..c068606e65 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
@@ -250,6 +250,11 @@ bool BaseRenderOpenGL3DShader::disableShadows() {
 
 void BaseRenderOpenGL3DShader::displayShadow(BaseObject *object, const Math::Vector3d &lightPos, bool lightPosRelative) {
 	if (_flatShadowMaskShader) {
+		if (object->_shadowType <= SHADOW_SIMPLE) {
+			// TODO: Display simple shadow here
+			return;
+		}
+
 		Math::Vector3d position = lightPos;
 		Math::Vector3d target = object->_posVector;
 




More information about the Scummvm-git-logs mailing list