PLAYGROUND3D: Introduce testing and playground environment for 3d renderers

This commit is contained in:
Paweł Kołodziejski 2021-10-24 12:39:07 +02:00
parent d545c467c0
commit 2776f7cb79
23 changed files with 1261 additions and 0 deletions

1
.gitignore vendored
View file

@ -121,6 +121,7 @@ project.xcworkspace
/dists/engine-data/testbed-audiocd-files/testbed.config
/dists/engine-data/testbed-audiocd-files/testbed.out
/dists/engine-data/playground3d
/doc/*.aux

View file

@ -497,6 +497,9 @@ endif
ifdef ENABLE_WINTERMUTE
DIST_FILES_SHADERS+=$(wildcard $(srcdir)/engines/wintermute/base/gfx/opengl/shaders/*)
endif
ifdef ENABLE_PLAYGROUND3D
DIST_FILES_SHADERS+=$(wildcard $(srcdir)/engines/playground3d/shaders/*)
endif
endif
.PHONY: all clean distclean plugins dist-src clean-toplevel manual

View file

@ -0,0 +1,22 @@
#!/bin/sh
# Create the directory structure
# Avoided bash shortcuts / file-seperators in interest of portability
if [ -e playground3d ]; then
echo "Game-data already present as playground3d/"
echo "To regenerate, remove and rerun"
exit 0
fi
mkdir playground3d
cd playground3d
# For game detection
echo "ScummVM rocks!" > PLAYGROUND3D
# back to the top
cd ..
echo "Game data created"

View file

@ -184,6 +184,10 @@ shaders/wme_shadow_volume.vertex FILE "engines/wintermute/base/gfx/ope
shaders/wme_sprite.fragment FILE "engines/wintermute/base/gfx/opengl/shaders/wme_sprite.fragment"
shaders/wme_sprite.vertex FILE "engines/wintermute/base/gfx/opengl/shaders/wme_sprite.vertex"
#endif
#if PLUGIN_ENABLED_STATIC(PLAYGROUND3D)
shaders/playground3d_cube.fragment FILE "engines/playground3d/shaders/playground3d_cube.fragment"
shaders/playground3d_cube.vertex FILE "engines/playground3d/shaders/playground3d_cube.vertex"
#endif
#endif
#endif

View file

@ -0,0 +1,3 @@
# This file is included from the main "configure" script
# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
add_engine playground3d "Playground 3d: the testing and plaground environment for 3d renderers" no "" "" "cxx11 tinygl 16bit highres"

View file

@ -0,0 +1,65 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "engines/advancedDetector.h"
#include "base/plugins.h"
#include "playground3d/playground3d.h"
static const PlainGameDescriptor playground3d_setting[] = {
{ "playground3d", "Playground 3d: the testing and plaground environment for 3d renderers" },
{ 0, 0 }
};
static const ADGameDescription playground3dDescriptions[] = {
{
"playground3d",
"",
AD_ENTRY1("PLAYGROUND3D", 0),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
GUIO1(GUIO_NOLAUNCHLOAD)
},
AD_TABLE_END_MARKER
};
class Playground3dMetaEngineDetection : public AdvancedMetaEngineDetection {
public:
Playground3dMetaEngineDetection() : AdvancedMetaEngineDetection(playground3dDescriptions, sizeof(ADGameDescription), playground3d_setting) {
_md5Bytes = 512;
}
const char *getEngineId() const override {
return "playground3d";
}
const char *getName() const override {
return "Playground 3d: the testing and plaground environment for 3d renderers";
}
const char *getOriginalCopyright() const override {
return "Copyright (C) ScummVM";
}
};
REGISTER_PLUGIN_STATIC(PLAYGROUND3D_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, Playground3dMetaEngineDetection);

View file

@ -0,0 +1,74 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "engines/playground3d/framelimiter.h"
#include "common/util.h"
namespace Playground3d {
namespace Gfx {
FrameLimiter::FrameLimiter(OSystem *system, const uint framerate) :
_system(system),
_speedLimitMs(0),
_startFrameTime(0),
_lastFrameDurationMs(_speedLimitMs) {
// The frame limiter is disabled when vsync is enabled.
_enabled = !_system->getFeatureState(OSystem::kFeatureVSync) && framerate != 0;
if (_enabled) {
_speedLimitMs = 1000 / CLIP<uint>(framerate, 0, 100);
}
}
void FrameLimiter::startFrame() {
uint currentTime = _system->getMillis();
if (_startFrameTime != 0) {
_lastFrameDurationMs = currentTime - _startFrameTime;
}
_startFrameTime = currentTime;
}
void FrameLimiter::delayBeforeSwap() {
uint endFrameTime = _system->getMillis();
uint frameDuration = endFrameTime - _startFrameTime;
if (_enabled && frameDuration < _speedLimitMs) {
_system->delayMillis(_speedLimitMs - frameDuration);
}
}
void FrameLimiter::pause(bool pause) {
if (!pause) {
// Make sure the frame duration value is consistent when resuming
_startFrameTime = 0;
}
}
uint FrameLimiter::getLastFrameDuration() const {
return _lastFrameDurationMs;
}
} // End of namespace Gfx
} // End of namespace Playground3d

View file

@ -0,0 +1,62 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef PLAYGROUND3D_GFX_FRAMELIMITER_H
#define PLAYGROUND3D_GFX_FRAMELIMITER_H
#include "common/system.h"
namespace Playground3d {
namespace Gfx {
/**
* A framerate limiter
*
* Ensures the framerate does not exceed the specified value
* by delaying until all of the timeslot allocated to the frame
* is consumed.
* Allows to curb CPU usage and have a stable framerate.
*/
class FrameLimiter {
public:
FrameLimiter(OSystem *system, const uint framerate);
void startFrame();
void delayBeforeSwap();
void pause(bool pause);
uint getLastFrameDuration() const;
private:
OSystem *_system;
bool _enabled;
uint _speedLimitMs;
uint _startFrameTime;
uint _lastFrameDurationMs;
};
} // End of namespace Gfx
} // End of namespace Playground3d
#endif // PLAYGROUND3D_GFX_FRAMELIMITER_H

