STARK: Add support for arbitrary resolutions

This commit is contained in:
Bastien Bouclet 2015-02-22 09:06:02 +01:00
parent 1c39348f58
commit 3438afcd42
10 changed files with 88 additions and 27 deletions

View file

@ -42,6 +42,8 @@ void Cursor::setMousePosition(Common::Point pos) {
}
void Cursor::render() {
_gfx->setScreenViewport(true); // The cursor is drawn unscaled
_gfx->drawSurface(_cursorTexture, _mousePos);
}

View file

@ -69,5 +69,32 @@ Texture *Driver::createTextureFromString(const Common::String &str, uint32 color
return texture;
}
void Driver::computeScreenViewport() {
int32 screenWidth = g_system->getWidth();
int32 screenHeight = g_system->getHeight();
if (g_system->getFeatureState(OSystem::kFeatureAspectRatioCorrection)) {
// 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);
} else {
// Aspect ratio correction disabled, just stretch
_screenViewport = Common::Rect(screenWidth, screenHeight);
}
}
Common::Rect Driver::gameViewport() const {
Common::Rect game = Common::Rect(_screenViewport.width(), _screenViewport.height() * kGameViewportHeight / kOriginalHeight);
game.translate(_screenViewport.left, _screenViewport.top + _screenViewport.height() * kBottomBorderHeight / kOriginalHeight);
return game;
}
} // End of namespace Gfx
} // End of namespace Stark

View file

@ -42,10 +42,10 @@ public:
virtual ~Driver() {}
virtual void setupScreen(int screenW, int screenH, bool fullscreen) = 0;
virtual void init() = 0;
virtual void setGameViewport() = 0;
virtual void setScreenViewport() = 0;
virtual void setScreenViewport(bool noScaling) = 0;
virtual void setupCamera(const Math::Matrix4 &projection, const Math::Matrix4 &view) = 0;
@ -77,13 +77,20 @@ public:
virtual void set3DMode() = 0;
static const int32 kOriginalWidth = 640;
static const int32 kOriginalHeight = 480;
static const int32 kTopBorderHeight = 36;
static const int32 kGameViewportWidth = 640;
static const int32 kGameViewportHeight = 365;
static const int32 kBottomBorderHeight = 79;
static const int32 kGameViewportWidth = 640;
protected:
int _screenWidth;
int _screenHeight;
void computeScreenViewport();
Common::Rect gameViewport() const;
Common::Rect _screenViewport;
};
} // End of namespace Gfx

View file

