diff --git a/docs/modernization/build-inventory.md b/docs/modernization/build-inventory.md index acc5f22..0204591 100644 --- a/docs/modernization/build-inventory.md +++ b/docs/modernization/build-inventory.md @@ -144,9 +144,10 @@ Known local toolchain state: status used by `RTT::create` and framebuffer bind/restore paths, plus RTT clear color/depth masks and color-write-mask query tokens. `RTT` no longer spells GL enum names directly. It also - validates Shape index-type and fill/stroke primitive-mode mapping used by the - legacy mesh draw path, plus the PanoPainter cube-face to OpenGL texture-target - mapping used by `TextureCube`. + validates Shape index-type, fill/stroke primitive-mode, buffer target, static + upload usage, and vertex attribute component/normalization mapping used by + the legacy mesh draw path, plus the PanoPainter cube-face to OpenGL + 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 diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index acaef04..f5e969c 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -405,8 +405,10 @@ used by `RTT::create` and framebuffer bind/restore paths, also live in `pp_renderer_gl`. RTT clear color/depth masks and color-write-mask query tokens also live in `pp_renderer_gl`. `RTT` no longer spells GL enum names directly. Mesh index-type and primitive-mode -decisions used by legacy `Shape` drawing and the PanoPainter cube-face to -OpenGL texture-target mapping used by `TextureCube` also live in +decisions used by legacy `Shape` drawing, plus Shape buffer targets, static +upload usage, and vertex attribute component/normalization tokens, also live +in `pp_renderer_gl`. The PanoPainter cube-face to +OpenGL texture-target mapping used by `TextureCube` also lives in `pp_renderer_gl`. The legacy app delegates extension, upload-format, framebuffer diagnostic, framebuffer blit, render-target setup, clear-state, 2D/cube texture setup, mesh draw-mode, and cube-face texture-target diff --git a/src/renderer_gl/opengl_capabilities.cpp b/src/renderer_gl/opengl_capabilities.cpp index 259a945..df1642e 100644 --- a/src/renderer_gl/opengl_capabilities.cpp +++ b/src/renderer_gl/opengl_capabilities.cpp @@ -11,9 +11,13 @@ constexpr std::uint32_t gl_unsigned_short = 0x1403U; constexpr std::uint32_t gl_unsigned_int = 0x1405U; constexpr std::uint32_t gl_float = 0x1406U; constexpr std::uint32_t gl_half_float = 0x140BU; +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_array_buffer = 0x8892U; +constexpr std::uint32_t gl_element_array_buffer = 0x8893U; +constexpr std::uint32_t gl_static_draw = 0x88E4U; constexpr std::uint32_t gl_red = 0x1903U; constexpr std::uint32_t gl_rgb = 0x1907U; constexpr std::uint32_t gl_rgba = 0x1908U; @@ -329,6 +333,31 @@ std::uint32_t primitive_mode_for_stroke_count(std::uint32_t vertex_or_index_coun return gl_lines; } +std::uint32_t array_buffer_target() noexcept +{ + return gl_array_buffer; +} + +std::uint32_t element_array_buffer_target() noexcept +{ + return gl_element_array_buffer; +} + +std::uint32_t static_draw_buffer_usage() noexcept +{ + return gl_static_draw; +} + +std::uint32_t vertex_attribute_float_component_type() noexcept +{ + return gl_float; +} + +std::uint32_t vertex_attribute_not_normalized() 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 fcb9c86..a23d807 100644 --- a/src/renderer_gl/opengl_capabilities.h +++ b/src/renderer_gl/opengl_capabilities.h @@ -75,6 +75,11 @@ 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 array_buffer_target() noexcept; +[[nodiscard]] std::uint32_t element_array_buffer_target() noexcept; +[[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 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/shape.cpp b/src/shape.cpp index bba55d1..bbaa4f2 100644 --- a/src/shape.cpp +++ b/src/shape.cpp @@ -6,6 +6,40 @@ #include +namespace { + +[[nodiscard]] GLenum array_buffer_target() noexcept +{ + return static_cast(pp::renderer::gl::array_buffer_target()); +} + +[[nodiscard]] GLenum element_array_buffer_target() noexcept +{ + return static_cast(pp::renderer::gl::element_array_buffer_target()); +} + +[[nodiscard]] GLenum static_draw_buffer_usage() noexcept +{ + return static_cast(pp::renderer::gl::static_draw_buffer_usage()); +} + +[[nodiscard]] GLenum vertex_attribute_float_component_type() noexcept +{ + return static_cast(pp::renderer::gl::vertex_attribute_float_component_type()); +} + +[[nodiscard]] GLboolean vertex_attribute_not_normalized() noexcept +{ + return static_cast(pp::renderer::gl::vertex_attribute_not_normalized()); +} + +[[nodiscard]] GLenum uint16_index_type() noexcept +{ + return static_cast(pp::renderer::gl::index_type_for_index_size(sizeof(GLushort))); +} + +} + bool Shape::create_buffers(GLushort * idx, GLvoid * vertices, int isize, int vsize) { index_type = static_cast(pp::renderer::gl::index_type_for_index_size(sizeof(GLushort))); @@ -36,12 +70,12 @@ bool Shape::create_buffers_imp(GLvoid* idx, GLvoid* vertices, int isize, int vsi return; } - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, isize, idx, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); - glBufferData(GL_ARRAY_BUFFER, vsize, vertices, GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(element_array_buffer_target(), buffers[1]); + glBufferData(element_array_buffer_target(), isize, idx, static_draw_buffer_usage()); + glBindBuffer(array_buffer_target(), buffers[0]); + glBufferData(array_buffer_target(), vsize, vertices, static_draw_buffer_usage()); + glBindBuffer(element_array_buffer_target(), 0); + glBindBuffer(array_buffer_target(), 0); #if USE_VBO glGenVertexArrays(2, arrays); @@ -57,12 +91,12 @@ bool Shape::create_buffers_imp(GLvoid* idx, GLvoid* vertices, int isize, int vsi glEnableVertexAttribArray(1); glEnableVertexAttribArray(2); glEnableVertexAttribArray(3); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); - glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)0); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, uvs)); - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, uvs2)); - glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, nor)); + glBindBuffer(element_array_buffer_target(), buffers[1]); + glBindBuffer(array_buffer_target(), buffers[0]); + glVertexAttribPointer(0, 4, vertex_attribute_float_component_type(), vertex_attribute_not_normalized(), sizeof(vertex_t), (GLvoid*)0); + glVertexAttribPointer(1, 2, vertex_attribute_float_component_type(), vertex_attribute_not_normalized(), sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, uvs)); + glVertexAttribPointer(2, 2, vertex_attribute_float_component_type(), vertex_attribute_not_normalized(), sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, uvs2)); + glVertexAttribPointer(3, 3, vertex_attribute_float_component_type(), vertex_attribute_not_normalized(), sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, nor)); } glBindVertexArray(0); #endif @@ -87,10 +121,10 @@ bool Shape::create_buffers(GLvoid* vertices, int vsize) if (vsize) { - glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); - glBufferData(GL_ARRAY_BUFFER, vsize, vertices, GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(array_buffer_target(), buffers[0]); + glBufferData(array_buffer_target(), vsize, vertices, static_draw_buffer_usage()); + glBindBuffer(element_array_buffer_target(), 0); + glBindBuffer(array_buffer_target(), 0); } #if USE_VBO @@ -107,11 +141,11 @@ bool Shape::create_buffers(GLvoid* vertices, int vsize) glEnableVertexAttribArray(1); glEnableVertexAttribArray(2); glEnableVertexAttribArray(3); - glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)0); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, uvs)); - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, uvs2)); - glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, nor)); + glBindBuffer(array_buffer_target(), buffers[0]); + glVertexAttribPointer(0, 4, vertex_attribute_float_component_type(), vertex_attribute_not_normalized(), sizeof(vertex_t), (GLvoid*)0); + glVertexAttribPointer(1, 2, vertex_attribute_float_component_type(), vertex_attribute_not_normalized(), sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, uvs)); + glVertexAttribPointer(2, 2, vertex_attribute_float_component_type(), vertex_attribute_not_normalized(), sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, uvs2)); + glVertexAttribPointer(3, 3, vertex_attribute_float_component_type(), vertex_attribute_not_normalized(), sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, nor)); } glBindVertexArray(0); #endif @@ -135,20 +169,20 @@ void Shape::draw_fill() const #else glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); - glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)0); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, uvs)); + glBindBuffer(array_buffer_target(), buffers[0]); + glVertexAttribPointer(0, 4, vertex_attribute_float_component_type(), vertex_attribute_not_normalized(), sizeof(vertex_t), (GLvoid*)0); + glVertexAttribPointer(1, 2, vertex_attribute_float_component_type(), vertex_attribute_not_normalized(), sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, uvs)); if (use_idx) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); - glDrawElements(type, count[0], GL_UNSIGNED_SHORT, ioff[0]); + glBindBuffer(element_array_buffer_target(), buffers[1]); + glDrawElements(type, count[0], uint16_index_type(), ioff[0]); } else glDrawArrays(type, 0, count[0]); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindBuffer(array_buffer_target(), 0); + glBindBuffer(element_array_buffer_target(), 0); #endif // USE_VBO }); } @@ -169,21 +203,21 @@ void Shape::draw_stroke() const #else glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); - glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)0); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, uvs)); + glBindBuffer(element_array_buffer_target(), buffers[1]); + glBindBuffer(array_buffer_target(), buffers[0]); + glVertexAttribPointer(0, 4, vertex_attribute_float_component_type(), vertex_attribute_not_normalized(), sizeof(vertex_t), (GLvoid*)0); + glVertexAttribPointer(1, 2, vertex_attribute_float_component_type(), vertex_attribute_not_normalized(), sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, uvs)); if (use_idx) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); - glDrawElements(type, count[1], GL_UNSIGNED_SHORT, ioff[1]); + glBindBuffer(element_array_buffer_target(), buffers[1]); + glDrawElements(type, count[1], uint16_index_type(), ioff[1]); } else glDrawArrays(type, 0, count[1]); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindBuffer(array_buffer_target(), 0); + glBindBuffer(element_array_buffer_target(), 0); #endif // USE_VBO }); } @@ -489,8 +523,8 @@ void Plane::update_vertices(const glm::vec4* data, const glm::vec2* uvs, const g App::I->render_task([this] { - glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + glBindBuffer(array_buffer_target(), buffers[0]); + glBufferData(array_buffer_target(), sizeof(vertices), vertices, static_draw_buffer_usage()); static GLushort idx[6 + 8]{ 0, 1, 2, 0, 2, 3, @@ -499,11 +533,11 @@ void Plane::update_vertices(const glm::vec4* data, const glm::vec2* uvs, const g 2, 3, 3, 0, }; - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(idx), idx, GL_STATIC_DRAW); + glBindBuffer(element_array_buffer_target(), buffers[1]); + glBufferData(element_array_buffer_target(), sizeof(idx), idx, static_draw_buffer_usage()); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindBuffer(array_buffer_target(), 0); + glBindBuffer(element_array_buffer_target(), 0); }); } void Circle::create_impl(float radius, int div, GLushort* idx, vertex_t* vertices) @@ -762,9 +796,9 @@ void LineSegment::update_vertices(const glm::vec4 data[2]) static vertex_t vertices[2]; vertices[0] = { data[0], { 0, 0 } }; // A vertices[1] = { data[1], { 0, 1 } }; // B - glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(array_buffer_target(), buffers[0]); + glBufferData(array_buffer_target(), sizeof(vertices), vertices, static_draw_buffer_usage()); + glBindBuffer(array_buffer_target(), 0); }); } void DynamicShape::update_vertices(vertex_t* vertices, int vcount) @@ -773,8 +807,8 @@ void DynamicShape::update_vertices(vertex_t* vertices, int vcount) { count[0] = vcount; count[1] = vcount; - glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_t) * vcount, vertices, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(array_buffer_target(), buffers[0]); + glBufferData(array_buffer_target(), sizeof(vertex_t) * vcount, vertices, static_draw_buffer_usage()); + glBindBuffer(array_buffer_target(), 0); }); } diff --git a/tests/renderer_gl/capabilities_tests.cpp b/tests/renderer_gl/capabilities_tests.cpp index cb789fe..3524d77 100644 --- a/tests/renderer_gl/capabilities_tests.cpp +++ b/tests/renderer_gl/capabilities_tests.cpp @@ -192,6 +192,7 @@ void maps_shape_index_and_primitive_modes(pp::tests::Harness& h) constexpr std::uint32_t gl_triangles = 0x0004U; constexpr std::uint32_t gl_unsigned_short = 0x1403U; constexpr std::uint32_t gl_unsigned_int = 0x1405U; + constexpr std::uint32_t gl_float = 0x1406U; PP_EXPECT(h, pp::renderer::gl::index_type_for_index_size(2U) == gl_unsigned_short); PP_EXPECT(h, pp::renderer::gl::index_type_for_index_size(4U) == gl_unsigned_int); @@ -206,6 +207,12 @@ void maps_shape_index_and_primitive_modes(pp::tests::Harness& h) PP_EXPECT(h, pp::renderer::gl::primitive_mode_for_stroke_count(1U) == gl_points); PP_EXPECT(h, pp::renderer::gl::primitive_mode_for_stroke_count(2U) == gl_lines); PP_EXPECT(h, pp::renderer::gl::primitive_mode_for_stroke_count(99U) == gl_lines); + + PP_EXPECT(h, pp::renderer::gl::array_buffer_target() == 0x8892U); + PP_EXPECT(h, pp::renderer::gl::element_array_buffer_target() == 0x8893U); + PP_EXPECT(h, pp::renderer::gl::static_draw_buffer_usage() == 0x88E4U); + PP_EXPECT(h, pp::renderer::gl::vertex_attribute_float_component_type() == gl_float); + PP_EXPECT(h, pp::renderer::gl::vertex_attribute_not_normalized() == 0U); } void maps_panopainter_cube_faces_to_texture_targets(pp::tests::Harness& h)