[Scummvm-git-logs] scummvm master -> fbdd7a3bfcbe64d4aff3be85e10d6d7718e6694d
aquadran
noreply at scummvm.org
Wed Nov 6 14:18:18 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:
fbdd7a3bfc WINTERMUTE: Restore effects material code from original. Added stub for effects in renderer.
Commit: fbdd7a3bfcbe64d4aff3be85e10d6d7718e6694d
https://github.com/scummvm/scummvm/commit/fbdd7a3bfcbe64d4aff3be85e10d6d7718e6694d
Author: PaweÅ KoÅodziejski (aquadran at gmail.com)
Date: 2024-11-06T15:18:13+01:00
Commit Message:
WINTERMUTE: Restore effects material code from original. Added stub for effects in renderer.
Changed paths:
A engines/wintermute/base/gfx/3deffect.cpp
A engines/wintermute/base/gfx/3deffect.h
A engines/wintermute/base/gfx/3deffect_params.cpp
A engines/wintermute/base/gfx/3deffect_params.h
engines/wintermute/ad/ad_actor_3dx.cpp
engines/wintermute/base/base_persistence_manager.cpp
engines/wintermute/base/base_persistence_manager.h
engines/wintermute/base/gfx/opengl/base_render_opengl3d.h
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/xmaterial.cpp
engines/wintermute/base/gfx/xmaterial.h
engines/wintermute/base/gfx/xmesh.cpp
engines/wintermute/base/gfx/xmesh.h
engines/wintermute/base/gfx/xmodel.cpp
engines/wintermute/base/gfx/xmodel.h
engines/wintermute/module.mk
diff --git a/engines/wintermute/ad/ad_actor_3dx.cpp b/engines/wintermute/ad/ad_actor_3dx.cpp
index 2f9f1e4dadb..e79eace568c 100644
--- a/engines/wintermute/ad/ad_actor_3dx.cpp
+++ b/engines/wintermute/ad/ad_actor_3dx.cpp
@@ -48,6 +48,7 @@
#include "engines/wintermute/base/gfx/3dshadow_volume.h"
#include "engines/wintermute/base/gfx/opengl/base_render_opengl3d.h"
#include "engines/wintermute/base/gfx/xmodel.h"
+#include "engines/wintermute/base/gfx/3deffect.h"
#include "engines/wintermute/base/gfx/xmath.h"
#include "engines/wintermute/base/gfx/3dutils.h"
#include "engines/wintermute/base/particles/part_emitter.h"
@@ -1831,12 +1832,10 @@ bool AdActor3DX::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisSta
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "SetEffect") == 0) {
stack->correctParams(2);
- /*const char *materialName =*/ stack->pop()->getString();
- /*const char *effectFilename =*/ stack->pop()->getString();
+ const char *materialName = stack->pop()->getString();
+ const char *effectFilename = stack->pop()->getString();
- warning("AdActor3DX::scCallMethod D3DX effects are not supported");
- //if (_xmodel && _xmodel->setMaterialEffect(materialName, effectFilename)) {
- if (_xmodel) {
+ if (_xmodel && _xmodel->setMaterialEffect(materialName, effectFilename)) {
stack->pushBool(true);
} else {
stack->pushBool(false);
@@ -1849,12 +1848,10 @@ bool AdActor3DX::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisSta
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "RemoveEffect") == 0) {
stack->correctParams(1);
- /*const char *materialName =*/ stack->pop()->getString();
+ const char *materialName = stack->pop()->getString();
stack->pop();
- warning("AdActor3DX::scCallMethod D3DX effects are not supported");
- // if (_xmodel && _xodel->removeMaterialEffect(materialName)) {
- if (_xmodel) {
+ if (_xmodel && _xmodel->removeMaterialEffect(materialName)) {
stack->pushBool(true);
} else {
stack->pushBool(false);
@@ -1867,13 +1864,11 @@ bool AdActor3DX::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisSta
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "SetEffectParam") == 0) {
stack->correctParams(3);
- /*const char *materialName =*/ stack->pop()->getString();
- /*const char *paramName =*/ stack->pop()->getString();
- /*ScValue *val =*/ stack->pop();
+ const char *materialName = stack->pop()->getString();
+ const char *paramName = stack->pop()->getString();
+ ScValue *val = stack->pop();
- warning("AdActor3DX::scCallMethod D3DX effects are not supported");
- // if (_xmodel && _xmodel->setMaterialEffectParam(materialName, paramName, val)) {
- if (_xmodel) {
+ if (_xmodel && _xmodel->setMaterialEffectParam(materialName, paramName, val)) {
stack->pushBool(true);
} else {
stack->pushBool(false);
@@ -1886,16 +1881,14 @@ bool AdActor3DX::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisSta
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "SetEffectParamVector") == 0) {
stack->correctParams(6);
- /*const char *materialName =*/ stack->pop()->getString();
- /*const char *paramName =*/ stack->pop()->getString();
- /*float x =*/ stack->pop()->getFloat();
- /*float y =*/ stack->pop()->getFloat();
- /*float z =*/ stack->pop()->getFloat();
- /*float w =*/ stack->pop()->getFloat();
-
- //if (_xmodel && _xmodel->setMaterialEffectParam(materialName, paramName, DXVector4(x, y, z, w))) {
- warning("AdActor3DX::scCallMethod D3DX effects are not supported");
- if (_xmodel) {
+ const char *materialName = stack->pop()->getString();
+ const char *paramName = stack->pop()->getString();
+ float x = stack->pop()->getFloat();
+ float y = stack->pop()->getFloat();
+ float z = stack->pop()->getFloat();
+ float w = stack->pop()->getFloat();
+
+ if (_xmodel && _xmodel->setMaterialEffectParam(materialName, paramName, DXVector4(x, y, z, w))) {
stack->pushBool(true);
} else {
stack->pushBool(false);
@@ -1908,18 +1901,16 @@ bool AdActor3DX::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisSta
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "SetEffectParamColor") == 0) {
stack->correctParams(3);
- /*const char *materialName =*/ stack->pop()->getString();
- /*const char *paramName =*/ stack->pop()->getString();
- /*uint32 color =*/ stack->pop()->getInt();
+ const char *materialName = stack->pop()->getString();
+ const char *paramName = stack->pop()->getString();
+ uint32 color = stack->pop()->getInt();
- //float r = RGBCOLGetR(color) / 255.0f;
- //float g = RGBCOLGetG(color) / 255.0f;
- //float b = RGBCOLGetB(color) / 255.0f;
- //float a = RGBCOLGetA(color) / 255.0f;
+ float r = RGBCOLGetR(color) / 255.0f;
+ float g = RGBCOLGetG(color) / 255.0f;
+ float b = RGBCOLGetB(color) / 255.0f;
+ float a = RGBCOLGetA(color) / 255.0f;
- //if (_xmodel && _xmodel->setMaterialEffectParam(materialName, paramName, DXVector4(r, g, b, a))) {
- warning("AdActor3DX::scCallMethod D3DX effects are not supported");
- if (_xmodel) {
+ if (_xmodel && _xmodel->setMaterialEffectParam(materialName, paramName, DXVector4(r, g, b, a))) {
stack->pushBool(true);
} else {
stack->pushBool(false);
@@ -2478,8 +2469,6 @@ bool AdActor3DX::updatePartEmitter() {
//////////////////////////////////////////////////////////////////////////
bool AdActor3DX::parseEffect(byte *buffer) {
- warning("AdActor3DX::parseEffect D3DX effect are not implemented");
-
TOKEN_TABLE_START(commands)
TOKEN_TABLE(MATERIAL)
TOKEN_TABLE(EFFECT_FILE)
@@ -2509,7 +2498,9 @@ bool AdActor3DX::parseEffect(byte *buffer) {
}
if (effectFile && material) {
- // TODO: Implement
+ if (!_xmodel->setMaterialEffect(material, effectFile)) {
+ _gameRef->LOG(0, "Error assigning effect to material '%s'", material);
+ }
}
delete[] effectFile;
diff --git a/engines/wintermute/base/base_persistence_manager.cpp b/engines/wintermute/base/base_persistence_manager.cpp
index 7ab5c206c4f..b6a441cf00a 100644
--- a/engines/wintermute/base/base_persistence_manager.cpp
+++ b/engines/wintermute/base/base_persistence_manager.cpp
@@ -850,6 +850,34 @@ bool BasePersistenceManager::transferVector3d(const char *name, DXVector3 *val)
}
}
+//////////////////////////////////////////////////////////////////////////
+// Vector4
+bool BasePersistenceManager::transferVector4d(const char *name, DXVector4 *val) {
+ if (_saving) {
+ putFloat(val->_x);
+ putFloat(val->_y);
+ putFloat(val->_z);
+ putFloat(val->_w);
+
+ if (_saveStream->err()) {
+ return STATUS_FAILED;
+ }
+
+ return STATUS_OK;
+ } else {
+ val->_x = getFloat();
+ val->_y = getFloat();
+ val->_z = getFloat();
+ val->_w = getFloat();
+
+ if (_loadStream->err()) {
+ return STATUS_FAILED;
+ }
+
+ return STATUS_OK;
+ }
+}
+
//////////////////////////////////////////////////////////////////////////
// Matrix4
bool BasePersistenceManager::transferMatrix4(const char *name, DXMatrix *val) {
diff --git a/engines/wintermute/base/base_persistence_manager.h b/engines/wintermute/base/base_persistence_manager.h
index 6eb9b0a35e0..abea8bad3d0 100644
--- a/engines/wintermute/base/base_persistence_manager.h
+++ b/engines/wintermute/base/base_persistence_manager.h
@@ -100,6 +100,7 @@ public:
bool transferVector2(const char *name, Vector2 *val);
#ifdef ENABLE_WME3D
bool transferVector3d(const char *name, DXVector3 *val);
+ bool transferVector4d(const char *name, DXVector4 *val);
bool transferMatrix4(const char *name, DXMatrix *val);
bool transferAngle(const char *name, float *val);
#endif
diff --git a/engines/wintermute/base/gfx/3deffect.cpp b/engines/wintermute/base/gfx/3deffect.cpp
new file mode 100644
index 00000000000..6d1e303230e
--- /dev/null
+++ b/engines/wintermute/base/gfx/3deffect.cpp
@@ -0,0 +1,75 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*
+ * This file is based on WME.
+ * http://dead-code.org/redir.php?target=wme
+ * Copyright (c) 2003-2013 Jan Nedoma and contributors
+ */
+
+#include "common/crc.h"
+
+#include "engines/wintermute/base/base_named_object.h"
+#include "engines/wintermute/base/base_file_manager.h"
+#include "engines/wintermute/base/gfx/3deffect.h"
+#include "engines/wintermute/utils/utils.h"
+
+namespace Wintermute {
+
+//////////////////////////////////////////////////////////////////////////
+Effect3D::Effect3D(BaseGame *inGame) : BaseClass(inGame) {
+ _effectHash = 0xFFFFFFFF;
+}
+
+//////////////////////////////////////////////////////////////////////////
+Effect3D::~Effect3D() {
+ _effectHash = 0xFFFFFFFF;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool Effect3D::invalidateDeviceObjects() {
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool Effect3D::restoreDeviceObjects() {
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool Effect3D::createFromFile(const Common::String &filename) {
+ uint32 size;
+ byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename, &size);
+ if (!buffer) {
+ return false;
+ }
+
+ _filename = filename;
+
+ Common::CRC32 crc;
+ _effectHash = crc.crcFast(buffer, size);
+
+ delete[] buffer;
+
+ return true;
+}
+
+} // namespace Wintermute
diff --git a/engines/wintermute/base/gfx/3deffect.h b/engines/wintermute/base/gfx/3deffect.h
new file mode 100644
index 00000000000..abb68c44b08
--- /dev/null
+++ b/engines/wintermute/base/gfx/3deffect.h
@@ -0,0 +1,54 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*
+ * This file is based on WME.
+ * http://dead-code.org/redir.php?target=wme
+ * Copyright (c) 2003-2013 Jan Nedoma and contributors
+ */
+
+#ifndef WINTERMUTE_3D_EFFECT_H
+#define WINTERMUTE_3D_EFFECT_H
+
+#include "engines/wintermute/base/base_named_object.h"
+
+namespace Wintermute {
+
+//////////////////////////////////////////////////////////////////////////
+class Effect3D : public BaseClass {
+public:
+ Effect3D(BaseGame *inGame);
+ ~Effect3D();
+
+ bool createFromFile(const Common::String &filename);
+ uint32 getEffectHash() { return _effectHash; }
+ bool invalidateDeviceObjects();
+ bool restoreDeviceObjects();
+ const char *getFileName() { return _filename.c_str(); }
+
+private:
+ Common::String _filename;
+ uint32 _effectHash;
+};
+
+} // namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/base/gfx/3deffect_params.cpp b/engines/wintermute/base/gfx/3deffect_params.cpp
new file mode 100644
index 00000000000..397a8d8ddbb
--- /dev/null
+++ b/engines/wintermute/base/gfx/3deffect_params.cpp
@@ -0,0 +1,200 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*
+ * This file is based on WME.
+ * http://dead-code.org/redir.php?target=wme
+ * Copyright (c) 2003-2013 Jan Nedoma and contributors
+ */
+
+#include "common/crc.h"
+
+#include "engines/wintermute/base/base_file_manager.h"
+#include "engines/wintermute/base/scriptables/script_value.h"
+#include "engines/wintermute/base/gfx/3deffect_params.h"
+
+namespace Wintermute {
+
+//////////////////////////////////////////////////////////////////////////
+Effect3DParams::Effect3DParam::Effect3DParam() {
+ setDefaultValues();
+}
+
+//////////////////////////////////////////////////////////////////////////
+Effect3DParams::Effect3DParam::Effect3DParam(const char *paramName) {
+ setDefaultValues();
+ _paramName = paramName;
+}
+
+//////////////////////////////////////////////////////////////////////////
+Effect3DParams::Effect3DParam::~Effect3DParam() {
+}
+
+//////////////////////////////////////////////////////////////////////////
+void Effect3DParams::Effect3DParam::setValue(char *val) {
+ _type = EP_STRING;
+ _valString = val;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void Effect3DParams::Effect3DParam::setValue(int val) {
+ _type = EP_INT;
+ _valInt = val;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void Effect3DParams::Effect3DParam::setValue(float val) {
+ _type = EP_FLOAT;
+ _valFloat = val;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void Effect3DParams::Effect3DParam::setValue(bool val) {
+ _type = EP_BOOL;
+ _valBool = val;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void Effect3DParams::Effect3DParam::setValue(DXVector4 val) {
+ _type = EP_VECTOR;
+ _valVector = val;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void Effect3DParams::Effect3DParam::setDefaultValues() {
+ _paramName = "";
+ _valString = "";
+ _valInt = 0;
+ _valFloat = 0;
+ _valBool = 0;
+ _valVector = DXVector4(0, 0, 0, 0);
+
+ _type = EP_UNKNOWN;
+
+ _initialized = false;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool Effect3DParams::Effect3DParam::persist(BasePersistenceManager *persistMgr) {
+ persistMgr->transferString(TMEMBER(_paramName));
+ persistMgr->transferSint32(TMEMBER_INT(_type));
+ persistMgr->transferString(TMEMBER(_valString));
+ persistMgr->transferSint32(TMEMBER(_valInt));
+ persistMgr->transferFloat(TMEMBER(_valFloat));
+ persistMgr->transferVector4d(TMEMBER(_valVector));
+ persistMgr->transferBool(TMEMBER(_valBool));
+
+ if (!persistMgr->getIsSaving()) {
+ _initialized = false;
+ }
+
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+Effect3DParams::Effect3DParams() {
+}
+
+//////////////////////////////////////////////////////////////////////////
+Effect3DParams::~Effect3DParams() {
+ clear();
+}
+
+//////////////////////////////////////////////////////////////////////////
+void Effect3DParams::clear() {
+ for (size_t i = 0; i < _params.size(); i++) {
+ delete _params[i];
+ _params[i] = nullptr;
+ }
+
+ _params.clear();
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool Effect3DParams::persist(BasePersistenceManager *persistMgr) {
+ if (persistMgr->getIsSaving()) {
+ uint32 numItems = _params.size();
+ persistMgr->transferUint32(TMEMBER(numItems));
+
+ for (uint32 i = 0; i < numItems; i++) {
+ _params[i]->persist(persistMgr);
+ }
+ } else {
+ uint32 numItems = 0;
+ persistMgr->transferUint32(TMEMBER(numItems));
+
+ for (uint32 i = 0; i < numItems; i++) {
+ Effect3DParam *param = new Effect3DParam();
+ param->persist(persistMgr);
+
+ _params.add(param);
+ }
+ }
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void Effect3DParams::setParam(const char *paramName, ScValue *val) {
+ Effect3DParam *param = getParamByName(paramName);
+
+ switch (val->getType()) {
+ case VAL_INT:
+ param->setValue(val->getInt());
+ break;
+ case VAL_FLOAT:
+ param->setValue((float)val->getFloat());
+ break;
+ case VAL_BOOL:
+ param->setValue(val->getBool());
+ break;
+ default:
+ param->setValue(val->getString());
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+void Effect3DParams::setParam(const char *paramName, DXVector4 val) {
+ Effect3DParam *param = getParamByName(paramName);
+ param->setValue(val);
+}
+
+//////////////////////////////////////////////////////////////////////////
+Effect3DParams::Effect3DParam *Effect3DParams::getParamByName(const char *paramName) {
+ Effect3DParam *param = nullptr;
+
+ for (uint32 i = 0; i < _params.size(); i++) {
+ if (_params[i]->getParamName() && strcmp(paramName, _params[i]->getParamName()) == 0) {
+ param = _params[i];
+ break;
+ }
+ }
+
+ if (!param) {
+ param = new Effect3DParam(paramName);
+ _params.add(param);
+ }
+
+ return param;
+}
+
+} // namespace Wintermute
diff --git a/engines/wintermute/base/gfx/3deffect_params.h b/engines/wintermute/base/gfx/3deffect_params.h
new file mode 100644
index 00000000000..285529eaab1
--- /dev/null
+++ b/engines/wintermute/base/gfx/3deffect_params.h
@@ -0,0 +1,96 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*
+ * This file is based on WME.
+ * http://dead-code.org/redir.php?target=wme
+ * Copyright (c) 2003-2013 Jan Nedoma and contributors
+ */
+
+#ifndef WINTERMUTE_3D_EFFECT_PARAMS_H
+#define WINTERMUTE_3D_EFFECT_PARAMS_H
+
+#include "engines/wintermute/base/base_game.h"
+
+namespace Wintermute {
+
+//////////////////////////////////////////////////////////////////////////
+class Effect3DParams {
+public:
+
+ //////////////////////////////////////////////////////////////////////////
+ class Effect3DParam {
+ public:
+
+ enum ParamType {
+ EP_UNKNOWN,
+ EP_STRING,
+ EP_FLOAT,
+ EP_INT,
+ EP_BOOL,
+ EP_VECTOR
+ };
+
+ Effect3DParam();
+ Effect3DParam(const char *paramName);
+ ~Effect3DParam();
+
+ void setValue(char *val);
+ void setValue(int val);
+ void setValue(float val);
+ void setValue(bool val);
+ void setValue(DXVector4 val);
+
+ const char *getParamName() const { return _paramName.c_str(); }
+
+ bool persist(BasePersistenceManager *persistMgr);
+
+ private:
+ void setDefaultValues();
+ ParamType _type;
+ Common::String _paramName;
+ bool _initialized;
+
+ Common::String _valString;
+ int _valInt;
+ float _valFloat;
+ DXVector4 _valVector;
+ bool _valBool;
+ };
+
+
+ //////////////////////////////////////////////////////////////////////////
+ Effect3DParams();
+ ~Effect3DParams();
+
+ bool persist(BasePersistenceManager *persistMgr);
+ void clear();
+ void setParam(const char *paramName, ScValue *val);
+ void setParam(const char *paramName, DXVector4 Val);
+
+private:
+ Effect3DParam *getParamByName(const char *paramName);
+ BaseArray<Effect3DParam *> _params;
+};
+
+} // namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/base/gfx/opengl/base_render_opengl3d.h b/engines/wintermute/base/gfx/opengl/base_render_opengl3d.h
index c9511b689cb..cefad6f67dd 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d.h
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d.h
@@ -41,6 +41,11 @@ namespace Wintermute {
class BaseSurfaceOpenGL3D;
class BaseRenderOpenGL3D : public BaseRenderer3D {
+ friend class BaseSurfaceOpenGL3D;
+ friend class Mesh3DSOpenGL;
+ friend class XMeshOpenGL;
+ friend class ShadowVolumeOpenGL;
+
struct SpriteVertex {
float x;
float y;
@@ -146,7 +151,7 @@ public:
bool setViewport3D(DXViewport *viewport) override;
-private:
+protected:
SimpleShadowVertex _simpleShadow[4]{};
Common::Array<DXVector4> _lightPositions;
Common::Array<DXVector3> _lightDirections;
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 c9cfde0c0ce..986cdaf5411 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h
@@ -42,6 +42,11 @@ namespace Wintermute {
class BaseSurfaceOpenGL3D;
class BaseRenderOpenGL3DShader : public BaseRenderer3D {
+ friend class BaseSurfaceOpenGL3DShader;
+ friend class Mesh3DSOpenGLShader;
+ friend class XMeshOpenGLShader;
+ friend class ShadowVolumeOpenGLShader;
+
struct SpriteVertex {
float x;
float y;
diff --git a/engines/wintermute/base/gfx/opengl/meshx_opengl.cpp b/engines/wintermute/base/gfx/opengl/meshx_opengl.cpp
index 2ee163dd8c4..097f193e20f 100644
--- a/engines/wintermute/base/gfx/opengl/meshx_opengl.cpp
+++ b/engines/wintermute/base/gfx/opengl/meshx_opengl.cpp
@@ -26,6 +26,8 @@
*/
#include "engines/wintermute/base/gfx/xmaterial.h"
+#include "engines/wintermute/base/gfx/3deffect.h"
+#include "engines/wintermute/base/gfx/3deffect_params.h"
#include "engines/wintermute/base/gfx/skin_mesh_helper.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/gfx/base_renderer3d.h"
@@ -35,6 +37,7 @@
#if defined(USE_OPENGL_GAME)
#include "engines/wintermute/base/gfx/opengl/base_surface_opengl3d.h"
+#include "engines/wintermute/base/gfx/opengl/base_render_opengl3d.h"
#include "engines/wintermute/base/gfx/opengl/meshx_opengl.h"
namespace Wintermute {
@@ -96,23 +99,27 @@ bool XMeshOpenGL::render(XModel *model) {
}
for (uint32 i = 0; i < numAttrs; i++) {
- int materialIndex = attrs[i]._attribId;
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, _materials[materialIndex]->_material._diffuse._data);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, _materials[materialIndex]->_material._diffuse._data);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, _materials[materialIndex]->_material._specular._data);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, _materials[materialIndex]->_material._emissive._data);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, _materials[materialIndex]->_material._power);
-
+ Material *mat = _materials[attrs[i]._attribId];
bool textureEnable = false;
- if (_materials[materialIndex]->getSurface()) {
+ if (mat->getSurface()) {
textureEnable = true;
glEnable(GL_TEXTURE_2D);
- static_cast<BaseSurfaceOpenGL3D *>(_materials[materialIndex]->getSurface())->setTexture();
+ static_cast<BaseSurfaceOpenGL3D *>(mat->getSurface())->setTexture();
} else {
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
}
+ if (mat->getEffect()) {
+ renderEffect(mat);
+ } else {
+ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat->_material._diffuse._data);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat->_material._diffuse._data);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat->_material._specular._data);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat->_material._emissive._data);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, mat->_material._power);
+ }
+
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
if (textureEnable)
@@ -144,6 +151,14 @@ bool XMeshOpenGL::renderFlatShadowModel() {
return true;
}
+void XMeshOpenGL::renderEffect(Material *material) {
+ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material->_material._diffuse._data);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, material->_material._diffuse._data);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material->_material._specular._data);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, material->_material._emissive._data);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material->_material._power);
+}
+
} // namespace Wintermute
#endif // defined(USE_OPENGL_GAME)
diff --git a/engines/wintermute/base/gfx/opengl/meshx_opengl.h b/engines/wintermute/base/gfx/opengl/meshx_opengl.h
index 952938b6229..be9837c7d70 100644
--- a/engines/wintermute/base/gfx/opengl/meshx_opengl.h
+++ b/engines/wintermute/base/gfx/opengl/meshx_opengl.h
@@ -30,6 +30,9 @@
#include "engines/wintermute/base/gfx/xmesh.h"
+class Effect3D;
+class Effect3DParams;
+
#if defined(USE_OPENGL_GAME)
namespace Wintermute {
@@ -41,6 +44,9 @@ public:
bool render(XModel *model) override;
bool renderFlatShadowModel() override;
+
+private:
+ void renderEffect(Material *material);
};
} // 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 74f343225fd..9294b1b7f25 100644
--- a/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.cpp
+++ b/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.cpp
@@ -26,6 +26,8 @@
*/
#include "engines/wintermute/base/gfx/xmaterial.h"
+#include "engines/wintermute/base/gfx/3deffect.h"
+#include "engines/wintermute/base/gfx/3deffect_params.h"
#include "engines/wintermute/base/gfx/skin_mesh_helper.h"
#include "engines/wintermute/base/gfx/base_renderer3d.h"
#include "engines/wintermute/base/base_game.h"
@@ -35,6 +37,7 @@
#if defined(USE_OPENGL_SHADERS)
#include "engines/wintermute/base/gfx/opengl/base_surface_opengl3d.h"
+#include "engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.h"
#include "engines/wintermute/base/gfx/opengl/meshx_opengl_shader.h"
namespace Wintermute {
@@ -125,23 +128,24 @@ bool XMeshOpenGLShader::render(XModel *model) {
_shader->enableVertexAttribute("texcoord", _vertexBuffer, 2, GL_FLOAT, false, 4 * vertexSize, 4 * textureOffset);
_shader->enableVertexAttribute("normal", _vertexBuffer, 3, GL_FLOAT, false, 4 * vertexSize, 4 * normalOffset);
- _shader->use(true);
-
for (uint32 i = 0; i < numAttrs; i++) {
- int materialIndex = attrs[i]._attribId;
-
- if (_materials[materialIndex]->getSurface()) {
+ Material *mat = _materials[attrs[i]._attribId];
+ if (mat->getSurface()) {
glEnable(GL_TEXTURE_2D);
- static_cast<BaseSurfaceOpenGL3D *>(_materials[materialIndex]->getSurface())->setTexture();
+ static_cast<BaseSurfaceOpenGL3D *>(mat->getSurface())->setTexture();
} else {
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
}
- // wme does not seem to care about specular or emissive light values
- Math::Vector4d diffuse(_materials[materialIndex]->_material._diffuse._data);
- _shader->setUniform("diffuse", diffuse);
- _shader->setUniform("ambient", diffuse);
+ if (mat->getEffect()) {
+ renderEffect(mat);
+ } else {
+ Math::Vector4d diffuse(mat->_material._diffuse._data);
+ _shader->use(true);
+ _shader->setUniform("diffuse", diffuse);
+ _shader->setUniform("ambient", diffuse);
+ }
size_t offsetFace = 4 * attrsTable->_ptr[i]._faceStart * 3;
glDrawElements(GL_TRIANGLES, attrsTable->_ptr[i]._faceCount * 3, GL_UNSIGNED_INT, (void *)offsetFace);
@@ -193,6 +197,13 @@ bool XMeshOpenGLShader::update(FrameNode *parentFrame) {
return true;
}
+void XMeshOpenGLShader::renderEffect(Material *material) {
+ Math::Vector4d diffuse(material->_material._diffuse._data);
+ _shader->use(true);
+ _shader->setUniform("diffuse", diffuse);
+ _shader->setUniform("ambient", diffuse);
+}
+
} // namespace Wintermute
#endif // defined(USE_OPENGL_SHADERS)
diff --git a/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.h b/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.h
index 5f63ba0a63f..49790ff6e0e 100644
--- a/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.h
+++ b/engines/wintermute/base/gfx/opengl/meshx_opengl_shader.h
@@ -30,6 +30,9 @@
#include "engines/wintermute/base/gfx/xmesh.h"
+class Effect3D;
+class Effect3DParams;
+
#if defined(USE_OPENGL_SHADERS)
#include "graphics/opengl/shader.h"
@@ -46,6 +49,9 @@ public:
bool renderFlatShadowModel() override;
bool update(FrameNode *parentFrame) override;
+private:
+ void renderEffect(Material *material);
+
protected:
GLuint _vertexBuffer;
GLuint _indexBuffer;
diff --git a/engines/wintermute/base/gfx/xframe_node.cpp b/engines/wintermute/base/gfx/xframe_node.cpp
index dd2b4320b94..e055eeccdad 100644
--- a/engines/wintermute/base/gfx/xframe_node.cpp
+++ b/engines/wintermute/base/gfx/xframe_node.cpp
@@ -444,6 +444,32 @@ bool FrameNode::setMaterialTheora(char *matName, VideoTheoraPlayer *theora) {
return true;
}
+//////////////////////////////////////////////////////////////////////////
+bool FrameNode::setMaterialEffect(char *matName, Effect3D *effect, Effect3DParams *params) {
+ for (uint32 i = 0; i < _meshes.size(); i++) {
+ _meshes[i]->setMaterialEffect(matName, effect, params);
+ }
+
+ for (uint32 i = 0; i < _frames.size(); i++) {
+ _frames[i]->setMaterialEffect(matName, effect, params);
+ }
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool FrameNode::removeMaterialEffect(const char *matName) {
+ for (uint32 i = 0; i < _meshes.size(); i++) {
+ _meshes[i]->removeMaterialEffect(matName);
+ }
+
+ for (uint32 i = 0; i < _frames.size(); i++) {
+ _frames[i]->removeMaterialEffect(matName);
+ }
+
+ return true;
+}
+
//////////////////////////////////////////////////////////////////////////
bool FrameNode::invalidateDeviceObjects() {
for (uint32 i = 0; i < _meshes.size(); i++) {
diff --git a/engines/wintermute/base/gfx/xframe_node.h b/engines/wintermute/base/gfx/xframe_node.h
index 13df5ede1cc..b150c176709 100644
--- a/engines/wintermute/base/gfx/xframe_node.h
+++ b/engines/wintermute/base/gfx/xframe_node.h
@@ -42,6 +42,8 @@ namespace Wintermute {
class XModel;
class XFileData;
class BaseSprite;
+class Effect3D;
+class Effect3DParams;
class FrameNode : public BaseNamedObject {
public:
@@ -71,6 +73,8 @@ public:
bool setMaterialSprite(char *matName, BaseSprite *sprite);
bool setMaterialTheora(char *matName, VideoTheoraPlayer *theora);
+ bool setMaterialEffect(char *matName, Effect3D *effect, Effect3DParams *params);
+ bool removeMaterialEffect(const char *matName);
bool invalidateDeviceObjects();
bool restoreDeviceObjects();
diff --git a/engines/wintermute/base/gfx/xmaterial.cpp b/engines/wintermute/base/gfx/xmaterial.cpp
index 9321744bb3c..feeec5b7c0e 100644
--- a/engines/wintermute/base/gfx/xmaterial.cpp
+++ b/engines/wintermute/base/gfx/xmaterial.cpp
@@ -30,6 +30,7 @@
#include "engines/wintermute/base/base_surface_storage.h"
#include "engines/wintermute/base/gfx/base_surface.h"
#include "engines/wintermute/base/gfx/xmaterial.h"
+#include "engines/wintermute/base/gfx/3deffect.h"
#include "engines/wintermute/base/gfx/xfile_loader.h"
#include "engines/wintermute/dcgf.h"
#include "engines/wintermute/utils/path_util.h"
@@ -48,6 +49,8 @@ Material::Material(BaseGame *inGame) : BaseNamedObject(inGame) {
_ownedSurface = false;
_sprite = nullptr;
_theora = nullptr;
+ _effect = nullptr;
+ _params = nullptr;
}
//////////////////////////////////////////////////////////////////////////
@@ -58,16 +61,21 @@ Material::~Material() {
_sprite = nullptr; // ref only
_theora = nullptr;
+ _effect = nullptr;
+ _params = nullptr;
}
//////////////////////////////////////////////////////////////////////////
bool Material::invalidateDeviceObjects() {
- // as long as we don't support D3DX effects, there is nothing to be done here
+ if (_effect)
+ return _effect->invalidateDeviceObjects();
return true;
}
//////////////////////////////////////////////////////////////////////////
bool Material::restoreDeviceObjects() {
+ if (_effect)
+ return _effect->restoreDeviceObjects();
return true;
}
@@ -129,6 +137,25 @@ bool Material::setTheora(VideoTheoraPlayer *theora, bool adoptName) {
return true;
}
+//////////////////////////////////////////////////////////////////////////
+bool Material::setEffect(Effect3D *effect, Effect3DParams *params, bool adoptName) {
+ if (!effect) {
+ _effect = nullptr;
+ _params = nullptr;
+ return true;
+ }
+
+ if (adoptName) {
+ setName(PathUtil::getFileNameWithoutExtension(effect->getFileName()).c_str());
+ }
+ _textureFilename = effect->getFileName();
+
+ _effect = effect;
+ _params = params;
+
+ return true;
+}
+
//////////////////////////////////////////////////////////////////////////
BaseSurface *Material::getSurface() {
if (_theora) {
diff --git a/engines/wintermute/base/gfx/xmaterial.h b/engines/wintermute/base/gfx/xmaterial.h
index fc22bdb2ef3..87a11e6485c 100644
--- a/engines/wintermute/base/gfx/xmaterial.h
+++ b/engines/wintermute/base/gfx/xmaterial.h
@@ -33,6 +33,8 @@
namespace Wintermute {
+class Effect3D;
+class Effect3DParams;
class BaseSprite;
class BaseSurface;
class VideoTheoraPlayer;
@@ -48,7 +50,11 @@ public:
bool setTexture(const Common::String &filename, bool adoptName = false);
bool setSprite(BaseSprite *sprite, bool adoptName = false);
bool setTheora(VideoTheoraPlayer *theora, bool adoptName = false);
+ bool setEffect(Effect3D *effect, Effect3DParams *params, bool adoptName = false);
+
BaseSurface *getSurface();
+ Effect3D *getEffect() { return _effect; }
+ Effect3DParams *getEffectParams() { return _params; }
bool invalidateDeviceObjects();
bool restoreDeviceObjects();
@@ -59,6 +65,8 @@ private:
bool _ownedSurface;
BaseSprite *_sprite;
VideoTheoraPlayer *_theora;
+ Effect3D *_effect;
+ Effect3DParams *_params;
};
} // namespace Wintermute
diff --git a/engines/wintermute/base/gfx/xmesh.cpp b/engines/wintermute/base/gfx/xmesh.cpp
index d09b7b71204..c26e7c60f66 100644
--- a/engines/wintermute/base/gfx/xmesh.cpp
+++ b/engines/wintermute/base/gfx/xmesh.cpp
@@ -34,6 +34,7 @@
#include "engines/wintermute/base/gfx/xmodel.h"
#include "engines/wintermute/base/gfx/xbuffer.h"
#include "engines/wintermute/base/gfx/xskinmesh.h"
+#include "engines/wintermute/base/gfx/3deffect.h"
#include "engines/wintermute/base/gfx/3dutils.h"
#include "engines/wintermute/base/base_engine.h"
#include "engines/wintermute/utils/path_util.h"
@@ -317,13 +318,33 @@ bool XMesh::setMaterialSprite(const Common::String &matName, BaseSprite *sprite)
//////////////////////////////////////////////////////////////////////////
bool XMesh::setMaterialTheora(const Common::String &matName, VideoTheoraPlayer *theora) {
for (uint32 i = 0; i < _materials.size(); i++) {
- if (_materials[i]->getName() && scumm_stricmp(_materials[i]->getName(), matName.c_str()) == 0) {
+ if (_materials[i]->getName() && scumm_stricmp(_materials[i]->getName(), matName.c_str()) == 0) {
_materials[i]->setTheora(theora);
}
}
return true;
}
+//////////////////////////////////////////////////////////////////////////
+bool XMesh::setMaterialEffect(const Common::String &matName, Effect3D *effect, Effect3DParams *params) {
+ for (uint32 i = 0; i < _materials.size(); i++) {
+ if (_materials[i]->getName() && scumm_stricmp(_materials[i]->getName(), matName.c_str()) == 0) {
+ _materials[i]->setEffect(effect, params);
+ }
+ }
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool XMesh::removeMaterialEffect(const Common::String &matName) {
+ for (uint32 i = 0; i < _materials.size(); i++) {
+ if (_materials[i]->getName() && scumm_stricmp(_materials[i]->getName(), matName.c_str()) == 0) {
+ _materials[i]->setEffect(nullptr, nullptr);
+ }
+ }
+ return true;
+}
+
//////////////////////////////////////////////////////////////////////////
bool XMesh::invalidateDeviceObjects() {
if (_skinMesh) {
diff --git a/engines/wintermute/base/gfx/xmesh.h b/engines/wintermute/base/gfx/xmesh.h
index 905d5b4e85b..e7d45837e6c 100644
--- a/engines/wintermute/base/gfx/xmesh.h
+++ b/engines/wintermute/base/gfx/xmesh.h
@@ -44,6 +44,8 @@ class ShadowVolume;
class VideoTheoraPlayer;
class SkinMeshHelper;
class DXMesh;
+class Effect3D;
+class Effect3DParams;
struct XMeshObject;
class XMesh : public BaseNamedObject {
@@ -66,6 +68,8 @@ public:
bool setMaterialSprite(const Common::String &matName, BaseSprite *sprite);
bool setMaterialTheora(const Common::String &matName, VideoTheoraPlayer *theora);
+ bool setMaterialEffect(const Common::String &matName, Effect3D *effect, Effect3DParams *params);
+ bool removeMaterialEffect(const Common::String &matName);
bool invalidateDeviceObjects();
bool restoreDeviceObjects();
diff --git a/engines/wintermute/base/gfx/xmodel.cpp b/engines/wintermute/base/gfx/xmodel.cpp
index 1385496a679..078104886f1 100644
--- a/engines/wintermute/base/gfx/xmodel.cpp
+++ b/engines/wintermute/base/gfx/xmodel.cpp
@@ -39,6 +39,7 @@
#include "engines/wintermute/base/gfx/xframe_node.h"
#include "engines/wintermute/base/gfx/xmaterial.h"
#include "engines/wintermute/base/gfx/xmodel.h"
+#include "engines/wintermute/base/gfx/3deffect.h"
#include "engines/wintermute/base/gfx/xfile.h"
#include "engines/wintermute/base/gfx/xfile_loader.h"
#include "engines/wintermute/dcgf.h"
@@ -858,6 +859,97 @@ bool XModel::setMaterialTheora(const char *materialName, const char *theoraFilen
return true;
}
+//////////////////////////////////////////////////////////////////////////
+bool XModel::setMaterialEffect(const char *materialName, const char *effectFilename) {
+ if (!materialName || !effectFilename)
+ return false;
+ if (!_rootFrame)
+ return false;
+
+
+ Effect3D *effect = new Effect3D(_gameRef);
+ if (!effect->createFromFile(effectFilename)) {
+ delete effect;
+ return false;
+ }
+
+ XModelMatSprite *matSprite = nullptr;
+ for (uint32 i = 0 ; i < _matSprites.size(); i++) {
+ if (scumm_stricmp(_matSprites[i]->_matName, materialName) == 0) {
+ matSprite = _matSprites[i];
+ break;
+ }
+ }
+ if (matSprite) {
+ matSprite->setEffect(effect);
+ } else {
+ matSprite = new XModelMatSprite(materialName, effect);
+ _matSprites.add(matSprite);
+ }
+ _rootFrame->setMaterialEffect(matSprite->_matName, matSprite->_effect, matSprite->_effectParams);
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool XModel::removeMaterialEffect(const char *materialName) {
+ if (!materialName)
+ return false;
+ if (!_rootFrame)
+ return false;
+
+ for (uint32 i = 0; i < _matSprites.size(); i++) {
+ if (scumm_stricmp(_matSprites[i]->_matName, materialName) == 0) {
+ delete _matSprites[i];
+ _matSprites[i] = nullptr;
+ _matSprites.remove_at(i);
+ _rootFrame->removeMaterialEffect(materialName);
+ return true;
+ }
+ }
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool XModel::setMaterialEffectParam(const char *materialName, const char *paramName, ScValue *val) {
+ if (!materialName)
+ return false;
+ if (!_rootFrame)
+ return false;
+
+
+ for (uint32 i = 0 ; i < _matSprites.size(); i++) {
+ if (scumm_stricmp(_matSprites[i]->_matName, materialName) == 0) {
+ if (_matSprites[i]->_effectParams) {
+ _matSprites[i]->_effectParams->setParam(paramName, val);
+ return true;
+ } else
+ return false;
+ }
+ }
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool XModel::setMaterialEffectParam(const char *materialName, const char *paramName, DXVector4 val) {
+ if (!materialName)
+ return false;
+ if (!_rootFrame)
+ return false;
+
+
+ for (uint32 i = 0; i < _matSprites.size(); i++) {
+ if (scumm_stricmp(_matSprites[i]->_matName, materialName) == 0) {
+ if (_matSprites[i]->_effectParams) {
+ _matSprites[i]->_effectParams->setParam(paramName, val);
+ return true;
+ } else
+ return false;
+ }
+ }
+ return false;
+}
+
//////////////////////////////////////////////////////////////////////////
bool XModel::initializeSimple() {
if (!_rootFrame) {
@@ -871,8 +963,18 @@ bool XModel::initializeSimple() {
} else if (_matSprites[i]->_sprite) {
_rootFrame->setMaterialSprite(_matSprites[i]->_matName, _matSprites[i]->_sprite);
}
+
+ if (_matSprites[i]->_effectFile) {
+ Effect3D *effect = new Effect3D(_gameRef);
+ if (effect->createFromFile(_matSprites[i]->_effectFile)) {
+ _matSprites[i]->_effect = effect;
+ _rootFrame->setMaterialEffect(_matSprites[i]->_matName, _matSprites[i]->_effect, _matSprites[i]->_effectParams);
+ } else {
+ delete effect;
+ effect = nullptr;
+ }
+ }
}
- // TODO: Effects
if (_parentModel) {
findBones(false, _parentModel);
diff --git a/engines/wintermute/base/gfx/xmodel.h b/engines/wintermute/base/gfx/xmodel.h
index 365f97640f9..b00b4f06930 100644
--- a/engines/wintermute/base/gfx/xmodel.h
+++ b/engines/wintermute/base/gfx/xmodel.h
@@ -31,6 +31,8 @@
#include "engines/wintermute/base/base_object.h"
#include "engines/wintermute/base/base_sprite.h"
#include "engines/wintermute/base/gfx/xmath.h"
+#include "engines/wintermute/base/gfx/3deffect.h"
+#include "engines/wintermute/base/gfx/3deffect_params.h"
#include "engines/wintermute/coll_templ.h"
#include "engines/wintermute/math/rect32.h"
#include "engines/wintermute/video/video_theora_player.h"
@@ -48,6 +50,8 @@ class FrameNode;
class Material;
class ShadowVolume;
class XFileData;
+class Effect3D;
+class Effect3DParams;
#define X_NUM_ANIMATION_CHANNELS 10
@@ -56,33 +60,64 @@ private:
class XModelMatSprite {
public:
char *_matName;
+ char *_effectFile;
BaseSprite *_sprite;
VideoTheoraPlayer *_theora;
+ Effect3D *_effect;
+ Effect3DParams *_effectParams;
XModelMatSprite() {
_matName = nullptr;
_sprite = nullptr;
_theora = nullptr;
+ _effect = nullptr;
+ _effectFile = nullptr;
+ _effectParams = nullptr;
}
XModelMatSprite(const char *matName, BaseSprite *sprite) {
_theora = nullptr;
_matName = nullptr;
+ _effect = nullptr;
BaseUtils::setString(&_matName, matName);
_sprite = sprite;
+ _effectFile = nullptr;
+ _effectParams = nullptr;
}
XModelMatSprite(const char *matName, VideoTheoraPlayer *theora) {
_sprite = nullptr;
_matName = nullptr;
+ _effect = nullptr;
BaseUtils::setString(&_matName, matName);
_theora = theora;
+ _effectFile = nullptr;
+ _effectParams = nullptr;
+ }
+
+ XModelMatSprite(const char *matName, Effect3D *effect) {
+ _sprite = nullptr;
+ _matName = nullptr;
+ _theora = nullptr;
+ BaseUtils::setString(&_matName, matName);
+ _effect = effect;
+ _effectFile = nullptr;
+ _effectParams = new Effect3DParams();
}
~XModelMatSprite() {
delete[] _matName;
+ _matName = nullptr;
+ delete _effectFile;
+ _effectFile = nullptr;
delete _sprite;
+ _sprite = nullptr;
delete _theora;
+ _theora = nullptr;
+ delete _effect;
+ _effect = nullptr;
+ delete _effectParams;
+ _effectParams = nullptr;
}
bool setSprite(BaseSprite *sprite) {
@@ -96,6 +131,7 @@ private:
bool setTheora(VideoTheoraPlayer *theora) {
delete _theora;
+ _theora = nullptr;
delete _sprite;
_sprite = nullptr;
_theora = theora;
@@ -103,12 +139,54 @@ private:
return true;
}
+ bool setEffect(Effect3D *effect) {
+ delete _effect;
+ _effect = effect;
+
+ if (!_effectParams)
+ _effectParams = new Effect3DParams();
+ else
+ _effectParams->clear();
+
+ return true;
+ }
+
bool persist(BasePersistenceManager *persistMgr) {
persistMgr->transferCharPtr(TMEMBER(_matName));
persistMgr->transferPtr(TMEMBER(_sprite));
persistMgr->transferPtr(TMEMBER(_theora));
+ if (persistMgr->getIsSaving()) {
+ char *effectFileName = nullptr;
+ if (_effect)
+ BaseUtils::setString(&effectFileName, _effect->getFileName());
+ else
+ effectFileName = nullptr;
+
+ persistMgr->transferCharPtr(TMEMBER(effectFileName));
+ delete[] effectFileName;
+ } else {
+ persistMgr->transferCharPtr(TMEMBER(_effectFile));
+ }
+
+ if (persistMgr->getIsSaving()) {
+ bool hasParams = _effectParams != nullptr;
+ persistMgr->transferBool(TMEMBER(hasParams));
+
+ if (hasParams)
+ _effectParams->persist(persistMgr);
+ } else {
+ bool hasParams;
+ persistMgr->transferBool(TMEMBER(hasParams));
+
+ if (hasParams) {
+ _effectParams = new Effect3DParams();
+ _effectParams->persist(persistMgr);
+ } else
+ _effectParams = nullptr;
+ }
+
return true;
}
};
@@ -161,6 +239,10 @@ public:
bool setMaterialSprite(const char *materialName, const char *spriteFilename);
bool setMaterialTheora(const char *materialName, const char *theoraFilename);
+ bool setMaterialEffect(const char *materialName, const char *effectFilename);
+ bool removeMaterialEffect(const char *materialName);
+ bool setMaterialEffectParam(const char *materialName, const char *paramName, ScValue *val);
+ bool setMaterialEffectParam(const char *materialName, const char *paramName, DXVector4 val);
bool initializeSimple();
bool invalidateDeviceObjects() override;
diff --git a/engines/wintermute/module.mk b/engines/wintermute/module.mk
index 7bde9e2ae52..28dcb973f48 100644
--- a/engines/wintermute/module.mk
+++ b/engines/wintermute/module.mk
@@ -162,6 +162,8 @@ MODULE_OBJS += \
ad/ad_waypoint_group3d.o \
base/gfx/3dcamera.o \
base/gfx/3dlight.o \
+ base/gfx/3deffect.o \
+ base/gfx/3deffect_params.o \
base/gfx/3dface.o \
base/gfx/3dloader_3ds.o \
base/gfx/3dmesh.o \
More information about the Scummvm-git-logs
mailing list