diff --git a/docs/modernization/build-inventory.md b/docs/modernization/build-inventory.md index 15b0e12..b17a9f1 100644 --- a/docs/modernization/build-inventory.md +++ b/docs/modernization/build-inventory.md @@ -132,10 +132,11 @@ Known local toolchain state: invalid channel counts rejected by `Texture2D::create(Image)`, and framebuffer status naming used by `RTT` diagnostics. It also validates Shape index-type and fill/stroke primitive-mode mapping used by the legacy - mesh draw path, plus the PanoPainter shader attribute binding catalog used - by legacy `Shader` creation. It also owns the PanoPainter shader uniform - catalog and legacy hash mapping used by `Shader` active-uniform discovery and - the uniform uniqueness check. + mesh draw path, plus the PanoPainter cube-face to OpenGL texture-target + mapping used by `TextureCube`. 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 mapping used by `Shader` + active-uniform discovery and the uniform uniqueness check. - `windows-msvc-vcpkg-headless` validates manifest install/configure/build/test for the current headless component matrix; see DEBT-0007 for remaining app and platform triplet migration. diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index badc41e..8da6f83 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -391,9 +391,10 @@ float texture support. It also owns the OpenGL texture upload-type mapping used by legacy `Texture2D` and `RTT` creation, plus image channel-count to texture format mapping for `Texture2D` image uploads and framebuffer status naming for `RTT` diagnostics. Mesh index-type and primitive-mode decisions used by legacy -`Shape` drawing also live in `pp_renderer_gl`. The legacy app delegates -extension, upload-format, framebuffer diagnostic, and mesh draw-mode -interpretation to that backend library. The PanoPainter shader attribute +`Shape` drawing and the PanoPainter cube-face to OpenGL texture-target mapping +used by `TextureCube` also live in `pp_renderer_gl`. The legacy app delegates +extension, upload-format, framebuffer diagnostic, mesh draw-mode, and cube-face +texture-target interpretation to that backend library. 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 @@ -640,10 +641,11 @@ Results: WebGL exclusion behavior, upload types for RGBA8/RGBA16F/RGBA32F internal formats, image channel-count format mapping including invalid counts, and framebuffer status names, plus Shape index-type and fill/stroke primitive - mode mapping. Shader attribute binding catalog validation covers the current - `pos`, `uvs`, `uvs2`, `col`, and `nor` bindings and rejects empty, unnamed, - null-name, and duplicate-name catalogs while preserving legacy shared - locations. Shader uniform catalog validation covers the 43 legacy uniform + mode mapping and PanoPainter cube-face texture-target order. Shader attribute + binding catalog validation covers the current `pos`, `uvs`, `uvs2`, `col`, + and `nor` bindings and rejects empty, unnamed, null-name, and duplicate-name + catalogs while preserving legacy shared locations. Shader uniform catalog + validation covers the 43 legacy uniform names used by `Shader`, preserves the legacy hash ids, and rejects empty, unnamed, null-name, mismatched-hash, and duplicate-name catalogs. - PowerShell analyze automation returns JSON summaries and includes the shader diff --git a/src/renderer_gl/opengl_capabilities.cpp b/src/renderer_gl/opengl_capabilities.cpp index f4a5871..992eab2 100644 --- a/src/renderer_gl/opengl_capabilities.cpp +++ b/src/renderer_gl/opengl_capabilities.cpp @@ -1,5 +1,7 @@ #include "renderer_gl/opengl_capabilities.h" +#include + namespace pp::renderer::gl { namespace { @@ -30,6 +32,12 @@ constexpr std::uint32_t gl_framebuffer_incomplete_read_buffer = 0x8CDCU; constexpr std::uint32_t gl_framebuffer_unsupported = 0x8CDDU; constexpr std::uint32_t gl_framebuffer_undefined = 0x8219U; constexpr std::uint32_t gl_framebuffer_incomplete_multisample = 0x8D56U; +constexpr std::uint32_t gl_texture_cube_map_positive_x = 0x8515U; +constexpr std::uint32_t gl_texture_cube_map_negative_x = 0x8516U; +constexpr std::uint32_t gl_texture_cube_map_positive_y = 0x8517U; +constexpr std::uint32_t gl_texture_cube_map_negative_y = 0x8518U; +constexpr std::uint32_t gl_texture_cube_map_positive_z = 0x8519U; +constexpr std::uint32_t gl_texture_cube_map_negative_z = 0x851AU; [[nodiscard]] bool contains(std::string_view text, std::string_view needle) noexcept { @@ -163,4 +171,28 @@ std::uint32_t primitive_mode_for_stroke_count(std::uint32_t vertex_or_index_coun return gl_lines; } +std::span panopainter_cube_face_texture_targets() noexcept +{ + static constexpr std::array targets { + gl_texture_cube_map_negative_z, // front + gl_texture_cube_map_negative_x, // right + gl_texture_cube_map_positive_z, // back + gl_texture_cube_map_positive_x, // left + gl_texture_cube_map_negative_y, // top + gl_texture_cube_map_positive_y, // bottom + }; + + return targets; +} + +std::uint32_t cube_face_texture_target(std::uint32_t face_index) noexcept +{ + const auto targets = panopainter_cube_face_texture_targets(); + if (face_index >= targets.size()) { + return 0U; + } + + return targets[face_index]; +} + } diff --git a/src/renderer_gl/opengl_capabilities.h b/src/renderer_gl/opengl_capabilities.h index c9de5de..6b6dd41 100644 --- a/src/renderer_gl/opengl_capabilities.h +++ b/src/renderer_gl/opengl_capabilities.h @@ -36,5 +36,7 @@ struct OpenGlPixelFormat { [[nodiscard]] std::uint32_t index_type_for_index_size(std::uint32_t index_size_bytes) noexcept; [[nodiscard]] std::uint32_t primitive_mode_for_fill_count(std::uint32_t vertex_or_index_count) noexcept; [[nodiscard]] std::uint32_t primitive_mode_for_stroke_count(std::uint32_t vertex_or_index_count) noexcept; +[[nodiscard]] std::span panopainter_cube_face_texture_targets() noexcept; +[[nodiscard]] std::uint32_t cube_face_texture_target(std::uint32_t face_index) noexcept; } diff --git a/src/texture.cpp b/src/texture.cpp index a2df446..22d572e 100644 --- a/src/texture.cpp +++ b/src/texture.cpp @@ -9,12 +9,12 @@ std::map TextureManager::m_textures; std::array TextureCube::m_faces_map { - GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, // front - GL_TEXTURE_CUBE_MAP_NEGATIVE_X, // right - GL_TEXTURE_CUBE_MAP_POSITIVE_Z, // back - GL_TEXTURE_CUBE_MAP_POSITIVE_X, // left - GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, // top - GL_TEXTURE_CUBE_MAP_POSITIVE_Y, // bottom + static_cast(pp::renderer::gl::cube_face_texture_target(0U)), + static_cast(pp::renderer::gl::cube_face_texture_target(1U)), + static_cast(pp::renderer::gl::cube_face_texture_target(2U)), + static_cast(pp::renderer::gl::cube_face_texture_target(3U)), + static_cast(pp::renderer::gl::cube_face_texture_target(4U)), + static_cast(pp::renderer::gl::cube_face_texture_target(5U)), }; TextureCube::TextureCube(TextureCube&& other) noexcept diff --git a/tests/renderer_gl/capabilities_tests.cpp b/tests/renderer_gl/capabilities_tests.cpp index 28e6998..a7d092e 100644 --- a/tests/renderer_gl/capabilities_tests.cpp +++ b/tests/renderer_gl/capabilities_tests.cpp @@ -158,6 +158,22 @@ void maps_shape_index_and_primitive_modes(pp::tests::Harness& h) PP_EXPECT(h, pp::renderer::gl::primitive_mode_for_stroke_count(99U) == gl_lines); } +void maps_panopainter_cube_faces_to_texture_targets(pp::tests::Harness& h) +{ + const auto targets = pp::renderer::gl::panopainter_cube_face_texture_targets(); + + PP_EXPECT(h, targets.size() == 6U); + PP_EXPECT(h, targets[0] == 0x851AU); + PP_EXPECT(h, targets[1] == 0x8516U); + PP_EXPECT(h, targets[2] == 0x8519U); + PP_EXPECT(h, targets[3] == 0x8515U); + PP_EXPECT(h, targets[4] == 0x8518U); + PP_EXPECT(h, targets[5] == 0x8517U); + PP_EXPECT(h, pp::renderer::gl::cube_face_texture_target(0U) == 0x851AU); + PP_EXPECT(h, pp::renderer::gl::cube_face_texture_target(5U) == 0x8517U); + PP_EXPECT(h, pp::renderer::gl::cube_face_texture_target(6U) == 0U); +} + void exposes_shader_attribute_binding_catalog(pp::tests::Harness& h) { const auto bindings = pp::renderer::gl::panopainter_shader_attribute_bindings(); @@ -260,6 +276,7 @@ int main() harness.run("maps_image_channel_count_to_texture_format", maps_image_channel_count_to_texture_format); harness.run("names_framebuffer_status_codes", names_framebuffer_status_codes); harness.run("maps_shape_index_and_primitive_modes", maps_shape_index_and_primitive_modes); + harness.run("maps_panopainter_cube_faces_to_texture_targets", maps_panopainter_cube_faces_to_texture_targets); harness.run("exposes_shader_attribute_binding_catalog", exposes_shader_attribute_binding_catalog); harness.run("rejects_invalid_shader_attribute_binding_catalogs", rejects_invalid_shader_attribute_binding_catalogs); harness.run("exposes_shader_uniform_catalog", exposes_shader_uniform_catalog);