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 // * https://www.coranac.com/tonc/text/mode7.htm
Graphic3DRenderer::Graphic3DRenderer() { Graphic3DRenderer::Graphic3DRenderer() {
mRTSize = {1280.f, 324.f};
if (mMainCamera == nullptr) { if (mMainCamera == nullptr) {
mMainCamera = std::make_unique<Camera>(); mMainCamera = std::make_unique<Camera>();
mMainCamera->SetPosition(0.0f, 1.5f, -8.0f); 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(); mMainCamera->UpdateCamView();
} }
@ -46,6 +48,11 @@ Graphic3DRenderer::Graphic3DRenderer() {
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) { void Graphic3DRenderer::UpdateCamera(CAMERA_MOVE type, const float value) {
switch (type) { switch (type) {
case CAMERA_MOVE_WALK: 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 V2 = M3D_V4LoadF3(&(projVertices + processedVerticesCnt)[indicePtr[i+1]]);
M3D_VECTOR V3 = M3D_V4LoadF3(&(projVertices + processedVerticesCnt)[indicePtr[i+2]]); 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); V1 = M3D_V3TransformNDCToViewport(V1, 0.f, 0.f, mRTSize.x, mRTSize.y, 1.f, 100.f);
V2 = M3D_V3TransformNDCToViewport(V2, 0.f, 0.f, 1280.f, 324.f, 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, 1280.f, 324.f, 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].position = sf::Vector2f(M3D_V4GetX(V1), M3D_V4GetY(V1));
v_tri[0].color = oMesh.vertices[indicePtr[i]].color; v_tri[0].color = oMesh.vertices[indicePtr[i]].color;

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <SFML/Graphics/RenderTexture.hpp> #include <SFML/Graphics/RenderTexture.hpp>
#include <SFML/System/Vector2.hpp>
#include "Camera.hpp" #include "Camera.hpp"
#include "../Utils/MeshHelper.hpp" #include "../Utils/MeshHelper.hpp"
@ -25,11 +26,15 @@ public:
Graphic3DRenderer(Graphic3DRenderer const&) = delete; Graphic3DRenderer(Graphic3DRenderer const&) = delete;
Graphic3DRenderer& operator= (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 UpdateCamera(CAMERA_MOVE type, const float value);
void Draw(sf::RenderTexture& context); void Draw(sf::RenderTexture& context);
private: private:
std::unique_ptr<Camera> mMainCamera; // Default player view 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 std::vector<std::shared_ptr<WorldObject>> mRenderList; // List of elements to be rendered next frame

View File

@ -2,37 +2,49 @@
#include <stdexcept> #include <stdexcept>
#include <SFML/System/Vector2.hpp>
#include <SFML/Graphics/Texture.hpp> #include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/Sprite.hpp> #include <SFML/Graphics/Sprite.hpp>
#include <SFML/Graphics/BlendMode.hpp> #include <SFML/Graphics/BlendMode.hpp>
#include <SFML/Graphics/RenderStates.hpp> #include <SFML/Graphics/RenderStates.hpp>
#include <SFML/Window/ContextSettings.hpp>
#include <SFML/Graphics/RectangleShape.hpp>
#include <SFML/Graphics/CircleShape.hpp> #include <SFML/Graphics/CircleShape.hpp>
void UI::DrawUIOnRenderWindow(std::shared_ptr<sf::RenderWindow> context) { void UI::SetRTSize(unsigned int w, unsigned int h, bool recreateCanvas) {
sf::Sprite spriteRender; mRTSize.x = w; mRTSize.y = h;
spriteRender.setTexture(this->mUIRender.getTexture());
spriteRender.setPosition(0.0f, 0.0f); // Don't resize/recreate canvas, this cut the fixed sprite
spriteRender.setScale(1.0f, 1.0f); //TODO: use scaling feature on the assets to put on the canvas, then resize the canvas
context->draw(spriteRender); if (recreateCanvas)
CreateDefaultRenderWindow();
} }
void UI::CreateDefaultRenderWindow() {
CockpitUI::CockpitUI() : UI() {
sf::ContextSettings sViewSettings; sf::ContextSettings sViewSettings;
sViewSettings.depthBits = 0; sViewSettings.depthBits = 0;
sViewSettings.stencilBits = 0; sViewSettings.stencilBits = 0;
sViewSettings.antialiasingLevel = 8; sViewSettings.antialiasingLevel = 8;
sViewSettings.sRgbCapable = true; 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"); throw std::runtime_error("Texture renderer creation failure");
mUIRender.setSmooth(true); mUIRender.setSmooth(true);
mUIRender.setRepeated(false); 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); mStaticCockpitTexture.setSrgb(true);
if (!mStaticCockpitTexture.loadFromFile("cockpit_ui_empty_rescaled.png", sf::IntRect(0, 0, 1280, 780))) 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(); mUIRender.display();
// OnScreen rendering // 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) { WorldUI::WorldUI(unsigned int w, unsigned int h, std::shared_ptr<Graphic3DRenderer> engineInstance) : UI(w, h), mWorld3D(engineInstance) {
sf::ContextSettings sViewSettings; CreateDefaultRenderWindow();
sViewSettings.depthBits = 0;
sViewSettings.stencilBits = 0;
sViewSettings.antialiasingLevel = 8;
sViewSettings.sRgbCapable = true;
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.clear(sf::Color::Black);
mUIRender.display(); mUIRender.display();
} }
@ -104,5 +107,5 @@ void WorldUI::Draw(std::shared_ptr<sf::RenderWindow> context) {
mUIRender.display(); mUIRender.display();
// OnScreen rendering // OnScreen rendering
DrawUIOnRenderWindow(context); UI::Draw(context);
} }

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <SFML/System/Vector2.hpp>
#include <SFML/Graphics/RenderTexture.hpp> #include <SFML/Graphics/RenderTexture.hpp>
#include <SFML/Graphics/RenderWindow.hpp> #include <SFML/Graphics/RenderWindow.hpp>
@ -10,13 +11,23 @@ class UI {
public: public:
virtual ~UI() = 0; 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 void Update() = 0;
virtual inline void Draw(std::shared_ptr<sf::RenderWindow> c) { DrawUIOnRenderWindow(c); } virtual inline void Draw(std::shared_ptr<sf::RenderWindow> c) { DrawUIOnRenderWindow(c); }
protected: 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 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 { class CockpitUI final : public UI {
public: public:
CockpitUI(); CockpitUI(unsigned int w, unsigned int h);
~CockpitUI() {} ~CockpitUI() {}
CockpitUI(CockpitUI&&) = default; CockpitUI(CockpitUI&&) = default;
@ -42,7 +53,7 @@ private:
class WorldUI final : public UI { class WorldUI final : public UI {
public: public:
WorldUI(std::shared_ptr<Graphic3DRenderer> engineInstance); WorldUI(unsigned int w, unsigned int h, std::shared_ptr<Graphic3DRenderer> engineInstance);
~WorldUI() {} ~WorldUI() {}
WorldUI(WorldUI&&) = default; WorldUI(WorldUI&&) = default;

View File

@ -11,15 +11,16 @@
using std::make_shared; using std::make_shared;
using std::make_unique; using std::make_unique;
#define TARGET_FPS (60)
Game* Game::smInstance = nullptr; Game* Game::smInstance = nullptr;
Game::Game(std::shared_ptr<sf::RenderWindow> mainWnd, bool dbgFlag) : mbDbgModeEnabled(dbgFlag), mMainWindow(mainWnd) { 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>(); mWorld3D = make_shared<Graphic3DRenderer>();
mCockpitUI = make_unique<CockpitUI>(); mCockpitUI = make_unique<CockpitUI>(wndWidth, (wndWidth * H_RATIO));
mWorldUI = make_unique<WorldUI>(mWorld3D); mWorldUI = make_unique<WorldUI>(wndWidth, std::floor((wndWidth * H_RATIO) * 0.45f), mWorld3D);
if (mbDbgModeEnabled) { if (mbDbgModeEnabled) {
mDbgUI = make_unique<DebugUI>(); mDbgUI = make_unique<DebugUI>();
@ -92,6 +93,12 @@ void Game::EventMouseMoved(int _x, int _y) {
mPrevMousePos.y = _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() { void Game::Update() {
// Refresh keyboard inputs // Refresh keyboard inputs
KeyboardInputsCheck(); KeyboardInputsCheck();

View File

@ -7,6 +7,12 @@
#include "Engine/Graphics/3DRenderer.hpp" #include "Engine/Graphics/3DRenderer.hpp"
#include "Engine/Utils/Timers.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 { typedef enum eGameStatus {
GAME_INIT, GAME_INIT,
@ -30,8 +36,13 @@ public:
Game(Game const&) = delete; Game(Game const&) = delete;
Game& operator= (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(); GAME_STATUS Tick();
void EventMouseMoved(int _x, int _y); void EventMouseMoved(int _x, int _y);
void EventWindowSizeChanged(unsigned int w, unsigned int h);
private: private:
Game(std::shared_ptr<sf::RenderWindow> mainWnd, bool dbgFlag) noexcept(false); Game(std::shared_ptr<sf::RenderWindow> mainWnd, bool dbgFlag) noexcept(false);

View File

@ -2,6 +2,7 @@
#include <SFML/Window/Event.hpp> #include <SFML/Window/Event.hpp>
#include <SFML/Graphics/RenderWindow.hpp> #include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Window/ContextSettings.hpp> #include <SFML/Window/ContextSettings.hpp>
#include <SFML/System/Vector2.hpp>
#include "icon.h" #include "icon.h"
#include "Engine/Misc/Logger.hpp" #include "Engine/Misc/Logger.hpp"
@ -9,15 +10,28 @@
#include "Game.hpp" #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) { int main(int argc, char** argv) {
Logger& log = Logger::getInstance(); Logger& log = Logger::getInstance();
log.PrintInfo(LOGGER_MSG_FT("Create main window")); 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 { try {
mainWindow = InitWindow(1280, 720, false); CreateWindow(mainWindow, wndParams);
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
log.PrintCritical(std::string(ex.what())); log.PrintCritical(std::string(ex.what()));
return EXIT_FAILURE; return EXIT_FAILURE;
@ -30,6 +44,7 @@ int main(int argc, char** argv) {
Game& arcadeGame = Game::getInstance(mainWindow, false); Game& arcadeGame = Game::getInstance(mainWindow, false);
#endif #endif
GAME_STATUS status = GAME_INIT; GAME_STATUS status = GAME_INIT;
sf::FloatRect visibleArea(0, 0, WNDSIZE_DEFAULT_W, WNDSIZE_DEFAULT_H);
for ( ;; ) { for ( ;; ) {
sf::Event event; sf::Event event;
@ -40,9 +55,11 @@ int main(int argc, char** argv) {
break; break;
case sf::Event::Resized: case sf::Event::Resized:
//TODO: Recreate window related resource visibleArea.width = event.size.width;
//event.size.width visibleArea.height = event.size.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; break;
//case sf::Event::LostFocus: //case sf::Event::LostFocus:
@ -73,6 +90,16 @@ int main(int argc, char** argv) {
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) { if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) {
mainWindow->close(); mainWindow->close();
status = GAME_QUIT; 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(); status = arcadeGame.Tick();
@ -85,32 +112,45 @@ int main(int argc, char** argv) {
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
static std::shared_ptr<sf::RenderWindow> InitWindow(unsigned int width, unsigned int height, bool fullscreen) { static void CreateWindow(std::shared_ptr<sf::RenderWindow> wnd, MainWindowParams& params) {
// Create default game window
sf::ContextSettings sWindowSettings;
sWindowSettings.depthBits = 0;
sWindowSettings.stencilBits = 0;
sWindowSettings.antialiasingLevel = 8;
sWindowSettings.sRgbCapable = true;
sf::Uint32 wndStyle = sf::Style::Close | sf::Style::Titlebar; sf::Uint32 wndStyle = sf::Style::Close | sf::Style::Titlebar;
if(fullscreen) sf::VideoMode vMode;
wndStyle = wndStyle | sf::Style::Fullscreen;
auto wnd = std::make_shared<sf::RenderWindow>(
sf::VideoMode(width, height), "ProtoTank",
wndStyle,
sWindowSettings
);
if (wnd == nullptr) 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->setVerticalSyncEnabled(false); // Never use simultaneously with framerate limiter
wnd->setFramerateLimit(60); // Never use simultaneously with VSync wnd->setFramerateLimit(60); // Never use simultaneously with VSync
wnd->setKeyRepeatEnabled(false); wnd->setKeyRepeatEnabled(false);
wnd->setMouseCursorVisible(true); wnd->setMouseCursorVisible(true);
wnd->setIcon(64, 64, _aicon_bin); 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);
}
*/