graphics frame rate fixed

This commit is contained in:
Ilusha 2024-03-19 16:39:18 +03:00
parent e41714c2bb
commit 29280949a8
7 changed files with 203 additions and 121 deletions

View file

@ -1,129 +1,27 @@
#include "Window.hpp" #include "GraphicApplication.hpp"
#include "Graphics.hpp"
#include "Timing.hpp"
#include "imgui.h" #include "imgui.h"
using namespace tp; using namespace tp;
class Application { class ExampleApplication : public Application {
public: public:
Application() : ExampleApplication() = default;
mApplicaitonModule("Application", nullptr, nullptr, mModuleDeps) {
mInitialized = mApplicaitonModule.initialize();
if (!mInitialized) return;
mWindow = Window::createWindow(); void processFrame(EventHandler* eventHandler) override {
// example
mDrawTimer.setDuration(1000.f / mDrawPerSecond);
mProcTimer.setDuration(1000.f / mProcPerSecond);
mPerSecondTimer.setDuration(1000.f);
} }
void run() { virtual void drawFrame(Canvas* canvas) override {
Graphics graphics(mWindow); ImGui::Text("Frames processed per second: %f", this->mFramesProcessedPerSecond);
auto eventHandler = new EventHandler(); ImGui::Text("Frames drawn per second: %f", this->mFramesDrawnPerSecond);
mWindow->setEventHandler(eventHandler);
mDrawTimer.reset();
mProcTimer.reset();
mPerSecondTimer.reset();
bool redrawNeeded = false;
while (!mWindow->shouldClose()) {
if (mProcTimer.isTimeout()) {
mWindow->processEvents();
while (eventHandler->isEvents()) {
eventHandler->processEvent();
processFrame(eventHandler);
redrawNeeded = true;
mFramesProcessed++;
} }
// graphics.procBegin(); virtual ~ExampleApplication() = default;
// graphics.procEnd();
redrawNeeded = true;
mFramesProcessed++;
mProcTimer.wait();
mProcTimer.reset();
}
if (mDrawTimer.isTimeout()) {
mDrawTimer.reset();
if (redrawNeeded) {
graphics.drawBegin();
drawFrame(graphics.getCanvas());
graphics.drawEnd();
mWindow->draw();
redrawNeeded = false;
mFramesDrawn++;
}
}
if (mPerSecondTimer.isTimeout()) {
mPerSecondTimer.reset();
mFramesProcessedPerSecond = mFramesProcessed;
mFramesDrawnPerSecond = mFramesDrawn;
mFramesDrawn = 0;
mFramesProcessed = 0;
}
}
delete eventHandler;
}
virtual void processFrame(EventHandler* eventHandler) {
}
virtual void drawFrame(Canvas* canvas) {
ImGui::Text("Frames processed per second: %f", mFramesProcessedPerSecond);
ImGui::Text("Frames drawn per second: %f", mFramesDrawnPerSecond);
}
~Application() {
if (!mInitialized) return;
Window::destroyWindow(mWindow);
mApplicaitonModule.deinitialize();
}
private:
ModuleManifest* mModuleDeps[2] = { &gModuleGraphics, nullptr };
ModuleManifest mApplicaitonModule;
Window* mWindow = nullptr;
bool mInitialized = false;
ualni mDrawPerSecond = 60;
ualni mProcPerSecond = 1000;
Timer mDrawTimer;
Timer mProcTimer;
Timer mPerSecondTimer;
halnf mFramesProcessedPerSecond = 0;
halnf mFramesDrawnPerSecond = 0;
halnf mFramesProcessed = 0;
halnf mFramesDrawn = 0;
}; };
int main() { int main() {
Application app; ExampleApplication app;
app.run(); app.run();
} }

View file

