Window size handling

Do the job, but need more control over resize limit
This commit is contained in:
JackCarterSmith 2024-10-29 19:14:17 +01:00
parent 6c44133074
commit db830a2a4e
Signed by: JackCarterSmith
GPG Key ID: 832E52F4E23F8F24
7 changed files with 145 additions and 61 deletions

View File

@ -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;

View File

@ -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

View File

@ -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);
}

View File

@ -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;

View File

@ -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();

View File

@ -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);

View File

@ -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);
}
*/