[Scummvm-git-logs] scummvm master -> 2776f7cb793f8540def3764ff15f86f77cef9d52

aquadran aquadran at gmail.com
Tue Oct 26 11:43:19 UTC 2021


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:
2776f7cb79 PLAYGROUND3D: Introduce testing and playground environment for 3d renderers


Commit: 2776f7cb793f8540def3764ff15f86f77cef9d52
    https://github.com/scummvm/scummvm/commit/2776f7cb793f8540def3764ff15f86f77cef9d52
Author: Paweł Kołodziejski (aquadran at gmail.com)
Date: 2021-10-26T13:43:16+02:00

Commit Message:
PLAYGROUND3D: Introduce testing and playground environment for 3d renderers

Changed paths:
  A dists/engine-data/create-playground3d-data.sh
  A engines/playground3d/configure.engine
  A engines/playground3d/detection.cpp
  A engines/playground3d/framelimiter.cpp
  A engines/playground3d/framelimiter.h
  A engines/playground3d/gfx.cpp
  A engines/playground3d/gfx.h
  A engines/playground3d/gfx_opengl.cpp
  A engines/playground3d/gfx_opengl.h
  A engines/playground3d/gfx_opengl_shaders.cpp
  A engines/playground3d/gfx_opengl_shaders.h
  A engines/playground3d/gfx_tinygl.cpp
  A engines/playground3d/gfx_tinygl.h
  A engines/playground3d/metaengine.cpp
  A engines/playground3d/module.mk
  A engines/playground3d/playground3d.cpp
  A engines/playground3d/playground3d.h
  A engines/playground3d/shaders/playground3d_cube.fragment
  A engines/playground3d/shaders/playground3d_cube.vertex
    .gitignore
    Makefile.common
    dists/scummvm.rc
    graphics/opengl/shader.cpp


diff --git a/.gitignore b/.gitignore
index a8474a65ad..8038064000 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
diff --git a/Makefile.common b/Makefile.common
index 303548335f..7317b4d3e2 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -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
diff --git a/dists/engine-data/create-playground3d-data.sh b/dists/engine-data/create-playground3d-data.sh
new file mode 100755
index 0000000000..e0c737ffb5
--- /dev/null
+++ b/dists/engine-data/create-playground3d-data.sh
@@ -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"
diff --git a/dists/scummvm.rc b/dists/scummvm.rc
index 1cc1bafdba..56cff34f63 100644
--- a/dists/scummvm.rc
+++ b/dists/scummvm.rc
@@ -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
 
diff --git a/engines/playground3d/configure.engine b/engines/playground3d/configure.engine
new file mode 100644
index 0000000000..a39709cd1a
--- /dev/null
+++ b/engines/playground3d/configure.engine
@@ -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"
diff --git a/engines/playground3d/detection.cpp b/engines/playground3d/detection.cpp
new file mode 100644
index 0000000000..32abc9656c
--- /dev/null
+++ b/engines/playground3d/detection.cpp
@@ -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);
diff --git a/engines/playground3d/framelimiter.cpp b/engines/playground3d/framelimiter.cpp
new file mode 100644
index 0000000000..e3040e61ea
--- /dev/null
+++ b/engines/playground3d/framelimiter.cpp
@@ -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
diff --git a/engines/playground3d/framelimiter.h b/engines/playground3d/framelimiter.h
new file mode 100644
index 0000000000..c06a31b134
--- /dev/null
+++ b/engines/playground3d/framelimiter.h
@@ -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
diff --git a/engines/playground3d/gfx.cpp b/engines/playground3d/gfx.cpp
new file mode 100644
index 0000000000..f6114abc6c
--- /dev/null
+++ b/engines/playground3d/gfx.cpp
@@ -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
diff --git a/engines/playground3d/gfx.h b/engines/playground3d/gfx.h
new file mode 100644
index 0000000000..055a85a0b4
--- /dev/null
+++ b/engines/playground3d/gfx.h
@@ -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
diff --git a/engines/playground3d/gfx_opengl.cpp b/engines/playground3d/gfx_opengl.cpp
new file mode 100644
index 0000000000..282336ff64
--- /dev/null
+++ b/engines/playground3d/gfx_opengl.cpp
@@ -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
diff --git a/engines/playground3d/gfx_opengl.h b/engines/playground3d/gfx_opengl.h
new file mode 100644
index 0000000000..1fad289568
--- /dev/null
+++ b/engines/playground3d/gfx_opengl.h
@@ -0,0 +1,54 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 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
diff --git a/engines/playground3d/gfx_opengl_shaders.cpp b/engines/playground3d/gfx_opengl_shaders.cpp
new file mode 100644
index 0000000000..a1c94ba589
--- /dev/null
+++ b/engines/playground3d/gfx_opengl_shaders.cpp
@@ -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
diff --git a/engines/playground3d/gfx_opengl_shaders.h b/engines/playground3d/gfx_opengl_shaders.h
new file mode 100644
index 0000000000..cc34b35162
--- /dev/null
+++ b/engines/playground3d/gfx_opengl_shaders.h
@@ -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
diff --git a/engines/playground3d/gfx_tinygl.cpp b/engines/playground3d/gfx_tinygl.cpp
new file mode 100644
index 0000000000..cf29600819
--- /dev/null
+++ b/engines/playground3d/gfx_tinygl.cpp
@@ -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
diff --git a/engines/playground3d/gfx_tinygl.h b/engines/playground3d/gfx_tinygl.h
new file mode 100644
index 0000000000..4e2660ead5
--- /dev/null
+++ b/engines/playground3d/gfx_tinygl.h
@@ -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
diff --git a/engines/playground3d/metaengine.cpp b/engines/playground3d/metaengine.cpp
new file mode 100644
index 0000000000..b4a4bbb4bd
--- /dev/null
+++ b/engines/playground3d/metaengine.cpp
@@ -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
diff --git a/engines/playground3d/module.mk b/engines/playground3d/module.mk
new file mode 100644
index 0000000000..d0e2f280c3
--- /dev/null
+++ b/engines/playground3d/module.mk
@@ -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
diff --git a/engines/playground3d/playground3d.cpp b/engines/playground3d/playground3d.cpp
new file mode 100644
index 0000000000..2ad0aa088b
--- /dev/null
+++ b/engines/playground3d/playground3d.cpp
@@ -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
diff --git a/engines/playground3d/playground3d.h b/engines/playground3d/playground3d.h
new file mode 100644
index 0000000000..d9c7bd9bec
--- /dev/null
+++ b/engines/playground3d/playground3d.h
@@ -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
diff --git a/engines/playground3d/shaders/playground3d_cube.fragment b/engines/playground3d/shaders/playground3d_cube.fragment
new file mode 100644
index 0000000000..433e5d0eb5
--- /dev/null
+++ b/engines/playground3d/shaders/playground3d_cube.fragment
@@ -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);
+	}
+}
diff --git a/engines/playground3d/shaders/playground3d_cube.vertex b/engines/playground3d/shaders/playground3d_cube.vertex
new file mode 100644
index 0000000000..6286101032
--- /dev/null
+++ b/engines/playground3d/shaders/playground3d_cube.vertex
@@ -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;
+	}
+}
diff --git a/graphics/opengl/shader.cpp b/graphics/opengl/shader.cpp
index ff552e5fe1..cb152200eb 100644
--- a/graphics/opengl/shader.cpp
+++ b/graphics/opengl/shader.cpp
@@ -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];




More information about the Scummvm-git-logs mailing list