#include "GL/gl3w.h" #include "GL/gl.h" #include "OpenGLRenderingBackend.hpp" #include "Debug.hpp" #include "imgui/imgui.h" #include "extern/imgui_impl_opengl3.h" #include "PathHelper.hpp" #include "elements/Texture.hpp" #include "TextureHelperOpenGL.hpp" #include "interfaces/IRenderer.hpp" #include "BehaviourScripts/Camera.hpp" #include "RenderTextureCreatorOpenGL.hpp" #include "CameraHelperOpenGL.hpp" #include "WindowManager.hpp" #if defined(TSE_GLFW) #include "GLFW/glfw3.h" #include "WindowGlfw.hpp" #include "extern/imgui_impl_glfw.h" using namespace TSE::GLFW; #elif defined(TSE_SDL3) #include "SDL3/SDL.h" #include "WindowSdl3.hpp" #include "extern/imgui_impl_sdl3.h" using namespace TSE::SDL3; #endif TSE::OpenGL::OpenGLRenderingBackend::OpenGLRenderingBackend(Color _backgroundColor, bool _vsync) : OpenGLRenderingBackend(_backgroundColor, _vsync, 0, false){ } TSE::OpenGL::OpenGLRenderingBackend::OpenGLRenderingBackend(Color _backgroundColor, bool _vsync, int _samples, bool _useseImGui) { backgroundColor = _backgroundColor; vsync = _vsync; samples = _samples; useseImGui = _useseImGui; } TSE::OpenGL::OpenGLRenderingBackend::~OpenGLRenderingBackend() { if(useseImGui) { ImGui_ImplOpenGL3_Shutdown(); #if defined(TSE_GLFW) ImGui_ImplGlfw_Shutdown(); #elif defined(TSE_SDL3) ImGui_ImplSDL3_Shutdown(); #endif ImGui::DestroyContext(); } } void TSE::OpenGL::OpenGLRenderingBackend::InitPreWindow() { IRenderTexture::factory = new RenderTextureCreatorOpenGL(); Texture::helper = new TextureHelperOpenGL(); Camera::helper = new CameraHelperOpenGL(); #if defined(TSE_GLFW) glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, TSE_OPENGL_VERSION_MAJOR); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, TSE_OPENGL_VERSION_MINOR); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_SAMPLES, samples); #elif defined(TSE_SDL3) SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, TSE_OPENGL_VERSION_MAJOR); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, TSE_OPENGL_VERSION_MINOR); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, samples); #endif } bool TSE::OpenGL::OpenGLRenderingBackend::InitPostWindow() { #if defined(TSE_GLFW) WindowGlfw* wnd = static_cast(window); glfwMakeContextCurrent(wnd->window); #elif defined(TSE_SDL3) WindowSdl3* wnd = static_cast(window); wnd->context = SDL_GL_CreateContext(wnd->window); SDL_GL_MakeCurrent(wnd->window, wnd->context); #endif if(gl3wInit()) { Debug::Log("Failed to initialize gl3w."); return false; } if(!gl3wIsSupported(TSE_OPENGL_VERSION_MAJOR, TSE_OPENGL_VERSION_MINOR)) { Debug::Log("gl3w dose not support the selected version of OpenGL."); return false; } #if defined(TSE_GLFW) if(vsync) glfwSwapInterval(1); else glfwSwapInterval(0); #elif defined(TSE_SDL3) if(vsync) { if(!SDL_GL_SetSwapInterval(-1)) SDL_GL_SetSwapInterval(1); } else SDL_GL_SetSwapInterval(0); #endif Debug::Log("OpenGL:" + std::string((const char*)glGetString(GL_VERSION))); Debug::Log("GLSL:" + std::string((const char*)glGetString(GL_SHADING_LANGUAGE_VERSION))); glEnable(GL_BLEND); glClearDepth(0.0); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_GEQUAL); glEnable(GL_MULTISAMPLE); glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); glFrontFace(GL_CW); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glClearColor(backgroundColor.r, backgroundColor.g, backgroundColor.b, backgroundColor.a); glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); return true; } std::string imguiIniPath; bool TSE::OpenGL::OpenGLRenderingBackend::InitEnd() { if(useseImGui) { GetAppDataPath(imguiIniPath); imguiIniPath += "/UI.cfg"; IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; io.IniFilename = imguiIniPath.c_str(); ImGui::StyleColorsDark(); #if defined(TSE_GLFW) WindowGlfw* wnd = static_cast(window); wnd->useImGui = true; ImGui_ImplGlfw_InitForOpenGL(wnd->window, true); #elif defined(TSE_SDL3) WindowSdl3* wnd = static_cast(window); wnd->useImGui = true; ImGui_ImplSDL3_InitForOpenGL(wnd->window, wnd->context); #endif ImGui_ImplOpenGL3_Init("#version 130"); Debug::Log("ImGui:" + std::string(ImGui::GetVersion())); } return true; } void TSE::OpenGL::OpenGLRenderingBackend::onResize(int width, int height) { glViewport(0,0,width, height); } void TSE::OpenGL::OpenGLRenderingBackend::onUpdate() const { int error = glGetError(); if(error != GL_NO_ERROR) { Debug::Log("OpenGL Error: " + std::to_string(error)); } #if defined(TSE_GLFW) WindowGlfw* wnd = static_cast(window); #elif defined(TSE_SDL3) WindowSdl3* wnd = static_cast(window); #endif if(useseImGui) { ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); if(ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable) { #if defined(TSE_GLFW) GLFWwindow* backup_current_context = glfwGetCurrentContext(); #elif defined(TSE_SDL3) SDL_GLContext backup_current_context = SDL_GL_GetCurrentContext(); #endif ImGui::UpdatePlatformWindows(); ImGui::RenderPlatformWindowsDefault(); #if defined(TSE_GLFW) glfwMakeContextCurrent(backup_current_context); #elif defined(TSE_SDL3) SDL_GL_MakeCurrent(wnd->window, backup_current_context); #endif } } #if defined(TSE_GLFW) glfwSwapBuffers(wnd->window); #elif defined(TSE_SDL3) SDL_GL_SwapWindow(wnd->window); #endif } void TSE::OpenGL::OpenGLRenderingBackend::onClear() const { for (int i = 0; i < IRenderer::camerasToRenderWith.size(); i++) { IRenderer::camerasToRenderWith[i]->Bind(); IRenderer::camerasToRenderWith[i]->UpdateRenderTarget(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); IRenderer::camerasToRenderWith[i]->Unbind(); } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if(useseImGui) { ImGui_ImplOpenGL3_NewFrame(); #if defined(TSE_GLFW) ImGui_ImplGlfw_NewFrame(); #elif defined(TSE_SDL3) ImGui_ImplSDL3_NewFrame(); #endif ImGui::NewFrame(); } } void TSE::OpenGL::OpenGLRenderingBackend::onClearDepthBuffer() const { for (int i = 0; i < IRenderer::camerasToRenderWith.size(); i++) { IRenderer::camerasToRenderWith[i]->Bind(); glClear(GL_DEPTH_BUFFER_BIT); IRenderer::camerasToRenderWith[i]->Unbind(); } glClear(GL_DEPTH_BUFFER_BIT); }