mirror of
https://github.com/Floriansylvain/SFMLplayground.git
synced 2026-08-19 11:43:24 +02:00
refac: rendering, debug overlay, & game mechanics
This commit is contained in:
@@ -1,39 +0,0 @@
|
|||||||
name: CI
|
|
||||||
|
|
||||||
on: [push, pull_request]
|
|
||||||
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
name: ${{ matrix.platform.name }} ${{ matrix.config.name }}
|
|
||||||
runs-on: ${{ matrix.platform.os }}
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
platform:
|
|
||||||
- { name: Windows VS2019, os: windows-2019 }
|
|
||||||
- { name: Windows VS2022, os: windows-2022 }
|
|
||||||
- { name: Linux GCC, os: ubuntu-latest }
|
|
||||||
- { name: Linux Clang, os: ubuntu-latest, flags: -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ }
|
|
||||||
- { name: macOS, os: macos-latest }
|
|
||||||
config:
|
|
||||||
- { name: Shared, flags: -DBUILD_SHARED_LIBS=TRUE }
|
|
||||||
- { name: Static, flags: -DBUILD_SHARED_LIBS=FALSE }
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Install Linux Dependencies
|
|
||||||
if: runner.os == 'Linux'
|
|
||||||
run: sudo apt-get update && sudo apt-get install libxrandr-dev libxcursor-dev libxi-dev libudev-dev libflac-dev libvorbis-dev libgl1-mesa-dev libegl1-mesa-dev libfreetype-dev
|
|
||||||
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Configure
|
|
||||||
run: cmake -B build ${{matrix.platform.flags}} ${{matrix.config.flags}}
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: cmake --build build --config Release
|
|
||||||
+9
-9
@@ -69,15 +69,15 @@ void Ball::updateColor() {
|
|||||||
constexpr float TRANSITION_SPEED = 0.05f;
|
constexpr float TRANSITION_SPEED = 0.05f;
|
||||||
|
|
||||||
sf::Color newColor;
|
sf::Color newColor;
|
||||||
newColor.r = static_cast<std::uint8_t>(static_cast<float>(currentColor.r) +
|
newColor.r = static_cast<std::uint8_t>(
|
||||||
TRANSITION_SPEED *
|
static_cast<float>(currentColor.r) +
|
||||||
(targetColor.r - currentColor.r));
|
TRANSITION_SPEED * static_cast<float>(targetColor.r - currentColor.r));
|
||||||
newColor.g = static_cast<std::uint8_t>(static_cast<float>(currentColor.g) +
|
newColor.g = static_cast<std::uint8_t>(
|
||||||
TRANSITION_SPEED *
|
static_cast<float>(currentColor.g) +
|
||||||
(targetColor.g - currentColor.g));
|
TRANSITION_SPEED * static_cast<float>(targetColor.g - currentColor.g));
|
||||||
newColor.b = static_cast<std::uint8_t>(static_cast<float>(currentColor.b) +
|
newColor.b = static_cast<std::uint8_t>(
|
||||||
TRANSITION_SPEED *
|
static_cast<float>(currentColor.b) +
|
||||||
(targetColor.b - currentColor.b));
|
TRANSITION_SPEED * static_cast<float>(targetColor.b - currentColor.b));
|
||||||
newColor.a = 255;
|
newColor.a = 255;
|
||||||
|
|
||||||
m_shape.setFillColor(newColor);
|
m_shape.setFillColor(newColor);
|
||||||
|
|||||||
+16
-24
@@ -43,36 +43,28 @@ void BatchRenderer::addBall(const Ball &ball) {
|
|||||||
const float radius = ball.getRadius();
|
const float radius = ball.getRadius();
|
||||||
const sf::Color color = ball.getColor();
|
const sf::Color color = ball.getColor();
|
||||||
|
|
||||||
sf::Vertex topLeft;
|
sf::Vertex vertices[4];
|
||||||
sf::Vertex topRight;
|
vertices[0].position = sf::Vector2f(position.x - radius, position.y - radius);
|
||||||
sf::Vertex bottomRight;
|
vertices[1].position = sf::Vector2f(position.x + radius, position.y - radius);
|
||||||
sf::Vertex bottomLeft;
|
vertices[2].position = sf::Vector2f(position.x + radius, position.y + radius);
|
||||||
|
vertices[3].position = sf::Vector2f(position.x - radius, position.y + radius);
|
||||||
topLeft.position = sf::Vector2f(position.x - radius, position.y - radius);
|
|
||||||
topRight.position = sf::Vector2f(position.x + radius, position.y - radius);
|
|
||||||
bottomRight.position = sf::Vector2f(position.x + radius, position.y + radius);
|
|
||||||
bottomLeft.position = sf::Vector2f(position.x - radius, position.y + radius);
|
|
||||||
|
|
||||||
const float xSize = static_cast<float>(m_circleTexture.getSize().x);
|
const float xSize = static_cast<float>(m_circleTexture.getSize().x);
|
||||||
const float ySize = static_cast<float>(m_circleTexture.getSize().y);
|
const float ySize = static_cast<float>(m_circleTexture.getSize().y);
|
||||||
|
vertices[0].texCoords = sf::Vector2f(0, 0);
|
||||||
|
vertices[1].texCoords = sf::Vector2f(xSize, 0);
|
||||||
|
vertices[2].texCoords = sf::Vector2f(xSize, ySize);
|
||||||
|
vertices[3].texCoords = sf::Vector2f(0, ySize);
|
||||||
|
|
||||||
topLeft.texCoords = sf::Vector2f(0, 0);
|
for (auto &v : vertices) v.color = color;
|
||||||
topRight.texCoords = sf::Vector2f(xSize, 0);
|
|
||||||
bottomRight.texCoords = sf::Vector2f(xSize, ySize);
|
|
||||||
bottomLeft.texCoords = sf::Vector2f(0, ySize);
|
|
||||||
|
|
||||||
topLeft.color = color;
|
m_vertices.append(vertices[0]);
|
||||||
topRight.color = color;
|
m_vertices.append(vertices[1]);
|
||||||
bottomRight.color = color;
|
m_vertices.append(vertices[2]);
|
||||||
bottomLeft.color = color;
|
|
||||||
|
|
||||||
m_vertices.append(topLeft);
|
m_vertices.append(vertices[0]);
|
||||||
m_vertices.append(topRight);
|
m_vertices.append(vertices[2]);
|
||||||
m_vertices.append(bottomRight);
|
m_vertices.append(vertices[3]);
|
||||||
|
|
||||||
m_vertices.append(topLeft);
|
|
||||||
m_vertices.append(bottomRight);
|
|
||||||
m_vertices.append(bottomLeft);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BatchRenderer::draw(sf::RenderWindow &window) const {
|
void BatchRenderer::draw(sf::RenderWindow &window) const {
|
||||||
|
|||||||
+3
-3
@@ -5,9 +5,9 @@ constexpr int WIDTH = 1920;
|
|||||||
constexpr int HEIGHT = 1080;
|
constexpr int HEIGHT = 1080;
|
||||||
constexpr float GRAVITY = 781.f;
|
constexpr float GRAVITY = 781.f;
|
||||||
constexpr float RESTITUTION = 0.8f;
|
constexpr float RESTITUTION = 0.8f;
|
||||||
constexpr float FRICTION = 0.9f;
|
constexpr float FRICTION = 0.99f;
|
||||||
constexpr float IMPULSE = 1000.f;
|
constexpr float IMPULSE = 1000.f;
|
||||||
constexpr float REST_PIXEL_VELOCITY = 2.0f;
|
constexpr float REST_PIXEL_VELOCITY = 2.0f;
|
||||||
constexpr float BALL_RADIUS = 50.f;
|
constexpr float BALL_RADIUS = 20.f;
|
||||||
constexpr unsigned BALL_QUANTITY = 10;
|
constexpr unsigned BALL_QUANTITY = 20;
|
||||||
} // namespace Constants
|
} // namespace Constants
|
||||||
|
|||||||
+1
-1
@@ -38,7 +38,7 @@ void DebugDraw::addVelocityLine(sf::VertexArray &lines, const Ball *ball) {
|
|||||||
const float velLength = VectorMath::length(velocity);
|
const float velLength = VectorMath::length(velocity);
|
||||||
const float clampedLength = std::max(0.f, std::min(velLength, 100.f));
|
const float clampedLength = std::max(0.f, std::min(velLength, 100.f));
|
||||||
|
|
||||||
addLine(lines, ballCenter, velocity, clampedLength, sf::Color::Red);
|
addLine(lines, ballCenter, velocity, clampedLength, sf::Color::Blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugDraw::drawBatchedLines(sf::RenderWindow &window,
|
void DebugDraw::drawBatchedLines(sf::RenderWindow &window,
|
||||||
|
|||||||
+36
-6
@@ -1,31 +1,61 @@
|
|||||||
#include "DebugOverlay.hpp"
|
#include "DebugOverlay.hpp"
|
||||||
|
|
||||||
|
#include <iomanip>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr float OVERLAY_MARGIN = 5.0f;
|
||||||
|
constexpr unsigned int FONT_SIZE = 18;
|
||||||
|
constexpr float AVG_UPDATE_INTERVAL = 0.5f;
|
||||||
|
constexpr float TEXT_UPDATE_INTERVAL = 0.05f;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
DebugOverlay::DebugOverlay(const std::string &fontPath)
|
DebugOverlay::DebugOverlay(const std::string &fontPath)
|
||||||
: m_font(fontPath), m_text(m_font) {
|
: m_font(fontPath), m_text(m_font) {
|
||||||
m_text.setCharacterSize(18);
|
m_text.setCharacterSize(FONT_SIZE);
|
||||||
m_text.setFillColor(sf::Color::White);
|
m_text.setFillColor(sf::Color::White);
|
||||||
m_text.setPosition(sf::Vector2f(5.f, 5.f));
|
m_text.setPosition({OVERLAY_MARGIN, OVERLAY_MARGIN});
|
||||||
|
m_frameTimeHistory.fill(0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugOverlay::update(const int drawCalls, const float timeScale,
|
void DebugOverlay::update(const int drawCalls, const float timeScale,
|
||||||
const sf::RenderWindow &window,
|
const sf::RenderWindow &window,
|
||||||
const size_t threadCount,
|
const size_t threadCount,
|
||||||
const size_t ballsPerThread) {
|
const size_t ballsPerThread) {
|
||||||
const float elapsed = m_fpsClock.restart().asSeconds();
|
const float frameTime = m_fpsClock.restart().asSeconds();
|
||||||
if (elapsed > 0.2f) m_fps = 1.f / elapsed;
|
|
||||||
|
m_frameTimeHistory[m_currentFrameIndex] = frameTime;
|
||||||
|
m_currentFrameIndex = (m_currentFrameIndex + 1) % FRAME_HISTORY_SIZE;
|
||||||
|
|
||||||
|
m_timeSinceLastAvgUpdate += frameTime;
|
||||||
|
if (m_timeSinceLastAvgUpdate >= AVG_UPDATE_INTERVAL) {
|
||||||
|
m_averageFrametime = 0.0f;
|
||||||
|
for (const float time : m_frameTimeHistory) m_averageFrametime += time;
|
||||||
|
m_averageFrametime /= FRAME_HISTORY_SIZE;
|
||||||
|
m_timeSinceLastAvgUpdate = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_timeSinceLastUpdate += frameTime;
|
||||||
|
if (m_timeSinceLastUpdate < TEXT_UPDATE_INTERVAL) return;
|
||||||
|
m_timeSinceLastUpdate = 0.0f;
|
||||||
|
|
||||||
const sf::Vector2i mousePos = sf::Mouse::getPosition(window);
|
const sf::Vector2i mousePos = sf::Mouse::getPosition(window);
|
||||||
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
|
|
||||||
oss << "Draw calls: " << drawCalls << "\n";
|
oss << "Draw calls: " << drawCalls << "\n";
|
||||||
oss << "Framerate: " << m_fps << " FPS\n";
|
|
||||||
oss << "Frame time: " << (elapsed * 1000.f) << " ms\n";
|
oss << std::fixed << std::setprecision(3);
|
||||||
|
oss << "Frame time: " << (frameTime * 1000.0f) << " ms\n";
|
||||||
|
oss << "Frame time (avg): " << (m_averageFrametime * 1000.0f) << " ms\n";
|
||||||
|
|
||||||
|
oss << std::defaultfloat << std::setprecision(6);
|
||||||
oss << "Mouse: " << mousePos.x << ", " << mousePos.y << "\n";
|
oss << "Mouse: " << mousePos.x << ", " << mousePos.y << "\n";
|
||||||
oss << "Time scale: " << timeScale << "\n";
|
oss << "Time scale: " << timeScale << "\n";
|
||||||
oss << "\nThreads: " << threadCount;
|
oss << "\nThreads: " << threadCount;
|
||||||
oss << "\nBalls per thread: " << ballsPerThread;
|
oss << "\nBalls per thread: " << ballsPerThread;
|
||||||
|
|
||||||
m_text.setString(oss.str());
|
m_text.setString(oss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,4 +19,11 @@ class DebugOverlay {
|
|||||||
sf::Text m_text;
|
sf::Text m_text;
|
||||||
sf::Clock m_fpsClock;
|
sf::Clock m_fpsClock;
|
||||||
float m_fps = 0.f;
|
float m_fps = 0.f;
|
||||||
|
float m_averageFrametime = 0.f;
|
||||||
|
float m_timeSinceLastAvgUpdate = 0.f;
|
||||||
|
float m_timeSinceLastUpdate = 0.f;
|
||||||
|
|
||||||
|
static constexpr size_t FRAME_HISTORY_SIZE = 60;
|
||||||
|
std::array<float, FRAME_HISTORY_SIZE> m_frameTimeHistory{};
|
||||||
|
size_t m_currentFrameIndex = 0u;
|
||||||
};
|
};
|
||||||
|
|||||||
+4
-2
@@ -25,7 +25,7 @@ Game::Game()
|
|||||||
m_threadPool(ThreadUtils::calculateSafeWorkerThreads()) {
|
m_threadPool(ThreadUtils::calculateSafeWorkerThreads()) {
|
||||||
m_window.create(sf::VideoMode({Constants::WIDTH, Constants::HEIGHT}),
|
m_window.create(sf::VideoMode({Constants::WIDTH, Constants::HEIGHT}),
|
||||||
"SFML Playground");
|
"SFML Playground");
|
||||||
m_window.setVerticalSyncEnabled(true);
|
m_window.setVerticalSyncEnabled(false);
|
||||||
m_windowSize = sf::Vector2f(Constants::WIDTH, Constants::HEIGHT);
|
m_windowSize = sf::Vector2f(Constants::WIDTH, Constants::HEIGHT);
|
||||||
m_objects.clear();
|
m_objects.clear();
|
||||||
|
|
||||||
@@ -46,6 +46,8 @@ void Game::processKeyPressed(const sf::Event::KeyPressed &keyPressed) {
|
|||||||
case sf::Keyboard::Key::D:
|
case sf::Keyboard::Key::D:
|
||||||
m_toggleDebug = !m_toggleDebug;
|
m_toggleDebug = !m_toggleDebug;
|
||||||
break;
|
break;
|
||||||
|
case sf::Keyboard::Key::Delete:
|
||||||
|
if (!m_objects.empty()) m_objects.pop_back();
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -205,7 +207,7 @@ void Game::render() {
|
|||||||
|
|
||||||
if (!m_toggleDebug) continue;
|
if (!m_toggleDebug) continue;
|
||||||
if (const auto *ball = dynamic_cast<Ball *>(object.get())) {
|
if (const auto *ball = dynamic_cast<Ball *>(object.get())) {
|
||||||
DebugDraw::addDirectionLine(m_debugLines, ball, m_window);
|
// DebugDraw::addDirectionLine(m_debugLines, ball, m_window);
|
||||||
DebugDraw::addVelocityLine(m_debugLines, ball);
|
DebugDraw::addVelocityLine(m_debugLines, ball);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user