[Scummvm-git-logs] scummvm master -> 9fd225639a2a8921cd1f365395e556f900c550db
aquadran
noreply at scummvm.org
Sat Oct 26 15:37:50 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:
9fd225639a WINTERMUTE: Restore original code for 3ds loader
Commit: 9fd225639a2a8921cd1f365395e556f900c550db
https://github.com/scummvm/scummvm/commit/9fd225639a2a8921cd1f365395e556f900c550db
Author: PaweÅ KoÅodziejski (aquadran at gmail.com)
Date: 2024-10-26T17:37:45+02:00
Commit Message:
WINTERMUTE: Restore original code for 3ds loader
Changed paths:
A engines/wintermute/base/gfx/3dface.cpp
A engines/wintermute/base/gfx/3dface.h
A engines/wintermute/base/gfx/3dvertex.cpp
A engines/wintermute/base/gfx/3dvertex.h
engines/wintermute/ad/ad_scene_geometry.cpp
engines/wintermute/ad/ad_waypoint_group3d.cpp
engines/wintermute/base/gfx/3dcamera.cpp
engines/wintermute/base/gfx/3dcamera.h
engines/wintermute/base/gfx/3dlight.cpp
engines/wintermute/base/gfx/3dlight.h
engines/wintermute/base/gfx/3dloader_3ds.cpp
engines/wintermute/base/gfx/3dloader_3ds.h
engines/wintermute/base/gfx/3dmesh.cpp
engines/wintermute/base/gfx/3dmesh.h
engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp
engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
engines/wintermute/base/gfx/opengl/mesh3ds_opengl.cpp
engines/wintermute/base/gfx/opengl/mesh3ds_opengl.h
engines/wintermute/base/gfx/opengl/mesh3ds_opengl_shader.cpp
engines/wintermute/base/gfx/opengl/mesh3ds_opengl_shader.h
engines/wintermute/base/gfx/opengl/shaders/wme_geometry.vertex
engines/wintermute/module.mk
diff --git a/engines/wintermute/ad/ad_scene_geometry.cpp b/engines/wintermute/ad/ad_scene_geometry.cpp
index e708c415135..5d4fb9dcbc6 100644
--- a/engines/wintermute/ad/ad_scene_geometry.cpp
+++ b/engines/wintermute/ad/ad_scene_geometry.cpp
@@ -182,78 +182,125 @@ bool AdSceneGeometry::loadFile(const char *filename) {
filenameTmp.replace(filenameTmp.size() - 3, 3, "geometry", 0, 8);
AdGeomExt *geomExt = getGeometryExtension(filenameTmp.begin());
- // Light3D, AdBlock, AdGeneric and AdWalkplane all inherit from BaseScriptable
- // the latter one is overriding the new operator such that instances are registered
- // in the system class registry
- // for the most part, the subclasses of BaseScriptable override the new operator themselves,
- // but here this is not the case. So these instances are not supposed to be registered
- // and doing so would create faulty savegames. The persistence of them will be handled by AdSceneGeometry
- SystemClassRegistry::getInstance()->_disabled = true;
-
- BaseArray<Mesh3DS *> meshes;
- BaseArray<Common::String> meshNames;
-
- if (!load3DSFile(filename, meshes, meshNames, _lights, _cameras, _gameRef)) {
+ Loader3DS *loader = new Loader3DS(_gameRef);
+ if (!loader->parseFile(filename)) {
+ delete loader;
delete geomExt;
return false;
}
uint i;
- // load meshes
- for (i = 0; i < meshes.size(); i++) {
- AdGeomExtNode *ExtNode = geomExt->matchName(meshNames[i].c_str());
+ SystemClassRegistry::getInstance()->_disabled = true;
- if (!ExtNode) {
+ // load meshes
+ for (i = 0; i < loader->getNumMeshes(); i++) {
+ AdGeomExtNode *extNode = geomExt->matchName(loader->getMeshName(i).c_str());
+ if (!extNode) {
continue;
}
- switch (ExtNode->_type) {
+ switch (extNode->_type) {
case GEOM_WALKPLANE: {
AdWalkplane *plane = new AdWalkplane(_gameRef);
- plane->setName(meshNames[i].c_str());
- plane->_mesh = meshes[i];
- plane->_mesh->computeNormals();
- plane->_mesh->fillVertexBuffer(0xFF0000FF); // original 0x700000FF
- plane->_receiveShadows = ExtNode->_receiveShadows;
- _planes.add(plane);
+ plane->setName(loader->getMeshName(i).c_str());
+ plane->_mesh = _gameRef->_renderer3D->createMesh3DS();
+ if (!loader->loadMesh(i, plane->_mesh)) {
+ delete plane->_mesh;
+ delete plane;
+ delete loader;
+ delete geomExt;
+ return false;
+ } else {
+ plane->_mesh->computeNormals();
+ plane->_mesh->fillVertexBuffer(0xD00000FF); // original 0x700000FF
+ plane->_receiveShadows = extNode->_receiveShadows;
+ _planes.add(plane);
+ }
}
break;
case GEOM_BLOCKED: {
AdBlock *block = new AdBlock(_gameRef);
- block->setName(meshNames[i].c_str());
- block->_mesh = meshes[i];
- block->_mesh->computeNormals();
- block->_mesh->fillVertexBuffer(0xFFFF0000); // original 0x70FF0000
- block->_receiveShadows = ExtNode->_receiveShadows;
- _blocks.add(block);
+ block->setName(loader->getMeshName(i).c_str());
+ block->_mesh = _gameRef->_renderer3D->createMesh3DS();
+ if (!loader->loadMesh(i, block->_mesh)) {
+ delete block->_mesh;
+ delete block;
+ delete loader;
+ delete geomExt;
+ return false;
+ } else {
+ block->_mesh->computeNormals();
+ block->_mesh->fillVertexBuffer(0xD0FF0000); // original 0x70FF0000
+ block->_receiveShadows = extNode->_receiveShadows;
+ _blocks.add(block);
+ }
}
break;
case GEOM_WAYPOINT: {
- Mesh3DS *mesh = meshes[i];
- if (_waypointGroups.size() == 0) {
- _waypointGroups.add(new AdWaypointGroup3D(_gameRef));
+ Mesh3DS *mesh = _gameRef->_renderer3D->createMesh3DS();
+ if (!loader->loadMesh(i, mesh)) {
+ delete mesh;
+ delete loader;
+ delete geomExt;
+ return false;
+ } else {
+ if (_waypointGroups.size() == 0) {
+ _waypointGroups.add(new AdWaypointGroup3D(_gameRef));
+ }
+ _waypointGroups[0]->addFromMesh(mesh);
+ delete mesh;
}
- _waypointGroups[0]->addFromMesh(mesh);
- delete mesh;
}
break;
case GEOM_GENERIC: {
AdGeneric *generic = new AdGeneric(_gameRef);
- generic->setName(meshNames[i].c_str());
- generic->_mesh = meshes[i];
- generic->_mesh->computeNormals();
- generic->_mesh->fillVertexBuffer(0xFF00FF00); // original 0x7000FF00
- generic->_receiveShadows = ExtNode->_receiveShadows;
- _generics.add(generic);
+ generic->setName(loader->getMeshName(i).c_str());
+ generic->_mesh = _gameRef->_renderer3D->createMesh3DS();
+ if (!loader->loadMesh(i, generic->_mesh)) {
+ delete generic->_mesh;
+ delete generic;
+ delete loader;
+ delete geomExt;
+ return false;
+ } else {
+ generic->_mesh->computeNormals();
+ generic->_mesh->fillVertexBuffer(0xD000FF00); // original 0x7000FF00
+ generic->_receiveShadows = extNode->_receiveShadows;
+ _generics.add(generic);
+ }
}
break;
}
}
+ // load cameras
+ for (i = 0; i < loader->getNumCameras(); i++) {
+ Camera3D *camera = new Camera3D(_gameRef);
+ if (!loader->loadCamera(i, camera)) {
+ delete camera;
+ delete loader;
+ delete geomExt;
+ return false;
+ } else
+ _cameras.add(camera);
+ }
+
+ // load lights
+ for (i = 0; i < loader->getNumLights(); i++) {
+ Light3D *light = new Light3D(_gameRef);
+ if (!loader->loadLight(i, light)) {
+ delete light;
+ delete loader;
+ delete geomExt;
+ return false;
+ } else
+ _lights.add(light);
+ }
+
SystemClassRegistry::getInstance()->_disabled = false;
if (_cameras.size() > 0) {
@@ -265,6 +312,7 @@ bool AdSceneGeometry::loadFile(const char *filename) {
setActiveLight(0);
}
+ delete loader;
delete geomExt;
// drop waypoints to the ground
@@ -426,16 +474,12 @@ float AdSceneGeometry::getHeightAt(DXVector3 pos, float tolerance, bool *intFoun
bool intFoundTmp = false;
for (uint32 i = 0; i < _planes.size(); i++) {
- for (int j = 0; j < _planes[i]->_mesh->faceCount(); j++) {
- uint16 *triangle = _planes[i]->_mesh->getFace(j);
- float *vp0 = _planes[i]->_mesh->getVertexPosition(triangle[0]);
- float *vp1 = _planes[i]->_mesh->getVertexPosition(triangle[1]);
- float *vp2 = _planes[i]->_mesh->getVertexPosition(triangle[2]);
- DXVector3 v0(vp0[0], vp0[1], vp0[2]);
- DXVector3 v1(vp1[0], vp1[1], vp1[2]);
- DXVector3 v2(vp2[0], vp2[1], vp2[2]);
-
- if (intersectTriangle(pos, dir, v0, v1, v2, &intersection._x, &intersection._y, &intersection._z)) {
+ for (int j = 0; j < _planes[i]->_mesh->_numFaces; j++) {
+ if (intersectTriangle(pos, dir,
+ _planes[i]->_mesh->_vertices[_planes[i]->_mesh->_faces[j]._vertices[0]]._pos,
+ _planes[i]->_mesh->_vertices[_planes[i]->_mesh->_faces[j]._vertices[1]]._pos,
+ _planes[i]->_mesh->_vertices[_planes[i]->_mesh->_faces[j]._vertices[2]]._pos,
+ &intersection._x, &intersection._y, &intersection._z)) {
if (intersection._y > pos._y + tolerance) {
continue; // only fall down
}
@@ -458,16 +502,14 @@ float AdSceneGeometry::getHeightAt(DXVector3 pos, float tolerance, bool *intFoun
//////////////////////////////////////////////////////////////////////////
bool AdSceneGeometry::directPathExists(DXVector3 *p1, DXVector3 *p2) {
+ DXVector3 v0, v1, v2;
+
// test walkplanes
for (uint i = 0; i < _planes.size(); i++) {
- for (int j = 0; j < _planes[i]->_mesh->faceCount(); j++) {
- uint16 *triangle = _planes[i]->_mesh->getFace(j);
- float *vp0 = _planes[i]->_mesh->getVertexPosition(triangle[0]);
- float *vp1 = _planes[i]->_mesh->getVertexPosition(triangle[1]);
- float *vp2 = _planes[i]->_mesh->getVertexPosition(triangle[2]);
- DXVector3 v0(vp0[0], vp0[1], vp0[2]);
- DXVector3 v1(vp1[0], vp1[1], vp1[2]);
- DXVector3 v2(vp2[0], vp2[1], vp2[2]);
+ for (int j = 0; j < _planes[i]->_mesh->_numFaces; j++) {
+ v0 = _planes[i]->_mesh->_vertices[_planes[i]->_mesh->_faces[j]._vertices[0]]._pos;
+ v1 = _planes[i]->_mesh->_vertices[_planes[i]->_mesh->_faces[j]._vertices[1]]._pos;
+ v2 = _planes[i]->_mesh->_vertices[_planes[i]->_mesh->_faces[j]._vertices[2]]._pos;
DXVector3 intersection;
float dist;
@@ -489,14 +531,10 @@ bool AdSceneGeometry::directPathExists(DXVector3 *p1, DXVector3 *p2) {
continue;
}
- for (int j = 0; j < _blocks[i]->_mesh->faceCount(); j++) {
- uint16 *triangle = _blocks[i]->_mesh->getFace(j);
- float *vp0 = _blocks[i]->_mesh->getVertexPosition(triangle[0]);
- float *vp1 = _blocks[i]->_mesh->getVertexPosition(triangle[1]);
- float *vp2 = _blocks[i]->_mesh->getVertexPosition(triangle[2]);
- DXVector3 v0(vp0[0], vp0[1], vp0[2]);
- DXVector3 v1(vp1[0], vp1[1], vp1[2]);
- DXVector3 v2(vp2[0], vp2[1], vp2[2]);
+ for (int j = 0; j < _blocks[i]->_mesh->_numFaces; j++) {
+ v0 = _blocks[i]->_mesh->_vertices[_blocks[i]->_mesh->_faces[j]._vertices[0]]._pos;
+ v1 = _blocks[i]->_mesh->_vertices[_blocks[i]->_mesh->_faces[j]._vertices[1]]._pos;
+ v2 = _blocks[i]->_mesh->_vertices[_blocks[i]->_mesh->_faces[j]._vertices[2]]._pos;
DXVector3 intersection;
float dist;
@@ -519,20 +557,18 @@ bool AdSceneGeometry::directPathExists(DXVector3 *p1, DXVector3 *p2) {
//////////////////////////////////////////////////////////////////////////
DXVector3 AdSceneGeometry::getBlockIntersection(DXVector3 *p1, DXVector3 *p2) {
+ DXVector3 v0, v1, v2;
+
// test blocks
for (uint i = 0; i < _blocks.size(); i++) {
if (!_blocks[i]->_active) {
continue;
}
- for (int j = 0; j < _blocks[i]->_mesh->faceCount(); j++) {
- uint16 *triangle = _blocks[i]->_mesh->getFace(j);
- float *vp0 = _blocks[i]->_mesh->getVertexPosition(triangle[0]);
- float *vp1 = _blocks[i]->_mesh->getVertexPosition(triangle[1]);
- float *vp2 = _blocks[i]->_mesh->getVertexPosition(triangle[2]);
- DXVector3 v0(vp0[0], vp0[1], vp0[2]);
- DXVector3 v1(vp1[0], vp1[1], vp1[2]);
- DXVector3 v2(vp2[0], vp2[1], vp2[2]);
+ for (int j = 0; j < _blocks[i]->_mesh->_numFaces; j++) {
+ v0 = _blocks[i]->_mesh->_vertices[_blocks[i]->_mesh->_faces[j]._vertices[0]]._pos;
+ v1 = _blocks[i]->_mesh->_vertices[_blocks[i]->_mesh->_faces[j]._vertices[1]]._pos;
+ v2 = _blocks[i]->_mesh->_vertices[_blocks[i]->_mesh->_faces[j]._vertices[2]]._pos;
DXVector3 intersection;
float dist;
@@ -684,16 +720,12 @@ bool AdSceneGeometry::convert2Dto3D(int x, int y, DXVector3 *pos) {
float minDist = FLT_MAX;
DXVector3 intersection, ray;
for (uint32 i = 0; i < _planes.size(); i++) {
- for (int j = 0; j < _planes[i]->_mesh->faceCount(); j++) {
- uint16 *triangle = _planes[i]->_mesh->getFace(j);
- float *vp0 = _planes[i]->_mesh->getVertexPosition(triangle[0]);
- float *vp1 = _planes[i]->_mesh->getVertexPosition(triangle[1]);
- float *vp2 = _planes[i]->_mesh->getVertexPosition(triangle[2]);
- DXVector3 v0(vp0[0], vp0[1], vp0[2]);
- DXVector3 v1(vp1[0], vp1[1], vp1[2]);
- DXVector3 v2(vp2[0], vp2[1], vp2[2]);
-
- if (intersectTriangle(vPickRayOrig, vPickRayDir, v0, v1, v2, &intersection._x, &intersection._y, &intersection._z)) {
+ for (int j = 0; j < _planes[i]->_mesh->_numFaces; j++) {
+ if (intersectTriangle(vPickRayOrig, vPickRayDir,
+ _planes[i]->_mesh->_vertices[_planes[i]->_mesh->_faces[j]._vertices[0]]._pos,
+ _planes[i]->_mesh->_vertices[_planes[i]->_mesh->_faces[j]._vertices[1]]._pos,
+ _planes[i]->_mesh->_vertices[_planes[i]->_mesh->_faces[j]._vertices[2]]._pos,
+ &intersection._x, &intersection._y, &intersection._z)) {
ray = intersection - vPickRayOrig;
float dist = DXVec3Length(&ray);
@@ -904,10 +936,10 @@ bool AdSceneGeometry::enableLights(DXVector3 point, BaseArray<char *> &ignoreLig
DXVector3 dif;
if (_lights[i]->_isSpotlight) {
- DXVector3 dir = _lights[i]->_target - _lights[i]->_position;
- dif = (_lights[i]->_position + dir * 0.75f) - point;
+ DXVector3 dir = _lights[i]->_target - _lights[i]->_pos;
+ dif = (_lights[i]->_pos + dir * 0.75f) - point;
} else {
- dif = _lights[i]->_position - point;
+ dif = _lights[i]->_pos - point;
}
_lights[i]->_distance = fabs(DXVec3Length(&dif));
@@ -1178,7 +1210,7 @@ uint32 AdSceneGeometry::getLightColor(const char *lightName) {
DXVector3 AdSceneGeometry::getLightPos(const char *lightName) {
for (uint i = 0; i < _lights.size(); i++) {
if (scumm_stricmp(lightName, _lights[i]->getName()) == 0) {
- return _lights[i]->_position;
+ return _lights[i]->_pos;
}
}
return DXVector3(0, 0, 0);
diff --git a/engines/wintermute/ad/ad_waypoint_group3d.cpp b/engines/wintermute/ad/ad_waypoint_group3d.cpp
index d32fda0b60d..c19fda41510 100644
--- a/engines/wintermute/ad/ad_waypoint_group3d.cpp
+++ b/engines/wintermute/ad/ad_waypoint_group3d.cpp
@@ -50,18 +50,18 @@ bool AdWaypointGroup3D::addFromMesh(Mesh3DS *mesh) {
DXVector3 min = DXVector3(0, 0, 0);
DXVector3 max = DXVector3(0, 0, 0);
- if (mesh->vertexCount() > 0) {
- min = max = mesh->getVertexPosition(0);
+ if (mesh->_numVertices > 0) {
+ min = max = mesh->_vertices[0]._pos;
}
- for (int i = 0; i < mesh->vertexCount(); i++) {
- min._x = MIN(min._x, mesh->getVertexPosition(i)[0]);
- min._y = MIN(min._y, mesh->getVertexPosition(i)[1]);
- min._z = MIN(min._z, mesh->getVertexPosition(i)[2]);
+ for (int i = 0; i < mesh->_numVertices; i++) {
+ min._x = MIN(min._x, mesh->_vertices[i]._pos._x);
+ min._y = MIN(min._y, mesh->_vertices[i]._pos._y);
+ min._z = MIN(min._z, mesh->_vertices[i]._pos._z);
- max._x = MAX(max._x, mesh->getVertexPosition(i)[0]);
- max._y = MAX(max._y, mesh->getVertexPosition(i)[1]);
- max._z = MAX(max._z, mesh->getVertexPosition(i)[2]);
+ max._x = MAX(max._x, mesh->_vertices[i]._pos._x);
+ max._y = MAX(max._y, mesh->_vertices[i]._pos._y);
+ max._z = MAX(max._z, mesh->_vertices[i]._pos._z);
}
DXVector3 *vect = new DXVector3;
diff --git a/engines/wintermute/base/gfx/3dcamera.cpp b/engines/wintermute/base/gfx/3dcamera.cpp
index 6dd3a27ac9b..3e6540333f2 100644
--- a/engines/wintermute/base/gfx/3dcamera.cpp
+++ b/engines/wintermute/base/gfx/3dcamera.cpp
@@ -41,7 +41,7 @@ namespace Wintermute {
//////////////////////////////////////////////////////////////////////////
Camera3D::Camera3D(BaseGame *inGame) : BaseNamedObject(inGame) {
- _position = DXVector3(0.0f, 0.0f, 0.0f);
+ _pos = DXVector3(0.0f, 0.0f, 0.0f);
_target = DXVector3(0.0f, 0.0f, 0.0f);
_bank = 0.0f;
_fov = _origFov = degToRad(45.0f);
@@ -62,14 +62,14 @@ bool Camera3D::getViewMatrix(DXMatrix *viewMatrix) {
DXVec3TransformCoord(&up, &up, &rot);
}
- DXMatrixLookAtLH(viewMatrix, &_position, &_target, &up);
+ DXMatrixLookAtLH(viewMatrix, &_pos, &_target, &up);
return true;
}
//////////////////////////////////////////////////////////////////////////
void Camera3D::setupPos(DXVector3 pos, DXVector3 target, float bank) {
- _position = pos;
+ _pos = pos;
_target = target;
_bank = bank;
}
@@ -79,23 +79,23 @@ void Camera3D::rotateView(float x, float y, float z) {
DXVector3 vVector; // Vector for the position/view.
// Get our view vector (The direciton we are facing)
- vVector = _target - _position; // This gets the direction of the view
+ vVector = _target - _pos; // This gets the direction of the view
// Rotate the view along the desired axis
if (x) {
// Rotate the view vector up or down, then add it to our position
- _target._z = (float)(_position._z + sin(x) * vVector._y + cos(x) * vVector._z);
- _target._y = (float)(_position._y + cos(x) * vVector._y - sin(x) * vVector._z);
+ _target._z = (float)(_pos._z + sin(x) * vVector._y + cos(x) * vVector._z);
+ _target._y = (float)(_pos._y + cos(x) * vVector._y - sin(x) * vVector._z);
}
if (y) {
// Rotate the view vector right or left, then add it to our position
- _target._z = (float)(_position._z + sin(y) * vVector._x + cos(y) * vVector._z);
- _target._x = (float)(_position._x + cos(y) * vVector._x - sin(y) * vVector._z);
+ _target._z = (float)(_pos._z + sin(y) * vVector._x + cos(y) * vVector._z);
+ _target._x = (float)(_pos._x + cos(y) * vVector._x - sin(y) * vVector._z);
}
if (z) {
// Rotate the view vector diagnally right or diagnally down, then add it to our position
- _target._x = (float)(_position._x + sin(z) * vVector._y + cos(z) * vVector._x);
- _target._y = (float)(_position._y + cos(z) * vVector._y - sin(z) * vVector._x);
+ _target._x = (float)(_pos._x + sin(z) * vVector._y + cos(z) * vVector._x);
+ _target._y = (float)(_pos._y + cos(z) * vVector._y - sin(z) * vVector._x);
}
}
@@ -104,47 +104,12 @@ void Camera3D::move(float speed) {
DXVector3 vector; // Init a vector for our view
// Get our view vector (The direciton we are facing)
- vector = _target - _position; // This gets the direction of the view
+ vector = _target - _pos; // This gets the direction of the view
- _position._x += vector._x * speed; // Add our acceleration to our position's X
- _position._z += vector._z * speed; // Add our acceleration to our position's Z
+ _pos._x += vector._x * speed; // Add our acceleration to our position's X
+ _pos._z += vector._z * speed; // Add our acceleration to our position's Z
_target._x += vector._x * speed; // Add our acceleration to our view's X
_target._z += vector._z * speed; // Add our acceleration to our view's Z
}
-bool Camera3D::loadFrom3DS(Common::MemoryReadStream &fileStream) {
- uint32 wholeChunkSize = fileStream.readUint32LE();
- int32 end = fileStream.pos() + wholeChunkSize - 6;
-
- _position._x = fileStream.readFloatLE();
- _position._z = fileStream.readFloatLE();
- _position._y = fileStream.readFloatLE();
-
- _target._x = fileStream.readFloatLE();
- _target._z = fileStream.readFloatLE();
- _target._y = fileStream.readFloatLE();
-
- _bank = fileStream.readFloatLE();
-
- float lens = fileStream.readFloatLE();
-
- if (lens > 0.0f) {
- _fov = degToRad(1900.0f / lens);
- } else {
- _fov = degToRad(45.0f);
- }
-
- _origFov = _fov;
-
- // discard all subchunks
- while (fileStream.pos() < end) {
- fileStream.readUint16LE(); // chunk id
- uint32 chunkSize = fileStream.readUint32LE();
-
- fileStream.seek(chunkSize - 6, SEEK_CUR);
- }
-
- return true;
-}
-
} // namespace Wintermute
diff --git a/engines/wintermute/base/gfx/3dcamera.h b/engines/wintermute/base/gfx/3dcamera.h
index f95b226be2b..ccc11e2e906 100644
--- a/engines/wintermute/base/gfx/3dcamera.h
+++ b/engines/wintermute/base/gfx/3dcamera.h
@@ -33,9 +33,6 @@
#include "engines/wintermute/base/base_named_object.h"
#include "engines/wintermute/base/gfx/xmath.h"
-#include "math/matrix4.h"
-#include "math/vector3d.h"
-
namespace Wintermute {
class Camera3D : public BaseNamedObject {
@@ -47,15 +44,13 @@ public:
Camera3D(BaseGame *inGame);
virtual ~Camera3D();
- DXVector3 _position;
+ DXVector3 _pos;
DXVector3 _target;
float _bank;
float _fov;
float _origFov;
float _nearClipPlane;
float _farClipPlane;
-
- bool loadFrom3DS(Common::MemoryReadStream &fileStream);
};
} // namespace Wintermute
diff --git a/engines/wintermute/base/gfx/3dface.cpp b/engines/wintermute/base/gfx/3dface.cpp
new file mode 100644
index 00000000000..45c3d2fd89f
--- /dev/null
+++ b/engines/wintermute/base/gfx/3dface.cpp
@@ -0,0 +1,49 @@
+/* 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 "engines/wintermute/base/gfx/3dface.h"
+#include "engines/wintermute/dcgf.h"
+
+namespace Wintermute {
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////
+Face3D::Face3D() {
+ for (int i = 0; i < 3; i++) {
+ _normals[i] = DXVector3(0, 0, 0);
+ _vertices[i] = 0;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+Face3D::~Face3D() {
+}
+
+} // namespace Wintermute
diff --git a/engines/wintermute/base/gfx/3dface.h b/engines/wintermute/base/gfx/3dface.h
new file mode 100644
index 00000000000..397416f72e0
--- /dev/null
+++ b/engines/wintermute/base/gfx/3dface.h
@@ -0,0 +1,46 @@
+/* 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_FACE_H
+#define WINTERMUTE_3D_FACE_H
+
+#include "engines/wintermute/base/gfx/xmath.h"
+
+namespace Wintermute {
+
+class Face3D {
+public:
+ Face3D();
+ virtual ~Face3D();
+
+ uint16 _vertices[3];
+ DXVector3 _normals[3];
+};
+
+} // namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/base/gfx/3dlight.cpp b/engines/wintermute/base/gfx/3dlight.cpp
index 758132d098f..7dbb5dd23aa 100644
--- a/engines/wintermute/base/gfx/3dlight.cpp
+++ b/engines/wintermute/base/gfx/3dlight.cpp
@@ -41,7 +41,7 @@ namespace Wintermute {
//////////////////////////////////////////////////////////////////////////
Light3D::Light3D(BaseGame *inGame) : BaseScriptable(inGame, false, false) {
_diffuseColor = BYTETORGBA(255, 255, 255, 255);
- _position = DXVector3(0, 0, 0);
+ _pos = DXVector3(0, 0, 0);
_target = DXVector3(0, 0, 0);
_isSpotlight = false;
_falloff = 0;
@@ -63,7 +63,7 @@ bool Light3D::setLight(int index) {
diffuse._z = RGBCOLGetB(_diffuseColor) / 256.0f;
diffuse._w = 1.0f;
- _gameRef->_renderer3D->setLightParameters(index, _position, _target - _position, diffuse, _isSpotlight);
+ _gameRef->_renderer3D->setLightParameters(index, _pos, _target - _pos, diffuse, _isSpotlight);
if (_active) {
_gameRef->_renderer3D->lightEnable(index, true);
@@ -75,7 +75,7 @@ bool Light3D::setLight(int index) {
//////////////////////////////////////////////////////////////////////////
bool Light3D::getViewMatrix(DXMatrix *viewMatrix) {
DXVector3 up = DXVector3(0.0f, 1.0f, 0.0f);
- DXMatrixLookAtLH(viewMatrix, &_position, &_target, &up);
+ DXMatrixLookAtLH(viewMatrix, &_pos, &_target, &up);
return true;
}
@@ -86,73 +86,4 @@ bool Light3D::persist(BasePersistenceManager *persistMgr) {
return true;
}
-bool Light3D::loadFrom3DS(Common::MemoryReadStream &fileStream) {
- uint32 wholeChunkSize = fileStream.readUint32LE();
- int32 end = fileStream.pos() + wholeChunkSize - 6;
-
- _position._x = fileStream.readFloatLE();
- _position._z = fileStream.readFloatLE();
- _position._y = fileStream.readFloatLE();
-
- while (fileStream.pos() < end) {
- uint16 chunkId = fileStream.readUint16LE();
- uint32 chunkSize = fileStream.readUint32LE();
-
- switch (chunkId) {
- case SPOTLIGHT:
- _target._x = fileStream.readFloatLE();
- _target._z = fileStream.readFloatLE();
- _target._y = fileStream.readFloatLE();
-
- // this is appearently not used
- fileStream.readFloatLE();
-
- _falloff = fileStream.readFloatLE();
- _isSpotlight = true;
- break;
-
- case LIGHT_IS_OFF:
- _active = false;
- break;
-
- case RGB_BYTE: {
- byte r = fileStream.readByte();
- byte g = fileStream.readByte();
- byte b = fileStream.readByte();
-
- _diffuseColor = r << 16;
- _diffuseColor |= g << 8;
- _diffuseColor |= b;
- _diffuseColor |= 255 << 24;
- break;
- }
-
- case RGB_FLOAT: {
- float r = fileStream.readFloatLE();
- float g = fileStream.readFloatLE();
- float b = fileStream.readFloatLE();
-
- _diffuseColor = static_cast<int32>(r * 255) << 16;
- _diffuseColor |= static_cast<int32>(g * 255) << 8;
- _diffuseColor |= static_cast<int32>(b * 255);
- _diffuseColor |= 255 << 24;
- break;
- }
-
- case RANGE_END:
- case 0x4659:
- case MULTIPLIER:
- case ROLL:
- case SPOT_SHADOW_MAP:
- case SPOT_RAY_TRACE_BIAS:
- case SPOT_RAY_TRACE:
- default:
- fileStream.seek(chunkSize - 6, SEEK_CUR);
- break;
- }
- }
-
- return true;
-}
-
} // namespace Wintermute
diff --git a/engines/wintermute/base/gfx/3dlight.h b/engines/wintermute/base/gfx/3dlight.h
index d18921e7408..e8427f8d39e 100644
--- a/engines/wintermute/base/gfx/3dlight.h
+++ b/engines/wintermute/base/gfx/3dlight.h
@@ -45,7 +45,7 @@ public:
Light3D(BaseGame *inGame);
virtual ~Light3D();
uint32 _diffuseColor;
- DXVector3 _position;
+ DXVector3 _pos;
DXVector3 _target;
bool _isSpotlight;
bool _active;
@@ -55,7 +55,6 @@ public:
bool _isAvailable;
bool setLight(int index = 0);
- bool loadFrom3DS(Common::MemoryReadStream &fileStream);
};
} // namespace Wintermute
diff --git a/engines/wintermute/base/gfx/3dloader_3ds.cpp b/engines/wintermute/base/gfx/3dloader_3ds.cpp
index 8771e0d14eb..6b4d3ac5903 100644
--- a/engines/wintermute/base/gfx/3dloader_3ds.cpp
+++ b/engines/wintermute/base/gfx/3dloader_3ds.cpp
@@ -19,109 +19,406 @@
*
*/
-#include "common/memstream.h"
-
+#include "engines/wintermute/dcgf.h"
+#include "engines/wintermute/math/math_util.h"
#include "engines/wintermute/base/base_file_manager.h"
-#include "engines/wintermute/base/base_game.h"
-#include "engines/wintermute/base/gfx/base_renderer3d.h"
-#include "engines/wintermute/base/gfx/3dcamera.h"
-#include "engines/wintermute/base/gfx/3dlight.h"
#include "engines/wintermute/base/gfx/3dloader_3ds.h"
-#include "engines/wintermute/base/gfx/3dmesh.h"
+#include "engines/wintermute/base/gfx/3dface.h"
+#include "engines/wintermute/base/gfx/3dvertex.h"
namespace Wintermute {
-bool load3DSObject(Common::MemoryReadStream &fileStream, BaseArray<Wintermute::Mesh3DS *> &meshes, BaseArray<Common::String> &meshNames,
- BaseArray<Wintermute::Light3D *> &lights, BaseArray<Wintermute::Camera3D *> &cameras, BaseGame *gameRef) {
- uint32 wholeChunkSize = fileStream.readUint32LE();
- int32 end = fileStream.pos() + wholeChunkSize - 6;
+#define MAIN3DS 0x4D4D // level 1
+#define EDIT3DS 0x3D3D // level 1
+#define NAMED_OBJECT 0x4000 // level 2
+#define TRIANGLE_MESH 0x4100 // level 3
+#define TRIANGLE_VERTEXLIST 0x4110 // level 4
+#define TRIANGLE_FACELIST 0x4120 // level 4
+#define CHUNK_CAMERA 0x4700 // level 3
+#define CHUNK_LIGHT 0x4600
+#define LIGHT_SPOTLIGHT 0x4610
+#define LIGHT_IS_OFF 0x4620
+#define RGB_FLOAT 0x0010
+#define RGB_BYTE 0x0011
+
+
+//////////////////////////////////////////////////////////////////////////
+Loader3DS::Loader3DS(BaseGame *inGame) : BaseNamedObject(inGame) {
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+Loader3DS::~Loader3DS() {
+ for (size_t i = 0; i < _objects.size(); i++)
+ delete _objects[i];
+ _objects.clear();
+}
- Common::String name;
- for (int8 current = fileStream.readByte(); current != 0; current = fileStream.readByte()) {
- name.insertChar(current, name.size());
- }
- while (fileStream.pos() < end) {
+
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+Loader3DS::FileObject3DS::FileObject3DS() {
+ _type = OBJ_3DS_NONE;
+
+ _numVertices = 0;
+ _vertices = nullptr;
+
+ _numFaces = 0;
+ _faces = nullptr;
+
+ _lightOff = false;
+ _lightSpotlight = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+Loader3DS::FileObject3DS::~FileObject3DS() {
+ if (_vertices != NULL)
+ delete[] _vertices;
+ if (_faces != NULL)
+ delete[] _faces;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool Loader3DS::parseFile(const Common::String &filename) {
+ _filename = filename;
+
+ uint32 fileSize;
+ byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename, &fileSize);
+ if (!buffer)
+ return false;
+
+ FileObject3DS *obj = nullptr;
+ uint16 i;
+
+ Common::MemoryReadStream fileStream(buffer, fileSize);
+
+ while (fileStream.pos() < fileStream.size()) {
uint16 chunkId = fileStream.readUint16LE();
+ uint32 chunkLength = fileStream.readUint32LE();
- Mesh3DS *mesh;
- Light3D *light;
- Camera3D *camera;
+ bool handled = true;
switch (chunkId) {
- case MESH:
- mesh = gameRef->_renderer3D->createMesh3DS();
- if (mesh->loadFrom3DS(fileStream)) {
- meshNames.add(name);
- meshes.add(mesh);
- } else {
- delete mesh;
- }
+ case MAIN3DS:
break;
- case LIGHT:
- light = new Light3D(gameRef);
- if (light->loadFrom3DS(fileStream)) {
- light->setName(name.c_str());
- lights.add(light);
- } else {
- delete light;
- }
+ case EDIT3DS:
break;
- case CAMERA:
- camera = new Camera3D(gameRef);
- if (camera->loadFrom3DS(fileStream)) {
- camera->setName(name.c_str());
- cameras.add(camera);
- } else {
- delete camera;
+ //////////////////////////////////////////////////////////////////////
+ // object ////////////////////////////////////////////////////////////
+ case NAMED_OBJECT: {
+ Common::String name;
+ for (int8 current = fileStream.readByte(); current != 0; current = fileStream.readByte()) {
+ name.insertChar(current, name.size());
+ }
+ obj = new FileObject3DS;
+ obj->_name = name;
+ _objects.add(obj);
}
break;
- default:
+
+ // mesh //////////////////////////////////////////////////////////////
+ case TRIANGLE_MESH:
+ if (obj == nullptr)
+ break;
+ obj->_type = OBJ_3DS_MESH;
+ break;
+
+
+ case TRIANGLE_VERTEXLIST:
+ if (obj == nullptr || obj->_type != OBJ_3DS_MESH)
+ break;
+
+ obj->_numVertices = fileStream.readUint16LE();
+ obj->_vertices = new DXVector3[obj->_numVertices];
+ for (i = 0; i < obj->_numVertices; i++) {
+ obj->_vertices[i]._x = fileStream.readFloatLE();
+ obj->_vertices[i]._z = fileStream.readFloatLE();
+ obj->_vertices[i]._y = fileStream.readFloatLE();
+ }
+ break;
+
+
+ case TRIANGLE_FACELIST:
+ if (obj == nullptr || obj->_type != OBJ_3DS_MESH)
+ break;
+
+ obj->_numFaces = fileStream.readUint16LE();
+
+ obj->_faces = new SFace[obj->_numFaces];
+ for (i = 0; i < obj->_numFaces; i++) {
+ obj->_faces[i]._a = fileStream.readUint16LE();
+ obj->_faces[i]._c = fileStream.readUint16LE();
+ obj->_faces[i]._b = fileStream.readUint16LE();
+ fileStream.readUint16LE(); // skip
+ }
+ break;
+
+
+ // camera //////////////////////////////////////////////////////////////
+ case CHUNK_CAMERA:
+ if (obj == nullptr)
+ break;
+ obj->_type = OBJ_3DS_CAMERA;
+
+ obj->_cameraPos._x = fileStream.readFloatLE();
+ obj->_cameraPos._z = fileStream.readFloatLE();
+ obj->_cameraPos._y = fileStream.readFloatLE();
+
+ obj->_cameraTarget._x = fileStream.readFloatLE();
+ obj->_cameraTarget._z = fileStream.readFloatLE();
+ obj->_cameraTarget._y = fileStream.readFloatLE();
+
+ obj->_cameraBank = fileStream.readFloatLE();
+ obj->_cameraLens = fileStream.readFloatLE();
+ if (obj->_cameraLens > 0)
+ obj->_cameraFOV = 1900.0f / obj->_cameraLens;
+ else
+ obj->_cameraFOV = 45.0f;
+ break;
+
+
+ // light //////////////////////////////////////////////////////////////
+ case CHUNK_LIGHT:
+ if (obj == nullptr)
+ break;
+ obj->_type = OBJ_3DS_LIGHT;
+
+ obj->_lightPos._x = fileStream.readFloatLE();
+ obj->_lightPos._z = fileStream.readFloatLE();
+ obj->_lightPos._y = fileStream.readFloatLE();
+ break;
+
+ case LIGHT_SPOTLIGHT:
+ if (obj == nullptr || obj->_type != OBJ_3DS_LIGHT)
+ break;
+
+ obj->_lightTarget._x = fileStream.readFloatLE();
+ obj->_lightTarget._z = fileStream.readFloatLE();
+ obj->_lightTarget._y = fileStream.readFloatLE();
+
+ obj->_lightHotspot = fileStream.readFloatLE();
+ obj->_lightFalloff = fileStream.readFloatLE();
+ obj->_lightSpotlight = true;
+ break;
+
+ case LIGHT_IS_OFF:
+ if (obj == nullptr || obj->_type != OBJ_3DS_LIGHT)
+ break;
+
+ obj->_lightOff = true;
+ break;
+
+
+ // colors ////////////////////////////////////////////////////////////////////////
+ case RGB_FLOAT:
+ if (obj && obj->_type == OBJ_3DS_LIGHT) {
+ float r, g, b;
+ r = fileStream.readFloatLE();
+ g = fileStream.readFloatLE();
+ b = fileStream.readFloatLE();
+
+ obj->_lightColor = BYTETORGBA((int)(r * 255), (int)(g * 255), (int)(b * 255), 255);
+ } else
+ handled = false;
+ break;
+
+ case RGB_BYTE:
+ if (obj && obj->_type == OBJ_3DS_LIGHT) {
+ byte r, g, b;
+ r = fileStream.readByte();
+ g = fileStream.readByte();
+ b = fileStream.readByte();
+
+ obj->_lightColor = BYTETORGBA(r, g, b, 255);
+ } else
+ handled = false;
break;
+
+ default:
+ handled = false;
}
+
+ if (!handled)
+ fileStream.seek(chunkLength - 6, SEEK_CUR);
}
+ delete[] buffer;
+
return true;
}
-bool load3DSFile(const char *filename, BaseArray<Wintermute::Mesh3DS *> &meshes, BaseArray<Common::String> &meshNames,
- BaseArray<Wintermute::Light3D *> &lights, BaseArray<Wintermute::Camera3D *> &cameras, BaseGame *gameRef) {
- uint32 fileSize = 0;
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename, &fileSize);
- if (buffer == nullptr) {
- return false;
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+uint Loader3DS::getNumMeshes() {
+ int ret = 0;
+
+ for (size_t i = 0; i < _objects.size(); i++)
+ if (_objects[i]->_type == OBJ_3DS_MESH)
+ ret++;
+
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+Common::String Loader3DS::getMeshName(int index) {
+ int pos = -1;
+
+ for (size_t i = 0; i < _objects.size(); i++) {
+ if (_objects[i]->_type == OBJ_3DS_MESH)
+ pos++;
+ if (pos == index)
+ return _objects[i]->_name;
}
+ return Common::String();
+}
- Common::MemoryReadStream fileStream(buffer, fileSize);
- while (fileStream.pos() < fileStream.size()) {
- uint16 chunkId = fileStream.readUint16LE();
- uint32 chunkSize = 0;
+//////////////////////////////////////////////////////////////////////////
+bool Loader3DS::loadMesh(int index, Mesh3DS *mesh) {
+ if (!mesh)
+ return false;
- switch (chunkId) {
- case MAIN:
- case EDITOR:
- chunkSize = fileStream.readUint32LE();
- break;
+ int pos = -1;
+ for (size_t i = 0; i < _objects.size(); i++) {
+ if (_objects[i]->_type == OBJ_3DS_MESH)
+ pos++;
+ if (pos == index){
+ FileObject3DS *obj = _objects[i];
+ mesh->cleanup();
- case OBJECT:
- load3DSObject(fileStream, meshes, meshNames, lights, cameras, gameRef);
- break;
+ mesh->_numVertices = obj->_numVertices;
+ mesh->_numFaces = obj->_numFaces;
- default:
- chunkSize = fileStream.readUint32LE();
- fileStream.seek(chunkSize - 6, SEEK_CUR);
- break;
+ int j;
+
+ mesh->_vertices = new Vertex3D[mesh->_numVertices];
+ for (j = 0; j < mesh->_numVertices; j++) {
+ mesh->_vertices[j]._pos._x = obj->_vertices[j]._x;
+ mesh->_vertices[j]._pos._y = obj->_vertices[j]._y;
+ mesh->_vertices[j]._pos._z = obj->_vertices[j]._z;
+ }
+
+ mesh->_faces = new Face3D[mesh->_numFaces];
+ for (j = 0; j < mesh->_numFaces; j++) {
+ mesh->_faces[j]._vertices[0] = obj->_faces[j]._a;
+ mesh->_faces[j]._vertices[1] = obj->_faces[j]._b;
+ mesh->_faces[j]._vertices[2] = obj->_faces[j]._c;
+ }
+
+ mesh->setName(obj->_name.c_str());
+
+ return true;
}
}
+ return false;
+}
- delete[] buffer;
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+uint Loader3DS::getNumLights() {
+ int ret = 0;
+
+ for (size_t i = 0; i < _objects.size(); i++)
+ if (_objects[i]->_type == OBJ_3DS_LIGHT)
+ ret++;
+
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+Common::String Loader3DS::getLightName(int index) {
+ int pos = -1;
+
+ for (size_t i = 0; i < _objects.size(); i++) {
+ if (_objects[i]->_type == OBJ_3DS_LIGHT)
+ pos++;
+ if (pos == index)
+ return _objects[i]->_name;
+ }
+ return NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool Loader3DS::loadLight(int index, Light3D *light) {
+ if (!light)
+ return false;
+
+ int pos = -1;
+ for (size_t i = 0; i < _objects.size(); i++) {
+ if (_objects[i]->_type == OBJ_3DS_LIGHT) {
+ pos++;
+ if (pos == index) {
+ light->setName(_objects[i]->_name.c_str());
+ light->_pos = _objects[i]->_lightPos;
+ light->_target = _objects[i]->_lightTarget;
+ light->_isSpotlight = _objects[i]->_lightSpotlight;
+ light->_active = !_objects[i]->_lightOff;
+ light->_diffuseColor = _objects[i]->_lightColor;
+ light->_falloff = _objects[i]->_lightFalloff;
+ }
+ }
+ }
return true;
}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+uint Loader3DS::getNumCameras() {
+ int ret = 0;
+
+ for (size_t i = 0; i < _objects.size(); i++)
+ if (_objects[i]->_type == OBJ_3DS_CAMERA)
+ ret++;
+
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+Common::String Loader3DS::getCameraName(int index) {
+ int pos = -1;
+ for (size_t i = 0; i < _objects.size(); i++) {
+ if (_objects[i]->_type == OBJ_3DS_CAMERA)
+ pos++;
+ if (pos == index)
+ return _objects[i]->_name;
+ }
+ return Common::String();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool Loader3DS::loadCamera(int index, Camera3D *camera) {
+ if (!camera) return
+ false;
+
+ int pos = -1;
+ for (size_t i = 0; i < _objects.size(); i++) {
+ if (_objects[i]->_type == OBJ_3DS_CAMERA)
+ pos++;
+ if (pos == index) {
+ camera->setupPos(_objects[i]->_cameraPos, _objects[i]->_cameraTarget, _objects[i]->_cameraBank);
+ camera->setName(_objects[i]->_name.c_str());
+ camera->_fov = camera->_origFov = degToRad(_objects[i]->_cameraFOV);
+
+ return true;
+ }
+ }
+ return false;
+}
+
} // namespace Wintermute
diff --git a/engines/wintermute/base/gfx/3dloader_3ds.h b/engines/wintermute/base/gfx/3dloader_3ds.h
index 519252abe8a..7d5b383f395 100644
--- a/engines/wintermute/base/gfx/3dloader_3ds.h
+++ b/engines/wintermute/base/gfx/3dloader_3ds.h
@@ -23,51 +23,70 @@
#define WINTERMUTE_3D_LOADER_3DS_H
#include "engines/wintermute/coll_templ.h"
+#include "engines/wintermute/base/base_named_object.h"
+#include "engines/wintermute/base/gfx/3dcamera.h"
+#include "engines/wintermute/base/gfx/3dlight.h"
+#include "engines/wintermute/base/gfx/3dmesh.h"
+
+#include "common/str.h"
namespace Wintermute {
-class BaseGame;
-class Light3D;
-class Camera3D;
-class Mesh3DS;
+class Loader3DS : public BaseNamedObject {
+public:
+ enum E3DSFileObjectType{
+ OBJ_3DS_NONE, OBJ_3DS_MESH, OBJ_3DS_CAMERA, OBJ_3DS_LIGHT
+ };
+
+ struct SFace{
+ uint16 _a;
+ uint16 _b;
+ uint16 _c;
+ };
-bool load3DSFile(const char *filename, BaseArray<Mesh3DS *> &meshes, BaseArray<Common::String> &meshNames,
- BaseArray<Light3D *> &lights, BaseArray<Camera3D *> &cameras, BaseGame *gameRef);
+ class FileObject3DS {
+ public:
+ DXVector3 _cameraTarget;
+ float _cameraBank;
+ float _cameraLens;
+ float _cameraFOV;
+ DXVector3 _cameraPos;
+ DXVector3 _lightTarget;
+ DXVector3 _lightPos;
+ uint32 _lightColor;
+ float _lightHotspot;
+ float _lightFalloff;
+ bool _lightOff;
+ bool _lightSpotlight;
+ bool _hidden;
+ uint16 _numCoordinates;
+ uint16 _numFaces;
+ SFace *_faces;
+ DXVector3 *_vertices;
+ uint16 _numVertices;
+ Common::String _name;
+ E3DSFileObjectType _type;
+ virtual ~FileObject3DS();
+ FileObject3DS();
+ };
-enum Chunks3DS {
- RGB_FLOAT = 0x0010,
- RGB_BYTE = 0x0011,
- EDITOR = 0x3D3D,
- OBJECT = 0x4000,
- MESH = 0x4100,
- VERTICES = 0x4110,
- FACES = 0x4120,
- FACES_MATERIAL = 0x4130,
- MAPPING_COORDS = 0x4140,
- SMOOTHING_GROUPS = 0x4150,
- LOCAL_COORDS = 0x4160,
- LIGHT = 0x4600,
- SPOTLIGHT = 0x4610,
- LIGHT_IS_OFF = 0x4620,
- SPOT_RAY_TRACE = 0x4627,
- SPOT_SHADOW_MAP = 0x4641,
- ROLL = 0x4656,
- SPOT_RAY_TRACE_BIAS = 0x4658,
- RANGE_END = 0x465A,
- MULTIPLIER = 0x465B,
- CAMERA = 0x4700,
- MAIN = 0x4D4D,
- KEYFRAMER = 0xB000,
- AMBIENT_INFO = 0xB001,
- MESH_INFO = 0xB002,
- CAMERA_INFO = 0xB003,
- CAMERA_TARGET_INFO = 0xB004,
- OMNI_LIGHT_INFO = 0xB005,
- SPOTLIGHT_TARGET_INFO = 0xB006,
- SPOTLIGHT_INFO = 0xB007,
- NODE_HEADER = 0xB010,
- ROLL_TRACK = 0xB024
+public:
+ Common::String getCameraName(int index);
+ Common::String getLightName(int index);
+ Common::String getMeshName(int index);
+ bool loadCamera(int index, Camera3D *camera);
+ uint getNumCameras();
+ bool loadLight(int index, Light3D *light);
+ uint getNumLights();
+ bool loadMesh(int index, Mesh3DS *mesh);
+ uint getNumMeshes();
+ bool parseFile(const Common::String &filename);
+ Common::String _filename;
+ Loader3DS(BaseGame *inGame);
+ virtual ~Loader3DS();
+ BaseArray<FileObject3DS *> _objects;
};
} // namespace Wintermute
+
#endif
diff --git a/engines/wintermute/base/gfx/3dmesh.cpp b/engines/wintermute/base/gfx/3dmesh.cpp
index 7680f489386..fd734e6ccf8 100644
--- a/engines/wintermute/base/gfx/3dmesh.cpp
+++ b/engines/wintermute/base/gfx/3dmesh.cpp
@@ -19,86 +19,131 @@
*
*/
+/*
+ * This file is based on WME.
+ * http://dead-code.org/redir.php?target=wme
+ * Copyright (c) 2003-2013 Jan Nedoma and contributors
+ */
+
#include "common/file.h"
+#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/gfx/3dloader_3ds.h"
#include "engines/wintermute/base/gfx/3dmesh.h"
namespace Wintermute {
-Mesh3DS::Mesh3DS() : _vertexData(nullptr), _vertexCount(0), _indexData(nullptr), _indexCount(0) {
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+
+//////////////////////////////////////////////////////////////////////////
+Mesh3DS::Mesh3DS(BaseGame *inGame) : BaseNamedObject(inGame) {
+ _vertices = nullptr;
+ _faces = nullptr;
+ _numFaces = _numVertices = 0;
+ _visible = true;
}
+//////////////////////////////////////////////////////////////////////////
Mesh3DS::~Mesh3DS() {
- delete[] _vertexData;
- delete[] _indexData;
+ cleanup();
}
-bool Mesh3DS::loadFrom3DS(Common::MemoryReadStream &fileStream) {
- uint32 wholeChunkSize = fileStream.readUint32LE();
- int32 end = fileStream.pos() + wholeChunkSize - 6;
-
- while (fileStream.pos() < end) {
- uint16 chunkId = fileStream.readUint16LE();
- uint32 chunkSize = fileStream.readUint32LE();
-
- switch (chunkId) {
- case VERTICES:
- _vertexCount = fileStream.readUint16LE();
- _vertexData = new GeometryVertex[_vertexCount]();
-
- for (int i = 0; i < _vertexCount; ++i) {
- _vertexData[i].x = fileStream.readFloatLE();
- _vertexData[i].z = fileStream.readFloatLE();
- _vertexData[i].y = fileStream.readFloatLE();
- }
- break;
-
- case FACES: {
- uint16 faceCount = fileStream.readUint16LE();
- _indexCount = 3 * faceCount;
- _indexData = new uint16[_indexCount];
-
- for (int i = 0; i < faceCount; ++i) {
- _indexData[i * 3 + 0] = fileStream.readUint16LE();
- _indexData[i * 3 + 2] = fileStream.readUint16LE();
- _indexData[i * 3 + 1] = fileStream.readUint16LE();
- fileStream.readUint16LE(); // not used
- }
- break;
- }
- case FACES_MATERIAL:
- case MAPPING_COORDS:
- case LOCAL_COORDS:
- case SMOOTHING_GROUPS:
- default:
- fileStream.seek(chunkSize - 6, SEEK_CUR);
- break;
+//////////////////////////////////////////////////////////////////////////
+void Mesh3DS::cleanup() {
+ delete[] _vertices;
+ _vertices = nullptr;
+ _numVertices = 0;
+
+ delete[] _faces;
+ _faces = nullptr;
+ _numFaces = 0;
+
+ _vb.free();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool Mesh3DS::createVertexBuffer() {
+ _vb.free();
+
+ if (_numFaces == 0)
+ return true;
+
+ int vbSize = _numFaces * sizeof(Mesh3DSVertex) * 3;
+ _vb = DXBuffer(vbSize);
+ if (_vb.ptr() == nullptr) {
+ _gameRef->LOG(0, "Error creating vertex buffer.");
+ return false;
+ } else
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool Mesh3DS::fillVertexBuffer(uint32 color) {
+ _vb.free();
+
+ if (_numFaces == 0)
+ return true;
+
+ int vbSize = _numFaces * sizeof(Mesh3DSVertex) * 3;
+ _vb = DXBuffer(vbSize);
+ if (_vb.ptr() == nullptr) {
+ _gameRef->LOG(0, "Error creating vertex buffer.");
+ return false;
+ }
+
+ Mesh3DSVertex *verts = (Mesh3DSVertex *)_vb.ptr();
+
+ for (int i = 0; i < _numFaces; i++) {
+ for (int j = 0; j < 3; j++) {
+ int iOutVert = i * 3 + j;
+ int iVertex = _faces[i]._vertices[j];
+
+ verts[iOutVert]._x = _vertices[iVertex]._pos._x;
+ verts[iOutVert]._y = _vertices[iVertex]._pos._y;
+ verts[iOutVert]._z = _vertices[iVertex]._pos._z;
+
+ verts[iOutVert]._nx = _faces[i]._normals[j]._x;
+ verts[iOutVert]._ny = _faces[i]._normals[j]._y;
+ verts[iOutVert]._nz = _faces[i]._normals[j]._z;
+
+ verts[iOutVert]._r = RGBCOLGetR(color) / 255.0f;
+ verts[iOutVert]._g = RGBCOLGetG(color) / 255.0f;
+ verts[iOutVert]._b = RGBCOLGetB(color) / 255.0f;
+ verts[iOutVert]._a = RGBCOLGetA(color) / 255.0f;
}
}
+ fillVertexBuffer();
+
return true;
}
+
+//////////////////////////////////////////////////////////////////////////
void Mesh3DS::computeNormals() {
- DXVector3 *normals = new DXVector3[_vertexCount];
- for (int i = 0; i < _vertexCount; ++i) {
+ DXVector3 *normals = new DXVector3[_numVertices];
+ for (int i = 0; i < _numVertices; ++i) {
normals[i]._x = 0.0f;
normals[i]._y = 0.0f;
normals[i]._z = 0.0f;
}
- for (int i = 0; i < faceCount(); ++i) {
- uint16 a = _indexData[3 * i + 0];
- uint16 b = _indexData[3 * i + 1];
- uint16 c = _indexData[3 * i + 2];
+ for (int i = 0; i < _numFaces; ++i) {
+ uint16 a = _faces[i]._vertices[0];
+ uint16 b = _faces[i]._vertices[1];
+ uint16 c = _faces[i]._vertices[2];
- DXVector3 v1(getVertexPosition(a));
- DXVector3 v2(getVertexPosition(b));
- DXVector3 v3(getVertexPosition(c));
+ DXVector3 *v1 = &_vertices[a]._pos;
+ DXVector3 *v2 = &_vertices[b]._pos;
+ DXVector3 *v3 = &_vertices[c]._pos;
- DXVector3 edge1 = v2 - v1;
- DXVector3 edge2 = v3 - v2;
+ DXVector3 edge1 = *v2 - *v1;
+ DXVector3 edge2 = *v3 - *v2;
DXVector3 normal;
DXVec3Cross(&normal, &edge1, &edge2);
DXVec3Normalize(&normal, &normal);
@@ -109,50 +154,20 @@ void Mesh3DS::computeNormals() {
}
// Assign the newly computed normals back to the vertices
- for (int i = 0; i < faceCount(); ++i) {
+ for (int i = 0; i < _numFaces; ++i) {
for (int j = 0; j < 3; j++) {
- DXVector3 normal;
- DXVec3Normalize(&normal, &normals[_indexData[3 * i + j]]);
- //_vertexData[_indexData[3 * i + j]].nx = normal._x;
- //_vertexData[_indexData[3 * i + j]].ny = normal._y;
- //_vertexData[_indexData[3 * i + j]].nz = normal._z;
+ DXVec3Normalize(&_faces[i]._normals[j], &normals[_faces[i]._vertices[j]]);
+ //_faces[i]._normals[j] = normals[_faces[i]._vertices[j]];
}
}
delete[] normals;
}
-void Mesh3DS::dumpVertexCoordinates(const char *filename) {
- Common::DumpFile dump;
- dump.open(filename);
-
- for (uint16 *index = _indexData; index < _indexData + _indexCount; ++index) {
- float x = _vertexData[*index].x;
- float y = _vertexData[*index].y;
- float z = _vertexData[*index].z;
-
- dump.writeString(Common::String::format("%u ", *index));
- dump.writeString(Common::String::format("%g ", x));
- dump.writeString(Common::String::format("%g ", y));
- dump.writeString(Common::String::format("%g\n", z));
- }
-}
-
-int Mesh3DS::faceCount() {
- // .3ds files have only triangles anyways
- return _indexCount / 3;
-}
-
-uint16 *Mesh3DS::getFace(int index) {
- return _indexData + 3 * index;
-}
-
-float *Mesh3DS::getVertexPosition(int index) {
- return reinterpret_cast<float *>(&((_vertexData + index)->x));
-}
-
-int Wintermute::Mesh3DS::vertexCount() {
- return _vertexCount;
+//////////////////////////////////////////////////////////////////////////
+bool Mesh3DS::persist(BasePersistenceManager *persistMgr) {
+ persistMgr->transferBool(TMEMBER(_visible));
+ return true;
}
} // namespace Wintermute
diff --git a/engines/wintermute/base/gfx/3dmesh.h b/engines/wintermute/base/gfx/3dmesh.h
index f889e1a992a..e9810d3903a 100644
--- a/engines/wintermute/base/gfx/3dmesh.h
+++ b/engines/wintermute/base/gfx/3dmesh.h
@@ -19,47 +19,57 @@
*
*/
+/*
+ * 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_MESH_H
#define WINTERMUTE_3D_MESH_H
#include "common/memstream.h"
-#include "math/vector4d.h"
-
+#include "engines/wintermute/base/base_named_object.h"
#include "engines/wintermute/base/gfx/xmath.h"
+#include "engines/wintermute/base/gfx/xbuffer.h"
+#include "engines/wintermute/base/gfx/3dface.h"
+#include "engines/wintermute/base/gfx/3dvertex.h"
namespace Wintermute {
-struct GeometryVertex {
- float x;
- float y;
- float z;
- float nx;
- float ny;
- float nz;
+#if defined(SCUMMVM_USE_PRAGMA_PACK)
+#pragma pack(4)
+#endif
+
+struct Mesh3DSVertex {
+ float _x, _y, _z;
+ float _nx, _ny, _nz;
+ float _r, _g, _b, _a;
};
-class Mesh3DS {
+#if defined(SCUMMVM_USE_PRAGMA_PACK)
+#pragma pack()
+#endif
+
+class Mesh3DS : public BaseNamedObject {
public:
- Mesh3DS();
- virtual ~Mesh3DS();
+ bool persist(BasePersistenceManager *persistMgr);
+ bool createVertexBuffer();
void computeNormals();
- virtual void fillVertexBuffer(uint32 color) = 0;
- virtual bool loadFrom3DS(Common::MemoryReadStream &fileStream);
+ void cleanup();
+ Mesh3DS(BaseGame *inGame);
+ virtual ~Mesh3DS();
+ bool fillVertexBuffer(uint32 color);
+ virtual void fillVertexBuffer() = 0;
virtual void render() = 0;
- virtual void dumpVertexCoordinates(const char *filename);
- virtual int faceCount();
- virtual uint16 *getFace(int index);
-
- virtual int vertexCount();
- virtual float *getVertexPosition(int index);
-protected:
- GeometryVertex *_vertexData;
- uint16 _vertexCount;
- uint16 *_indexData;
- uint16 _indexCount;
- DXVector4 _color;
+ Face3D *_faces;
+ uint16 _numFaces;
+ uint16 _numVertices;
+ Vertex3D *_vertices;
+ DXBuffer _vb;
+ bool _visible;
};
} // namespace Wintermute
diff --git a/engines/wintermute/base/gfx/3dvertex.cpp b/engines/wintermute/base/gfx/3dvertex.cpp
new file mode 100644
index 00000000000..04ac27a4fb6
--- /dev/null
+++ b/engines/wintermute/base/gfx/3dvertex.cpp
@@ -0,0 +1,46 @@
+/* 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 "engines/wintermute/base/gfx/3dvertex.h"
+#include "engines/wintermute/dcgf.h"
+
+namespace Wintermute {
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////
+Vertex3D::Vertex3D() {
+ _pos = DXVector3(0, 0, 0);
+}
+
+//////////////////////////////////////////////////////////////////////////
+Vertex3D::~Vertex3D() {
+}
+
+} // namespace Wintermute
diff --git a/engines/wintermute/base/gfx/3dvertex.h b/engines/wintermute/base/gfx/3dvertex.h
new file mode 100644
index 00000000000..80590412945
--- /dev/null
+++ b/engines/wintermute/base/gfx/3dvertex.h
@@ -0,0 +1,45 @@
+/* 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_VERTEX_H
+#define WINTERMUTE_3D_VERTEX_H
+
+#include "engines/wintermute/base/gfx/xmath.h"
+
+namespace Wintermute {
+
+class Vertex3D {
+public:
+ Vertex3D();
+ virtual ~Vertex3D();
+
+ DXVector3 _pos;
+};
+
+} // namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp b/engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp
index fa4c071d91c..10ba76fc9df 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d.cpp
@@ -770,24 +770,24 @@ void BaseRenderOpenGL3D::renderSceneGeometry(const BaseArray<AdWalkplane *> &pla
if (lights[i]->_active) {
glBegin(GL_LINES);
glColor3f(1.0f, 1.0f, 0.0f);
- DXVector3 right = lights[i]->_position + DXVector3(1000.0f, 0.0f, 0.0f);
- DXVector3 up = lights[i]->_position + DXVector3(0.0f, 1000.0f, 0.0f);
- DXVector3 backward = lights[i]->_position + DXVector3(0.0f, 0.0f, 1000.0f);
- DXVector3 left = lights[i]->_position + DXVector3(-1000.0f, 0.0f, 0.0f);
- DXVector3 down = lights[i]->_position + DXVector3(0.0f, -1000.0f, 0.0f);
- DXVector3 forward = lights[i]->_position + DXVector3(0.0f, 0.0f, -1000.0f);
-
- glVertex3fv(lights[i]->_position);
+ DXVector3 right = lights[i]->_pos + DXVector3(1000.0f, 0.0f, 0.0f);
+ DXVector3 up = lights[i]->_pos + DXVector3(0.0f, 1000.0f, 0.0f);
+ DXVector3 backward = lights[i]->_pos + DXVector3(0.0f, 0.0f, 1000.0f);
+ DXVector3 left = lights[i]->_pos + DXVector3(-1000.0f, 0.0f, 0.0f);
+ DXVector3 down = lights[i]->_pos + DXVector3(0.0f, -1000.0f, 0.0f);
+ DXVector3 forward = lights[i]->_pos + DXVector3(0.0f, 0.0f, -1000.0f);
+
+ glVertex3fv(lights[i]->_pos);
glVertex3fv(right);
- glVertex3fv(lights[i]->_position);
+ glVertex3fv(lights[i]->_pos);
glVertex3fv(up);
- glVertex3fv(lights[i]->_position);
+ glVertex3fv(lights[i]->_pos);
glVertex3fv(backward);
- glVertex3fv(lights[i]->_position);
+ glVertex3fv(lights[i]->_pos);
glVertex3fv(left);
- glVertex3fv(lights[i]->_position);
+ glVertex3fv(lights[i]->_pos);
glVertex3fv(down);
- glVertex3fv(lights[i]->_position);
+ glVertex3fv(lights[i]->_pos);
glVertex3fv(forward);
glEnd();
}
@@ -840,7 +840,7 @@ void BaseRenderOpenGL3D::renderShadowGeometry(const BaseArray<AdWalkplane *> &pl
}
Mesh3DS *BaseRenderOpenGL3D::createMesh3DS() {
- return new Mesh3DSOpenGL();
+ return new Mesh3DSOpenGL(_gameRef);
}
XMesh *BaseRenderOpenGL3D::createXMesh() {
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 ba35b1f217f..f9908a8870b 100644
--- a/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
+++ b/engines/wintermute/base/gfx/opengl/base_render_opengl3d_shader.cpp
@@ -564,7 +564,7 @@ bool BaseRenderOpenGL3DShader::initRenderer(int width, int height, bool windowed
_spriteShader->enableVertexAttribute("texcoord", _spriteVBO, 2, GL_FLOAT, false, sizeof(SpriteVertexShader), 8);
_spriteShader->enableVertexAttribute("color", _spriteVBO, 4, GL_FLOAT, false, sizeof(SpriteVertexShader), 16);
- static const char *geometryAttributes[] = { "position", nullptr };
+ static const char *geometryAttributes[] = { "position", "color", nullptr };
_geometryShader = OpenGL::Shader::fromFiles("wme_geometry", geometryAttributes);
static const char *shadowVolumeAttributes[] = { "position", nullptr };
@@ -917,7 +917,7 @@ void BaseRenderOpenGL3DShader::renderShadowGeometry(const BaseArray<AdWalkplane
}
Mesh3DS *BaseRenderOpenGL3DShader::createMesh3DS() {
- return new Mesh3DSOpenGLShader(_geometryShader);
+ return new Mesh3DSOpenGLShader(_gameRef, _geometryShader);
}
XMesh *BaseRenderOpenGL3DShader::createXMesh() {
diff --git a/engines/wintermute/base/gfx/opengl/mesh3ds_opengl.cpp b/engines/wintermute/base/gfx/opengl/mesh3ds_opengl.cpp
index 73b3cbe795c..2933791e556 100644
--- a/engines/wintermute/base/gfx/opengl/mesh3ds_opengl.cpp
+++ b/engines/wintermute/base/gfx/opengl/mesh3ds_opengl.cpp
@@ -29,24 +29,27 @@
namespace Wintermute {
-Mesh3DSOpenGL::Mesh3DSOpenGL() {
+Mesh3DSOpenGL::Mesh3DSOpenGL(BaseGame *inGame) : Mesh3DS(inGame) {
}
Mesh3DSOpenGL::~Mesh3DSOpenGL() {
}
-void Mesh3DSOpenGL::fillVertexBuffer(uint32 color) {
- _color._x = RGBCOLGetR(color) / 255.0f;
- _color._y = RGBCOLGetG(color) / 255.0f;
- _color._z = RGBCOLGetB(color) / 255.0f;
- _color._w = RGBCOLGetA(color) / 255.0f;
+void Mesh3DSOpenGL::fillVertexBuffer() {
+ _vertexCount = _numFaces * 3;
+ _vertexData = (Mesh3DSVertex *)_vb.ptr();
}
void Mesh3DSOpenGL::render() {
- glColor4f(_color._x, _color._y, _color._z, _color._w);
+ if (_vertexCount == 0)
+ return;
+
glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, sizeof(GeometryVertex), reinterpret_cast<byte *>(_vertexData));
- glDrawElements(GL_TRIANGLES, _indexCount, GL_UNSIGNED_SHORT, _indexData);
+ glEnableClientState(GL_COLOR_ARRAY);
+ glVertexPointer(3, GL_FLOAT, sizeof(Mesh3DSVertex), &_vertexData[0]._x);
+ glColorPointer(4, GL_FLOAT, sizeof(Mesh3DSVertex), &_vertexData[0]._r);
+ glDrawArrays(GL_TRIANGLES, 0, _vertexCount);
+ glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}
diff --git a/engines/wintermute/base/gfx/opengl/mesh3ds_opengl.h b/engines/wintermute/base/gfx/opengl/mesh3ds_opengl.h
index f6e458016de..352f4a945f1 100644
--- a/engines/wintermute/base/gfx/opengl/mesh3ds_opengl.h
+++ b/engines/wintermute/base/gfx/opengl/mesh3ds_opengl.h
@@ -30,10 +30,14 @@ namespace Wintermute {
class Mesh3DSOpenGL : public Mesh3DS {
public:
- Mesh3DSOpenGL();
+ Mesh3DSOpenGL(BaseGame *inGame);
~Mesh3DSOpenGL();
- void fillVertexBuffer(uint32 color) override;
+ void fillVertexBuffer() override;
void render() override;
+
+private:
+ Mesh3DSVertex *_vertexData;
+ uint16 _vertexCount;
};
} // namespace Wintermute
diff --git a/engines/wintermute/base/gfx/opengl/mesh3ds_opengl_shader.cpp b/engines/wintermute/base/gfx/opengl/mesh3ds_opengl_shader.cpp
index 9be3c3f9a73..301d717970f 100644
--- a/engines/wintermute/base/gfx/opengl/mesh3ds_opengl_shader.cpp
+++ b/engines/wintermute/base/gfx/opengl/mesh3ds_opengl_shader.cpp
@@ -29,7 +29,7 @@
namespace Wintermute {
-Mesh3DSOpenGLShader::Mesh3DSOpenGLShader(OpenGL::Shader *shader) : _shader(shader) {
+Mesh3DSOpenGLShader::Mesh3DSOpenGLShader(BaseGame *inGame, OpenGL::Shader *shader) : Mesh3DS(inGame), _shader(shader) {
glGenBuffers(1, &_vertexBuffer);
glGenBuffers(1, &_indexBuffer);
}
@@ -39,34 +39,25 @@ Mesh3DSOpenGLShader::~Mesh3DSOpenGLShader() {
glDeleteBuffers(1, &_indexBuffer);
}
-void Mesh3DSOpenGLShader::fillVertexBuffer(uint32 color) {
- _color._x = RGBCOLGetR(color) / 255.0f;
- _color._y = RGBCOLGetG(color) / 255.0f;
- _color._z = RGBCOLGetB(color) / 255.0f;
- _color._w = RGBCOLGetA(color) / 255.0f;
+void Mesh3DSOpenGLShader::fillVertexBuffer() {
+ _vertexCount = _numFaces * 3;
+ _vertexData = (Mesh3DSVertex *)_vb.ptr();
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
- glBufferData(GL_ARRAY_BUFFER, sizeof(GeometryVertex) * _vertexCount, _vertexData, GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(Mesh3DSVertex) * _vertexCount, _vertexData, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, 2 * _indexCount, _indexData, GL_STATIC_DRAW);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void Mesh3DSOpenGLShader::render() {
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
+ if (_vertexCount == 0)
+ return;
- _shader->enableVertexAttribute("position", _vertexBuffer, 3, GL_FLOAT, false, sizeof(GeometryVertex), 0);
+ _shader->enableVertexAttribute("position", _vertexBuffer, 3, GL_FLOAT, false, sizeof(Mesh3DSVertex), 0);
+ _shader->enableVertexAttribute("color", _vertexBuffer, 4, GL_FLOAT, false, sizeof(Mesh3DSVertex), 24);
_shader->use(true);
- Math::Vector4d color = Math::Vector4d(_color._x, _color._y, _color._z, 1.0f);
- _shader->setUniform("color", color);
-
- glDrawElements(GL_TRIANGLES, _indexCount, GL_UNSIGNED_SHORT, 0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glDrawArrays(GL_TRIANGLES, 0, _vertexCount);
}
} // namespace Wintermute
diff --git a/engines/wintermute/base/gfx/opengl/mesh3ds_opengl_shader.h b/engines/wintermute/base/gfx/opengl/mesh3ds_opengl_shader.h
index 54f65815fee..420619f9836 100644
--- a/engines/wintermute/base/gfx/opengl/mesh3ds_opengl_shader.h
+++ b/engines/wintermute/base/gfx/opengl/mesh3ds_opengl_shader.h
@@ -32,12 +32,14 @@ namespace Wintermute {
class Mesh3DSOpenGLShader : public Mesh3DS {
public:
- Mesh3DSOpenGLShader(OpenGL::Shader *shader);
+ Mesh3DSOpenGLShader(BaseGame *inGame, OpenGL::Shader *shader);
~Mesh3DSOpenGLShader();
- void fillVertexBuffer(uint32 color) override;
+ void fillVertexBuffer() override;
void render() override;
private:
+ Mesh3DSVertex *_vertexData;
+ uint16 _vertexCount;
GLuint _vertexBuffer;
GLuint _indexBuffer;
OpenGL::Shader *_shader;
diff --git a/engines/wintermute/base/gfx/opengl/shaders/wme_geometry.vertex b/engines/wintermute/base/gfx/opengl/shaders/wme_geometry.vertex
index a3c25bd53a6..69fe6c6826e 100644
--- a/engines/wintermute/base/gfx/opengl/shaders/wme_geometry.vertex
+++ b/engines/wintermute/base/gfx/opengl/shaders/wme_geometry.vertex
@@ -1,10 +1,9 @@
in vec3 position;
+in vec4 color;
uniform highp mat4 viewMatrix;
uniform highp mat4 projMatrix;
-uniform vec4 color;
-
out vec4 Color;
void main() {
diff --git a/engines/wintermute/module.mk b/engines/wintermute/module.mk
index 9710e382b73..f79c2254ad9 100644
--- a/engines/wintermute/module.mk
+++ b/engines/wintermute/module.mk
@@ -161,9 +161,11 @@ MODULE_OBJS += \
ad/ad_waypoint_group3d.o \
base/gfx/3dcamera.o \
base/gfx/3dlight.o \
+ base/gfx/3dface.o \
base/gfx/3dloader_3ds.o \
base/gfx/3dmesh.o \
base/gfx/3dshadow_volume.o \
+ base/gfx/3dvertex.o \
base/gfx/base_renderer3d.o \
base/gfx/skin_mesh_helper.o \
base/gfx/xactive_animation.o \
More information about the Scummvm-git-logs
mailing list