diff --git a/docs/modernization/build-inventory.md b/docs/modernization/build-inventory.md index c11f976..384bc5f 100644 --- a/docs/modernization/build-inventory.md +++ b/docs/modernization/build-inventory.md @@ -133,7 +133,9 @@ Known local toolchain state: invalid channel counts rejected by `Texture2D::create(Image)`, RGBA8/RGBA32F readback formats, byte-count math, and PBO pixel-buffer target/usage/access mapping used by `RTT` and `PBO` readbacks, and framebuffer status naming - used by `RTT` diagnostics. It also owns and + 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 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 e96218b..7ff14ae 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -391,7 +391,9 @@ float texture support. It also owns the OpenGL texture upload-type mapping used by legacy `Texture2D` and `RTT` creation, RGBA pixel-format mapping used by `RTT` texture allocation, plus image channel-count to texture format mapping for `Texture2D` image uploads and framebuffer status naming for -`RTT` diagnostics. RGBA8/RGBA32F readback formats, byte-count math, and PBO +`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 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 diff --git a/src/renderer_gl/opengl_capabilities.cpp b/src/renderer_gl/opengl_capabilities.cpp index f71e83a..3a76fca 100644 --- a/src/renderer_gl/opengl_capabilities.cpp +++ b/src/renderer_gl/opengl_capabilities.cpp @@ -123,6 +123,11 @@ std::uint32_t texture_upload_type_for_internal_format(std::uint32_t internal_for } } +std::uint32_t unsigned_byte_component_type() noexcept +{ + return gl_unsigned_byte; +} + std::uint32_t rgba_pixel_format() noexcept { return gl_rgba; diff --git a/src/renderer_gl/opengl_capabilities.h b/src/renderer_gl/opengl_capabilities.h index d307583..8173e24 100644 --- a/src/renderer_gl/opengl_capabilities.h +++ b/src/renderer_gl/opengl_capabilities.h @@ -43,6 +43,7 @@ struct OpenGlReadbackFormat { OpenGlRuntime runtime) noexcept; [[nodiscard]] std::uint32_t texture_upload_type_for_internal_format(std::uint32_t internal_format) noexcept; +[[nodiscard]] std::uint32_t unsigned_byte_component_type() noexcept; [[nodiscard]] std::uint32_t rgba_pixel_format() noexcept; [[nodiscard]] OpenGlPixelFormat texture_format_for_channel_count(std::uint32_t channel_count) noexcept; [[nodiscard]] OpenGlReadbackFormat rgba8_readback_format() noexcept; diff --git a/src/texture.cpp b/src/texture.cpp index f9015bc..465fcab 100644 --- a/src/texture.cpp +++ b/src/texture.cpp @@ -7,6 +7,25 @@ #include +namespace { + +[[nodiscard]] GLenum texture_2d_target() noexcept +{ + return static_cast(pp::renderer::gl::texture_2d_target()); +} + +[[nodiscard]] GLenum framebuffer_target() noexcept +{ + return static_cast(pp::renderer::gl::framebuffer_target()); +} + +[[nodiscard]] GLenum draw_framebuffer_binding_query() noexcept +{ + return static_cast(pp::renderer::gl::draw_framebuffer_binding_query()); +} + +} + std::map TextureManager::m_textures; std::array TextureCube::m_faces_map { static_cast(pp::renderer::gl::cube_face_texture_target(0U)), @@ -125,21 +144,35 @@ Image Texture2D::get_image() const noexcept return; GLint oldFboID; - glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldFboID); + glGetIntegerv(draw_framebuffer_binding_query(), &oldFboID); - glBindFramebuffer(GL_FRAMEBUFFER, fboID); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_tex, 0); - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status == GL_FRAMEBUFFER_COMPLETE) + glBindFramebuffer(framebuffer_target(), fboID); + glFramebufferTexture2D( + framebuffer_target(), + static_cast(pp::renderer::gl::framebuffer_color_attachment()), + texture_2d_target(), + m_tex, + 0); + GLenum status = glCheckFramebufferStatus(framebuffer_target()); + if (status == static_cast(pp::renderer::gl::framebuffer_complete_status())) { - glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, ret.m_data.get()); + const auto readback = pp::renderer::gl::rgba8_readback_format(); + glReadPixels( + 0, + 0, + m_width, + m_height, + static_cast(readback.pixel_format), + static_cast(readback.component_type), + ret.m_data.get()); } else { - LOG("Texture2D::get_image() failed because framebuffer status = %d", (int)status); + LOG("Texture2D::get_image() failed because: %s", + pp::renderer::gl::framebuffer_status_name(static_cast(status))); } - glBindFramebuffer(GL_FRAMEBUFFER, oldFboID); + glBindFramebuffer(framebuffer_target(), oldFboID); glDeleteFramebuffers(1, &fboID); }); return ret; @@ -181,7 +214,7 @@ bool Texture2D::create(int width, int height, GLint internal_format, GLint forma bind(); const auto ifmt = static_cast( pp::renderer::gl::texture_upload_type_for_internal_format(static_cast(internal_format))); - glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, format, ifmt, data); + glTexImage2D(texture_2d_target(), 0, internal_format, width, height, 0, format, ifmt, data); unbind(); }); return true; @@ -205,7 +238,7 @@ void Texture2D::create_mipmaps() App::I->render_task([this] { bind(); - glGenerateMipmap(GL_TEXTURE_2D); + glGenerateMipmap(texture_2d_target()); unbind(); has_mips = true; }); @@ -253,13 +286,13 @@ void Texture2D::destroy() void Texture2D::bind() const { assert(App::I->is_render_thread()); - glBindTexture(GL_TEXTURE_2D, m_tex); + glBindTexture(texture_2d_target(), m_tex); } void Texture2D::unbind() const { assert(App::I->is_render_thread()); - glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(texture_2d_target(), 0); } void Texture2D::update(const uint8_t* data) @@ -267,7 +300,16 @@ void Texture2D::update(const uint8_t* data) App::I->render_task([this, data] { bind(); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_width, m_height, m_format, GL_UNSIGNED_BYTE, data); + glTexSubImage2D( + texture_2d_target(), + 0, + 0, + 0, + m_width, + m_height, + m_format, + static_cast(pp::renderer::gl::unsigned_byte_component_type()), + data); }); } diff --git a/tests/renderer_gl/capabilities_tests.cpp b/tests/renderer_gl/capabilities_tests.cpp index fc08bf1..d6cd8e9 100644 --- a/tests/renderer_gl/capabilities_tests.cpp +++ b/tests/renderer_gl/capabilities_tests.cpp @@ -84,6 +84,7 @@ void selects_texture_upload_type_from_internal_format(pp::tests::Harness& h) PP_EXPECT(h, pp::renderer::gl::texture_upload_type_for_internal_format(gl_rgba32f) == gl_float); PP_EXPECT(h, pp::renderer::gl::texture_upload_type_for_internal_format(gl_rgba16f) == gl_half_float); PP_EXPECT(h, pp::renderer::gl::texture_upload_type_for_internal_format(0U) == gl_unsigned_byte); + PP_EXPECT(h, pp::renderer::gl::unsigned_byte_component_type() == gl_unsigned_byte); PP_EXPECT(h, pp::renderer::gl::rgba_pixel_format() == 0x1908U); }