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

aquadran noreply at scummvm.org
Fri May 9 09:28:41 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:
c125e49284 WINTERMUTE: Implemented flat shadow rendering for classic renderer


Commit: c125e492844449eb19dd9402078c34d8a9338973
    https://github.com/scummvm/scummvm/commit/c125e492844449eb19dd9402078c34d8a9338973
Author: Paweł Kołodziejski (aquadran at gmail.com)
Date: 2025-05-09T11:28:36+02:00

Commit Message:
WINTERMUTE: Implemented flat shadow rendering for classic renderer

Changed paths:
    engines/wintermute/ad/ad_actor_3dx.cpp
    engines/wintermute/ad/ad_actor_3dx.h
    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/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/xframe_node.cpp
    engines/wintermute/base/gfx/xframe_node.h
    engines/wintermute/base/gfx/xmath.cpp
    engines/wintermute/base/gfx/xmath.h
    engines/wintermute/base/gfx/xmesh.h
    engines/wintermute/base/gfx/xmodel.cpp
    engines/wintermute/base/gfx/xmodel.h


diff --git a/engines/wintermute/ad/ad_actor_3dx.cpp b/engines/wintermute/ad/ad_actor_3dx.cpp
index 8b6a275658f..bf947a003f9 100644
--- a/engines/wintermute/ad/ad_actor_3dx.cpp
+++ b/engines/wintermute/ad/ad_actor_3dx.cpp
@@ -396,10 +396,13 @@ bool AdActor3DX::display() {
 	if (shadowType == SHADOW_STENCIL) {
 		displayShadowVolume();
 	} else if (shadowType > SHADOW_NONE) {
-		DXVector3 lightPos = DXVector3(_shadowLightPos._x * _scale3D,
-									   _shadowLightPos._y * _scale3D,
-									   _shadowLightPos._z * _scale3D);
-		_gameRef->_renderer3D->displayShadow(this, &lightPos, true);
+		bool simpleShadow = shadowType <= SHADOW_SIMPLE;
+		if (!_gameRef->_supportsRealTimeShadows)
+			simpleShadow = true;
+		if (simpleShadow)
+			_gameRef->_renderer3D->displaySimpleShadow(this);
+		else
+			displayFlatShadow();
 	}
 
 	_gameRef->_renderer3D->setSpriteBlendMode(_blendMode, true);
@@ -525,6 +528,38 @@ bool AdActor3DX::displayShadowVolume() {
 	return true;
 }
 
+bool AdActor3DX::displayFlatShadow() {
+	DXMatrix shadowMat;
+	DXVector3 pos;
+	DXVector3 target;
+
+	if (!_xmodel) {
+		return false;
+	}
+
+	DXVector3 lightPos = DXVector3(_shadowLightPos._x * _scale3D,
+								   _shadowLightPos._y * _scale3D,
+								   _shadowLightPos._z * _scale3D);
+	pos = _posVector + lightPos;
+	target = _posVector;
+
+	DXMatrix origWorld;
+	_gameRef->_renderer3D->getWorldTransform(&origWorld);
+
+	DXVector4 lightVector = { lightPos._x, lightPos._y, lightPos._z, 0 };
+	DXPlane plane = { 0, 1, 0, -target._y };
+
+	DXMatrixShadow(&shadowMat, &lightVector, &plane);
+	DXMatrix shadowWorld = _worldMatrix * shadowMat;
+
+	_gameRef->_renderer3D->setWorldTransform(shadowWorld);
+	_xmodel->renderFlatShadowModel(_shadowColor);
+
+	_gameRef->_renderer3D->setWorldTransform(origWorld);
+
+	return true;
+}
+
 //////////////////////////////////////////////////////////////////////////
 bool AdActor3DX::updateAttachments() {
 	for (uint32 i = 0; i < _attachments.size(); i++) {
diff --git a/engines/wintermute/ad/ad_actor_3dx.h b/engines/wintermute/ad/ad_actor_3dx.h
index 3be4ac484bb..d0979076019 100644
--- a/engines/wintermute/ad/ad_actor_3dx.h
+++ b/engines/wintermute/ad/ad_actor_3dx.h
@@ -49,6 +49,7 @@ public:
 	DXVector3 _partOffset;
 
 	bool displayShadowVolume();
+	bool displayFlatShadow();
 	bool restoreDeviceObjects() override;
 	bool invalidateDeviceObjects() override;
 	int32 _stateAnimChannel;
diff --git a/engines/wintermute/base/gfx/base_renderer3d.h b/engines/wintermute/base/gfx/base_renderer3d.h
index b034f83aef2..ff9ec4f57ec 100644
--- a/engines/wintermute/base/gfx/base_renderer3d.h
+++ b/engines/wintermute/base/gfx/base_renderer3d.h
@@ -78,7 +78,6 @@ public:
 	virtual bool enableShadows() = 0;
 	virtual bool disableShadows() = 0;
 	virtual bool stencilSupported() = 0;
-	virtual void displayShadow(BaseObject *object, const DXVector3 *light, bool lightPosRelative) = 0;
 	virtual bool invalidateTexture(BaseSurfaceOpenGL3D *texture) = 0;
 
 	Graphics::TSpriteBlendMode _blendMode;
@@ -163,6 +162,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 displaySimpleShadow(BaseObject *object) = 0;
+
 	virtual void postfilter() = 0;
 	virtual void setPostfilter(PostFilter postFilter) = 0;
 	bool flip() override;
diff --git a/engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp b/engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp
index 0506137742a..303b14ddd80 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp
@@ -682,7 +682,7 @@ BaseImage *BaseRenderOpenGL3D::takeScreenshot() {
 }
 
 bool BaseRenderOpenGL3D::enableShadows() {
-	_gameRef->_supportsRealTimeShadows = false;
+	_gameRef->_supportsRealTimeShadows = true;
 	return true;
 }
 
@@ -690,21 +690,10 @@ bool BaseRenderOpenGL3D::disableShadows() {
 	return true;
 }
 
-void BaseRenderOpenGL3D::displayShadow(BaseObject *object, const DXVector3 *lightPos, bool lightPosRelative) {
-	if (!_ready || !object || !lightPos)
+void BaseRenderOpenGL3D::displaySimpleShadow(BaseObject *object) {
+	if (!_ready || !object)
 		return;
 
-	// redirect simple shadow if needed
-	bool simpleShadow = _gameRef->getMaxShadowType(object) <= SHADOW_SIMPLE;
-	if (!_gameRef->_supportsRealTimeShadows)
-		simpleShadow = true;
-	if (simpleShadow)
-		return renderSimpleShadow(object);
-
-	// TODO: to be implemented
-}
-
-void BaseRenderOpenGL3D::renderSimpleShadow(BaseObject *object) {
 	BaseSurface *shadowImage;
 	if (object->_shadowImage) {
 		shadowImage = object->_shadowImage;
diff --git a/engines/wintermute/base/gfx/opengl/base_render_opengl3d.h b/engines/wintermute/base/gfx/opengl/base_render_opengl3d.h
index c17e1295bc5..9fd87c61fd3 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d.h
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d.h
@@ -85,7 +85,6 @@ public:
 
 	bool enableShadows() override;
 	bool disableShadows() override;
-	void displayShadow(BaseObject *object, const DXVector3 *lightPos, bool lightPosRelative) override;
 	bool stencilSupported() override;
 
 	void dumpData(const char *filename) override {}
@@ -152,7 +151,7 @@ public:
 	void setPostfilter(PostFilter postFilter) override { _postFilterMode = postFilter; };
 
 private:
-	void renderSimpleShadow(BaseObject *object);
+	void displaySimpleShadow(BaseObject *object) override;
 
 	SimpleShadowVertex _simpleShadow[4]{};
 	Common::Array<DXVector4> _lightPositions;
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 ddd8ec18259..8e2e52d2f06 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
@@ -664,22 +664,10 @@ bool BaseRenderOpenGL3DShader::disableShadows() {
 	return true;
 }
 
-void BaseRenderOpenGL3DShader::displayShadow(BaseObject *object, const DXVector3 *lightPos, bool lightPosRelative) {
-	if (!_ready || !object || !lightPos)
+void BaseRenderOpenGL3DShader::displaySimpleShadow(BaseObject *object) {
+	if (!_ready || !object)
 		return;
 
-	// redirect simple shadow if needed
-	bool simpleShadow = _gameRef->getMaxShadowType(object) <= SHADOW_SIMPLE;
-	if (!_gameRef->_supportsRealTimeShadows)
-		simpleShadow = true;
-	if (simpleShadow)
-		return renderSimpleShadow(object);
-
-	// TODO: to be implemented
-	return;
-}
-
-void BaseRenderOpenGL3DShader::renderSimpleShadow(BaseObject *object) {
 	// TODO: to be implemented
 }
 
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 dbe28bbeef8..92d9c00c5f1 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h
@@ -75,7 +75,6 @@ public:
 
 	bool enableShadows() override;
 	bool disableShadows() override;
-	void displayShadow(BaseObject *object, const DXVector3 *lightPos, bool lightPosRelative) override;
 	bool stencilSupported() override;
 
 	void dumpData(const char *filename) override {}
@@ -143,7 +142,7 @@ public:
 	OpenGL::Shader *_shadowMaskShader;
 
 private:
-	void renderSimpleShadow(BaseObject *object);
+	void displaySimpleShadow(BaseObject *object) override;
 
 	DXMatrix _glProjectionMatrix;
 	float _alphaRef;
diff --git a/engines/wintermute/base/gfx/opengl/meshx_opengl.cpp b/engines/wintermute/base/gfx/opengl/meshx_opengl.cpp
index ca2d65f6d55..4003ba0b2fc 100644
--- a/engines/wintermute/base/gfx/opengl/meshx_opengl.cpp
+++ b/engines/wintermute/base/gfx/opengl/meshx_opengl.cpp
@@ -150,7 +150,95 @@ bool XMeshOpenGL::render(XModel *model) {
 	return true;
 }
 
-bool XMeshOpenGL::renderFlatShadowModel() {
+bool XMeshOpenGL::renderFlatShadowModel(uint32 shadowColor) {
+	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;
+
+	auto fvf = _blendedMesh->getFVF();
+	uint32 vertexSize = DXGetFVFVertexSize(fvf) / sizeof(float);
+	float *vertexData = (float *)_blendedMesh->getVertexBuffer().ptr();
+	if (vertexData == nullptr) {
+		return false;
+	}
+	uint32 *indexData = (uint32 *)_blendedMesh->getIndexBuffer().ptr();
+
+	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;
+	}
+
+	if (noAttrs) {
+		attrs[0]._attribId = 0;
+		attrs[0]._vertexStart = attrs[0]._faceStart = 0;
+		attrs[0]._vertexCount = _blendedMesh->getNumVertices();
+		attrs[0]._faceCount = _blendedMesh->getNumFaces();
+	}
+
+	glBindTexture(GL_TEXTURE_2D, 0);
+	glDisable(GL_TEXTURE_2D);
+
+	glDisable(GL_LIGHTING);
+	glShadeModel(GL_FLAT);
+
+	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);
+
+	for (uint32 i = 0; i < numAttrs; i++) {
+		glEnableClientState(GL_VERTEX_ARRAY);
+
+		glVertexPointer(3, GL_FLOAT, vertexSize * sizeof(float), vertexData);
+
+		glDrawElements(GL_TRIANGLES, attrsTable->_ptr[i]._faceCount * 3, GL_UNSIGNED_INT, indexData + attrsTable->_ptr[i]._faceStart * 3);
+
+		glDisableClientState(GL_VERTEX_ARRAY);
+	}
+
+
+	glStencilFunc(GL_EQUAL, 1, (GLuint)~0);
+	glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
+
+	glColor4ub(RGBCOLGetR(shadowColor), RGBCOLGetG(shadowColor), RGBCOLGetB(shadowColor), RGBCOLGetA(shadowColor));
+    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++) {
+		glEnableClientState(GL_VERTEX_ARRAY);
+
+		glVertexPointer(3, GL_FLOAT, vertexSize * sizeof(float), vertexData);
+
+		glDrawElements(GL_TRIANGLES, attrsTable->_ptr[i]._faceCount * 3, GL_UNSIGNED_INT, indexData + attrsTable->_ptr[i]._faceStart * 3);
+
+		glDisableClientState(GL_VERTEX_ARRAY);
+	}
+
+	if (noAttrs) {
+		delete[] attrs;
+	}
+
+	glDisable(GL_BLEND);
+	glDisable(GL_STENCIL_TEST);
+	glShadeModel(GL_SMOOTH);
+	glEnable(GL_LIGHTING);
+
 	return true;
 }
 
diff --git a/engines/wintermute/base/gfx/opengl/meshx_opengl.h b/engines/wintermute/base/gfx/opengl/meshx_opengl.h
index be9837c7d70..308dd65b98d 100644
--- a/engines/wintermute/base/gfx/opengl/meshx_opengl.h
+++ b/engines/wintermute/base/gfx/opengl/meshx_opengl.h
@@ -43,7 +43,7 @@ public:
 	~XMeshOpenGL() override;
 
 	bool render(XModel *model) override;
-	bool renderFlatShadowModel() override;
+	bool renderFlatShadowModel(uint32 shadowColor) override;
 
 private:
 	void renderEffect(Material *material);
diff --git a/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.cpp b/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.cpp
index 64f4d4b4c64..6002e42f1a9 100644
--- a/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.cpp
+++ b/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.cpp
@@ -167,7 +167,7 @@ bool XMeshOpenGLShader::render(XModel *model) {
 	return true;
 }
 
-bool XMeshOpenGLShader::renderFlatShadowModel() {
+bool XMeshOpenGLShader::renderFlatShadowModel(uint32 shadowColor) {
 	float *vertexData = (float *)_blendedMesh->getVertexBuffer().ptr();
 	uint32 vertexSize = DXGetFVFVertexSize(_blendedMesh->getFVF()) / sizeof(float);
 	if (vertexData == nullptr) {
diff --git a/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.h b/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.h
index 49790ff6e0e..419e062f137 100644
--- a/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.h
+++ b/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.h
@@ -46,7 +46,7 @@ public:
 
 	bool loadFromXData(const Common::String &filename, XFileData *xobj) override;
 	bool render(XModel *model) override;
-	bool renderFlatShadowModel() override;
+	bool renderFlatShadowModel(uint32 shadowColor) override;
 	bool update(FrameNode *parentFrame) override;
 
 private:
diff --git a/engines/wintermute/base/gfx/xframe_node.cpp b/engines/wintermute/base/gfx/xframe_node.cpp
index e055eeccdad..857b3f57411 100644
--- a/engines/wintermute/base/gfx/xframe_node.cpp
+++ b/engines/wintermute/base/gfx/xframe_node.cpp
@@ -356,18 +356,18 @@ bool FrameNode::render(XModel *model) {
 	return true;
 }
 
-bool FrameNode::renderFlatShadowModel() {
+bool FrameNode::renderFlatShadowModel(uint32 shadowColor) {
 	bool res = true;
 
 	for (uint32 i = 0; i < _meshes.size(); i++) {
-		res = _meshes[i]->renderFlatShadowModel();
+		res = _meshes[i]->renderFlatShadowModel(shadowColor);
 		if (!res) {
 			return res;
 		}
 	}
 
 	for (uint32 i = 0; i < _frames.size(); i++) {
-		res = _frames[i]->renderFlatShadowModel();
+		res = _frames[i]->renderFlatShadowModel(shadowColor);
 		if (!res) {
 			return res;
 		}
diff --git a/engines/wintermute/base/gfx/xframe_node.h b/engines/wintermute/base/gfx/xframe_node.h
index 49961508ee7..d0da55cb4f6 100644
--- a/engines/wintermute/base/gfx/xframe_node.h
+++ b/engines/wintermute/base/gfx/xframe_node.h
@@ -50,7 +50,7 @@ public:
 	bool updateMeshes();
 	bool resetMatrices();
 	bool render(XModel *model);
-	bool renderFlatShadowModel();
+	bool renderFlatShadowModel(uint32 shadowColor);
 	bool updateShadowVol(ShadowVolume *shadow, DXMatrix *modelMat, DXVector3 *light, float extrusionDepth);
 
 	bool loadFromXData(const Common::String &filename, XModel *model, XFileData *xobj);
diff --git a/engines/wintermute/base/gfx/xmath.cpp b/engines/wintermute/base/gfx/xmath.cpp
index 3485d5906e0..3b616d5f9fb 100644
--- a/engines/wintermute/base/gfx/xmath.cpp
+++ b/engines/wintermute/base/gfx/xmath.cpp
@@ -187,6 +187,13 @@ DXQuaternion::operator const float* () const {
 	return (const float *)&_x;
 }
 
+DXPlane::DXPlane(float fa, float fb, float fc, float fd) {
+	_a = fa;
+	_b = fb;
+	_c = fc;
+	_d = fd;
+}
+
 DXMatrix *DXMatrixTranspose(DXMatrix *pout, const DXMatrix *pm) {
 	uint32 i, j;
 	DXMatrix m;
@@ -661,4 +668,48 @@ DXMatrix *DXMatrixOrthoOffCenterLH(DXMatrix *pout, float l, float r, float b, fl
 	return pout;
 }
 
+DXPlane *DXPlaneNormalize(DXPlane *out, const DXPlane *p) {
+	float norm;
+	
+	norm = sqrtf(p->_a * p->_a + p->_b * p->_b + p->_c * p->_c);
+	if (norm) {
+		out->_a = p->_a / norm;
+		out->_b = p->_b / norm;
+		out->_c = p->_c / norm;
+		out->_d = p->_d / norm;
+	} else {
+		out->_a = 0.0f;
+		out->_b = 0.0f;
+		out->_c = 0.0f;
+		out->_d = 0.0f;
+	}
+	
+	return out;
+}
+
+DXMatrix *DXMatrixShadow(DXMatrix *pout, const DXVector4 *plight, const DXPlane *pplane) {
+	DXPlane nplane;
+	float dot;
+
+	DXPlaneNormalize(&nplane, pplane);
+	dot = DXPlaneDot(&nplane, plight);
+	pout->_m[0][0] = dot - nplane._a * plight->_x;
+	pout->_m[0][1] = -nplane._a * plight->_y;
+	pout->_m[0][2] = -nplane._a * plight->_z;
+	pout->_m[0][3] = -nplane._a * plight->_w;
+	pout->_m[1][0] = -nplane._b * plight->_x;
+	pout->_m[1][1] = dot - nplane._b * plight->_y;
+	pout->_m[1][2] = -nplane._b * plight->_z;
+	pout->_m[1][3] = -nplane._b * plight->_w;
+	pout->_m[2][0] = -nplane._c * plight->_x;
+	pout->_m[2][1] = -nplane._c * plight->_y;
+	pout->_m[2][2] = dot - nplane._c * plight->_z;
+	pout->_m[2][3] = -nplane._c * plight->_w;
+	pout->_m[3][0] = -nplane._d * plight->_x;
+	pout->_m[3][1] = -nplane._d * plight->_y;
+	pout->_m[3][2] = -nplane._d * plight->_z;
+	pout->_m[3][3] = dot - nplane._d * plight->_w;
+	return pout;
+}
+
 } // End of namespace Wintermute
diff --git a/engines/wintermute/base/gfx/xmath.h b/engines/wintermute/base/gfx/xmath.h
index 5c8cf9567d0..de6b2ff31c5 100644
--- a/engines/wintermute/base/gfx/xmath.h
+++ b/engines/wintermute/base/gfx/xmath.h
@@ -111,6 +111,7 @@ struct DXPlane {
 	float           _d;
 
 	DXPlane() {}
+	DXPlane(float fa, float fb, float fc, float fd);
 };
 
 struct DXMatrix {
@@ -176,6 +177,7 @@ DXVector3 *DXVec3Project(DXVector3 *pout, const DXVector3 *pv, const DXViewport
                          const DXMatrix *pprojection, const DXMatrix *pview, const DXMatrix *pworld);
 DXMatrix *DXMatrixTranspose(DXMatrix *pout, const DXMatrix *pm);
 DXVector4 *DXVec4Transform(DXVector4 *pout, const DXVector4 *pv, const DXMatrix *pm);
+DXMatrix *DXMatrixShadow(DXMatrix *pout, const DXVector4 *plight, const DXPlane *pplane);
 
 static inline DXMatrix *DXMatrixIdentity(DXMatrix *pout) {
 	(*pout)._m[0][1] = 0.0f;
@@ -233,6 +235,15 @@ static inline float DXVec3Length(const DXVector3 *pv) {
 	return sqrtf(pv->_x * pv->_x + pv->_y * pv->_y + pv->_z * pv->_z);
 }
 
+static inline float DXVec4Dot(const DXVector4 *pv1, const DXVector4 *pv2) {
+	return (pv1->_x) * (pv2->_x) + (pv1->_y) * (pv2->_y) + (pv1->_z) * (pv2->_z) + (pv1->_w) * (pv2->_w);
+}
+
+static inline float DXPlaneDot(const DXPlane *pp, const DXVector4 *pv) {
+	return ((pp->_a) * (pv->_x) + (pp->_b) * (pv->_y) + (pp->_c) * (pv->_z) + (pp->_d) * (pv->_w) );
+}
+
+
 } // End of namespace Wintermute
 
 #endif
diff --git a/engines/wintermute/base/gfx/xmesh.h b/engines/wintermute/base/gfx/xmesh.h
index 07d4e11ec4e..df21886c02e 100644
--- a/engines/wintermute/base/gfx/xmesh.h
+++ b/engines/wintermute/base/gfx/xmesh.h
@@ -55,7 +55,7 @@ public:
 	bool findBones(FrameNode *rootFrame);
 	virtual bool update(FrameNode *parentFrame);
 	virtual bool render(XModel *model) = 0;
-	virtual bool renderFlatShadowModel() = 0;
+	virtual bool renderFlatShadowModel(uint32 shadowColor) = 0;
 	bool updateShadowVol(ShadowVolume *shadow, DXMatrix *modelMat, DXVector3 *light, float extrusionDepth);
 
 	bool pickPoly(DXVector3 *pickRayOrig, DXVector3 *pickRayDir);
diff --git a/engines/wintermute/base/gfx/xmodel.cpp b/engines/wintermute/base/gfx/xmodel.cpp
index 078104886f1..1014b0815e6 100644
--- a/engines/wintermute/base/gfx/xmodel.cpp
+++ b/engines/wintermute/base/gfx/xmodel.cpp
@@ -511,7 +511,7 @@ bool XModel::render() {
 	}
 }
 
-bool XModel::renderFlatShadowModel() {
+bool XModel::renderFlatShadowModel(uint32 shadowColor) {
 	if (_rootFrame) {
 		if(_owner && !_owner->_drawBackfaces) {
 			_gameRef->_renderer3D->enableCulling();
@@ -519,7 +519,7 @@ bool XModel::renderFlatShadowModel() {
 			_gameRef->_renderer3D->disableCulling();
 		}
 
-		return _rootFrame->renderFlatShadowModel();
+		return _rootFrame->renderFlatShadowModel(shadowColor);
 	} else {
 		return false;
 	}
diff --git a/engines/wintermute/base/gfx/xmodel.h b/engines/wintermute/base/gfx/xmodel.h
index 76a2397f0e4..b47fd22c328 100644
--- a/engines/wintermute/base/gfx/xmodel.h
+++ b/engines/wintermute/base/gfx/xmodel.h
@@ -206,7 +206,7 @@ public:
 
 	bool update() override;
 	bool render();
-	bool renderFlatShadowModel();
+	bool renderFlatShadowModel(uint32 shadowColor);
 	bool reset();
 
 	bool updateShadowVol(ShadowVolume *shadow, DXMatrix *modelMat, DXVector3 *light, float extrusionDepth);




More information about the Scummvm-git-logs mailing list