Extract canvas object draw and brush panel services

This commit is contained in:
2026-06-16 18:43:14 +02:00
parent b56a46a82c
commit a5002a4e3e
10 changed files with 504 additions and 279 deletions

View File

@@ -10,6 +10,7 @@
#include "legacy_canvas_stroke_edge_services.h"
#include "legacy_canvas_stroke_execution_services.h"
#include "legacy_canvas_stroke_shader_services.h"
#include "legacy_canvas_object_draw_services.h"
#include "legacy_canvas_projection_services.h"
#include "legacy_canvas_stroke_services.h"
#include "legacy_ui_gl_dispatch.h"
@@ -2531,149 +2532,12 @@ void Canvas::clear_context()
void Canvas::draw_objects_direct(std::function<void(const glm::mat4& camera, const glm::mat4& proj, int i)> observer, Layer& layer, int frame)
{
App::I->render_task([&]
{
// save viewport and clear color states
const auto vp = query_canvas_viewport();
const auto cc = query_canvas_clear_color();
auto blend = query_canvas_capability(blend_state());
// prepare common states
apply_canvas_viewport(0, 0, layer.w, layer.h);
apply_canvas_capability(blend_state(), false);
GLuint rboID = allocate_canvas_depth_renderbuffer(layer.w, layer.h);
glm::mat4 proj = glm::perspective(glm::radians(90.f), 1.f, .01f, 1000.f);
for (int i = 0; i < 6; i++)
{
glm::mat4 plane_camera = glm::lookAt(glm::vec3(0), m_plane_origin[i], m_plane_tangent[i]);
layer.rtt(i, frame).bindFramebuffer();
attach_canvas_depth_renderbuffer(rboID);
observer(plane_camera, proj, i);
attach_canvas_depth_renderbuffer(0);
layer.rtt(i, frame).unbindFramebuffer();
layer.face(i, frame) = true;
layer.box(i, frame) = { 0, 0, layer.w, layer.h };
}
delete_canvas_renderbuffer(rboID);
// restore viewport and clear color states
blend ? apply_canvas_capability(blend_state(), true) : apply_canvas_capability(blend_state(), false);
apply_canvas_viewport(vp.x, vp.y, vp.width, vp.height);
apply_canvas_clear_color(cc);
set_active_texture_unit(0);
});
pp::panopainter::legacy_canvas_draw_objects_direct(*this, std::move(observer), layer, frame);
}
void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm::mat4& proj, int i)> observer, Layer& layer, int frame, bool save_history)
{
App::I->render_task([&]
{
// save viewport and clear color states
const auto vp = query_canvas_viewport();
const auto cc = query_canvas_clear_color();
auto blend = query_canvas_capability(blend_state());
// prepare common states
apply_canvas_viewport(0, 0, layer.w, layer.h);
apply_canvas_capability(blend_state(), false);
GLuint rboID = allocate_canvas_depth_renderbuffer(layer.w, layer.h);
RTT rtt;
rtt.create(layer.w, layer.h);
rtt.bindFramebuffer();
attach_canvas_depth_renderbuffer(rboID);
rtt.unbindFramebuffer();
// allocate action to add to history
ActionStroke* action;
if (save_history)
{
action = new ActionStroke;
action->was_saved = !m_unsaved;
}
glm::mat4 proj = glm::perspective(glm::radians(90.f), 1.f, .01f, 1000.f);
for (int i = 0; i < 6; i++)
{
glm::mat4 plane_camera = glm::lookAt(glm::vec3(0), m_plane_origin[i], m_plane_tangent[i]);
rtt.bindFramebuffer();
rtt.clear({ 1, 1, 1, 0 });
observer(plane_camera, proj, i);
rtt.unbindFramebuffer();
glm::vec4 bounds = rtt.calc_bounds();
layer.rtt(i, frame).bindFramebuffer();
glm::vec2 box_sz = zw(bounds) - xy(bounds);
bool has_data = box_sz.x > 0 && box_sz.y > 0;
if (save_history)
{
// save image before commit
if (has_data)
{
action->m_image[i] = std::make_unique<uint8_t[]>(box_sz.x * box_sz.y * 4);
layer.rtt(i, frame).readPixelsRgba8(
static_cast<int>(bounds.x),
static_cast<int>(bounds.y),
static_cast<int>(box_sz.x),
static_cast<int>(box_sz.y),
action->m_image[i].get());
action->m_box[i] = bounds;
}
action->m_old_box[i] = layer.box(i, frame);
action->m_old_dirty[i] = layer.face(i, frame);
}
// draw the tmp layer into the actual layer
if (has_data)
{
pp::panopainter::setup_legacy_canvas_draw_merge_texture_shader(
pp::panopainter::LegacyCanvasDrawMergeTextureUniforms {
.mvp = glm::ortho(-0.5f, 0.5f, -0.5f, 0.5f),
.texture_slot = 0,
});
set_active_texture_unit(0);
m_sampler_nearest.bind(0);
rtt.bindTexture();
m_plane.draw_fill();
rtt.unbindTexture();
layer.face(i, frame) = true;
layer.box(i, frame) = { glm::min(xy(layer.box(i, frame)), xy(bounds)), glm::max(zw(layer.box(i, frame)), zw(bounds)) };
}
layer.rtt(i, frame).unbindFramebuffer();
}
if (save_history)
{
// save history
action->m_layer_idx = m_current_layer_idx;
action->m_frame_idx = frame;
action->m_canvas = this;
//action->m_stroke = std::move(m_current_stroke);
ActionManager::add(action);
}
delete_canvas_renderbuffer(rboID);
rtt.destroy();
// restore viewport and clear color states
blend ? apply_canvas_capability(blend_state(), true) : apply_canvas_capability(blend_state(), false);
apply_canvas_viewport(vp.x, vp.y, vp.width, vp.height);
apply_canvas_clear_color(cc);
set_active_texture_unit(0);
});
pp::panopainter::legacy_canvas_draw_objects(*this, std::move(observer), layer, frame, save_history);
}
void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm::mat4& proj, int i)> observer, int frame, bool save_history)