@ -0,0 +1,89 @@
#include "GraphicApplication.hpp"
using namespace tp;
Application::Application() :
mApplicationModule("Application", nullptr, nullptr, mModuleDeps) {
mInitialized = mApplicationModule.initialize();
if (!mInitialized) return;
mWindow = Window::createWindow();
mDrawTimer.setDuration(1000.f / mDrawPerSecond);
mProcTimer.setDuration(1000.f / mProcPerSecond);
mPerSecondTimer.setDuration(1000.f);
}
void Application::run() {
Graphics graphics(mWindow);
auto eventHandler = new EventHandler();
mWindow->setEventHandler(eventHandler);
mDrawTimer.reset();
mProcTimer.reset();
mPerSecondTimer.reset();
bool redrawNeeded = false;
while (!mWindow->shouldClose()) {
if (mProcTimer.isTimeout()) {
mWindow->processEvents();
while (eventHandler->isEvents()) {
eventHandler->processEvent();
processFrame(eventHandler);
redrawNeeded = true;
mFramesProcessed++;
}
mProcTimer.wait();
mProcTimer.reset();
}
if (mDrawTimer.isTimeout()) {
mDrawTimer.reset();
if (redrawNeeded) {
graphics.drawBegin();
drawFrame(graphics.getCanvas());
graphics.drawEnd();
mWindow->draw();
redrawNeeded = false;
mFramesDrawn++;
}
}
if (mPerSecondTimer.isTimeout()) {
mPerSecondTimer.reset();
mFramesProcessedPerSecond = mFramesProcessed;
mFramesDrawnPerSecond = mFramesDrawn;
mFramesDrawn = 0;
mFramesProcessed = 0;
}
}
delete eventHandler;
}
void Application::processFrame(EventHandler* eventHandler) {}
void Application::drawFrame(Canvas* canvas) {
// ImGui::Text("Frames processed per second: %f", mFramesProcessedPerSecond);
// ImGui::Text("Frames drawn per second: %f", mFramesDrawnPerSecond);
}
Application::~Application() {
if (!mInitialized) return;
Window::destroyWindow(mWindow);
mApplicationModule.deinitialize();
}

View file

