summaryrefslogtreecommitdiffstats
path: root/src/Render.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Render.cpp272
1 files changed, 195 insertions, 77 deletions
diff --git a/src/Render.cpp b/src/Render.cpp
index c739b77..19e89f6 100644
--- a/src/Render.cpp
+++ b/src/Render.cpp
@@ -4,6 +4,10 @@
#include "Shader.hpp"
#include "AssetManager.hpp"
#include "Event.hpp"
+#include "DebugInfo.hpp"
+
+#include <imgui.h>
+#include "imgui_impl_sdl_gl3.h"
Render::Render(unsigned int windowWidth, unsigned int windowHeight, std::string windowTitle) : timer(std::chrono::milliseconds(0)) {
InitSfml(windowWidth, windowHeight, windowTitle);
@@ -15,21 +19,31 @@ Render::Render(unsigned int windowWidth, unsigned int windowHeight, std::string
}
Render::~Render() {
- delete window;
+ ImGui_ImplSdlGL3_Shutdown();
+ SDL_GL_DeleteContext(glContext);
+ SDL_DestroyWindow(window);
+ SDL_Quit();
}
void Render::InitSfml(unsigned int WinWidth, unsigned int WinHeight, std::string WinTitle) {
LOG(INFO) << "Creating window: " << WinWidth << "x" << WinHeight << " \"" << WinTitle << "\"";
- sf::ContextSettings contextSetting;
- contextSetting.majorVersion = 3;
- contextSetting.minorVersion = 3;
- contextSetting.attributeFlags = contextSetting.Core;
- contextSetting.depthBits = 24;
- window = new sf::Window(sf::VideoMode(WinWidth, WinHeight), WinTitle, sf::Style::Default, contextSetting);
- glCheckError();
- window->setPosition(sf::Vector2i(sf::VideoMode::getDesktopMode().width / 2 - window->getSize().x / 2,
- sf::VideoMode::getDesktopMode().height / 2 - window->getSize().y / 2));
- window->setKeyRepeatEnabled(false);
+
+ if (SDL_Init(SDL_INIT_VIDEO) < 0)
+ throw std::runtime_error("SDL initalization failed: " + std::string(SDL_GetError()));
+
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
+
+ window = SDL_CreateWindow(WinTitle.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WinWidth, WinHeight, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
+ if (!window)
+ throw std::runtime_error("Window creation failed: " + std::string(SDL_GetError()));
+
+ glContext = SDL_GL_CreateContext(window);
+ if (!glContext)
+ throw std::runtime_error("OpenGl context creation failed: " + std::string(SDL_GetError()));
+
SetMouseCapture(false);
renderState.WindowWidth = WinWidth;
renderState.WindowHeight = WinHeight;
@@ -43,7 +57,9 @@ void Render::InitGlew() {
if (glewStatus != GLEW_OK) {
LOG(FATAL) << "Failed to initialize GLEW: " << glewGetErrorString(glewStatus);
}
- glViewport(0, 0, window->getSize().x, window->getSize().y);
+ int width, height;
+ SDL_GL_GetDrawableSize(window, &width, &height);
+ glViewport(0, 0, width, height);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
@@ -58,12 +74,18 @@ void Render::PrepareToRendering() {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, AssetManager::Instance().GetTextureAtlas());
AssetManager::Instance().GetTextureAtlasIndexes();
+
+ ImGui_ImplSdlGL3_Init(window);
}
void Render::UpdateKeyboard() {
- sf::Keyboard::Key toUpdate[] = { sf::Keyboard::A,sf::Keyboard::W,sf::Keyboard::S,sf::Keyboard::D,sf::Keyboard::Space };
+ if (ImGui::GetIO().WantCaptureKeyboard)
+ return;
+
+ SDL_Scancode toUpdate[] = { SDL_SCANCODE_A,SDL_SCANCODE_W,SDL_SCANCODE_S,SDL_SCANCODE_D,SDL_SCANCODE_SPACE };
+ const Uint8 *kbState = SDL_GetKeyboardState(0);
for (auto key : toUpdate) {
- bool isPressed = sf::Keyboard::isKeyPressed(key);
+ bool isPressed = kbState[key];
if (!isKeyPressed[key] && isPressed) {
EventAgregator::PushEvent(EventType::KeyPressed, KeyPressedData{ key });
}
@@ -81,6 +103,7 @@ void Render::RenderFrame() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
if (renderWorld)
world->Render(renderState);
@@ -88,62 +111,67 @@ void Render::RenderFrame() {
world->Update(timer.RemainTimeMs());
}
- window->display();
+ RenderGui();
+
+ SDL_GL_SwapWindow(window);
}
void Render::HandleEvents() {
- sf::Event event;
- while (window->pollEvent(event)) {
+ SDL_PumpEvents();
+ SDL_Event event;
+ while (SDL_PollEvent(&event)) {
+ ImGui_ImplSdlGL3_ProcessEvent(&event);
+
switch (event.type) {
- case sf::Event::Closed:
+ case SDL_QUIT:
LOG(INFO) << "Received close event by window closing";
isRunning = false;
break;
- case sf::Event::Resized:
- glViewport(0, 0, window->getSize().x, window->getSize().y);
- renderState.WindowWidth = window->getSize().x;
- renderState.WindowHeight = window->getSize().y;
- break;
- case sf::Event::KeyPressed:
- if (!window->hasFocus()) break;
- switch (event.key.code) {
- case sf::Keyboard::Escape:
- LOG(INFO) << "Received close event by esc";
- isRunning = false;
- break;
- case sf::Keyboard::T:
- SetMouseCapture(!isMouseCaptured);
+ case SDL_WINDOWEVENT: {
+ switch (event.window.event) {
+ case SDL_WINDOWEVENT_RESIZED: {
+ int width, height;
+ SDL_GL_GetDrawableSize(window, &width, &height);
+ glViewport(0, 0, width, height);
+ renderState.WindowWidth = width;
+ renderState.WindowHeight = height;
break;
- case sf::Keyboard::U:
- EventAgregator::PushEvent(EventType::ConnectToServer, ConnectToServerData{ "10.1.1.2", 25565 });
+ }
+ case SDL_WINDOWEVENT_FOCUS_GAINED:
+ HasFocus = true;
break;
- case sf::Keyboard::I:
- EventAgregator::PushEvent(EventType::Disconnect, DisconnectData{ "Manual disconnect" });
+ case SDL_WINDOWEVENT_FOCUS_LOST:
+ HasFocus = false;
+ SetMouseCapture(false);
break;
- case sf::Keyboard::K:
- if (renderWorld) {
- world->MaxRenderingDistance--;
- if (world->MaxRenderingDistance <= 0)
- world->MaxRenderingDistance = 1;
- LOG(INFO) << "Decreased rendering distance: " << world->MaxRenderingDistance;
- EventAgregator::PushEvent(EventType::UpdateSectionsRender, UpdateSectionsRenderData{});
+ }
+ break;
+ }
+ case SDL_KEYDOWN:
+ switch (event.key.keysym.scancode) {
+ case SDL_SCANCODE_ESCAPE:
+ if (state == GlobalState::Playing) {
+ state = GlobalState::Paused;
+ SetMouseCapture(false);
}
- break;
- case sf::Keyboard::L:
- if (renderWorld) {
- world->MaxRenderingDistance++;
- LOG(INFO) << "Increased rendering distance: " << world->MaxRenderingDistance;
- EventAgregator::PushEvent(EventType::UpdateSectionsRender, UpdateSectionsRenderData{});
+ else if (state == GlobalState::Paused) {
+ state = GlobalState::Playing;
+ SetMouseCapture(true);
+ }
+ else if (state == GlobalState::MainMenu) {
+ LOG(INFO) << "Received close event by esc";
+ isRunning = false;
}
- break;
- default:
break;
}
- case sf::Event::KeyReleased:
- if (!window->hasFocus()) break;
- switch (event.key.code) {
- default:
- break;
+ break;
+ case SDL_MOUSEMOTION:
+ if (isMouseCaptured) {
+ double deltaX = event.motion.xrel;
+ double deltaY = event.motion.yrel;
+ deltaX *= sensetivity;
+ deltaY *= sensetivity * -1;
+ EventAgregator::DirectEventCall(EventType::MouseMoved, MouseMovedData{ deltaX,deltaY });
}
default:
break;
@@ -151,20 +179,24 @@ void Render::HandleEvents() {
}
}
-void Render::HandleMouseCapture() {
- sf::Vector2i mousePos = sf::Mouse::getPosition(*window);
- sf::Vector2i center = sf::Vector2i(window->getSize().x / 2, window->getSize().y / 2);
- sf::Mouse::setPosition(center, *window);
- mouseXDelta = (mousePos - center).x, mouseYDelta = (center - mousePos).y;
- const float Sensetivity = 0.7f;
- EventAgregator::DirectEventCall(EventType::MouseMoved, MouseMovedData{ mouseXDelta * Sensetivity, mouseYDelta * Sensetivity});
+void Render::HandleMouseCapture() {
}
void Render::SetMouseCapture(bool IsCaptured) {
- window->setMouseCursorVisible(!isMouseCaptured);
- sf::Mouse::setPosition(sf::Vector2i(window->getSize().x / 2, window->getSize().y / 2), *window);
- isMouseCaptured = IsCaptured;
- window->setMouseCursorVisible(!IsCaptured);
+ if (IsCaptured == isMouseCaptured)
+ return;
+ isMouseCaptured = IsCaptured;
+
+ if (isMouseCaptured) {
+ SDL_GetGlobalMouseState(&prevMouseX, &prevMouseY);
+ }
+
+ SDL_CaptureMouse(IsCaptured ? SDL_TRUE : SDL_FALSE);
+ SDL_SetRelativeMouseMode(IsCaptured ? SDL_TRUE : SDL_FALSE);
+
+ if (!isMouseCaptured) {
+ SDL_WarpMouseGlobal(prevMouseX, prevMouseY);
+ }
}
void Render::ExecuteRenderLoop() {
@@ -172,49 +204,135 @@ void Render::ExecuteRenderLoop() {
listener.RegisterHandler(EventType::ConnectionSuccessfull, [this](EventData eventData) {
auto data = std::get<ConnectionSuccessfullData>(eventData);
- window->setTitle("Logging in...");
+ stateString = "Logging in...";
});
listener.RegisterHandler(EventType::PlayerConnected, [this](EventData eventData) {
auto data = std::get<PlayerConnectedData>(eventData);
- window->setTitle("Loading terrain...");
+ stateString = "Loading terrain...";
world = std::make_unique<RendererWorld>(data.ptr);
});
listener.RegisterHandler(EventType::RemoveLoadingScreen, [this](EventData eventData) {
- window->setTitle("Playing");
+ stateString = "Playing";
renderWorld = true;
+ state = GlobalState::Playing;
+ SetMouseCapture(true);
});
listener.RegisterHandler(EventType::ConnectionFailed, [this](EventData eventData) {
- window->setTitle("Connection failed: " + std::get<ConnectionFailedData>(eventData).reason);
+ stateString = "Connection failed: " + std::get<ConnectionFailedData>(eventData).reason;
renderWorld = false;
world.reset();
+ state = GlobalState::MainMenu;
});
listener.RegisterHandler(EventType::Disconnected, [this](EventData eventData) {
- window->setTitle("Disconnected: " + std::get<DisconnectedData>(eventData).reason);
+ stateString = "Disconnected: " + std::get<DisconnectedData>(eventData).reason;
renderWorld = false;
world.reset();
+ state = GlobalState::MainMenu;
});
listener.RegisterHandler(EventType::Connecting, [this](EventData eventData) {
- window->setTitle("Connecting to the server...");
+ stateString = "Connecting to the server...";
+ state = GlobalState::Loading;
});
+
+ state = GlobalState::MainMenu;
while (isRunning) {
HandleEvents();
- if (window->hasFocus()) UpdateKeyboard();
+ if (HasFocus) UpdateKeyboard();
if (isMouseCaptured) HandleMouseCapture();
glCheckError();
RenderFrame();
while (listener.IsEventsQueueIsNotEmpty())
listener.HandleEvent();
- if (renderWorld) {
- window->setTitle("FPS: " + std::to_string(1.0 / timer.GetRealDeltaS()));
- }
timer.Update();
}
EventAgregator::PushEvent(EventType::Exit, ExitData{});
}
+
+void Render::RenderGui() {
+ ImGui_ImplSdlGL3_NewFrame(window);
+
+ if (isMouseCaptured) {
+ auto& io = ImGui::GetIO();
+ io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
+ }
+ const ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings;
+
+ //ImGui::ShowTestWindow();
+
+ ImGui::SetNextWindowPos(ImVec2(10, 10));
+ ImGui::Begin("DebugInfo", 0, ImVec2(0, 0), 0.4f, windowFlags);
+ ImGui::Text("Debug Info:");
+ ImGui::Separator();
+ ImGui::Text("State: %s", stateString.c_str());
+ ImGui::Text("FPS: %.1f (%.3fms)", ImGui::GetIO().Framerate, 1000.0f / ImGui::GetIO().Framerate);
+ float gameTime = DebugInfo::gameThreadTime / 100.0f;
+ ImGui::Text("TPS: %.1f (%.2fms)", 1000.0f/gameTime, gameTime);
+ ImGui::Text("Sections loaded: %d", (int)DebugInfo::totalSections);
+ ImGui::Text("SectionsRenderer: %d (%d)", (int)DebugInfo::renderSections, (int)DebugInfo::readyRenderer);
+ ImGui::End();
+
+
+ switch (state) {
+ case GlobalState::MainMenu: {
+ ImGui::SetNextWindowPosCenter();
+ ImGui::Begin("Menu",0, windowFlags);
+ static char buff[512] = "127.0.0.1";
+ static int port = 25565;
+ if (ImGui::Button("Connect")) {
+ EventAgregator::PushEvent(EventType::ConnectToServer, ConnectToServerData{ buff, (unsigned short)port });
+ }
+ ImGui::InputText("Address", buff, 512);
+ ImGui::InputInt("Port", &port);
+ ImGui::Separator();
+ if (ImGui::Button("Exit"))
+ isRunning = false;
+ ImGui::End();
+ break;
+ }
+ case GlobalState::Loading:
+ break;
+ case GlobalState::Playing:
+ break;
+ case GlobalState::Paused: {
+ ImGui::SetNextWindowPosCenter();
+ ImGui::Begin("Pause Menu", 0, windowFlags);
+ if (ImGui::Button("Continue")) {
+ state = GlobalState::Playing;
+ SetMouseCapture(true);
+ }
+ ImGui::Separator();
+ static float distance = world->MaxRenderingDistance;
+ ImGui::SliderFloat("Render distance", &distance, 1.0f, 16.0f);
+
+ static float sense = sensetivity;
+ ImGui::SliderFloat("Sensetivity", &sense, 0.01f, 1.0f);
+
+ if (ImGui::Button("Apply settings")) {
+ if (distance != world->MaxRenderingDistance) {
+ world->MaxRenderingDistance = distance;
+ EventAgregator::PushEvent(EventType::UpdateSectionsRender, UpdateSectionsRenderData{});
+ }
+ if (sense != sensetivity)
+ sensetivity = sense;
+ }
+ ImGui::Separator();
+
+ if (ImGui::Button("Disconnect")) {
+ EventAgregator::PushEvent(EventType::Disconnect, DisconnectData{ "Disconnected by user" });
+ }
+ ImGui::End();
+ break;
+ }
+ case GlobalState::InitialLoading:
+ break;
+ }
+
+ ImGui::Render();
+} \ No newline at end of file