diff --git a/docs/modernization/build-inventory.md b/docs/modernization/build-inventory.md index 384bc5f..acc5f22 100644 --- a/docs/modernization/build-inventory.md +++ b/docs/modernization/build-inventory.md @@ -135,7 +135,8 @@ Known local toolchain state: mapping used by `RTT` and `PBO` readbacks, and framebuffer status naming used by `RTT` and `Texture2D` diagnostics. It also owns the 2D texture target, framebuffer setup, readback format, mipmap target, and update component-type - tokens used by `Texture2D`. It also owns and + tokens used by `Texture2D`, plus cube-map binding and allocation face targets + used by `TextureCube`. It also owns and validates framebuffer blit color mask and linear/nearest filters used by `RTT::resize` and `RTT::copy`, plus the default linear clamp-to-edge render-target texture parameters, texture/renderbuffer targets, depth format, diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index 7ff14ae..acaef04 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -393,7 +393,9 @@ by legacy `Texture2D` and `RTT` creation, RGBA pixel-format mapping used by format mapping for `Texture2D` image uploads and framebuffer status naming for `RTT` and `Texture2D` diagnostics. `Texture2D` 2D texture binding, upload, mipmap generation, framebuffer readback setup, and update component-type tokens -now delegate to `pp_renderer_gl`. RGBA8/RGBA32F readback formats, byte-count math, and PBO +now delegate to `pp_renderer_gl`. `TextureCube` cube-map binding, allocation +face targets, RGBA allocation format, and unsigned-byte component type also +delegate to `pp_renderer_gl`. RGBA8/RGBA32F readback formats, byte-count math, and PBO pixel-buffer target/usage/access tokens used by `RTT` and `PBO` readbacks now live in `pp_renderer_gl`. The framebuffer blit color mask and linear/nearest filter tokens used by `RTT::resize` and `RTT::copy`, plus the default @@ -407,8 +409,8 @@ decisions used by legacy `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, framebuffer blit, render-target setup, clear-state, -mesh draw-mode, and cube-face texture-target interpretation to that backend -library. Sampler wrap, min/mag filter, and desktop border-color parameter +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 diff --git a/src/renderer_gl/opengl_capabilities.cpp b/src/renderer_gl/opengl_capabilities.cpp index 3a76fca..259a945 100644 --- a/src/renderer_gl/opengl_capabilities.cpp +++ b/src/renderer_gl/opengl_capabilities.cpp @@ -45,6 +45,7 @@ constexpr std::uint32_t gl_framebuffer_incomplete_multisample = 0x8D56U; constexpr std::uint32_t gl_color_buffer_bit = 0x00004000U; constexpr std::uint32_t gl_depth_buffer_bit = 0x00000100U; constexpr std::uint32_t gl_color_writemask = 0x0C23U; +constexpr std::uint32_t gl_texture_cube_map = 0x8513U; 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; @@ -328,6 +329,20 @@ std::uint32_t primitive_mode_for_stroke_count(std::uint32_t vertex_or_index_coun return gl_lines; } +std::uint32_t texture_cube_map_target() noexcept +{ + return gl_texture_cube_map; +} + +std::uint32_t cube_map_allocation_face_texture_target(std::uint32_t face_index) noexcept +{ + if (face_index >= 6U) { + return 0U; + } + + return gl_texture_cube_map_positive_x + face_index; +} + std::span panopainter_cube_face_texture_targets() noexcept { static constexpr std::array targets { diff --git a/src/renderer_gl/opengl_capabilities.h b/src/renderer_gl/opengl_capabilities.h index 8173e24..fcb9c86 100644 --- a/src/renderer_gl/opengl_capabilities.h +++ b/src/renderer_gl/opengl_capabilities.h @@ -75,6 +75,8 @@ struct OpenGlReadbackFormat { [[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::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; [[nodiscard]] std::uint32_t cube_face_texture_target(std::uint32_t face_index) noexcept; [[nodiscard]] std::span default_render_target_texture_parameters() noexcept; diff --git a/src/texture.cpp b/src/texture.cpp index 465fcab..aecfc0c 100644 --- a/src/texture.cpp +++ b/src/texture.cpp @@ -14,6 +14,11 @@ namespace { return static_cast(pp::renderer::gl::texture_2d_target()); } +[[nodiscard]] GLenum texture_cube_map_target() noexcept +{ + return static_cast(pp::renderer::gl::texture_cube_map_target()); +} + [[nodiscard]] GLenum framebuffer_target() noexcept { return static_cast(pp::renderer::gl::framebuffer_target()); @@ -66,11 +71,21 @@ bool TextureCube::create(int resolution) noexcept if (!m_cubetex_id) return; - glBindTexture(GL_TEXTURE_CUBE_MAP, m_cubetex_id); + glBindTexture(texture_cube_map_target(), m_cubetex_id); + const auto format = pp::renderer::gl::texture_format_for_channel_count(4U); + const auto component_type = static_cast(pp::renderer::gl::unsigned_byte_component_type()); for (GLuint i = 0; i < 6; i++) { - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA8, - m_resolution, m_resolution, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glTexImage2D( + static_cast(pp::renderer::gl::cube_map_allocation_face_texture_target(i)), + 0, + static_cast(format.internal_format), + m_resolution, + m_resolution, + 0, + static_cast(format.pixel_format), + component_type, + nullptr); } }); return m_cubetex_id != 0; @@ -82,7 +97,7 @@ void TextureCube::destroy() noexcept { App::I->render_task([f=m_faces, id=m_cubetex_id] { - glDeleteTextures(f.size(), f.data()); + glDeleteTextures(static_cast(f.size()), f.data()); glDeleteTextures(1, &id); }); m_cubetex_id = 0; @@ -94,7 +109,7 @@ void TextureCube::destroy() noexcept void TextureCube::bind() const noexcept { assert(App::I->is_render_thread()); - glBindTexture(GL_TEXTURE_CUBE_MAP, m_cubetex_id); + glBindTexture(texture_cube_map_target(), m_cubetex_id); } bool TextureManager::load(const char* path, bool generate_mipmaps) diff --git a/tests/renderer_gl/capabilities_tests.cpp b/tests/renderer_gl/capabilities_tests.cpp index d6cd8e9..cb789fe 100644 --- a/tests/renderer_gl/capabilities_tests.cpp +++ b/tests/renderer_gl/capabilities_tests.cpp @@ -212,6 +212,15 @@ 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, pp::renderer::gl::texture_cube_map_target() == 0x8513U); + PP_EXPECT(h, pp::renderer::gl::cube_map_allocation_face_texture_target(0U) == 0x8515U); + PP_EXPECT(h, pp::renderer::gl::cube_map_allocation_face_texture_target(1U) == 0x8516U); + PP_EXPECT(h, pp::renderer::gl::cube_map_allocation_face_texture_target(2U) == 0x8517U); + PP_EXPECT(h, pp::renderer::gl::cube_map_allocation_face_texture_target(3U) == 0x8518U); + PP_EXPECT(h, pp::renderer::gl::cube_map_allocation_face_texture_target(4U) == 0x8519U); + PP_EXPECT(h, pp::renderer::gl::cube_map_allocation_face_texture_target(5U) == 0x851AU); + PP_EXPECT(h, pp::renderer::gl::cube_map_allocation_face_texture_target(6U) == 0U); + PP_EXPECT(h, targets.size() == 6U); PP_EXPECT(h, targets[0] == 0x851AU); PP_EXPECT(h, targets[1] == 0x8516U);