#pragma once #include #include #include "log.h" #include "renderer_gl/opengl_capabilities.h" namespace pp::legacy::ui_gl { inline void enable_opengl_state(std::uint32_t state) noexcept { glEnable(static_cast(state)); } inline std::uint8_t is_opengl_state_enabled(std::uint32_t state) noexcept { return static_cast(glIsEnabled(static_cast(state))); } inline void disable_opengl_state(std::uint32_t state) noexcept { glDisable(static_cast(state)); } inline void activate_opengl_texture(std::uint32_t texture_unit) noexcept { glActiveTexture(static_cast(texture_unit)); } inline void clear_opengl_buffer(std::uint32_t mask) noexcept { glClear(static_cast(mask)); } inline void set_opengl_color_mask(std::uint8_t r, std::uint8_t g, std::uint8_t b, std::uint8_t a) noexcept { glColorMask(r, g, b, a); } inline void get_opengl_boolean(std::uint32_t name, std::uint8_t* value) noexcept { glGetBooleanv(static_cast(name), reinterpret_cast(value)); } inline void set_opengl_clear_color(float r, float g, float b, float a) noexcept { glClearColor(r, g, b, a); } inline void set_opengl_blend_func(std::uint32_t source_factor, std::uint32_t destination_factor) noexcept { glBlendFunc(static_cast(source_factor), static_cast(destination_factor)); } inline void set_opengl_blend_equation(std::uint32_t equation) noexcept { glBlendEquation(static_cast(equation)); } inline void set_opengl_blend_equation_separate(std::uint32_t color_equation, std::uint32_t alpha_equation) noexcept { glBlendEquationSeparate(static_cast(color_equation), static_cast(alpha_equation)); } inline void set_opengl_viewport(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height) noexcept { glViewport(static_cast(x), static_cast(y), static_cast(width), static_cast(height)); } inline void set_opengl_scissor(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height) noexcept { glScissor(static_cast(x), static_cast(y), static_cast(width), static_cast(height)); } inline void bind_opengl_texture(std::uint32_t target, std::uint32_t texture) noexcept { glBindTexture(static_cast(target), static_cast(texture)); } inline void bind_opengl_framebuffer(std::uint32_t target, std::uint32_t framebuffer) noexcept { glBindFramebuffer(static_cast(target), static_cast(framebuffer)); } inline void read_opengl_pixels( std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height, std::uint32_t pixel_format, std::uint32_t component_type, void* pixels) noexcept { glReadPixels( static_cast(x), static_cast(y), static_cast(width), static_cast(height), static_cast(pixel_format), static_cast(component_type), pixels); } inline void get_opengl_integer_scalar(std::uint32_t name, std::int32_t* value) noexcept { GLint raw_value = 0; glGetIntegerv(static_cast(name), &raw_value); *value = static_cast(raw_value); } inline void get_opengl_integer(std::uint32_t name, std::int32_t* values) noexcept { GLint raw_values[4] {}; glGetIntegerv(static_cast(name), raw_values); values[0] = static_cast(raw_values[0]); values[1] = static_cast(raw_values[1]); values[2] = static_cast(raw_values[2]); values[3] = static_cast(raw_values[3]); } inline void get_opengl_float(std::uint32_t name, float* values) noexcept { glGetFloatv(static_cast(name), values); } inline std::array query_viewport(const char* context) { std::array viewport {}; get_opengl_integer(pp::renderer::gl::viewport_query(), viewport.data()); (void)context; return viewport; } inline pp::renderer::gl::OpenGlViewportRect query_viewport_rect(const char* context) { const auto result = pp::renderer::gl::query_opengl_viewport( pp::renderer::gl::OpenGlViewportQueryDispatch { .get_integer = get_opengl_integer, }); if (!result.ok()) LOG("%s viewport query dispatch failed because: %s", context, result.status().message); return result.value(); } inline std::array query_clear_color(const char* context) { std::array color {}; get_opengl_float(pp::renderer::gl::color_clear_value_query(), color.data()); (void)context; return color; } inline bool query_capability(std::uint32_t state, const char* context) { const auto result = pp::renderer::gl::query_opengl_capability_state( state, pp::renderer::gl::OpenGlCapabilityStateQueryDispatch { .is_enabled = is_opengl_state_enabled, }); if (!result.ok()) { LOG("%s capability query failed because: %s", context, result.status().message); return false; } return result.value(); } inline std::uint32_t query_read_framebuffer(const char* context) { std::int32_t read_framebuffer = 0; get_opengl_integer_scalar(pp::renderer::gl::read_framebuffer_binding_query(), &read_framebuffer); (void)context; return static_cast(read_framebuffer); } inline void set_capability(std::uint32_t state, bool enabled, const char* context) { const auto status = pp::renderer::gl::apply_opengl_capability( state, enabled, pp::renderer::gl::OpenGlCapabilityDispatch { .enable = enable_opengl_state, .disable = disable_opengl_state, }); if (!status.ok()) LOG("%s capability dispatch failed because: %s", context, status.message); } inline void activate_texture_unit(std::uint32_t unit_index, const char* context) { const auto status = pp::renderer::gl::activate_opengl_texture_unit( unit_index, pp::renderer::gl::OpenGlActiveTextureDispatch { .active_texture = activate_opengl_texture, }); if (!status.ok()) LOG("%s active texture dispatch failed because: %s", context, status.message); } inline void set_blend_enabled(bool enabled, const char* context) { set_capability(pp::renderer::gl::blend_state(), enabled, context); } inline void apply_viewport( std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height, const char* context) { const auto status = pp::renderer::gl::apply_opengl_viewport( pp::renderer::gl::OpenGlViewportRect { .x = x, .y = y, .width = width, .height = height, }, pp::renderer::gl::OpenGlViewportDispatch { .viewport = set_opengl_viewport, }); if (!status.ok()) LOG("%s viewport dispatch failed because: %s", context, status.message); } inline void apply_scissor_rect( std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height, const char* context) { const auto status = pp::renderer::gl::apply_opengl_scissor_rect( pp::renderer::gl::OpenGlScissorRect { .enabled = 1U, .x = x, .y = y, .width = width, .height = height, }, pp::renderer::gl::OpenGlScissorDispatch { .enable = enable_opengl_state, .disable = disable_opengl_state, .scissor = set_opengl_scissor, }); if (!status.ok()) LOG("%s scissor dispatch failed because: %s", context, status.message); } inline void clear_depth_buffer(const char* context) { const auto status = pp::renderer::gl::clear_opengl_buffers( pp::renderer::gl::framebuffer_depth_buffer_mask(), pp::renderer::gl::OpenGlBufferClearDispatch { .clear = clear_opengl_buffer, }); if (!status.ok()) LOG("%s depth clear dispatch failed because: %s", context, status.message); } inline void set_color_write_mask( std::uint8_t r, std::uint8_t g, std::uint8_t b, std::uint8_t a, const char* context) { const auto status = pp::renderer::gl::apply_opengl_color_write_mask( pp::renderer::gl::OpenGlColorWriteMask { .r = r, .g = g, .b = b, .a = a, }, pp::renderer::gl::OpenGlColorWriteMaskDispatch { .color_mask = set_opengl_color_mask, }); if (!status.ok()) LOG("%s color mask dispatch failed because: %s", context, status.message); } inline void read_framebuffer_rgba8_pixel( std::uint32_t framebuffer, std::int32_t x, std::int32_t y, void* pixel, const char* context) { const auto status = pp::renderer::gl::readback_opengl_framebuffer( pp::renderer::gl::OpenGlFramebufferReadback { .framebuffer = framebuffer, .x = x, .y = y, .width = 1, .height = 1, .format = pp::renderer::gl::rgba8_readback_format(), .pixels = pixel, }, pp::renderer::gl::OpenGlFramebufferReadbackDispatch { .get_integer = get_opengl_integer_scalar, .bind_framebuffer = bind_opengl_framebuffer, .read_pixels = read_opengl_pixels, }); if (!status.ok()) LOG("%s pixel readback dispatch failed because: %s", context, status.message); } inline void clear_color_buffer(std::array color, const char* context) { const auto status = pp::renderer::gl::clear_opengl_render_target( pp::renderer::gl::OpenGlDefaultClear { .color = color, .mask = pp::renderer::gl::framebuffer_color_buffer_mask(), }, pp::renderer::gl::OpenGlClearDispatch { .clear_color = set_opengl_clear_color, .clear = clear_opengl_buffer, }); if (!status.ok()) LOG("%s clear dispatch failed because: %s", context, status.message); } inline void set_clear_color(std::array color, const char* context) { const auto status = pp::renderer::gl::clear_opengl_render_target( pp::renderer::gl::OpenGlDefaultClear { .color = color, .mask = pp::renderer::gl::framebuffer_color_buffer_mask(), }, pp::renderer::gl::OpenGlClearDispatch { .clear_color = set_opengl_clear_color, .clear = [](std::uint32_t) noexcept {}, }); if (!status.ok()) LOG("%s clear-color dispatch failed because: %s", context, status.message); } inline void unbind_texture_2d(const char* context) { const auto status = pp::renderer::gl::bind_opengl_texture_2d( 0U, pp::renderer::gl::OpenGlTexture2DBindDispatch { .bind_texture = bind_opengl_texture, }); if (!status.ok()) LOG("%s texture bind dispatch failed because: %s", context, status.message); } inline void bind_texture_cube(std::uint32_t texture_id, const char* context) { const auto status = pp::renderer::gl::bind_opengl_texture_cube( texture_id, pp::renderer::gl::OpenGlTexture2DBindDispatch { .bind_texture = bind_opengl_texture, }); if (!status.ok()) LOG("%s cube texture bind dispatch failed because: %s", context, status.message); } } // namespace pp::legacy::ui_gl