@ -3,6 +3,8 @@
#include "WindowContext.hpp" #include "WindowContext.hpp"
#include "Allocators.hpp" #include "Allocators.hpp"
#include "Rect.hpp"
#include <GL/glew.h> #include <GL/glew.h>
#ifdef ENV_OS_WINDOWS #ifdef ENV_OS_WINDOWS
@ -92,11 +94,8 @@ void Window::destroyWindow(Window* window) {
bool Window::shouldClose() const { return glfwWindowShouldClose(mContext->window); } bool Window::shouldClose() const { return glfwWindowShouldClose(mContext->window); }
void Window::processEvents() { void Window::processEvents() {
glfwPollEvents(); glfwWaitEvents();
checkAxisUpdates();
int w, h;
glfwGetWindowSize(mContext->window, &w, &h);
mSize = { (halnf) w, (halnf) h };
} }
void Window::draw() { void Window::draw() {
@ -111,6 +110,35 @@ void Window::setEventHandler(EventHandler* eventHandler) { mEventHandler = event
EventHandler* Window::getEventHandler() { return mEventHandler; } EventHandler* Window::getEventHandler() { return mEventHandler; }
void Window::checkAxisUpdates() {
if (!mEventHandler) return;
int w, h;
glfwGetWindowSize(mContext->window, &w, &h);
if (mSize != Vec2F((halnf) w, (halnf) h)) {
mSize = { (halnf) w, (halnf) h };
mEventHandler->postEvent(InputID::WINDOW_RESIZE, {});
}
double x, y;
glfwGetCursorPos(mContext->window, &x, &y);
int posX, posY;
glfwGetWindowPos(mContext->window, &posX, &posY);
if (mPointerPos != Vec2F{ (halnf) x, (halnf) y }) {
mPointerPos = { (halnf) x, (halnf) y };
auto pos = Vec2F{ (halnf) posX, (halnf) posY };
RectF windowRec = { { 0, 0 }, mSize };
if (windowRec.isInside(mPointerPos)) {
mEventHandler->postEvent(InputID::MOUSE1, { {}, {}, mPointerPos });
}
}
}
static void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) { static void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) {
auto* self = static_cast<Window*>(glfwGetWindowUserPointer(window)); auto* self = static_cast<Window*>(glfwGetWindowUserPointer(window));
@ -119,6 +147,8 @@ static void keyCallback(GLFWwindow* window, int key, int scancode, int action, i
EventHandler* eventHandler = self->getEventHandler(); EventHandler* eventHandler = self->getEventHandler();
if (!eventHandler) return; if (!eventHandler) return;
self->checkAxisUpdates();
// post key event // post key event
/* /*
if (action == GLFW_PRESS) { if (action == GLFW_PRESS) {
@ -137,6 +167,8 @@ static void mouseButtonCallback(GLFWwindow* window, int button, int action, int
EventHandler* eventHandler = self->getEventHandler(); EventHandler* eventHandler = self->getEventHandler();
if (!eventHandler) return; if (!eventHandler) return;
self->checkAxisUpdates();
// post mouse button event // post mouse button event
// inputManager->mouseButtonStates[button] = action; // inputManager->mouseButtonStates[button] = action;
// inputManager->isEvent = true; // inputManager->isEvent = true;

View file

@ -60,11 +60,27 @@ namespace tp {
~EventHandler(); ~EventHandler();
public: // Event Poster Interface public: // Event Poster Interface
void postEvent(InputID inputID, InputEvent inputEvent); // Record event
// Record event
void postEvent(InputID inputID, InputEvent inputEvent) {
mMutex.lock();
mEventQueue.pushBack({ inputID, inputEvent });
mMutex.unlock();
}
public: // User interface public: // User interface
bool isEvents() { return false; } bool isEvents() {
void processEvent() {} mMutex.lock();
auto res = mEventQueue.length();
mMutex.unlock();
return res;
}
void processEvent() {
mMutex.lock();
mEventQueue.popFront();
mMutex.unlock();
}
const Vec2F& getPointer() const; const Vec2F& getPointer() const;
@ -78,7 +94,7 @@ namespace tp {
std::mutex mMutex = {}; std::mutex mMutex = {};
// Store thread protected queue of posted events // Store thread protected queue of posted events
List<InputEvent> mEventQueue; List<std::pair<InputID, InputEvent>> mEventQueue;
// input states // input states
Vec2F mPointer; Vec2F mPointer;

View file

@ -0,0 +1,41 @@
#pragma once
#include "Window.hpp"
#include "Graphics.hpp"
#include "Timing.hpp"
namespace tp {
class Application {
public:
Application();
void run();
virtual void processFrame(EventHandler* eventHandler);
virtual void drawFrame(Canvas* canvas);
virtual ~Application();
protected:
ModuleManifest* mModuleDeps[2] = { &gModuleGraphics, nullptr };
ModuleManifest mApplicationModule;
Window* mWindow = nullptr;
bool mInitialized = false;
ualni mDrawPerSecond = 60;
ualni mProcPerSecond = 160;
Timer mDrawTimer;
Timer mProcTimer;
Timer mPerSecondTimer;
halnf mFramesProcessedPerSecond = 0;
halnf mFramesDrawnPerSecond = 0;
halnf mFramesProcessed = 0;
halnf mFramesDrawn = 0;
};
}

View file

@ -146,5 +146,7 @@ namespace tp {
MOUSE_DOWN = 507, MOUSE_DOWN = 507,
LAST_KEY_CODE = 508, LAST_KEY_CODE = 508,
WINDOW_RESIZE = 1000,
}; };
} }

View file

@ -29,8 +29,12 @@ namespace tp {
[[nodiscard]] bool shouldClose() const; [[nodiscard]] bool shouldClose() const;
[[nodiscard]] const Vec2F& getSize() const; [[nodiscard]] const Vec2F& getSize() const;
void checkAxisUpdates();
private: private:
Vec2F mSize; Vec2F mSize;
Vec2F mPointerPos;
Context* mContext; Context* mContext;
EventHandler* mEventHandler = nullptr; EventHandler* mEventHandler = nullptr;
}; };