Route RTT utility clears through GL backend
This commit is contained in:
@@ -464,6 +464,45 @@ pp::foundation::Status clear_panopainter_default_target(OpenGlClearDispatch disp
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Status clear_opengl_render_target(
|
||||
OpenGlDefaultClear clear,
|
||||
OpenGlClearDispatch dispatch) noexcept
|
||||
{
|
||||
if (dispatch.clear_color == nullptr || dispatch.clear == nullptr) {
|
||||
return pp::foundation::Status::invalid_argument("OpenGL render-target clear dispatch callbacks must not be null");
|
||||
}
|
||||
|
||||
if (clear.mask == 0U) {
|
||||
return pp::foundation::Status::invalid_argument("OpenGL render-target clear mask is invalid");
|
||||
}
|
||||
|
||||
dispatch.clear_color(clear.color[0], clear.color[1], clear.color[2], clear.color[3]);
|
||||
dispatch.clear(clear.mask);
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Status clear_opengl_color_buffer_with_write_mask(
|
||||
OpenGlColorMaskedClear clear,
|
||||
OpenGlColorMaskedClearDispatch dispatch) noexcept
|
||||
{
|
||||
if (dispatch.get_boolean == nullptr
|
||||
|| dispatch.color_mask == nullptr
|
||||
|| dispatch.clear_color == nullptr
|
||||
|| dispatch.clear == nullptr) {
|
||||
return pp::foundation::Status::invalid_argument(
|
||||
"OpenGL color-masked clear dispatch callbacks must not be null");
|
||||
}
|
||||
|
||||
std::array<std::uint8_t, 4> old_mask {};
|
||||
dispatch.get_boolean(color_write_mask_query(), old_mask.data());
|
||||
|
||||
dispatch.color_mask(clear.mask.r, clear.mask.g, clear.mask.b, clear.mask.a);
|
||||
dispatch.clear_color(clear.color[0], clear.color[1], clear.color[2], clear.color[3]);
|
||||
dispatch.clear(framebuffer_color_buffer_mask());
|
||||
dispatch.color_mask(old_mask[0], old_mask[1], old_mask[2], old_mask[3]);
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Status apply_opengl_viewport(
|
||||
OpenGlViewportRect viewport,
|
||||
OpenGlViewportDispatch dispatch) noexcept
|
||||
|
||||
@@ -316,9 +316,15 @@ using OpenGlCapabilityFn = void (*)(std::uint32_t state) noexcept;
|
||||
using OpenGlIsEnabledFn = std::uint8_t (*)(std::uint32_t state) noexcept;
|
||||
using OpenGlGetIntegerFn = void (*)(std::uint32_t name, std::int32_t* value) noexcept;
|
||||
using OpenGlGetFloatFn = void (*)(std::uint32_t name, float* value) noexcept;
|
||||
using OpenGlGetBooleanFn = void (*)(std::uint32_t name, std::uint8_t* value) noexcept;
|
||||
using OpenGlActiveTextureFn = void (*)(std::uint32_t texture_unit) noexcept;
|
||||
using OpenGlClearColorFn = void (*)(float r, float g, float b, float a) noexcept;
|
||||
using OpenGlClearFn = void (*)(std::uint32_t mask) noexcept;
|
||||
using OpenGlColorMaskFn = void (*)(
|
||||
std::uint8_t r,
|
||||
std::uint8_t g,
|
||||
std::uint8_t b,
|
||||
std::uint8_t a) noexcept;
|
||||
using OpenGlViewportFn = void (*)(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height) noexcept;
|
||||
using OpenGlScissorFn = void (*)(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height) noexcept;
|
||||
using OpenGlBlendFuncFn = void (*)(std::uint32_t source_factor, std::uint32_t destination_factor) noexcept;
|
||||
@@ -547,11 +553,23 @@ struct OpenGlDefaultClear {
|
||||
std::uint32_t mask = 0;
|
||||
};
|
||||
|
||||
struct OpenGlColorMaskedClear {
|
||||
OpenGlColorWriteMask mask;
|
||||
std::array<float, 4> color {};
|
||||
};
|
||||
|
||||
struct OpenGlClearDispatch {
|
||||
OpenGlClearColorFn clear_color = nullptr;
|
||||
OpenGlClearFn clear = nullptr;
|
||||
};
|
||||
|
||||
struct OpenGlColorMaskedClearDispatch {
|
||||
OpenGlGetBooleanFn get_boolean = nullptr;
|
||||
OpenGlColorMaskFn color_mask = nullptr;
|
||||
OpenGlClearColorFn clear_color = nullptr;
|
||||
OpenGlClearFn clear = nullptr;
|
||||
};
|
||||
|
||||
struct OpenGlViewportDispatch {
|
||||
OpenGlViewportFn viewport = nullptr;
|
||||
};
|
||||
@@ -854,6 +872,12 @@ struct OpenGlMeshDeleteDispatch {
|
||||
OpenGlExtensionQueryDispatch dispatch);
|
||||
[[nodiscard]] OpenGlDefaultClear panopainter_default_clear() noexcept;
|
||||
[[nodiscard]] pp::foundation::Status clear_panopainter_default_target(OpenGlClearDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status clear_opengl_render_target(
|
||||
OpenGlDefaultClear clear,
|
||||
OpenGlClearDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status clear_opengl_color_buffer_with_write_mask(
|
||||
OpenGlColorMaskedClear clear,
|
||||
OpenGlColorMaskedClearDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status apply_opengl_viewport(
|
||||
OpenGlViewportRect viewport,
|
||||
OpenGlViewportDispatch dispatch) noexcept;
|
||||
|
||||
81
src/rtt.cpp
81
src/rtt.cpp
@@ -29,11 +29,31 @@ void query_opengl_integer(std::uint32_t name, std::int32_t* value) noexcept
|
||||
glGetIntegerv(static_cast<GLenum>(name), reinterpret_cast<GLint*>(value));
|
||||
}
|
||||
|
||||
void query_opengl_boolean(std::uint32_t name, std::uint8_t* value) noexcept
|
||||
{
|
||||
glGetBooleanv(static_cast<GLenum>(name), reinterpret_cast<GLboolean*>(value));
|
||||
}
|
||||
|
||||
void bind_opengl_framebuffer(std::uint32_t target, std::uint32_t framebuffer) noexcept
|
||||
{
|
||||
glBindFramebuffer(static_cast<GLenum>(target), static_cast<GLuint>(framebuffer));
|
||||
}
|
||||
|
||||
void set_opengl_clear_color(float r, float g, float b, float a) noexcept
|
||||
{
|
||||
glClearColor(r, g, b, a);
|
||||
}
|
||||
|
||||
void clear_opengl_buffers(std::uint32_t mask) noexcept
|
||||
{
|
||||
glClear(static_cast<GLbitfield>(mask));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void gen_opengl_textures(std::uint32_t count, std::uint32_t* ids) noexcept
|
||||
{
|
||||
glGenTextures(static_cast<GLsizei>(count), reinterpret_cast<GLuint*>(ids));
|
||||
@@ -649,26 +669,41 @@ void RTT::unbindFramebuffer()
|
||||
void RTT::clear(glm::vec4 color)
|
||||
{
|
||||
assert(App::I->is_render_thread());
|
||||
glClearColor(color.r, color.g, color.b, color.a);
|
||||
glClear(static_cast<GLbitfield>(
|
||||
pp::renderer::gl::framebuffer_color_buffer_mask()
|
||||
| pp::renderer::gl::framebuffer_depth_buffer_mask()));
|
||||
const auto status = pp::renderer::gl::clear_opengl_render_target(
|
||||
pp::renderer::gl::OpenGlDefaultClear {
|
||||
.color = { color.r, color.g, color.b, color.a },
|
||||
.mask = pp::renderer::gl::framebuffer_color_buffer_mask()
|
||||
| pp::renderer::gl::framebuffer_depth_buffer_mask(),
|
||||
},
|
||||
pp::renderer::gl::OpenGlClearDispatch {
|
||||
.clear_color = set_opengl_clear_color,
|
||||
.clear = clear_opengl_buffers,
|
||||
});
|
||||
if (!status.ok())
|
||||
LOG("RTT::clear() failed because: %s", status.message);
|
||||
}
|
||||
|
||||
void RTT::clear_mask(glm::bool4 mask, glm::vec4 color)
|
||||
{
|
||||
assert(App::I->is_render_thread());
|
||||
// save old state
|
||||
std::array<GLboolean, 4> old_mask;
|
||||
glGetBooleanv(static_cast<GLenum>(pp::renderer::gl::color_write_mask_query()), old_mask.data());
|
||||
|
||||
// clear with mask
|
||||
glColorMask(mask.r, mask.g, mask.b, mask.a);
|
||||
glClearColor(color.r, color.g, color.b, color.a);
|
||||
glClear(static_cast<GLbitfield>(pp::renderer::gl::framebuffer_color_buffer_mask()));
|
||||
|
||||
// restore old state
|
||||
glColorMask(old_mask[0], old_mask[1], old_mask[2], old_mask[3]);
|
||||
const auto status = pp::renderer::gl::clear_opengl_color_buffer_with_write_mask(
|
||||
pp::renderer::gl::OpenGlColorMaskedClear {
|
||||
.mask = {
|
||||
.r = static_cast<std::uint8_t>(mask.r),
|
||||
.g = static_cast<std::uint8_t>(mask.g),
|
||||
.b = static_cast<std::uint8_t>(mask.b),
|
||||
.a = static_cast<std::uint8_t>(mask.a),
|
||||
},
|
||||
.color = { color.r, color.g, color.b, color.a },
|
||||
},
|
||||
pp::renderer::gl::OpenGlColorMaskedClearDispatch {
|
||||
.get_boolean = query_opengl_boolean,
|
||||
.color_mask = set_opengl_color_mask,
|
||||
.clear_color = set_opengl_clear_color,
|
||||
.clear = clear_opengl_buffers,
|
||||
});
|
||||
if (!status.ok())
|
||||
LOG("RTT::clear_mask() failed because: %s", status.message);
|
||||
}
|
||||
|
||||
glm::ivec4 RTT::calc_bounds() const noexcept
|
||||
@@ -803,13 +838,25 @@ float * RTT::createBufferFloat() const noexcept
|
||||
void RTT::bindTexture()
|
||||
{
|
||||
assert(App::I->is_render_thread());
|
||||
glBindTexture(texture_2d_target(), texID);
|
||||
const auto status = pp::renderer::gl::bind_opengl_texture_2d(
|
||||
static_cast<std::uint32_t>(texID),
|
||||
pp::renderer::gl::OpenGlTexture2DBindDispatch {
|
||||
.bind_texture = bind_opengl_texture,
|
||||
});
|
||||
if (!status.ok())
|
||||
LOG("RTT::bindTexture() failed because: %s", status.message);
|
||||
}
|
||||
|
||||
void RTT::unbindTexture()
|
||||
{
|
||||
assert(App::I->is_render_thread());
|
||||
glBindTexture(texture_2d_target(), 0);
|
||||
const auto status = pp::renderer::gl::bind_opengl_texture_2d(
|
||||
0U,
|
||||
pp::renderer::gl::OpenGlTexture2DBindDispatch {
|
||||
.bind_texture = bind_opengl_texture,
|
||||
});
|
||||
if (!status.ok())
|
||||
LOG("RTT::unbindTexture() failed because: %s", status.message);
|
||||
}
|
||||
|
||||
Image RTT::get_image() const noexcept
|
||||
|
||||
Reference in New Issue
Block a user