View file

@ -0,0 +1,166 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "engines/playground3d/gfx.h"
#include "engines/util.h"
#include "common/config-manager.h"
#include "graphics/renderer.h"
#include "graphics/surface.h"
#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS) || defined(USE_GLES2)
#include "graphics/opengl/context.h"
#endif
#include "math/glmath.h"
namespace Playground3d {
const float Renderer::cubeVertices[] = {
// S T X Y Z NX NY NZ R G B
0.0f, 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // blue
1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, // magenta
0.0f, 0.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // cyan
1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, // white
0.0f, 1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, // red
1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, // black
0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, 0.0f, // yellow
1.0f, 0.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, // green
0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, // magenta
1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // red
0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // white
1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, // yellow
0.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // black
1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, // blue
0.0f, 0.0f, -1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, // green
1.0f, 0.0f, -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, // cyan
0.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // cyan
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, // white
0.0f, 0.0f, -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // green
1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, // yellow
0.0f, 1.0f, -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // black
1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, // red
0.0f, 0.0f, -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // blue
1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f // magenta
};
Renderer::Renderer(OSystem *system)
: _system(system) {
}
Renderer::~Renderer() {
}
Common::Rect Renderer::viewport() const {
return _screenViewport;
}
void Renderer::computeScreenViewport() {
int32 screenWidth = _system->getWidth();
int32 screenHeight = _system->getHeight();
// Aspect ratio correction
int32 viewportWidth = MIN<int32>(screenWidth, screenHeight * kOriginalWidth / kOriginalHeight);
int32 viewportHeight = MIN<int32>(screenHeight, screenWidth * kOriginalHeight / kOriginalWidth);
_screenViewport = Common::Rect(viewportWidth, viewportHeight);
// Pillarboxing
_screenViewport.translate((screenWidth - viewportWidth) / 2, (screenHeight - viewportHeight) / 2);
}
Math::Matrix4 Renderer::makeProjectionMatrix(float fov, float nearClip, float farClip) const {
float aspectRatio = kOriginalWidth / (float) kOriginalHeight;
float xmaxValue = nearClip * tanf(fov * M_PI / 360.0f);
float ymaxValue = xmaxValue / aspectRatio;
return Math::makeFrustumMatrix(-xmaxValue, xmaxValue, -ymaxValue, ymaxValue, nearClip, farClip);
}
void Renderer::setupCameraPerspective(float pitch, float heading, float fov) {
_projectionMatrix = makeProjectionMatrix(fov, 1.0f, 10000.0f);
_modelViewMatrix = Math::Matrix4(180.0f - heading, pitch, 0.0f, Math::EO_XYZ);
Math::Matrix4 proj = _projectionMatrix;
Math::Matrix4 model = _modelViewMatrix;
proj.transpose();
model.transpose();
_mvpMatrix = proj * model;
_mvpMatrix.transpose();
}
Renderer *createRenderer(OSystem *system) {
Common::String rendererConfig = ConfMan.get("renderer");
Graphics::RendererType desiredRendererType = Graphics::parseRendererTypeCode(rendererConfig);
Graphics::RendererType matchingRendererType = Graphics::getBestMatchingAvailableRendererType(desiredRendererType);
bool isAccelerated = matchingRendererType != Graphics::kRendererTypeTinyGL;
uint width = Renderer::kOriginalWidth;
uint height = Renderer::kOriginalHeight;
if (isAccelerated) {
initGraphics3d(width, height);
} else {
initGraphics(width, height, nullptr);
}
#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS) || defined(USE_GLES2)
bool backendCapableOpenGL = g_system->hasFeature(OSystem::kFeatureOpenGLForGame);
#endif
#if defined(USE_OPENGL_GAME)
// Check the OpenGL context actually supports shaders
if (backendCapableOpenGL && matchingRendererType == Graphics::kRendererTypeOpenGLShaders && !OpenGLContext.shadersSupported) {
matchingRendererType = Graphics::kRendererTypeOpenGL;
}
#endif
if (matchingRendererType != desiredRendererType && desiredRendererType != Graphics::kRendererTypeDefault) {
// Display a warning if unable to use the desired renderer
warning("Unable to create a '%s' renderer", rendererConfig.c_str());
}
#if defined(USE_GLES2) || defined(USE_OPENGL_SHADERS)
if (backendCapableOpenGL && matchingRendererType == Graphics::kRendererTypeOpenGLShaders) {
return CreateGfxOpenGLShader(system);
}
#endif
#if defined(USE_OPENGL_GAME) && !defined(USE_GLES2)
if (backendCapableOpenGL && matchingRendererType == Graphics::kRendererTypeOpenGL) {
return CreateGfxOpenGL(system);
}
#endif
if (matchingRendererType == Graphics::kRendererTypeTinyGL) {
return CreateGfxTinyGL(system);
}
error("Unable to create a '%s' renderer", rendererConfig.c_str());
}
} // End of namespace Playground3d

