Window size handling
Do the job, but need more control over resize limit
This commit is contained in:
parent
6c44133074
commit
db830a2a4e
@ -21,10 +21,12 @@
|
||||
// * https://www.coranac.com/tonc/text/mode7.htm
|
||||
|
||||
Graphic3DRenderer::Graphic3DRenderer() {
|
||||
mRTSize = {1280.f, 324.f};
|
||||
|
||||
if (mMainCamera == nullptr) {
|
||||
mMainCamera = std::make_unique<Camera>();
|
||||
mMainCamera->SetPosition(0.0f, 1.5f, -8.0f);
|
||||
mMainCamera->SetFrustrum(90.0f, 1280.f/324.f, 1.0f, 100.f);
|
||||
mMainCamera->SetFrustrum(90.0f, mRTSize.x/mRTSize.y, 1.0f, 100.f);
|
||||
mMainCamera->UpdateCamView();
|
||||
}
|
||||
|
||||
@ -46,6 +48,11 @@ Graphic3DRenderer::Graphic3DRenderer() {
|
||||
|
||||
Graphic3DRenderer::~Graphic3DRenderer() {}
|
||||
|
||||
void Graphic3DRenderer::SetRTSize(unsigned int w, unsigned int h) {
|
||||
mRTSize.x = w; mRTSize.y = h;
|
||||
mMainCamera->SetFrustrum(90.0f, mRTSize.x/mRTSize.y, 1.0f, 100.f);
|
||||
}
|
||||
|
||||
void Graphic3DRenderer::UpdateCamera(CAMERA_MOVE type, const float value) {
|
||||
switch (type) {
|
||||
case CAMERA_MOVE_WALK:
|
||||
@ -129,9 +136,9 @@ void Graphic3DRenderer::Draw(sf::RenderTexture& context) {
|
||||
M3D_VECTOR V2 = M3D_V4LoadF3(&(projVertices + processedVerticesCnt)[indicePtr[i+1]]);
|
||||
M3D_VECTOR V3 = M3D_V4LoadF3(&(projVertices + processedVerticesCnt)[indicePtr[i+2]]);
|
||||
|
||||
V1 = M3D_V3TransformNDCToViewport(V1, 0.f, 0.f, 1280.f, 324.f, 1.f, 100.f);
|
||||
V2 = M3D_V3TransformNDCToViewport(V2, 0.f, 0.f, 1280.f, 324.f, 1.f, 100.f);
|
||||
V3 = M3D_V3TransformNDCToViewport(V3, 0.f, 0.f, 1280.f, 324.f, 1.f, 100.f);
|
||||
V1 = M3D_V3TransformNDCToViewport(V1, 0.f, 0.f, mRTSize.x, mRTSize.y, 1.f, 100.f);
|
||||
V2 = M3D_V3TransformNDCToViewport(V2, 0.f, 0.f, mRTSize.x, mRTSize.y, 1.f, 100.f);
|
||||
V3 = M3D_V3TransformNDCToViewport(V3, 0.f, 0.f, mRTSize.x, mRTSize.y, 1.f, 100.f);
|
||||
|
||||
v_tri[0].position = sf::Vector2f(M3D_V4GetX(V1), M3D_V4GetY(V1));
|
||||
v_tri[0].color = oMesh.vertices[indicePtr[i]].color;
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <SFML/Graphics/RenderTexture.hpp>
|
||||
#include <SFML/System/Vector2.hpp>
|
||||
|
||||
#include "Camera.hpp"
|
||||
#include "../Utils/MeshHelper.hpp"
|
||||
@ -25,11 +26,15 @@ public:
|
||||
Graphic3DRenderer(Graphic3DRenderer const&) = delete;
|
||||
Graphic3DRenderer& operator= (Graphic3DRenderer const&) = delete;
|
||||
|
||||
const sf::Vector2f& GetRTSize() const noexcept { return mRTSize; }
|
||||
void SetRTSize(unsigned int w, unsigned int h);
|
||||
|
||||
void UpdateCamera(CAMERA_MOVE type, const float value);
|
||||
void Draw(sf::RenderTexture& context);
|
||||
|
||||
private:
|
||||
std::unique_ptr<Camera> mMainCamera; // Default player view
|
||||
sf::Vector2f mRTSize;
|
||||
|
||||
std::vector<std::shared_ptr<WorldObject>> mRenderList; // List of elements to be rendered next frame
|
||||
|
||||
|
@ -2,37 +2,49 @@
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <SFML/System/Vector2.hpp>
|
||||
#include <SFML/Graphics/Texture.hpp>
|
||||
#include <SFML/Graphics/Sprite.hpp>
|
||||
#include <SFML/Graphics/BlendMode.hpp>
|
||||
#include <SFML/Graphics/RenderStates.hpp>
|
||||
#include <SFML/Window/ContextSettings.hpp>
|
||||
|
||||
#include <SFML/Graphics/RectangleShape.hpp>
|
||||
#include <SFML/Graphics/CircleShape.hpp>
|
||||
|
||||
|
||||
void UI::DrawUIOnRenderWindow(std::shared_ptr<sf::RenderWindow> context) {
|
||||
sf::Sprite spriteRender;
|
||||
spriteRender.setTexture(this->mUIRender.getTexture());
|
||||
spriteRender.setPosition(0.0f, 0.0f);
|
||||
spriteRender.setScale(1.0f, 1.0f);
|
||||
context->draw(spriteRender);
|
||||
void UI::SetRTSize(unsigned int w, unsigned int h, bool recreateCanvas) {
|
||||
mRTSize.x = w; mRTSize.y = h;
|
||||
|
||||
// Don't resize/recreate canvas, this cut the fixed sprite
|
||||
//TODO: use scaling feature on the assets to put on the canvas, then resize the canvas
|
||||
if (recreateCanvas)
|
||||
CreateDefaultRenderWindow();
|
||||
}
|
||||
|
||||
|
||||
CockpitUI::CockpitUI() : UI() {
|
||||
void UI::CreateDefaultRenderWindow() {
|
||||
sf::ContextSettings sViewSettings;
|
||||
sViewSettings.depthBits = 0;
|
||||
sViewSettings.stencilBits = 0;
|
||||
sViewSettings.antialiasingLevel = 8;
|
||||
sViewSettings.sRgbCapable = true;
|
||||
|
||||
if (!mUIRender.create(1280, 720, sViewSettings))
|
||||
if (!mUIRender.create(mRTSize.x, mRTSize.y, sViewSettings))
|
||||
throw std::runtime_error("Texture renderer creation failure");
|
||||
|
||||
mUIRender.setSmooth(true);
|
||||
mUIRender.setRepeated(false);
|
||||
}
|
||||
|
||||
void UI::DrawUIOnRenderWindow(std::shared_ptr<sf::RenderWindow> context, float& viewX, float& viewY) {
|
||||
sf::Sprite spriteRender;
|
||||
spriteRender.setTexture(this->mUIRender.getTexture());
|
||||
spriteRender.setPosition(0.0f, 0.0f);
|
||||
spriteRender.setScale(mRTSize.x / viewX, mRTSize.y / viewY);
|
||||
context->draw(spriteRender);
|
||||
}
|
||||
|
||||
|
||||
CockpitUI::CockpitUI(unsigned int w, unsigned int h) : UI(w, h) {
|
||||
CreateDefaultRenderWindow();
|
||||
|
||||
mStaticCockpitTexture.setSrgb(true);
|
||||
if (!mStaticCockpitTexture.loadFromFile("cockpit_ui_empty_rescaled.png", sf::IntRect(0, 0, 1280, 780)))
|
||||
@ -65,24 +77,15 @@ void CockpitUI::Draw(std::shared_ptr<sf::RenderWindow> context) {
|
||||
mUIRender.display();
|
||||
|
||||
// OnScreen rendering
|
||||
DrawUIOnRenderWindow(context);
|
||||
auto tvSize = sf::Vector2f(1280.f, 720.f);
|
||||
DrawUIOnRenderWindow(context, tvSize);
|
||||
}
|
||||
|
||||
|
||||
WorldUI::WorldUI(std::shared_ptr<Graphic3DRenderer> engineInstance) : UI(), mWorld3D(engineInstance) {
|
||||
sf::ContextSettings sViewSettings;
|
||||
sViewSettings.depthBits = 0;
|
||||
sViewSettings.stencilBits = 0;
|
||||
sViewSettings.antialiasingLevel = 8;
|
||||
sViewSettings.sRgbCapable = true;
|
||||
WorldUI::WorldUI(unsigned int w, unsigned int h, std::shared_ptr<Graphic3DRenderer> engineInstance) : UI(w, h), mWorld3D(engineInstance) {
|
||||
CreateDefaultRenderWindow();
|
||||
|
||||
if (!mUIRender.create(1280, 324, sViewSettings)) // Only the upper of the screen is renderer as the UI hide whats left.
|
||||
throw std::runtime_error("Texture renderer creation failure");
|
||||
|
||||
mUIRender.setSmooth(true);
|
||||
mUIRender.setRepeated(false);
|
||||
mUIRender.clear(sf::Color::Black);
|
||||
|
||||
mUIRender.display();
|
||||
}
|
||||
|
||||
@ -104,5 +107,5 @@ void WorldUI::Draw(std::shared_ptr<sf::RenderWindow> context) {
|
||||
mUIRender.display();
|
||||
|
||||
// OnScreen rendering
|
||||
DrawUIOnRenderWindow(context);
|
||||
UI::Draw(context);
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <SFML/System/Vector2.hpp>
|
||||
#include <SFML/Graphics/RenderTexture.hpp>
|
||||
#include <SFML/Graphics/RenderWindow.hpp>
|
||||
|
||||
@ -10,13 +11,23 @@ class UI {
|
||||
public:
|
||||
virtual ~UI() = 0;
|
||||
|
||||
const sf::Vector2f& GetRTSize() const noexcept { return mRTSize; }
|
||||
void SetRTSize(unsigned int w, unsigned int h, bool recreateCanvas = false);
|
||||
|
||||
virtual void Update() = 0;
|
||||
virtual inline void Draw(std::shared_ptr<sf::RenderWindow> c) { DrawUIOnRenderWindow(c); }
|
||||
|
||||
protected:
|
||||
UI(unsigned int w, unsigned int h) : mRTSize(sf::Vector2f(w, h)) {}
|
||||
UI(sf::Vector2f size) : mRTSize(size) {}
|
||||
|
||||
sf::Vector2f mRTSize;
|
||||
sf::RenderTexture mUIRender; // The screen to draw onto
|
||||
|
||||
void DrawUIOnRenderWindow(std::shared_ptr<sf::RenderWindow> context);
|
||||
void CreateDefaultRenderWindow();
|
||||
void DrawUIOnRenderWindow(std::shared_ptr<sf::RenderWindow> context, float& viewX, float& viewY);
|
||||
inline void DrawUIOnRenderWindow(std::shared_ptr<sf::RenderWindow> context) { DrawUIOnRenderWindow(context, mRTSize); }
|
||||
inline void DrawUIOnRenderWindow(std::shared_ptr<sf::RenderWindow> context, sf::Vector2f& view) { DrawUIOnRenderWindow(context, view.x, view.y); }
|
||||
|
||||
};
|
||||
|
||||
@ -24,7 +35,7 @@ inline UI::~UI() {}
|
||||
|
||||
class CockpitUI final : public UI {
|
||||
public:
|
||||
CockpitUI();
|
||||
CockpitUI(unsigned int w, unsigned int h);
|
||||
~CockpitUI() {}
|
||||
|
||||
CockpitUI(CockpitUI&&) = default;
|
||||
@ -42,7 +53,7 @@ private:
|
||||
|
||||
class WorldUI final : public UI {
|
||||
public:
|
||||
WorldUI(std::shared_ptr<Graphic3DRenderer> engineInstance);
|
||||
WorldUI(unsigned int w, unsigned int h, std::shared_ptr<Graphic3DRenderer> engineInstance);
|
||||
~WorldUI() {}
|
||||
|
||||
WorldUI(WorldUI&&) = default;
|
||||
|
15
Game.cpp
15
Game.cpp
@ -11,15 +11,16 @@
|
||||
using std::make_shared;
|
||||
using std::make_unique;
|
||||
|
||||
#define TARGET_FPS (60)
|
||||
|
||||
|
||||
Game* Game::smInstance = nullptr;
|
||||
|
||||
Game::Game(std::shared_ptr<sf::RenderWindow> mainWnd, bool dbgFlag) : mbDbgModeEnabled(dbgFlag), mMainWindow(mainWnd) {
|
||||
unsigned int wndWidth, wndHeight;
|
||||
GetDefaultWindowSize(wndWidth, wndHeight);
|
||||
|
||||
mWorld3D = make_shared<Graphic3DRenderer>();
|
||||
mCockpitUI = make_unique<CockpitUI>();
|
||||
mWorldUI = make_unique<WorldUI>(mWorld3D);
|
||||
mCockpitUI = make_unique<CockpitUI>(wndWidth, (wndWidth * H_RATIO));
|
||||
mWorldUI = make_unique<WorldUI>(wndWidth, std::floor((wndWidth * H_RATIO) * 0.45f), mWorld3D);
|
||||
|
||||
if (mbDbgModeEnabled) {
|
||||
mDbgUI = make_unique<DebugUI>();
|
||||
@ -92,6 +93,12 @@ void Game::EventMouseMoved(int _x, int _y) {
|
||||
mPrevMousePos.y = _y;
|
||||
}
|
||||
|
||||
void Game::EventWindowSizeChanged(unsigned int w, unsigned int h) {
|
||||
mCockpitUI->SetRTSize(static_cast<float>(w), (w * H_RATIO));
|
||||
mWorldUI->SetRTSize(static_cast<float>(w), std::floor((w * H_RATIO) * 0.45f), true);
|
||||
mWorld3D->SetRTSize(static_cast<float>(w), std::floor((w * H_RATIO) * 0.45f));
|
||||
}
|
||||
|
||||
void Game::Update() {
|
||||
// Refresh keyboard inputs
|
||||
KeyboardInputsCheck();
|
||||
|
11
Game.hpp
11
Game.hpp
@ -7,6 +7,12 @@
|
||||
#include "Engine/Graphics/3DRenderer.hpp"
|
||||
#include "Engine/Utils/Timers.hpp"
|
||||
|
||||
#define WNDSIZE_DEFAULT_W (1280)
|
||||
#define WNDSIZE_DEFAULT_H (720)
|
||||
#define W_RATIO (16.f / 9.f)
|
||||
#define H_RATIO (9.f / 16.f)
|
||||
#define TARGET_FPS (60)
|
||||
|
||||
|
||||
typedef enum eGameStatus {
|
||||
GAME_INIT,
|
||||
@ -30,8 +36,13 @@ public:
|
||||
Game(Game const&) = delete;
|
||||
Game& operator= (Game const&) = delete;
|
||||
|
||||
static void GetDefaultWindowSize(unsigned int& w, unsigned int& h) noexcept {
|
||||
w = WNDSIZE_DEFAULT_W; h = WNDSIZE_DEFAULT_H;
|
||||
}
|
||||
|
||||
GAME_STATUS Tick();
|
||||
void EventMouseMoved(int _x, int _y);
|
||||
void EventWindowSizeChanged(unsigned int w, unsigned int h);
|
||||
|
||||
private:
|
||||
Game(std::shared_ptr<sf::RenderWindow> mainWnd, bool dbgFlag) noexcept(false);
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <SFML/Window/Event.hpp>
|
||||
#include <SFML/Graphics/RenderWindow.hpp>
|
||||
#include <SFML/Window/ContextSettings.hpp>
|
||||
#include <SFML/System/Vector2.hpp>
|
||||
|
||||
#include "icon.h"
|
||||
#include "Engine/Misc/Logger.hpp"
|
||||
@ -9,15 +10,28 @@
|
||||
#include "Game.hpp"
|
||||
|
||||
|
||||
static std::shared_ptr<sf::RenderWindow> InitWindow(unsigned int width, unsigned int height, bool fullscreen);
|
||||
struct MainWindowParams {
|
||||
sf::Vector2u wndSize = {0, 0}; // Ignored on fullscreen mode
|
||||
sf::ContextSettings wndContextSettings;
|
||||
bool wndFullscreen = false;
|
||||
};
|
||||
|
||||
static void CreateWindow(std::shared_ptr<sf::RenderWindow> wnd, MainWindowParams& params);
|
||||
//static void ForceWindowRatio(sf::RenderWindow* wnd);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
Logger& log = Logger::getInstance();
|
||||
|
||||
log.PrintInfo(LOGGER_MSG_FT("Create main window"));
|
||||
std::shared_ptr<sf::RenderWindow> mainWindow = nullptr;
|
||||
MainWindowParams wndParams;
|
||||
Game::GetDefaultWindowSize(wndParams.wndSize.x, wndParams.wndSize.y);
|
||||
wndParams.wndContextSettings.depthBits = 0;
|
||||
wndParams.wndContextSettings.stencilBits = 0;
|
||||
wndParams.wndContextSettings.antialiasingLevel = 8;
|
||||
wndParams.wndContextSettings.sRgbCapable = true;
|
||||
auto mainWindow = std::make_shared<sf::RenderWindow>();
|
||||
try {
|
||||
mainWindow = InitWindow(1280, 720, false);
|
||||
CreateWindow(mainWindow, wndParams);
|
||||
} catch (const std::exception& ex) {
|
||||
log.PrintCritical(std::string(ex.what()));
|
||||
return EXIT_FAILURE;
|
||||
@ -30,6 +44,7 @@ int main(int argc, char** argv) {
|
||||
Game& arcadeGame = Game::getInstance(mainWindow, false);
|
||||
#endif
|
||||
GAME_STATUS status = GAME_INIT;
|
||||
sf::FloatRect visibleArea(0, 0, WNDSIZE_DEFAULT_W, WNDSIZE_DEFAULT_H);
|
||||
|
||||
for ( ;; ) {
|
||||
sf::Event event;
|
||||
@ -40,9 +55,11 @@ int main(int argc, char** argv) {
|
||||
break;
|
||||
|
||||
case sf::Event::Resized:
|
||||
//TODO: Recreate window related resource
|
||||
//event.size.width
|
||||
//event.size.height
|
||||
visibleArea.width = event.size.width;
|
||||
visibleArea.height = event.size.height;
|
||||
mainWindow->setView(sf::View(visibleArea)); // Adapt the view resolution
|
||||
arcadeGame.EventWindowSizeChanged(event.size.width, event.size.height);
|
||||
//ForceWindowRatio(mainWindow.get());
|
||||
break;
|
||||
|
||||
//case sf::Event::LostFocus:
|
||||
@ -73,6 +90,16 @@ int main(int argc, char** argv) {
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) {
|
||||
mainWindow->close();
|
||||
status = GAME_QUIT;
|
||||
} else if ((sf::Keyboard::isKeyPressed(sf::Keyboard::LAlt) || sf::Keyboard::isKeyPressed(sf::Keyboard::RAlt)) && sf::Keyboard::isKeyPressed(sf::Keyboard::Enter)) {
|
||||
wndParams.wndFullscreen = !wndParams.wndFullscreen;
|
||||
try {
|
||||
CreateWindow(mainWindow, wndParams);
|
||||
} catch (const std::exception& ex) {
|
||||
log.PrintCritical(std::string(ex.what()));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
arcadeGame.EventWindowSizeChanged(mainWindow->getSize().x, mainWindow->getSize().y);
|
||||
}
|
||||
|
||||
status = arcadeGame.Tick();
|
||||
@ -85,32 +112,45 @@ int main(int argc, char** argv) {
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static std::shared_ptr<sf::RenderWindow> InitWindow(unsigned int width, unsigned int height, bool fullscreen) {
|
||||
// Create default game window
|
||||
sf::ContextSettings sWindowSettings;
|
||||
sWindowSettings.depthBits = 0;
|
||||
sWindowSettings.stencilBits = 0;
|
||||
sWindowSettings.antialiasingLevel = 8;
|
||||
sWindowSettings.sRgbCapable = true;
|
||||
|
||||
static void CreateWindow(std::shared_ptr<sf::RenderWindow> wnd, MainWindowParams& params) {
|
||||
sf::Uint32 wndStyle = sf::Style::Close | sf::Style::Titlebar;
|
||||
if(fullscreen)
|
||||
wndStyle = wndStyle | sf::Style::Fullscreen;
|
||||
|
||||
auto wnd = std::make_shared<sf::RenderWindow>(
|
||||
sf::VideoMode(width, height), "ProtoTank",
|
||||
wndStyle,
|
||||
sWindowSettings
|
||||
);
|
||||
sf::VideoMode vMode;
|
||||
|
||||
if (wnd == nullptr)
|
||||
throw std::runtime_error("Failed to create the window");
|
||||
throw std::invalid_argument("Failed to create the window");
|
||||
|
||||
if (params.wndFullscreen) {
|
||||
vMode = sf::VideoMode::getFullscreenModes().front();
|
||||
wndStyle = sf::Style::Fullscreen;
|
||||
} else {
|
||||
vMode = sf::VideoMode(params.wndSize.x, params.wndSize.y);
|
||||
wndStyle = sf::Style::Close | sf::Style::Titlebar | sf::Style::Resize;
|
||||
}
|
||||
/*if(mode == BORDERLESS) {
|
||||
//vMode = sf::VideoMode::getFullscreenModes().front();
|
||||
//vMode = sf::VideoMode(params.wndSize.x, params.wndSize.y);
|
||||
vMode = sf::VideoMode::getDesktopMode();
|
||||
wndStyle = sf::Style::None;
|
||||
}*/
|
||||
|
||||
wnd->create(vMode, "ProtoTank", wndStyle, params.wndContextSettings);
|
||||
|
||||
wnd->setVerticalSyncEnabled(false); // Never use simultaneously with framerate limiter
|
||||
wnd->setFramerateLimit(60); // Never use simultaneously with VSync
|
||||
wnd->setKeyRepeatEnabled(false);
|
||||
wnd->setMouseCursorVisible(true);
|
||||
wnd->setIcon(64, 64, _aicon_bin);
|
||||
|
||||
return wnd;
|
||||
}
|
||||
|
||||
/*
|
||||
inline static void ForceWindowRatio(sf::RenderWindow* wnd) {
|
||||
auto wndSize = wnd->getSize();
|
||||
|
||||
if (wndSize.y * W_RATIO <= wndSize.x)
|
||||
wndSize.x = wndSize.y * W_RATIO;
|
||||
else if (wndSize.x * H_RATIO <= wndSize.y)
|
||||
wndSize.y = wndSize.x * H_RATIO;
|
||||
|
||||
wnd->setSize(wndSize);
|
||||
}
|
||||
*/
|
Loading…
x
Reference in New Issue
Block a user