diff --git a/engines/stark/gfx/driver.h b/engines/stark/gfx/driver.h index cd8ffc6b5fe..80cc292d5c6 100644 --- a/engines/stark/gfx/driver.h +++ b/engines/stark/gfx/driver.h @@ -29,7 +29,7 @@ //#include "engines/stark/color.h" #include "graphics/surface.h" #include "common/rect.h" -//#include "math/vector3d.h" +#include "math/vector3d.h" namespace Stark { @@ -43,6 +43,9 @@ public: virtual void setupScreen(int screenW, int screenH, bool fullscreen) = 0; + virtual void setupPerspective(float fov, float nearClipPlane, float farClipPlane) = 0; + virtual void setupCamera(const Math::Vector3d &position, const Math::Vector3d &lookAt) = 0; + virtual void clearScreen() = 0; virtual void flipBuffer() = 0; diff --git a/engines/stark/gfx/opengl.cpp b/engines/stark/gfx/opengl.cpp index d7f7b674d01..8ee276ce3d1 100644 --- a/engines/stark/gfx/opengl.cpp +++ b/engines/stark/gfx/opengl.cpp @@ -26,8 +26,12 @@ #include "engines/stark/gfx/opengl.h" #include "common/system.h" + #include "graphics/pixelbuffer.h" +#include "math/glmath.h" +#include "math/matrix4.h" + #ifdef USE_OPENGL #ifdef SDL_BACKEND @@ -67,6 +71,23 @@ void OpenGLGfxDriver::setupScreen(int screenW, int screenH, bool fullscreen) { */ } +void OpenGLGfxDriver::setupPerspective(float fov, float nearClipPlane, float farClipPlane) { + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + Math::Matrix4 m = Math::makePerspectiveMatrix(fov, _screenWidth / _screenHeight, nearClipPlane, farClipPlane); + glMultMatrixf(m.getData()); +} + +void OpenGLGfxDriver::setupCamera(const Math::Vector3d &position, const Math::Vector3d &lookAt) { + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + Math::Matrix4 lookMatrix = Math::makeLookAtMatrix(position, lookAt, Math::Vector3d(0.0, 0.0, 1.0)); + glMultMatrixf(lookMatrix.getData()); + glTranslatef(-position.x(), -position.y(), -position.z()); +} + void OpenGLGfxDriver::clearScreen() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } @@ -80,6 +101,8 @@ void OpenGLGfxDriver::drawSurface(const Graphics::Surface *surface, Common::Poin if (rect.isEmpty()) rect = Common::Rect(surface->w, surface->h); + dest.y += 36; // 36px is the height of the top black border + start2DMode(); float rasterX = (2 * (float)dest.x / (float)_screenWidth); diff --git a/engines/stark/gfx/opengl.h b/engines/stark/gfx/opengl.h index 7adffd46a9d..d1b44e4ae85 100644 --- a/engines/stark/gfx/opengl.h +++ b/engines/stark/gfx/opengl.h @@ -43,6 +43,9 @@ public: void setupScreen(int screenW, int screenH, bool fullscreen); + void setupPerspective(float fov, float nearClipPlane, float farClipPlane) override; + void setupCamera(const Math::Vector3d &position, const Math::Vector3d &lookAt) override; + void clearScreen(); void flipBuffer(); diff --git a/engines/stark/gfx/tinygl.cpp b/engines/stark/gfx/tinygl.cpp index c7acce56280..e6912799418 100644 --- a/engines/stark/gfx/tinygl.cpp +++ b/engines/stark/gfx/tinygl.cpp @@ -32,6 +32,9 @@ //#include "engines/stark/font.h" #include "engines/stark/gfx/tinygl.h" +#include "math/glmath.h" +#include "math/matrix4.h" + namespace Stark { TinyGLGfxDriver::TinyGLGfxDriver() { @@ -77,6 +80,23 @@ void TinyGLGfxDriver::setupScreen(int screenW, int screenH, bool fullscreen) { */ } +void TinyGLGfxDriver::setupPerspective(float fov, float nearClipPlane, float farClipPlane) { + tglMatrixMode(TGL_PROJECTION); + tglLoadIdentity(); + + Math::Matrix4 m = Math::makePerspectiveMatrix(fov, _screenWidth / _screenHeight, nearClipPlane, farClipPlane); + tglMultMatrixf(m.getData()); +} + +void TinyGLGfxDriver::setupCamera(const Math::Vector3d &position, const Math::Vector3d &lookAt) { + tglMatrixMode(TGL_MODELVIEW); + tglLoadIdentity(); + + Math::Matrix4 lookMatrix = Math::makeLookAtMatrix(position, lookAt, Math::Vector3d(0.0, 0.0, 1.0)); + tglMultMatrixf(lookMatrix.getData()); + tglTranslatef(-position.x(), -position.y(), -position.z()); +} + void TinyGLGfxDriver::clearScreen() { _zb->clear(true, 0, true, 0, 0, 0); } diff --git a/engines/stark/gfx/tinygl.h b/engines/stark/gfx/tinygl.h index 86558d50c33..4f2f221b31a 100644 --- a/engines/stark/gfx/tinygl.h +++ b/engines/stark/gfx/tinygl.h @@ -41,6 +41,9 @@ public: void setupScreen(int screenW, int screenH, bool fullscreen); + void setupPerspective(float fov, float nearClipPlane, float farClipPlane) override; + void setupCamera(const Math::Vector3d &position, const Math::Vector3d &lookAt) override; + void clearScreen(); void flipBuffer(); diff --git a/engines/stark/resources/camera.cpp b/engines/stark/resources/camera.cpp index 8f2b3bac4c5..73b8525887d 100644 --- a/engines/stark/resources/camera.cpp +++ b/engines/stark/resources/camera.cpp @@ -21,8 +21,11 @@ */ #include "engines/stark/resources/camera.h" -#include "engines/stark/xrcreader.h" + #include "engines/stark/debug.h" +#include "engines/stark/scene.h" +#include "engines/stark/stark.h" +#include "engines/stark/xrcreader.h" namespace Stark { @@ -32,10 +35,17 @@ Camera::~Camera() { Camera::Camera(Resource *parent, byte subType, uint16 index, const Common::String &name) : Resource(parent, subType, index, name), _f1(0), - _fov(0) { + _fov(45), + _nearClipPlane(100.0), + _farClipPlane(64000.0) { _type = ResourceType::kCamera; } +void Camera::setClipPlanes(float near, float far) { + _nearClipPlane = near; + _farClipPlane = far; +} + void Camera::readData(XRCReadStream *stream) { _position = stream->readVector3(); _lookAt = stream->readVector3(); @@ -45,6 +55,13 @@ void Camera::readData(XRCReadStream *stream) { _v4 = stream->readVector3(); } +void Camera::onEnterLocation() { + Resource::onEnterLocation(); + + Scene *scene = StarkServices::instance().scene; + scene->initCamera(_position, _lookAt, _fov, _viewport, _nearClipPlane, _farClipPlane); +} + void Camera::printData() { Common::Debug debug = streamDbg(); debug << "position: " << _position << "\n"; diff --git a/engines/stark/resources/camera.h b/engines/stark/resources/camera.h index a4cd1e7d7e5..c70217a9970 100644 --- a/engines/stark/resources/camera.h +++ b/engines/stark/resources/camera.h @@ -38,9 +38,16 @@ class XRCReadStream; class Camera : public Resource { public: + static const ResourceType::Type TYPE = ResourceType::kCamera; + Camera(Resource *parent, byte subType, uint16 index, const Common::String &name); virtual ~Camera(); + // Resource API + void onEnterLocation() override; + + void setClipPlanes(float near, float far); + protected: void readData(XRCReadStream *stream) override; void printData() override; @@ -51,6 +58,9 @@ protected: float _fov; Common::Rect _viewport; Math::Vector3d _v4; + + float _nearClipPlane; + float _farClipPlane; }; } // End of namespace Stark diff --git a/engines/stark/resources/layer.cpp b/engines/stark/resources/layer.cpp index d64fabb6f30..79167480525 100644 --- a/engines/stark/resources/layer.cpp +++ b/engines/stark/resources/layer.cpp @@ -22,6 +22,7 @@ #include "engines/stark/resources/layer.h" +#include "engines/stark/resources/camera.h" #include "engines/stark/resources/item.h" #include "engines/stark/xrcreader.h" @@ -100,7 +101,7 @@ Layer3D::~Layer3D() { Layer3D::Layer3D(Resource *parent, byte subType, uint16 index, const Common::String &name) : Layer(parent, subType, index, name), _field_54(1), - _field_58(75), + _maxShadowLength(75), _nearClipPlane(100.0), _farClipPlane(64000.0), _backgroundItem(nullptr) { @@ -113,7 +114,7 @@ void Layer3D::readData(XRCReadStream *stream) { _nearClipPlane = stream->readFloat(); _farClipPlane = stream->readFloat(); if (stream->isDataLeft()) { - _field_58 = stream->readUint32LE(); + _maxShadowLength = stream->readUint32LE(); } } @@ -122,6 +123,9 @@ void Layer3D::onAllLoaded() { _items = listChildren(); _backgroundItem = findChildWithSubtype(Item::kItemSub8); + + Camera *camera = findChild(); + camera->setClipPlanes(_nearClipPlane, _farClipPlane); } RenderEntry *Layer3D::getBackgroundRenderEntry() { @@ -164,7 +168,7 @@ void Layer3D::printData() { Layer::printData(); debug("field_54: %d", _field_54); - debug("field_58: %d", _field_58); + debug("maxShadowLength: %d", _maxShadowLength); debug("nearClipPlane: %f", _nearClipPlane); debug("farClipPlane: %f", _farClipPlane); } diff --git a/engines/stark/resources/layer.h b/engines/stark/resources/layer.h index 2157ec97df3..cb1ab1cf9df 100644 --- a/engines/stark/resources/layer.h +++ b/engines/stark/resources/layer.h @@ -97,7 +97,7 @@ protected: void printData() override; uint32 _field_54; - uint32 _field_58; + uint32 _maxShadowLength; float _nearClipPlane; float _farClipPlane; diff --git a/engines/stark/scene.cpp b/engines/stark/scene.cpp index c485fdc9a6c..7072ff4f528 100644 --- a/engines/stark/scene.cpp +++ b/engines/stark/scene.cpp @@ -21,30 +21,25 @@ */ #include "engines/stark/scene.h" -#include "engines/stark/archive.h" -#include "engines/stark/xmg.h" -#include "engines/stark/visual/actor.h" +#include "engines/stark/archive.h" +#include "engines/stark/gfx/driver.h" #include "engines/stark/gfx/renderentry.h" +#include "engines/stark/visual/actor.h" +#include "engines/stark/xmg.h" namespace Stark { -Scene::Scene(GfxDriver *gfx) : _gfx(gfx) { +Scene::Scene(GfxDriver *gfx) : + _gfx(gfx), + _fov(45.0), + _nearClipPlane(100.0), + _farClipPlane(64000.0) { // Open the scene archive XARCArchive xarc; if (!xarc.open("45/00/00.xarc")) warning("couldn't open archive"); -// _elements.push_back(SceneElementXMG::load(&xarc, "house_layercenter.xmg", 0, 0)); -// //_elements.push_back(SceneElementXMG::load(&xarc, "vista-scapehaze-more-fog3-final.xmg", 0, 0)); -// _elements.push_back(SceneElementXMG::load(&xarc, "house_prop01_pillow.xmg", 384, 267)); -// _elements.push_back(SceneElementXMG::load(&xarc, "house_prop02_pillow.xmg", 324, 299)); -// _elements.push_back(SceneElementXMG::load(&xarc, "house_prop03_pillow.xmg", 141, 312)); -// _elements.push_back(SceneElementXMG::load(&xarc, "house_prop4_armrest.xmg", 171, 184)); -// _elements.push_back(SceneElementXMG::load(&xarc, "house_prop5_chair.xmg", 170, 164)); -// _elements.push_back(SceneElementXMG::load(&xarc, "house_prop6_wall.xmg", 0, 0)); -// _elements.push_back(SceneElementXMG::load(&xarc, "house_prop8_pillar.xmg", 534, 0)); - VisualActor *actor = VisualActor::load(&xarc, "oldapril.cir"); actor->setAnim(&xarc, "oldapril_idle.ani"); actor->setTexture(&xarc, "oldapril.tm"); @@ -58,12 +53,24 @@ Scene::Scene(GfxDriver *gfx) : _gfx(gfx) { Scene::~Scene() { } +void Scene::initCamera(const Math::Vector3d &position, const Math::Vector3d &lookAt, + float fov, Common::Rect viewport, float nearClipPlane, float farClipPlane) { + _cameraPosition = position; + _cameraLookAt = lookAt; + _fov = fov; + _viewport = viewport; + _nearClipPlane = nearClipPlane; + _farClipPlane = farClipPlane; +} + void Scene::render(RenderEntryArray renderEntries, uint32 delta) { RenderEntryArray allElements; allElements.push_back(renderEntries); allElements.push_back(_elements); // setup cam + _gfx->setupPerspective(_fov, _nearClipPlane, _farClipPlane); + _gfx->setupCamera(_cameraPosition, _cameraPosition + _cameraLookAt); // Draw bg diff --git a/engines/stark/scene.h b/engines/stark/scene.h index 362ad0af584..3e24f2f52ce 100644 --- a/engines/stark/scene.h +++ b/engines/stark/scene.h @@ -24,7 +24,11 @@ #define STARK_SCENE_H #include "common/array.h" +#include "common/rect.h" +#include "math/vector3d.h" + +#include "engines/stark/actor.h" #include "engines/stark/gfx/renderentry.h" namespace Stark { @@ -47,9 +51,20 @@ public: */ void render(RenderEntryArray renderEntries, uint32 delta); + void initCamera(const Math::Vector3d &position, const Math::Vector3d &lookAt, + float fov, Common::Rect viewport, float nearClipPlane, float farClipPlane); + private: GfxDriver *_gfx; RenderEntryArray _elements; + + Math::Vector3d _cameraPosition; + Math::Vector3d _cameraLookAt; + float _fov; + Common::Rect _viewport; + float _nearClipPlane; + float _farClipPlane; + }; } // End of namespace Stark diff --git a/engines/stark/stark.cpp b/engines/stark/stark.cpp index 3bb6d7ff493..3dd79b65f0f 100644 --- a/engines/stark/stark.cpp +++ b/engines/stark/stark.cpp @@ -94,6 +94,7 @@ Common::Error StarkEngine::run() { _global = new Global(); _resourceProvider = new ResourceProvider(_archiveLoader, _stateProvider, _global); _randomSource = new Common::RandomSource("stark"); + _scene = new Scene(_gfx); // Setup the public services StarkServices &services = StarkServices::instance(); @@ -101,6 +102,7 @@ Common::Error StarkEngine::run() { services.resourceProvider = _resourceProvider; services.global = _global; services.randomSource = _randomSource; + services.scene = _scene; // Load global resources _resourceProvider->initGlobal(); @@ -117,9 +119,6 @@ Common::Error StarkEngine::run() { } void StarkEngine::mainLoop() { - // Load the initial scene - _scene = new Scene(_gfx); - while (!shouldQuit()) { // Process events Common::Event e; diff --git a/engines/stark/stark.h b/engines/stark/stark.h index c42de4bee76..c1a82eb2561 100644 --- a/engines/stark/stark.h +++ b/engines/stark/stark.h @@ -61,12 +61,14 @@ public: archiveLoader = nullptr; resourceProvider = nullptr; randomSource = nullptr; + scene = nullptr; } Global *global; ArchiveLoader *archiveLoader; ResourceProvider *resourceProvider; Common::RandomSource *randomSource; + Scene *scene; }; class StarkEngine : public Engine { diff --git a/engines/stark/visual/actor.cpp b/engines/stark/visual/actor.cpp index b8fefaa1ebc..a93286e4610 100644 --- a/engines/stark/visual/actor.cpp +++ b/engines/stark/visual/actor.cpp @@ -80,17 +80,13 @@ void VisualActor::update(uint32 delta) { void VisualActor::render(Stark::GfxDriver *gfx) { // Prepare vertex list and push to gfx driver // HACK: Purely because I just want to see something for now -static double ctr = 0; -ctr += .1; gfx->set3DMode(); - glPushMatrix(); - glLoadIdentity(); - glScalef(0.005f, .005f, -.005f); - glTranslatef(0, -20.f, 100.f); - glRotatef(20, .3f, 1.f, 0.f); - - glRotatef(180, 0.f, 1.f, 0.f); - //glRotatef((ctr * 10.3f), -4.0f, 10.0f, 1.0f); +// glPushMatrix(); +// glLoadIdentity(); +// glScalef(0.005f, .005f, -.005f); +// glTranslatef(0, -20.f, 100.f); +// glRotatef(20, .3f, 1.f, 0.f); +// glScalef(0.005f, .005f, -.005f); glEnable(GL_TEXTURE_2D); @@ -148,7 +144,7 @@ ctr += .1; } } - glPopMatrix(); +// glPopMatrix(); } } // End of namespace Stark