diff --git a/docs/modernization/build-inventory.md b/docs/modernization/build-inventory.md index 0204591..30f00be 100644 --- a/docs/modernization/build-inventory.md +++ b/docs/modernization/build-inventory.md @@ -150,8 +150,10 @@ Known local toolchain state: texture-target mapping used by `TextureCube`. It also owns and validates sampler wrap S/T/R, min/mag filter, and desktop border-color parameter mapping used by legacy `Sampler`. The PanoPainter - shader attribute binding catalog used by legacy `Shader` creation also lives - here. It also owns the PanoPainter shader uniform catalog and legacy hash + shader attribute binding catalog, shader stage tokens, compile/link status + queries, active-uniform count query, and matrix-uniform transpose token used + by legacy `Shader` creation also live here. `Shader` no longer spells GL enum + names directly. It also owns the PanoPainter shader uniform catalog and legacy hash mapping used by `Shader` active-uniform discovery and the uniform uniqueness check. - `windows-msvc-vcpkg-headless` validates manifest install/configure/build/test diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index f5e969c..a9d941a 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -414,10 +414,12 @@ framebuffer diagnostic, framebuffer blit, render-target setup, clear-state, 2D/cube texture setup, mesh draw-mode, and cube-face texture-target interpretation to that backend library. Sampler wrap, min/mag filter, and desktop border-color parameter mapping for legacy `Sampler` also lives in `pp_renderer_gl`. The PanoPainter shader attribute -binding catalog also lives in `pp_renderer_gl` and is consumed by legacy -`Shader` creation. Shader uniform hashing, catalog validation, active-uniform -mapping, and the legacy uniform uniqueness check now delegate to -`pp_renderer_gl` as well. The existing renderer classes are not yet fully +binding catalog, shader stage tokens, compile/link status queries, active-uniform +count query, and matrix-uniform transpose token also live in `pp_renderer_gl` +and are consumed by legacy `Shader` creation. Shader uniform hashing, catalog +validation, active-uniform mapping, and the legacy uniform uniqueness check now +delegate to `pp_renderer_gl` as well. `Shader` no longer spells GL enum names +directly. The existing renderer classes are not yet fully behind the renderer interfaces. Implementation tasks: diff --git a/src/renderer_gl/opengl_capabilities.cpp b/src/renderer_gl/opengl_capabilities.cpp index df1642e..d7b80e5 100644 --- a/src/renderer_gl/opengl_capabilities.cpp +++ b/src/renderer_gl/opengl_capabilities.cpp @@ -15,6 +15,11 @@ constexpr std::uint32_t gl_false = 0U; constexpr std::uint32_t gl_points = 0x0000U; constexpr std::uint32_t gl_lines = 0x0001U; constexpr std::uint32_t gl_triangles = 0x0004U; +constexpr std::uint32_t gl_fragment_shader = 0x8B30U; +constexpr std::uint32_t gl_vertex_shader = 0x8B31U; +constexpr std::uint32_t gl_compile_status = 0x8B81U; +constexpr std::uint32_t gl_link_status = 0x8B82U; +constexpr std::uint32_t gl_active_uniforms = 0x8B86U; constexpr std::uint32_t gl_array_buffer = 0x8892U; constexpr std::uint32_t gl_element_array_buffer = 0x8893U; constexpr std::uint32_t gl_static_draw = 0x88E4U; @@ -358,6 +363,36 @@ std::uint32_t vertex_attribute_not_normalized() noexcept return gl_false; } +std::uint32_t vertex_shader_stage() noexcept +{ + return gl_vertex_shader; +} + +std::uint32_t fragment_shader_stage() noexcept +{ + return gl_fragment_shader; +} + +std::uint32_t shader_compile_status_query() noexcept +{ + return gl_compile_status; +} + +std::uint32_t program_link_status_query() noexcept +{ + return gl_link_status; +} + +std::uint32_t active_uniform_count_query() noexcept +{ + return gl_active_uniforms; +} + +std::uint32_t matrix_uniform_not_transposed() noexcept +{ + return gl_false; +} + std::uint32_t texture_cube_map_target() noexcept { return gl_texture_cube_map; diff --git a/src/renderer_gl/opengl_capabilities.h b/src/renderer_gl/opengl_capabilities.h index a23d807..c8ccb95 100644 --- a/src/renderer_gl/opengl_capabilities.h +++ b/src/renderer_gl/opengl_capabilities.h @@ -80,6 +80,12 @@ struct OpenGlReadbackFormat { [[nodiscard]] std::uint32_t static_draw_buffer_usage() noexcept; [[nodiscard]] std::uint32_t vertex_attribute_float_component_type() noexcept; [[nodiscard]] std::uint32_t vertex_attribute_not_normalized() noexcept; +[[nodiscard]] std::uint32_t vertex_shader_stage() noexcept; +[[nodiscard]] std::uint32_t fragment_shader_stage() noexcept; +[[nodiscard]] std::uint32_t shader_compile_status_query() noexcept; +[[nodiscard]] std::uint32_t program_link_status_query() noexcept; +[[nodiscard]] std::uint32_t active_uniform_count_query() noexcept; +[[nodiscard]] std::uint32_t matrix_uniform_not_transposed() noexcept; [[nodiscard]] std::uint32_t texture_cube_map_target() noexcept; [[nodiscard]] std::uint32_t cube_map_allocation_face_texture_target(std::uint32_t face_index) noexcept; [[nodiscard]] std::span panopainter_cube_face_texture_targets() noexcept; diff --git a/src/shader.cpp b/src/shader.cpp index 2191172..443e18d 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -3,8 +3,45 @@ #include "shader.h" #include "asset.h" #include "app.h" +#include "renderer_gl/opengl_capabilities.h" #include "renderer_gl/shader_bindings.h" +#include + +namespace { + +[[nodiscard]] GLenum vertex_shader_stage() noexcept +{ + return static_cast(pp::renderer::gl::vertex_shader_stage()); +} + +[[nodiscard]] GLenum fragment_shader_stage() noexcept +{ + return static_cast(pp::renderer::gl::fragment_shader_stage()); +} + +[[nodiscard]] GLenum shader_compile_status_query() noexcept +{ + return static_cast(pp::renderer::gl::shader_compile_status_query()); +} + +[[nodiscard]] GLenum program_link_status_query() noexcept +{ + return static_cast(pp::renderer::gl::program_link_status_query()); +} + +[[nodiscard]] GLenum active_uniform_count_query() noexcept +{ + return static_cast(pp::renderer::gl::active_uniform_count_query()); +} + +[[nodiscard]] GLboolean matrix_uniform_not_transposed() noexcept +{ + return static_cast(pp::renderer::gl::matrix_uniform_not_transposed()); +} + +} + std::map ShaderManager::m_shaders; Shader* ShaderManager::m_current; bool ShaderManager::ext_framebuffer_fetch = false; @@ -40,10 +77,10 @@ std::string Shader::read(const std::string& path) for (const auto& l : split(data, '\n')) { - std::smatch m; - if (std::regex_search(l, m, reg_include)) + std::smatch include_match; + if (std::regex_search(l, include_match, reg_include)) { - std::string inc = base + "/" + m[1].str(); + std::string inc = base + "/" + include_match[1].str(); if (Asset::exist(inc.c_str())) { std::string subdata = read(inc); @@ -169,7 +206,7 @@ bool Shader::create(const std::string& vertex, const std::string& fragment) int infolen; const GLchar* source; - auto vs = glCreateShader(GL_VERTEX_SHADER); + auto vs = glCreateShader(vertex_shader_stage()); if (!vs) { ret = false; @@ -178,7 +215,7 @@ bool Shader::create(const std::string& vertex, const std::string& fragment) source = vertex.c_str(); glShaderSource(vs, 1, &source, nullptr); glCompileShader(vs); - glGetShaderiv(vs, GL_COMPILE_STATUS, &status); + glGetShaderiv(vs, shader_compile_status_query(), &status); glGetShaderInfoLog(vs, sizeof(infolog), &infolen, infolog); if (infolen > 0) { @@ -192,7 +229,7 @@ bool Shader::create(const std::string& vertex, const std::string& fragment) return; } - auto fs = glCreateShader(GL_FRAGMENT_SHADER); + auto fs = glCreateShader(fragment_shader_stage()); if (!fs) { glDeleteShader(vs); @@ -202,7 +239,7 @@ bool Shader::create(const std::string& vertex, const std::string& fragment) source = fragment.c_str(); glShaderSource(fs, 1, &source, nullptr); glCompileShader(fs); - glGetShaderiv(fs, GL_COMPILE_STATUS, &status); + glGetShaderiv(fs, shader_compile_status_query(), &status); glGetShaderInfoLog(fs, sizeof(infolog), &infolen, infolog); if (infolen > 0) { @@ -238,7 +275,7 @@ bool Shader::create(const std::string& vertex, const std::string& fragment) } glLinkProgram(ps); - glGetProgramiv(ps, GL_LINK_STATUS, &status); + glGetProgramiv(ps, program_link_status_query(), &status); glGetProgramInfoLog(ps, sizeof(infolog), &infolen, infolog); if (infolen > 0) LOG("LINK SHADER: %s\n%s", m_path.c_str(), infolog); @@ -257,7 +294,7 @@ bool Shader::create(const std::string& vertex, const std::string& fragment) const GLsizei bufSize = 64; // maximum name length GLchar name[bufSize]; // variable name in GLSL GLsizei length; // name length - glGetProgramiv(ps, GL_ACTIVE_UNIFORMS, &count); + glGetProgramiv(ps, active_uniform_count_query(), &count); for (int i = 0; i < count; i++) { glGetActiveUniform(ps, (GLuint)i, bufSize, &length, &size, &type, name); @@ -318,7 +355,7 @@ void Shader::u_mat4(kShaderUniform id, const glm::mat4& m) { if (m_umap.count(id) == 0) LOG("UNIFORM mat4 %d NOT FOUND in shader %d", (int)id, (int)name) - else glUniformMatrix4fv(m_umap[id], 1, GL_FALSE, glm::value_ptr(m)); + else glUniformMatrix4fv(m_umap[id], 1, matrix_uniform_not_transposed(), glm::value_ptr(m)); } void Shader::u_int(kShaderUniform id, int i) { @@ -327,9 +364,9 @@ void Shader::u_int(kShaderUniform id, int i) else glUniform1i(m_umap[id], i); } -void Shader::u_int(const char* name, int i) +void Shader::u_int(const char* uniform_name, int i) { - glUniform1i(glGetAttribLocation(prog, name), i); + glUniform1i(glGetAttribLocation(prog, uniform_name), i); } void Shader::u_float(kShaderUniform id, float f) { @@ -337,9 +374,9 @@ void Shader::u_float(kShaderUniform id, float f) LOG("UNIFORM float %d NOT FOUND in shader %d", (int)id, (int)name) else glUniform1f(m_umap[id], f); } -GLint Shader::GetAttribLocation(const char* name) +GLint Shader::GetAttribLocation(const char* attribute_name) { - return glGetAttribLocation(prog, name); + return glGetAttribLocation(prog, attribute_name); } bool ShaderManager::load(kShader id, const std::string& path) diff --git a/src/shader.h b/src/shader.h index f6dedd8..d44bd40 100644 --- a/src/shader.h +++ b/src/shader.h @@ -99,9 +99,9 @@ public: void u_vec2(kShaderUniform id, const glm::vec2& v); void u_mat4(kShaderUniform id, const glm::mat4& m); void u_int(kShaderUniform id, int i); - void u_int(const char* name, int i); + void u_int(const char* uniform_name, int i); void u_float(kShaderUniform id, float f); - GLint GetAttribLocation(const char* name); + GLint GetAttribLocation(const char* attribute_name); }; class ShaderManager diff --git a/tests/renderer_gl/capabilities_tests.cpp b/tests/renderer_gl/capabilities_tests.cpp index 3524d77..8b1f631 100644 --- a/tests/renderer_gl/capabilities_tests.cpp +++ b/tests/renderer_gl/capabilities_tests.cpp @@ -285,6 +285,13 @@ void exposes_shader_attribute_binding_catalog(pp::tests::Harness& h) { const auto bindings = pp::renderer::gl::panopainter_shader_attribute_bindings(); + PP_EXPECT(h, pp::renderer::gl::vertex_shader_stage() == 0x8B31U); + PP_EXPECT(h, pp::renderer::gl::fragment_shader_stage() == 0x8B30U); + PP_EXPECT(h, pp::renderer::gl::shader_compile_status_query() == 0x8B81U); + PP_EXPECT(h, pp::renderer::gl::program_link_status_query() == 0x8B82U); + PP_EXPECT(h, pp::renderer::gl::active_uniform_count_query() == 0x8B86U); + PP_EXPECT(h, pp::renderer::gl::matrix_uniform_not_transposed() == 0U); + PP_EXPECT(h, bindings.size() == 5U); PP_EXPECT(h, pp::renderer::gl::validate_shader_attribute_bindings(bindings).ok()); PP_EXPECT(h, std::strcmp(bindings[0].name, "pos") == 0);