View file

@ -0,0 +1,80 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef PLAYGROUND3D_GFX_H
#define PLAYGROUND3D_GFX_H
#include "common/rect.h"
#include "common/system.h"
#include "math/frustum.h"
#include "math/matrix4.h"
#include "math/vector3d.h"
namespace Playground3d {
class Renderer {
public:
Renderer(OSystem *system);
virtual ~Renderer();
virtual void init() = 0;
virtual void clear() = 0;
/**
* Swap the buffers, making the drawn screen visible
*/
virtual void flipBuffer() { }
Common::Rect viewport() const;
void setupCameraPerspective(float pitch, float heading, float fov);
static const int kOriginalWidth = 640;
static const int kOriginalHeight = 480;
void computeScreenViewport();
virtual void drawCube(const Math::Vector3d &pos, const Math::Vector3d &roll) = 0;
protected:
OSystem *_system;
Common::Rect _screenViewport;
Math::Matrix4 _projectionMatrix;
Math::Matrix4 _modelViewMatrix;
Math::Matrix4 _mvpMatrix;
static const float cubeVertices[11 * 6 * 4];
Math::Matrix4 makeProjectionMatrix(float fov, float nearClip, float farClip) const;
};
Renderer *CreateGfxOpenGL(OSystem *system);
Renderer *CreateGfxOpenGLShader(OSystem *system);
Renderer *CreateGfxTinyGL(OSystem *system);
Renderer *createRenderer(OSystem *system);
} // End of namespace Playground3d
#endif // PLAYGROUND3D_GFX_H