@ -22,6 +22,7 @@
#include "engines/stark/gfx/opengls.h"
#include "common/config-manager.h"
#include "common/system.h"
#include "math/matrix4.h"
@ -55,11 +56,11 @@ OpenGLSDriver::~OpenGLSDriver() {
delete _boxShader;
}
void OpenGLSDriver::setupScreen(int screenW, int screenH, bool fullscreen) {
g_system->setupScreen(screenW, screenH, fullscreen, true);
void OpenGLSDriver::init() {
bool fullscreen = ConfMan.getBool("fullscreen");
g_system->setupScreen(kOriginalWidth, kOriginalHeight, fullscreen, true);
_screenWidth = screenW;
_screenHeight = screenH;
computeScreenViewport();
static const char* attributes[] = { "position", "texcoord", nullptr };
_boxShader = Graphics::Shader::fromFiles("stark_box", attributes);
@ -69,18 +70,29 @@ void OpenGLSDriver::setupScreen(int screenW, int screenH, bool fullscreen) {
}
void OpenGLSDriver::setGameViewport() {
_viewport = Common::Rect(kGameViewportWidth, kGameViewportHeight);
_viewport.translate(0, _screenHeight - kGameViewportHeight - kTopBorderHeight);
_viewport = gameViewport();
_unscaledViewport = Common::Rect(kGameViewportWidth, kGameViewportHeight);
_unscaledViewport.translate(0, kBottomBorderHeight);
glViewport(_viewport.left, _viewport.top, _viewport.width(), _viewport.height());
}
void OpenGLSDriver::setScreenViewport() {
_viewport = Common::Rect(_screenWidth, _screenHeight);
void OpenGLSDriver::setScreenViewport(bool noScaling) {
if (noScaling) {
_viewport = Common::Rect(g_system->getWidth(), g_system->getHeight());
_unscaledViewport = _viewport;
} else {
_viewport = _screenViewport;
_unscaledViewport = Common::Rect(kOriginalWidth, kOriginalHeight);
}
glViewport(_viewport.left, _viewport.top, _viewport.width(), _viewport.height());
}
Math::Vector2d OpenGLSDriver::scaled(float x, float y) const {
return Math::Vector2d(x / (float) _unscaledViewport.width(), y / (float) _unscaledViewport.height());
}
void OpenGLSDriver::setupCamera(const Math::Matrix4 &projection, const Math::Matrix4 &view) {
}
@ -114,18 +126,18 @@ void OpenGLSDriver::drawSurface(const Texture *texture, const Common::Point &des
const float tHeight = 1.0;
// Destination rectangle
const float sLeft = dest.x / (float) _viewport.width();
const float sTop = dest.y / (float) _viewport.height();
const float sWidth = texture->width() / (float) _viewport.width();
const float sHeight = texture->height() / (float) _viewport.height();
const float sLeft = dest.x;
const float sTop = dest.y;
const float sWidth = texture->width();
const float sHeight = texture->height();
start2DMode();
_boxShader->use();
_boxShader->setUniform("textured", true);
_boxShader->setUniform("color", Math::Vector4d(1.0f, 1.0f, 1.0f, 1.0f));
_boxShader->setUniform("verOffsetXY", Math::Vector2d(sLeft, sTop));
_boxShader->setUniform("verSizeWH", Math::Vector2d(sWidth, sHeight));
_boxShader->setUniform("verOffsetXY", scaled(sLeft, sTop));
_boxShader->setUniform("verSizeWH", scaled(sWidth, sHeight));
_boxShader->setUniform("texOffsetXY", Math::Vector2d(tLeft, tTop));
_boxShader->setUniform("texSizeWH", Math::Vector2d(tWidth, tHeight));

View file

@ -23,13 +23,16 @@
#ifndef STARK_GFX_OPENGLS_H
#define STARK_GFX_OPENGLS_H
#include "common/rect.h"
#include "common/system.h"
#if defined(USE_GLES2) || defined(USE_OPENGL_SHADERS)
#include "engines/stark/gfx/driver.h"
#include "common/rect.h"
#include "math/vector2d.h"
namespace Graphics {
class Shader;
}
@ -42,10 +45,10 @@ public:
OpenGLSDriver();
~OpenGLSDriver();
void setupScreen(int screenW, int screenH, bool fullscreen);
void init() override;
void setGameViewport() override;
void setScreenViewport() override;
void setScreenViewport(bool noScaling) override;
void setupCamera(const Math::Matrix4 &projection, const Math::Matrix4 &view) override;
@ -63,7 +66,10 @@ private:
void start2DMode();
void end2DMode();
Math::Vector2d scaled(float x, float y) const;
Common::Rect _viewport;
Common::Rect _unscaledViewport;
Graphics::Shader *_boxShader;
uint32 _boxVBO;

View file

@ -37,8 +37,8 @@ OpenGlTexture::OpenGlTexture() :
bind();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

View file

@ -116,7 +116,6 @@ void Scene::render(Gfx::RenderEntryArray renderEntries) {
// draw actors
// draw overlay
_gfx->setScreenViewport();
}
} // End of namespace Stark

View file

@ -162,8 +162,10 @@ void DialogPlayer::clearSubtitles() {
}
void DialogPlayer::renderText() {
if (_texture) {
Gfx::Driver *gfx = StarkServices::instance().gfx;
gfx->setScreenViewport(false);
gfx->drawSurface(_texture, Common::Point(10, 400));
}
}

View file

@ -80,6 +80,8 @@ void UserInterface::scrollLocation(int32 dX, int32 dY) {
}
void UserInterface::render() {
// TODO: Move this elsewhere
Common::String debugStr;
Global *global = StarkServices::instance().global;
@ -93,7 +95,10 @@ void UserInterface::render() {
Gfx::Texture *debugTexture = _gfx->createTextureFromString(debugStr, 0xF0FF0F00);
_gfx->setScreenViewport(false);
_gfx->drawSurface(debugTexture, Common::Point(0,0));
delete debugTexture;
}

View file

@ -94,7 +94,7 @@ Common::Error StarkEngine::run() {
_gfx = Gfx::Driver::create();
// Get the screen prepared
_gfx->setupScreen(640, 480, ConfMan.getBool("fullscreen"));
_gfx->init();
_archiveLoader = new ArchiveLoader();
_stateProvider = new StateProvider();
@ -207,7 +207,8 @@ void StarkEngine::updateDisplayScene() {
bool StarkEngine::hasFeature(EngineFeature f) const {
return
(f == kSupportsLoadingDuringRuntime) ||
(f == kSupportsSavingDuringRuntime);
(f == kSupportsSavingDuringRuntime) ||
(f == kSupportsArbitraryResolutions);
}
bool StarkEngine::canLoadGameStateCurrently() {