diff options
| -rw-r--r-- | Jamroot.jam | 1 | ||||
| -rw-r--r-- | gfx/gl/gldebug.cpp | 20 | ||||
| -rw-r--r-- | gfx/gl/gldebug.h | 52 | ||||
| -rw-r--r-- | gfx/gl/program.cpp | 3 | ||||
| -rw-r--r-- | gfx/gl/program.h | 5 | ||||
| -rw-r--r-- | gfx/gl/sceneRenderer.cpp | 99 | ||||
| -rw-r--r-- | gfx/gl/sceneRenderer.h | 4 | ||||
| -rw-r--r-- | gfx/gl/shadowMapper.cpp | 3 | ||||
| -rw-r--r-- | gfx/gl/shadowStenciller.cpp | 4 | ||||
| -rw-r--r-- | ui/mainApplication.cpp | 6 | ||||
| -rw-r--r-- | ui/window.cpp | 8 |
11 files changed, 156 insertions, 49 deletions
diff --git a/Jamroot.jam b/Jamroot.jam index 7d116c0..34ce9ac 100644 --- a/Jamroot.jam +++ b/Jamroot.jam @@ -17,6 +17,7 @@ lib boost_program_options : : <link>shared ; project i-like-trains : requirements <cxxstd>23 <linkflags>-Wl,-z,defs + <variant>debug:<define>GLDEBUG=1 <variant>release:<lto>on-thin <variant>profile:<lto>on-thin <toolset>tidy:<enable>all diff --git a/gfx/gl/gldebug.cpp b/gfx/gl/gldebug.cpp new file mode 100644 index 0000000..518d4fb --- /dev/null +++ b/gfx/gl/gldebug.cpp @@ -0,0 +1,20 @@ +#if GLDEBUG == 2 +// Level 2 is out of line because its "complex" + +# include "gldebug.h" +# include <format> + +glDebugScope::glDebugScope(GLuint id, const std::source_location & location) +{ + const auto fullMsg = std::format("{} ({}:{})", location.function_name(), location.file_name(), location.line()); + glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, id, static_cast<GLsizei>(fullMsg.length()), fullMsg.c_str()); +} + +glDebugScope::glDebugScope(GLuint id, const std::string_view msg, const std::source_location & location) +{ + const auto fullMsg + = std::format("{} @ {} ({}:{})", msg, location.function_name(), location.file_name(), location.line()); + glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, id, static_cast<GLsizei>(fullMsg.length()), fullMsg.c_str()); +} + +#endif diff --git a/gfx/gl/gldebug.h b/gfx/gl/gldebug.h new file mode 100644 index 0000000..5cfd099 --- /dev/null +++ b/gfx/gl/gldebug.h @@ -0,0 +1,52 @@ +#pragma once +#ifndef GLDEBUG +# define GLDEBUG 0 +#endif + +#include "special_members.h" +#include <glad/gl.h> +#include <source_location> +#include <string_view> + +class [[nodiscard]] glDebugScope { +public: + explicit glDebugScope(GLuint id, const std::source_location & = std::source_location::current()); + explicit glDebugScope( + GLuint id, std::string_view msg, const std::source_location & = std::source_location::current()); + + ~glDebugScope(); + + constexpr + operator bool() const + { + return true; + } + + NO_MOVE(glDebugScope); + NO_COPY(glDebugScope); +}; + +#if GLDEBUG > 0 +inline glDebugScope::~glDebugScope() +{ + glPopDebugGroup(); +} +# if GLDEBUG == 1 +// Level 1 is inlined for performance because they're thin wrappers +inline glDebugScope::glDebugScope(GLuint id, const std::source_location & location) : + glDebugScope {id, location.function_name()} +{ +} + +inline glDebugScope::glDebugScope(GLuint id, const std::string_view msg, const std::source_location &) +{ + glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, id, static_cast<GLsizei>(msg.length()), msg.data()); +} +# endif +#else +inline glDebugScope::glDebugScope(GLuint, const std::source_location &) { } + +inline glDebugScope::glDebugScope(GLuint, const std::string_view, const std::source_location &) { } + +inline glDebugScope::~glDebugScope() = default; +#endif diff --git a/gfx/gl/program.cpp b/gfx/gl/program.cpp index fdd4c6f..da85456 100644 --- a/gfx/gl/program.cpp +++ b/gfx/gl/program.cpp @@ -1,5 +1,5 @@ #include "program.h" -#include "shader.h" +#include "gldebug.h" #include <format> #include <glm/gtc/type_ptr.hpp> #include <glm/gtx/transform.hpp> @@ -9,6 +9,7 @@ void Program::linkAndValidate() const { + glDebugScope _ {m_program}; glLinkProgram(m_program); checkProgramError(m_program, GL_LINK_STATUS, "Error linking shader program"); diff --git a/gfx/gl/program.h b/gfx/gl/program.h index 20be1aa..2b06d2d 100644 --- a/gfx/gl/program.h +++ b/gfx/gl/program.h @@ -1,5 +1,6 @@ #pragma once +#include "gldebug.h" #include "shader.h" // IWYU pragma: export #include <glRef.h> #include <glad/gl.h> @@ -14,7 +15,9 @@ class Program { public: Program() = delete; - template<typename... S> explicit Program(const S &... srcs) + template<typename... S> explicit Program(const S &... srcs) : Program {glDebugScope {0}, srcs...} { } + + template<typename... S> explicit Program(glDebugScope, const S &... srcs) { (glAttachShader(m_program, srcs.compile()), ...); linkAndValidate(); diff --git a/gfx/gl/sceneRenderer.cpp b/gfx/gl/sceneRenderer.cpp index 9a4d153..65b4609 100644 --- a/gfx/gl/sceneRenderer.cpp +++ b/gfx/gl/sceneRenderer.cpp @@ -14,7 +14,9 @@ static constexpr const std::array<const glm::i8vec4, 4> displayVAOdata {{ {1, -1, 1, 0}, }}; -SceneRenderer::SceneRenderer(ScreenAbsCoord s, GLuint o) : +SceneRenderer::SceneRenderer(ScreenAbsCoord s, GLuint o) : SceneRenderer {s, o, glDebugScope {o}} { } + +SceneRenderer::SceneRenderer(ScreenAbsCoord s, GLuint o, glDebugScope) : camera {{-1250000, -1250000, 35.0F}, quarter_pi, ratio(s), 100, 10000000}, size {s}, output {o}, lighting {lighting_vs, lighting_fs}, shadowMapper {{2048, 2048}} { @@ -59,6 +61,7 @@ SceneRenderer::SceneRenderer(ScreenAbsCoord s, GLuint o) : void SceneRenderer::resize(ScreenAbsCoord newSize) { + glDebugScope _ {output}; size = newSize; camera.setAspect(ratio(size)); const auto configuregdata = [this](const GLuint data, const GLint iformat, const GLenum format) { @@ -77,55 +80,66 @@ SceneRenderer::resize(ScreenAbsCoord newSize) void SceneRenderer::render(const SceneProvider & scene) const { + glDebugScope _ {output}; shader.setViewProjection(camera.getPosition(), camera.getViewProjection()); glViewport(0, 0, size.x, size.y); - // Geometry/colour pass - writes albedo, normal and position textures - glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); - glEnable(GL_BLEND); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_DEPTH_TEST); - glClearColor(0, 0, 0, 1); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - scene.content(shader, camera); - - // Environment pass - - // * ambient - clears illumination texture - see setAmbientLight - // * directional - updates shadowMapper, reads normal and position, writes illumination - see setDirectionalLight - scene.environment(shader, *this); - - // Scene lights pass - - // * per light - reads normal and position, writes illumination - glBindFramebuffer(GL_FRAMEBUFFER, gBufferIll); - glBlendFunc(GL_ONE, GL_ONE); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, gPosition); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, gNormal); - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D_ARRAY, shadowMapper); - glDisable(GL_DEPTH_TEST); - scene.lights(shader); - - // Composition pass - reads albedo and illumination, writes output - glBindFramebuffer(GL_FRAMEBUFFER, output); - glViewport(0, 0, size.x, size.y); - glCullFace(GL_BACK); - glDisable(GL_BLEND); - glDisable(GL_DEPTH_TEST); - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, gAlbedoSpec); - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, gIllumination); - lighting.use(); - renderQuad(); + if (glDebugScope _ {gBuffer, "Geometry/colour pass"}) { + // Geometry/colour pass - writes albedo, normal and position textures + glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); + glEnable(GL_BLEND); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_DEPTH_TEST); + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + scene.content(shader, camera); + } + + if (glDebugScope _ {gBufferIll, "Environment pass"}) { + // Environment pass - + // * ambient - clears illumination texture - see setAmbientLight + // * directional - updates shadowMapper, reads normal and position, writes illumination - see + // setDirectionalLight + scene.environment(shader, *this); + } + + if (glDebugScope _ {gBufferIll, "Scene lighting pass"}) { + // Scene lights pass - + // * per light - reads normal and position, writes illumination + glBindFramebuffer(GL_FRAMEBUFFER, gBufferIll); + glBlendFunc(GL_ONE, GL_ONE); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, gPosition); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, gNormal); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D_ARRAY, shadowMapper); + glDisable(GL_DEPTH_TEST); + scene.lights(shader); + } + + if (glDebugScope _ {output, "Composition pass"}) { + // Composition pass - reads albedo and illumination, writes output + glBindFramebuffer(GL_FRAMEBUFFER, output); + glViewport(0, 0, size.x, size.y); + glCullFace(GL_BACK); + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, gAlbedoSpec); + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, gIllumination); + lighting.use(); + renderQuad(); + } } void SceneRenderer::setAmbientLight(const RGB & colour) const { + glDebugScope _ {output}; glBindFramebuffer(GL_FRAMEBUFFER, gBufferIll); glClearColor(colour.r, colour.g, colour.b, 1.0F); glClear(GL_COLOR_BUFFER_BIT); @@ -136,6 +150,7 @@ SceneRenderer::setDirectionalLight( const RGB & colour, const LightDirection & direction, const SceneProvider & scene) const { if (colour.r > 0 || colour.g > 0 || colour.b > 0) { + glDebugScope _ {output}; const auto lvp = shadowMapper.update(scene, direction, camera); glBindFramebuffer(GL_FRAMEBUFFER, gBufferIll); glBlendFunc(GL_ONE, GL_ONE); diff --git a/gfx/gl/sceneRenderer.h b/gfx/gl/sceneRenderer.h index 31f0cda..05921a1 100644 --- a/gfx/gl/sceneRenderer.h +++ b/gfx/gl/sceneRenderer.h @@ -2,6 +2,7 @@ #include "gfx/lightDirection.h" #include "glArrays.h" +#include "gldebug.h" #include "program.h" #include "sceneProvider.h" #include "sceneShader.h" @@ -11,7 +12,8 @@ class SceneRenderer { public: - explicit SceneRenderer(ScreenAbsCoord size, GLuint output); + SceneRenderer(ScreenAbsCoord size, GLuint output); + SceneRenderer(ScreenAbsCoord size, GLuint output, glDebugScope); void resize(ScreenAbsCoord size); diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp index 3cb73f7..486ba1c 100644 --- a/gfx/gl/shadowMapper.cpp +++ b/gfx/gl/shadowMapper.cpp @@ -16,6 +16,7 @@ #include "gfx/lightDirection.h" #include "gfx/renderable.h" #include "gl_traits.h" +#include "gldebug.h" #include "location.h" #include "maths.h" #include "sceneProvider.h" @@ -32,6 +33,7 @@ ShadowMapper::ShadowMapper(const TextureAbsCoord & s) : shadowDynamicPointInstWithTextures_fs}, size {s} { + glDebugScope _ {depthMap}; glBindTexture(GL_TEXTURE_2D_ARRAY, depthMap); glTexImage3D( GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT, size.x, size.y, 4, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); @@ -83,6 +85,7 @@ ShadowMapper::getBandViewExtents(const Camera & camera, const glm::mat4 & lightV ShadowMapper::Definitions ShadowMapper::update(const SceneProvider & scene, const LightDirection & dir, const Camera & camera) const { + glDebugScope _ {depthMap}; glCullFace(GL_FRONT); glEnable(GL_DEPTH_TEST); diff --git a/gfx/gl/shadowStenciller.cpp b/gfx/gl/shadowStenciller.cpp index 86b77e4..a6124f5 100644 --- a/gfx/gl/shadowStenciller.cpp +++ b/gfx/gl/shadowStenciller.cpp @@ -1,5 +1,4 @@ #include "shadowStenciller.h" -#include "gfx/gl/program.h" #include "gfx/gl/shaders/fs-shadowStencil.h" #include "gfx/gl/shaders/gs-shadowStencil.h" #include "gfx/gl/shaders/vs-shadowStencil.h" @@ -7,12 +6,14 @@ #include "gfx/models/mesh.h" #include "glArrays.h" #include "gl_traits.h" +#include "gldebug.h" #include "maths.h" #include <stdexcept> ShadowStenciller::ShadowStenciller() : shadowCaster {shadowStencil_vs, shadowStencil_gs, shadowStencil_fs}, viewProjections {} { + glDebugScope _ {fbo}; glBindFramebuffer(GL_FRAMEBUFFER, fbo); glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); @@ -50,6 +51,7 @@ ShadowStenciller::createStencilTexture(GLsizei width, GLsizei height) void ShadowStenciller::renderStencil(const glTexture & stencil, const MeshBase & mesh, const Texture::AnyPtr texture) const { + glDebugScope _ {fbo}; glBindFramebuffer(GL_FRAMEBUFFER, fbo); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, stencil, 0); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { diff --git a/ui/mainApplication.cpp b/ui/mainApplication.cpp index 78f4fd4..bb91c21 100644 --- a/ui/mainApplication.cpp +++ b/ui/mainApplication.cpp @@ -2,6 +2,7 @@ #include "backends/imgui_impl_sdl2.h" #include "game/gamestate.h" #include "game/worldobject.h" +#include "gfx/gl/gldebug.h" void MainApplication::mainLoop() @@ -13,10 +14,13 @@ MainApplication::mainLoop() const auto t_passed = std::chrono::duration_cast<TickDuration>(t_end - t_start); if (gameState) { + glDebugScope _ {0, "Tick all game state world objects"}; gameState->world.apply(&WorldObject::tick, t_passed); } windows.apply(&Window::tick, t_passed); - windows.apply(&Window::refresh); + if (glDebugScope _ {0, "Refresh all windows"}) { + windows.apply(&Window::refresh); + } ImGui::UpdatePlatformWindows(); ImGui::RenderPlatformWindowsDefault(); diff --git a/ui/window.cpp b/ui/window.cpp index c85cebe..9d8dc1a 100644 --- a/ui/window.cpp +++ b/ui/window.cpp @@ -1,6 +1,7 @@ #include "window.h" #include "backends/imgui_impl_opengl3.h" #include "backends/imgui_impl_sdl2.h" +#include "gfx/gl/gldebug.h" #include <glad/gl.h> #include <glm/glm.hpp> @@ -14,6 +15,7 @@ Window::Window(ScreenAbsCoord size, const char * title, Uint32 flags) : void Window::clear(float r, float g, float b, float a) const { + glDebugScope _ {0}; glClearColor(r, g, b, a); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } @@ -56,8 +58,10 @@ Window::refresh() const content->render(); // Render UI stuff here } - ImGui::Render(); - ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + if (glDebugScope _ {0, "ImGui post"}) { + ImGui::Render(); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + } swapBuffers(); } |