View file

@ -0,0 +1,104 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "common/rect.h"
#include "common/textconsole.h"
#if defined(USE_OPENGL_GAME) && !defined(USE_GLES2)
#include "graphics/opengl/context.h"
#include "graphics/surface.h"
#include "engines/playground3d/gfx.h"
#include "engines/playground3d/gfx_opengl.h"
namespace Playground3d {
Renderer *CreateGfxOpenGL(OSystem *system) {
return new OpenGLRenderer(system);
}
OpenGLRenderer::OpenGLRenderer(OSystem *system) :
Renderer(system) {
}
OpenGLRenderer::~OpenGLRenderer() {
}
void OpenGLRenderer::init() {
debug("Initializing OpenGL Renderer");
computeScreenViewport();
#if defined(USE_OPENGL_SHADERS)
// The ShaderSurfaceRenderer sets an array buffer which conflict with fixed pipeline rendering
glBindBuffer(GL_ARRAY_BUFFER, 0);
#endif // defined(USE_OPENGL_SHADERS)
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
}
void OpenGLRenderer::clear() {
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void OpenGLRenderer::drawFace(uint face) {
glBegin(GL_TRIANGLE_STRIP);
for (uint i = 0; i < 4; i++) {
glColor3f(cubeVertices[11 * (4 * face + i) + 8], cubeVertices[11 * (4 * face + i) + 9], cubeVertices[11 * (4 * face + i) + 10]);
glVertex3f(cubeVertices[11 * (4 * face + i) + 2], cubeVertices[11 * (4 * face + i) + 3], cubeVertices[11 * (4 * face + i) + 4]);
glNormal3f(cubeVertices[11 * (4 * face + i) + 5], cubeVertices[11 * (4 * face + i) + 6], cubeVertices[11 * (4 * face + i) + 7]);
}
glEnd();
}
void OpenGLRenderer::drawCube(const Math::Vector3d &pos, const Math::Vector3d &roll) {
Common::Rect vp = viewport();
glViewport(vp.left, _system->getHeight() - vp.top - vp.height(), vp.width(), vp.height());
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(_projectionMatrix.getData());
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(_modelViewMatrix.getData());
glTranslatef(pos.x(), pos.y(), pos.z());
glRotatef(roll.x(), 1.0f, 0.0f, 0.0f);
glRotatef(roll.y(), 0.0f, 1.0f, 0.0f);
glRotatef(roll.z(), 0.0f, 0.0f, 1.0f);
for (uint i = 0; i < 6; i++) {
drawFace(i);
}
}
} // End of namespace Playground3d
#endif

View file

@ -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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef PLAYGROUND3D_GFX_OPENGL_H
#define PLAYGROUND3D_GFX_OPENGL_H
#include "common/rect.h"
#include "common/system.h"
#include "math/vector3d.h"
#include "graphics/opengl/system_headers.h"
#include "engines/playground3d/gfx.h"
namespace Playground3d {
class OpenGLRenderer : public Renderer {
public:
OpenGLRenderer(OSystem *_system);
virtual ~OpenGLRenderer();
virtual void init() override;
virtual void clear() override;
virtual void drawCube(const Math::Vector3d &pos, const Math::Vector3d &roll) override;
private:
void drawFace(uint face);
};
} // End of namespace Playground3d
#endif // PLAYGROUND3D_GFX_OPENGL_H

View file

@ -0,0 +1,101 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "common/rect.h"
#include "common/textconsole.h"
#if defined(USE_GLES2) || defined(USE_OPENGL_SHADERS)
#include "graphics/surface.h"
#include "math/glmath.h"
#include "math/vector2d.h"
#include "math/rect2d.h"
#include "math/quat.h"
#include "graphics/opengl/shader.h"
#include "engines/playground3d/gfx.h"
#include "engines/playground3d/gfx_opengl_shaders.h"
namespace Playground3d {
Renderer *CreateGfxOpenGLShader(OSystem *system) {
return new ShaderRenderer(system);
}
ShaderRenderer::ShaderRenderer(OSystem *system) :
Renderer(system),
_currentViewport(kOriginalWidth, kOriginalHeight),
_cubeShader(nullptr),
_cubeVBO(0) {
}
ShaderRenderer::~ShaderRenderer() {
OpenGL::ShaderGL::freeBuffer(_cubeVBO);
delete _cubeShader;
}
void ShaderRenderer::init() {
debug("Initializing OpenGL Renderer with shaders");
computeScreenViewport();
glEnable(GL_DEPTH_TEST);
static const char* attributes[] = { "position", "normal", "color", "texcoord", NULL };
_cubeShader = OpenGL::ShaderGL::fromFiles("playground3d_cube", attributes);
_cubeVBO = OpenGL::ShaderGL::createBuffer(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices);
_cubeShader->enableVertexAttribute("texcoord", _cubeVBO, 2, GL_FLOAT, GL_FALSE, 11 * sizeof(float), 0);
_cubeShader->enableVertexAttribute("position", _cubeVBO, 3, GL_FLOAT, GL_FALSE, 11 * sizeof(float), 8);
_cubeShader->enableVertexAttribute("normal", _cubeVBO, 3, GL_FLOAT, GL_FALSE, 11 * sizeof(float), 20);
_cubeShader->enableVertexAttribute("color", _cubeVBO, 3, GL_FLOAT, GL_FALSE, 11 * sizeof(float), 32);
}
void ShaderRenderer::clear() {
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void ShaderRenderer::drawCube(const Math::Vector3d &pos, const Math::Vector3d &roll) {
Common::Rect vp = viewport();
glViewport(vp.left, _system->getHeight() - vp.top - vp.height(), vp.width(), vp.height());
auto rotateMatrix = (Math::Quaternion::fromEuler(roll.x(), roll.y(), roll.z(), Math::EO_XYZ)).inverse().toMatrix();
_cubeShader->use();
_cubeShader->setUniform("textured", false);
_cubeShader->setUniform("mvpMatrix", _mvpMatrix);
_cubeShader->setUniform("rotateMatrix", rotateMatrix);
_cubeShader->setUniform("modelPos", pos);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
glDrawArrays(GL_TRIANGLE_STRIP, 8, 4);
glDrawArrays(GL_TRIANGLE_STRIP, 12, 4);
glDrawArrays(GL_TRIANGLE_STRIP, 16, 4);
glDrawArrays(GL_TRIANGLE_STRIP, 20, 4);
}
} // End of namespace Playground3d
#endif

View file

@ -0,0 +1,58 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef PLAYGROUND3D_GFX_OPENGL_SHADERS_H
#define PLAYGROUND3D_GFX_OPENGL_SHADERS_H
#include "common/rect.h"
#include "math/rect2d.h"
#include "graphics/opengl/shader.h"
#include "graphics/opengl/system_headers.h"
#include "engines/playground3d/gfx.h"
namespace Playground3d {
class ShaderRenderer : public Renderer {
public:
ShaderRenderer(OSystem *_system);
virtual ~ShaderRenderer();
virtual void init() override;
virtual void clear() override;
virtual void drawCube(const Math::Vector3d &pos, const Math::Vector3d &roll) override;
private:
OpenGL::ShaderGL *_cubeShader;
GLuint _cubeVBO;
Common::Rect _currentViewport;
};
} // End of namespace Playground3d
#endif // PLAYGROUND3D_GFX_OPENGL_SHADERS_H

View file

@ -0,0 +1,109 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "common/config-manager.h"
#include "common/rect.h"
#include "common/textconsole.h"
#include "graphics/surface.h"
#include "graphics/tinygl/zblit.h"
#include "math/vector2d.h"
#include "math/glmath.h"
#include "engines/playground3d/gfx.h"
#include "engines/playground3d/gfx_tinygl.h"
namespace Playground3d {
Renderer *CreateGfxTinyGL(OSystem *system) {
return new TinyGLRenderer(system);
}
TinyGLRenderer::TinyGLRenderer(OSystem *system) :
Renderer(system),
_fb(NULL) {
}
TinyGLRenderer::~TinyGLRenderer() {
}
void TinyGLRenderer::init() {
debug("Initializing Software 3D Renderer");
computeScreenViewport();
_fb = new TinyGL::FrameBuffer(kOriginalWidth, kOriginalHeight, g_system->getScreenFormat());
TinyGL::glInit(_fb, 512);
tglEnableDirtyRects(ConfMan.getBool("dirtyrects"));
tglMatrixMode(TGL_PROJECTION);
tglLoadIdentity();
tglMatrixMode(TGL_MODELVIEW);
tglLoadIdentity();
tglDisable(TGL_LIGHTING);
tglEnable(TGL_DEPTH_TEST);
}
void TinyGLRenderer::clear() {
tglClearColor(0.5f, 0.5f, 0.5f, 1.0f);
tglClear(TGL_COLOR_BUFFER_BIT | TGL_DEPTH_BUFFER_BIT);
}
void TinyGLRenderer::drawFace(uint face) {
tglBegin(TGL_TRIANGLE_STRIP);
for (uint i = 0; i < 4; i++) {
tglColor3f(cubeVertices[11 * (4 * face + i) + 8], cubeVertices[11 * (4 * face + i) + 9], cubeVertices[11 * (4 * face + i) + 10]);
tglVertex3f(cubeVertices[11 * (4 * face + i) + 2], cubeVertices[11 * (4 * face + i) + 3], cubeVertices[11 * (4 * face + i) + 4]);
tglNormal3f(cubeVertices[11 * (4 * face + i) + 5], cubeVertices[11 * (4 * face + i) + 6], cubeVertices[11 * (4 * face + i) + 7]);
}
tglEnd();
}
void TinyGLRenderer::drawCube(const Math::Vector3d &pos, const Math::Vector3d &roll) {
Common::Rect vp = viewport();
tglViewport(vp.left, _system->getHeight() - vp.top - vp.height(), vp.width(), vp.height());
tglMatrixMode(TGL_PROJECTION);
tglLoadMatrixf(_projectionMatrix.getData());
tglMatrixMode(TGL_MODELVIEW);
tglLoadMatrixf(_modelViewMatrix.getData());
tglTranslatef(pos.x(), pos.y(), pos.z());
tglRotatef(roll.x(), 1.0f, 0.0f, 0.0f);
tglRotatef(roll.y(), 0.0f, 1.0f, 0.0f);
tglRotatef(roll.z(), 0.0f, 0.0f, 1.0f);
for (uint i = 0; i < 6; i++) {
drawFace(i);
}
}
void TinyGLRenderer::flipBuffer() {
TinyGL::tglPresentBuffer();
g_system->copyRectToScreen(_fb->getPixelBuffer(), _fb->linesize, 0, 0, _fb->xsize, _fb->ysize);
}
} // End of namespace Playground3d

View file

@ -0,0 +1,58 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef PLAYGROUND3D_GFX_TINYGL_H
#define PLAYGROUND3D_GFX_TINYGL_H
#include "common/rect.h"
#include "common/system.h"
#include "math/vector3d.h"
#include "graphics/tinygl/zgl.h"
#include "engines/playground3d/gfx.h"
namespace Playground3d {
class TinyGLRenderer : public Renderer {
public:
TinyGLRenderer(OSystem *_system);
virtual ~TinyGLRenderer();
virtual void init() override;
virtual void clear() override;
virtual void drawCube(const Math::Vector3d &pos, const Math::Vector3d &roll) override;
virtual void flipBuffer() override;
private:
void drawFace(uint face);
TinyGL::FrameBuffer *_fb;
};
} // End of namespace Playground3d
#endif // PLAYGROUND3D_GFX_TINYGL_H

View file

@ -0,0 +1,51 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "base/plugins.h"
#include "common/system.h"
#include "engines/advancedDetector.h"
#include "playground3d/playground3d.h"
class Playground3dMetaEngine : public AdvancedMetaEngine {
public:
const char *getName() const override {
return "playground3d";
}
Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription * /* desc */) const override {
*engine = new Playground3d::Playground3dEngine(syst);
return Common::kNoError;
}
bool hasFeature(MetaEngineFeature f) const override {
return false;
}
};
#if PLUGIN_ENABLED_DYNAMIC(PLAYGROUND3D)
REGISTER_PLUGIN_DYNAMIC(PLAYGROUND3D, PLUGIN_TYPE_ENGINE, Playground3dMetaEngine);
#else
REGISTER_PLUGIN_STATIC(PLAYGROUND3D, PLUGIN_TYPE_ENGINE, Playground3dMetaEngine);
#endif

View file

@ -0,0 +1,24 @@
MODULE := engines/playground3d
MODULE_OBJS := \
metaengine.o \
framelimiter.o \
gfx.o \
gfx_opengl.o \
gfx_opengl_shaders.o \
gfx_tinygl.o \
playground3d.o
MODULE_DIRS += \
engines/playground3d
# This module can be built as a plugin
ifeq ($(ENABLE_PLAYGROUND3D), DYNAMIC_PLUGIN)
PLUGIN := 1
endif
# Include common rules
include $(srcdir)/rules.mk
# Detection objects
DETECT_OBJS += $(MODULE)/detection.o

View file

@ -0,0 +1,117 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "common/scummsys.h"
#include "common/config-manager.h"
#include "common/events.h"
#include "graphics/renderer.h"
#include "engines/util.h"
#include "playground3d/playground3d.h"
namespace Playground3d {
bool Playground3dEngine::hasFeature(EngineFeature f) const {
// The TinyGL renderer does not support arbitrary resolutions for now
Common::String rendererConfig = ConfMan.get("renderer");
Graphics::RendererType desiredRendererType = Graphics::parseRendererTypeCode(rendererConfig);
Graphics::RendererType matchingRendererType = Graphics::getBestMatchingAvailableRendererType(desiredRendererType);
bool softRenderer = matchingRendererType == Graphics::kRendererTypeTinyGL;
return
(f == kSupportsReturnToLauncher) ||
(f == kSupportsArbitraryResolutions && !softRenderer);
}
Playground3dEngine::Playground3dEngine(OSystem *syst)
: Engine(syst), _system(syst), _frameLimiter(0),
_rotateAngleX(45), _rotateAngleY(45), _rotateAngleZ(10) {
}
Playground3dEngine::~Playground3dEngine() {
delete _frameLimiter;
delete _gfx;
}
Common::Error Playground3dEngine::run() {
_gfx = createRenderer(_system);
_gfx->init();
_gfx->clear();
_frameLimiter = new Gfx::FrameLimiter(_system, ConfMan.getInt("engine_speed"));
_system->showMouse(true);
while (!shouldQuit()) {
processInput();
drawFrame();
}
_system->showMouse(false);
return Common::kNoError;
}
void Playground3dEngine::processInput() {
Common::Event event;
while (getEventManager()->pollEvent(event)) {
if (event.type == Common::EVENT_SCREEN_CHANGED) {
_gfx->computeScreenViewport();
}
}
}
void Playground3dEngine::drawAndRotateCube() {
Math::Vector3d pos = Math::Vector3d(0.0f, 0.0f, 6.0f);
_gfx->drawCube(pos, Math::Vector3d(_rotateAngleX, _rotateAngleY, _rotateAngleZ));
_rotateAngleX += 0.25;
_rotateAngleY += 0.50;
_rotateAngleZ += 0.10;
if (_rotateAngleX >= 360)
_rotateAngleX = 0;
if (_rotateAngleY >= 360)
_rotateAngleY = 0;
if (_rotateAngleZ >= 360)
_rotateAngleZ = 0;
}
void Playground3dEngine::drawFrame() {
_gfx->clear();
float pitch = 0.0f;
float heading = 0.0f;
float fov = 45.0f;
_gfx->setupCameraPerspective(pitch, heading, fov);
drawAndRotateCube();
_gfx->flipBuffer();
_frameLimiter->delayBeforeSwap();
_system->updateScreen();
_frameLimiter->startFrame();
}
} // End of namespace Playground3d

View file

@ -0,0 +1,60 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef PLAYGROUND3D_H
#define PLAYGROUND3D_H
#include "common/array.h"
#include "engines/engine.h"
#include "engines/playground3d/gfx.h"
#include "engines/playground3d/framelimiter.h"
namespace Playground3d {
class Playground3dEngine : public Engine {
public:
Playground3dEngine(OSystem *syst);
~Playground3dEngine() override;
Common::Error run() override;
bool hasFeature(EngineFeature f) const override;
void processInput();
void drawFrame();
private:
OSystem *_system;
Renderer *_gfx;
Gfx::FrameLimiter *_frameLimiter;
float _rotateAngleX, _rotateAngleY, _rotateAngleZ;
void drawAndRotateCube();
};
} // End of namespace Playground3d
#endif // PLAYGROUND3D_H

View file

@ -0,0 +1,15 @@
in vec2 Texcoord;
in vec3 Color;
OUTPUT
uniform bool textured;
uniform sampler2D tex;
void main()
{
outColor = vec4(Color, 1.0);
if (textured) {
outColor *= texture(tex, Texcoord);
}
}

View file

@ -0,0 +1,28 @@
in vec3 position;
in vec3 color;
in vec3 normal;
in vec2 texcoord;
uniform mat4 mvpMatrix;
uniform mat4 projMatrix;
uniform mat4 modelMatrix;
uniform mat4 rotateMatrix;
uniform bool textured;
uniform vec3 modelPos;
out vec2 Texcoord;
out vec3 Color;
void main()
{
Texcoord = texcoord;
vec4 pos = rotateMatrix * vec4(position, 1.0);
gl_Position = mvpMatrix * (pos + vec4(modelPos, 1.0));
if (textured) {
Color = vec3(1.0);
} else {
Color = color;
}
}

View file

@ -40,6 +40,7 @@ static const GLchar *readFile(const Common::String &filename) {
SearchMan.addDirectory("MYST3_SHADERS", "engines/myst3", 0, 2);
SearchMan.addDirectory("STARK_SHADERS", "engines/stark", 0, 2);
SearchMan.addDirectory("WINTERMUTE_SHADERS", "engines/wintermute/base/gfx/opengl", 0, 5);
SearchMan.addDirectory("PLAYGROUND3D_SHADERS", "engines/playground3d", 0, 2);
file.open(Common::String("shaders/") + filename);
if (!file.isOpen())
error("Could not open shader %s!", filename.c_str());
@ -47,6 +48,7 @@ static const GLchar *readFile(const Common::String &filename) {
SearchMan.remove("MYST3_SHADERS");
SearchMan.remove("STARK_SHADERS");
SearchMan.remove("WINTERMUTE_SHADERS");
SearchMan.remove("PLAYGROUND3D_SHADERS");
const int32 size = file.size();
GLchar *shaderSource = new GLchar[size + 1];