Extract final canvas wrappers and preview mix pass
This commit is contained in:
@@ -79,13 +79,13 @@ What is still carrying too much live ownership:
|
|||||||
|
|
||||||
Current hotspot files:
|
Current hotspot files:
|
||||||
|
|
||||||
- `src/canvas.cpp`: 368 lines
|
- `src/canvas.cpp`: 17 lines
|
||||||
- `src/app_layout.cpp`: 125 lines
|
- `src/app_layout.cpp`: 125 lines
|
||||||
- `src/canvas_modes.cpp`: 402 lines
|
- `src/canvas_modes.cpp`: 402 lines
|
||||||
- `src/node.cpp`: 260 lines
|
- `src/node.cpp`: 260 lines
|
||||||
- `src/main.cpp`: 130 lines
|
- `src/main.cpp`: 130 lines
|
||||||
- `src/node_panel_brush.cpp`: 255 lines
|
- `src/node_panel_brush.cpp`: 231 lines
|
||||||
- `src/node_stroke_preview.cpp`: 490 lines
|
- `src/node_stroke_preview.cpp`: 343 lines
|
||||||
- `src/node_canvas.cpp`: 219 lines
|
- `src/node_canvas.cpp`: 219 lines
|
||||||
- `src/app.cpp`: 113 lines
|
- `src/app.cpp`: 113 lines
|
||||||
- `src/app_dialogs.cpp`: 168 lines
|
- `src/app_dialogs.cpp`: 168 lines
|
||||||
@@ -262,6 +262,10 @@ Current architecture mismatches that must be treated as real blockers:
|
|||||||
pass planning, shader setup, and live render request assembly now also
|
pass planning, shader setup, and live render request assembly now also
|
||||||
routes through `src/legacy_node_stroke_preview_runtime_services.*` instead
|
routes through `src/legacy_node_stroke_preview_runtime_services.*` instead
|
||||||
of staying inline in `src/node_stroke_preview.cpp`, while
|
of staying inline in `src/node_stroke_preview.cpp`, while
|
||||||
|
`NodeStrokePreview` remaining mix-pass planning and execution now also route
|
||||||
|
through `src/legacy_node_stroke_preview_draw_services.*`, which trims the
|
||||||
|
last dedicated mix-orchestration pocket from `src/node_stroke_preview.cpp`,
|
||||||
|
while
|
||||||
`NodeCanvas::draw()` unmerged-pass blend-gate, layer-orientation, and
|
`NodeCanvas::draw()` unmerged-pass blend-gate, layer-orientation, and
|
||||||
callback-assembly setup now also route through
|
callback-assembly setup now also route through
|
||||||
`execute_node_canvas_draw_unmerged_pass(...)`, which trims another coherent
|
`execute_node_canvas_draw_unmerged_pass(...)`, which trims another coherent
|
||||||
@@ -320,7 +324,11 @@ Current architecture mismatches that must be treated as real blockers:
|
|||||||
panel UI pocket, while the retained `LegacyBrushPresetListServices` block
|
panel UI pocket, while the retained `LegacyBrushPresetListServices` block
|
||||||
now also lives in `src/legacy_brush_preset_list_services.*` instead of
|
now also lives in `src/legacy_brush_preset_list_services.*` instead of
|
||||||
staying inline in `src/node_panel_brush.cpp`, which trims another retained
|
staying inline in `src/node_panel_brush.cpp`, which trims another retained
|
||||||
preset workflow pocket, while `NodeCanvas::handle_event()` now also routes
|
preset popup tail now also lives in `src/legacy_brush_preset_panel_ui.*`
|
||||||
|
instead of staying inline in `src/node_panel_brush.cpp`, which removes the
|
||||||
|
last inline brush-panel popup close handler from the live node. The
|
||||||
|
broader preset workflow pocket still remains, while `NodeCanvas::handle_event()`
|
||||||
|
now also routes
|
||||||
through `execute_node_canvas_handle_event(...)`, which trims another coherent
|
through `execute_node_canvas_handle_event(...)`, which trims another coherent
|
||||||
input-routing block from `src/node_canvas.cpp` even though the file is still
|
input-routing block from `src/node_canvas.cpp` even though the file is still
|
||||||
a live canvas/controller shell, while `NodeCanvas` restore/clear context,
|
a live canvas/controller shell, while `NodeCanvas` restore/clear context,
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ Completed, blocked, and superseded task history moved to
|
|||||||
- `pp_legacy_paint_document`: 7 files, about 5709 lines
|
- `pp_legacy_paint_document`: 7 files, about 5709 lines
|
||||||
- `pp_legacy_app`: 20 files, about 4368 lines
|
- `pp_legacy_app`: 20 files, about 4368 lines
|
||||||
- `pp_legacy_ui_core`: 20 files, about 3770 lines
|
- `pp_legacy_ui_core`: 20 files, about 3770 lines
|
||||||
- The biggest single-file choke points are still `src/canvas.cpp`,
|
- The biggest single-file choke points are still `src/canvas_modes.cpp`,
|
||||||
`src/app_layout.cpp`, `src/canvas_modes.cpp`, `src/node.cpp`,
|
`src/node.cpp`,
|
||||||
`src/main.cpp`, `src/node_panel_brush.cpp`, `src/node_stroke_preview.cpp`,
|
`src/main.cpp`, `src/node_panel_brush.cpp`, `src/node_stroke_preview.cpp`,
|
||||||
`src/node_canvas.cpp`, `src/app.cpp`, and `src/app_dialogs.cpp`.
|
`src/node_canvas.cpp`, `src/app.cpp`, and `src/app_dialogs.cpp`.
|
||||||
- The platform boundary is not finished:
|
- The platform boundary is not finished:
|
||||||
@@ -90,11 +90,16 @@ looks like a wrapper around the old renderer shell.
|
|||||||
Status: In Progress
|
Status: In Progress
|
||||||
|
|
||||||
Why now:
|
Why now:
|
||||||
`src/canvas.cpp` is still the biggest single architectural blocker at about
|
The live `Canvas` ownership boundary is still active, but `src/canvas.cpp`
|
||||||
429 lines, with `src/canvas_modes.cpp` now materially thinner and the next
|
itself is now down to a thin static singleton plus mode-table shell. The
|
||||||
remaining render-shell pressure shifting toward preview/canvas nodes.
|
remaining canvas pressure now sits in the extracted legacy canvas service
|
||||||
|
files and the preview/canvas node render paths rather than the old monolithic
|
||||||
|
translation unit.
|
||||||
|
|
||||||
Current slice:
|
Current slice:
|
||||||
|
- The remaining `Canvas` member wrappers in `src/canvas.cpp` now live in the
|
||||||
|
extracted canvas service files, leaving `canvas.cpp` as the static singleton
|
||||||
|
and mode-table shell.
|
||||||
- Canvas state-management helpers for picking, clear/clear-all, layer
|
- Canvas state-management helpers for picking, clear/clear-all, layer
|
||||||
add/remove/order/lookups, animation frame control, resize, and snapshot
|
add/remove/order/lookups, animation frame control, resize, and snapshot
|
||||||
save/restore now live in `src/legacy_canvas_state_services.cpp` instead of
|
save/restore now live in `src/legacy_canvas_state_services.cpp` instead of
|
||||||
@@ -213,6 +218,9 @@ Current slice:
|
|||||||
`legacy_node_stroke_preview_execution_services.h`, which trims another
|
`legacy_node_stroke_preview_execution_services.h`, which trims another
|
||||||
coherent pass-setup block from `src/node_stroke_preview.cpp`, but broader
|
coherent pass-setup block from `src/node_stroke_preview.cpp`, but broader
|
||||||
preview-pass orchestration is still inline.
|
preview-pass orchestration is still inline.
|
||||||
|
- `NodeStrokePreview` remaining mix-pass planning and execution now also route
|
||||||
|
through `legacy_node_stroke_preview_draw_services.*`, which trims the last
|
||||||
|
dedicated mix-orchestration pocket from `src/node_stroke_preview.cpp`.
|
||||||
- `NodeStrokePreview::draw_stroke_immediate()` immediate preview pass
|
- `NodeStrokePreview::draw_stroke_immediate()` immediate preview pass
|
||||||
sequencing now also routes through the private
|
sequencing now also routes through the private
|
||||||
`execute_stroke_draw_immediate_pass_sequence(...)` helper, which removes
|
`execute_stroke_draw_immediate_pass_sequence(...)` helper, which removes
|
||||||
@@ -1136,6 +1144,10 @@ Current slice:
|
|||||||
`src/node_panel_brush.cpp`, which materially thins another retained preset
|
`src/node_panel_brush.cpp`, which materially thins another retained preset
|
||||||
panel UI pocket even though cloud/package worker ownership remains the
|
panel UI pocket even though cloud/package worker ownership remains the
|
||||||
follow-up.
|
follow-up.
|
||||||
|
- `NodePanelBrushPreset` popup-close event handling now also lives in
|
||||||
|
`src/legacy_brush_preset_panel_ui.*` instead of staying inline in
|
||||||
|
`src/node_panel_brush.cpp`, which trims the remaining inline popup tail
|
||||||
|
from the live brush panel file.
|
||||||
- The retained `LegacyBrushPresetListServices` block now also lives in
|
- The retained `LegacyBrushPresetListServices` block now also lives in
|
||||||
`src/legacy_brush_preset_list_services.*` instead of staying inline in
|
`src/legacy_brush_preset_list_services.*` instead of staying inline in
|
||||||
`src/node_panel_brush.cpp`, which trims another retained preset workflow
|
`src/node_panel_brush.cpp`, which trims another retained preset workflow
|
||||||
|
|||||||
402
src/canvas.cpp
402
src/canvas.cpp
@@ -1,256 +1,5 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "log.h"
|
|
||||||
#include "canvas.h"
|
#include "canvas.h"
|
||||||
#include "legacy_canvas_render_shell_services.h"
|
|
||||||
#include "legacy_ui_gl_dispatch.h"
|
|
||||||
#include "legacy_canvas_stroke_erase_services.h"
|
|
||||||
#include "legacy_gl_renderbuffer_dispatch.h"
|
|
||||||
#include "legacy_canvas_stroke_commit_services.h"
|
|
||||||
#include "legacy_canvas_stroke_composite_services.h"
|
|
||||||
#include "legacy_canvas_stroke_edge_services.h"
|
|
||||||
#include "legacy_canvas_stroke_execution_services.h"
|
|
||||||
#include "legacy_canvas_stroke_runtime_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_overlay_services.h"
|
|
||||||
#include "app_core/document_canvas.h"
|
|
||||||
#include "texture.h"
|
|
||||||
#include "node_progress_bar.h"
|
|
||||||
#include "paint_renderer/compositor.h"
|
|
||||||
#include "renderer_gl/opengl_capabilities.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include <array>
|
|
||||||
#include <condition_variable>
|
|
||||||
#include <deque>
|
|
||||||
#include <mutex>
|
|
||||||
#include <stop_token>
|
|
||||||
#include <thread>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <numeric>
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#include <Foundation/Foundation.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
GLint current_canvas_stroke_internal_format()
|
|
||||||
{
|
|
||||||
const auto renderer_features = ShaderManager::render_device_features();
|
|
||||||
if (renderer_features.float32_linear_filtering)
|
|
||||||
return static_cast<GLint>(pp::renderer::gl::rgba32f_internal_format());
|
|
||||||
if (renderer_features.float16_render_targets)
|
|
||||||
return static_cast<GLint>(pp::renderer::gl::rgba16f_internal_format());
|
|
||||||
return static_cast<GLint>(pp::renderer::gl::rgba8_internal_format());
|
|
||||||
}
|
|
||||||
|
|
||||||
GLint rgba8_internal_format()
|
|
||||||
{
|
|
||||||
return static_cast<GLint>(pp::renderer::gl::rgba8_internal_format());
|
|
||||||
}
|
|
||||||
|
|
||||||
pp::renderer::RenderDeviceFeatures canvas_render_device_features() noexcept
|
|
||||||
{
|
|
||||||
return ShaderManager::render_device_features();
|
|
||||||
}
|
|
||||||
|
|
||||||
pp::paint_renderer::CanvasStrokeRasterizationPlan canvas_stroke_rasterization_plan(
|
|
||||||
int width,
|
|
||||||
int height) noexcept
|
|
||||||
{
|
|
||||||
return pp::panopainter::plan_legacy_canvas_stroke_rasterization(
|
|
||||||
canvas_render_device_features(),
|
|
||||||
width,
|
|
||||||
height);
|
|
||||||
}
|
|
||||||
|
|
||||||
pp::paint_renderer::CanvasStrokeFeedbackPlan canvas_destination_feedback_plan(
|
|
||||||
int width,
|
|
||||||
int height) noexcept
|
|
||||||
{
|
|
||||||
return canvas_stroke_rasterization_plan(width, height).feedback;
|
|
||||||
}
|
|
||||||
|
|
||||||
pp::paint_renderer::CanvasStrokeMaterialPlan canvas_stroke_material_plan(
|
|
||||||
const Brush& brush,
|
|
||||||
bool destination_feedback_needed) noexcept
|
|
||||||
{
|
|
||||||
return pp::panopainter::plan_legacy_canvas_stroke_material(
|
|
||||||
pp::paint_renderer::CanvasStrokeMaterialRequest {
|
|
||||||
.destination_feedback_needed = destination_feedback_needed,
|
|
||||||
.pattern_enabled = brush.m_pattern_enabled,
|
|
||||||
.pattern_eachsample = brush.m_pattern_eachsample,
|
|
||||||
.wet_blend = brush.m_tip_wet > 0.F,
|
|
||||||
.mix_blend = brush.m_tip_mix > 0.F,
|
|
||||||
.noise_enabled = brush.m_tip_noise > 0.F,
|
|
||||||
.dual_brush_enabled = brush.m_dual_enabled,
|
|
||||||
.dual_blend_mode = brush.m_dual_blend_mode,
|
|
||||||
.pattern_blend_mode = brush.m_pattern_blend_mode,
|
|
||||||
.dual_alpha = brush.m_dual_opacity,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pp::renderer::Extent2D canvas_stroke_extent(int width, int height) noexcept
|
|
||||||
{
|
|
||||||
return pp::renderer::Extent2D {
|
|
||||||
.width = static_cast<std::uint32_t>(std::max(width, 0)),
|
|
||||||
.height = static_cast<std::uint32_t>(std::max(height, 0)),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pp::paint_renderer::CanvasBlendGatePlan draw_merge_blend_gate_plan(
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
const std::vector<std::shared_ptr<Layer>>& layers,
|
|
||||||
const Brush* brush) noexcept
|
|
||||||
{
|
|
||||||
std::vector<int> layer_blend_modes;
|
|
||||||
layer_blend_modes.reserve(layers.size());
|
|
||||||
for (const auto& layer : layers) {
|
|
||||||
if (!layer) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
layer_blend_modes.push_back(layer->m_blend_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto plan = pp::paint_renderer::plan_canvas_blend_gate(
|
|
||||||
canvas_render_device_features(),
|
|
||||||
pp::paint_renderer::CanvasBlendGateRequest {
|
|
||||||
.extent = pp::renderer::Extent2D {
|
|
||||||
.width = static_cast<std::uint32_t>(std::max(width, 0)),
|
|
||||||
.height = static_cast<std::uint32_t>(std::max(height, 0)),
|
|
||||||
},
|
|
||||||
.layer_blend_modes = layer_blend_modes,
|
|
||||||
.has_stroke_blend_mode = brush != nullptr,
|
|
||||||
.stroke_blend_mode = brush ? brush->m_blend_mode : 0,
|
|
||||||
});
|
|
||||||
if (plan) {
|
|
||||||
return plan.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
pp::paint_renderer::CanvasBlendGatePlan fallback;
|
|
||||||
fallback.shader_blend = true;
|
|
||||||
fallback.complex_blend = true;
|
|
||||||
fallback.compatibility_fallback = true;
|
|
||||||
return fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLenum depth_test_state()
|
|
||||||
{
|
|
||||||
return static_cast<GLenum>(pp::renderer::gl::depth_test_state());
|
|
||||||
}
|
|
||||||
|
|
||||||
GLenum scissor_test_state()
|
|
||||||
{
|
|
||||||
return static_cast<GLenum>(pp::renderer::gl::scissor_test_state());
|
|
||||||
}
|
|
||||||
|
|
||||||
GLenum blend_state()
|
|
||||||
{
|
|
||||||
return static_cast<GLenum>(pp::renderer::gl::blend_state());
|
|
||||||
}
|
|
||||||
|
|
||||||
GLint texture_filter_linear()
|
|
||||||
{
|
|
||||||
return static_cast<GLint>(pp::renderer::gl::linear_texture_filter());
|
|
||||||
}
|
|
||||||
|
|
||||||
GLint texture_filter_linear_mipmap_linear()
|
|
||||||
{
|
|
||||||
return static_cast<GLint>(pp::renderer::gl::linear_mipmap_linear_texture_filter());
|
|
||||||
}
|
|
||||||
|
|
||||||
GLint texture_filter_nearest()
|
|
||||||
{
|
|
||||||
return static_cast<GLint>(pp::renderer::gl::nearest_texture_filter());
|
|
||||||
}
|
|
||||||
|
|
||||||
GLint texture_wrap_repeat()
|
|
||||||
{
|
|
||||||
return static_cast<GLint>(pp::renderer::gl::repeat_texture_wrap());
|
|
||||||
}
|
|
||||||
|
|
||||||
GLint texture_wrap_clamp_to_border()
|
|
||||||
{
|
|
||||||
return static_cast<GLint>(pp::renderer::gl::clamp_to_border_texture_wrap());
|
|
||||||
}
|
|
||||||
|
|
||||||
pp::renderer::gl::OpenGlPixelFormat texture_format_for_image_channels(int channel_count)
|
|
||||||
{
|
|
||||||
return pp::renderer::gl::texture_format_for_channel_count(static_cast<std::uint32_t>(channel_count));
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_active_texture_unit(std::uint32_t unit_index)
|
|
||||||
{
|
|
||||||
pp::legacy::ui_gl::activate_texture_unit(unit_index, "Canvas");
|
|
||||||
}
|
|
||||||
|
|
||||||
void unbind_texture_2d()
|
|
||||||
{
|
|
||||||
pp::legacy::ui_gl::unbind_texture_2d("Canvas");
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply_canvas_viewport(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height)
|
|
||||||
{
|
|
||||||
pp::legacy::ui_gl::apply_viewport(x, y, width, height, "Canvas");
|
|
||||||
}
|
|
||||||
|
|
||||||
pp::renderer::gl::OpenGlViewportRect query_canvas_viewport()
|
|
||||||
{
|
|
||||||
return pp::legacy::ui_gl::query_viewport_rect("Canvas");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::array<float, 4> query_canvas_clear_color()
|
|
||||||
{
|
|
||||||
return pp::legacy::ui_gl::query_clear_color("Canvas");
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply_canvas_clear_color(std::array<float, 4> color)
|
|
||||||
{
|
|
||||||
pp::legacy::ui_gl::set_clear_color(color, "Canvas");
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply_canvas_scissor(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height)
|
|
||||||
{
|
|
||||||
pp::legacy::ui_gl::apply_scissor_rect(x, y, width, height, "Canvas");
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply_canvas_capability(std::uint32_t state, bool enabled)
|
|
||||||
{
|
|
||||||
pp::legacy::ui_gl::set_capability(state, enabled, "Canvas");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool query_canvas_capability(std::uint32_t state)
|
|
||||||
{
|
|
||||||
return pp::legacy::ui_gl::query_capability(state, "Canvas");
|
|
||||||
}
|
|
||||||
|
|
||||||
GLuint allocate_canvas_depth_renderbuffer(int width, int height)
|
|
||||||
{
|
|
||||||
return static_cast<GLuint>(pp::legacy::gl_renderbuffer::allocate_depth_renderbuffer(
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
"OpenGL canvas depth renderbuffer allocation"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void attach_canvas_depth_renderbuffer(GLuint renderbuffer)
|
|
||||||
{
|
|
||||||
pp::legacy::gl_renderbuffer::attach_depth_renderbuffer(
|
|
||||||
static_cast<std::uint32_t>(renderbuffer),
|
|
||||||
"OpenGL canvas depth renderbuffer attachment");
|
|
||||||
}
|
|
||||||
|
|
||||||
void delete_canvas_renderbuffer(GLuint renderbuffer)
|
|
||||||
{
|
|
||||||
pp::legacy::gl_renderbuffer::delete_renderbuffer(
|
|
||||||
static_cast<std::uint32_t>(renderbuffer),
|
|
||||||
"OpenGL canvas renderbuffer delete");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Canvas* Canvas::I;
|
Canvas* Canvas::I;
|
||||||
std::vector<CanvasMode*> Canvas::modes[] = {
|
std::vector<CanvasMode*> Canvas::modes[] = {
|
||||||
@@ -267,154 +16,3 @@ std::vector<CanvasMode*> Canvas::modes[] = {
|
|||||||
{ new CanvasModeMaskLine, new CanvasModeBasicCamera }, // mask-poly
|
{ new CanvasModeMaskLine, new CanvasModeBasicCamera }, // mask-poly
|
||||||
{ new CanvasModeFloodFill, new CanvasModeBasicCamera }, // flood-fill
|
{ new CanvasModeFloodFill, new CanvasModeBasicCamera }, // flood-fill
|
||||||
};
|
};
|
||||||
|
|
||||||
void Canvas::stroke_end() { pp::panopainter::legacy_canvas_stroke_end(*this); }
|
|
||||||
void Canvas::stroke_cancel() { pp::panopainter::legacy_canvas_stroke_cancel(*this); }
|
|
||||||
void Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz)
|
|
||||||
{
|
|
||||||
pp::panopainter::legacy_canvas_stroke_draw_mix(*this, bb_min, bb_sz);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::array<std::vector<vertex_t>, 6> Canvas::stroke_draw_project(std::array<vertex_t, 4>& B, bool project_3d /*= false*/, glm::mat4 mv /*= glm::mat4(1)*/) const
|
|
||||||
{
|
|
||||||
return pp::panopainter::legacy_canvas_stroke_draw_project(*this, B, project_3d, mv);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Canvas::draw_merge_temporary_paint_branch(
|
|
||||||
int layer_index,
|
|
||||||
int plane_index,
|
|
||||||
std::shared_ptr<Layer> layer,
|
|
||||||
const Brush& brush,
|
|
||||||
const glm::mat4& ortho)
|
|
||||||
{
|
|
||||||
pp::panopainter::legacy_canvas_draw_merge_temporary_paint_branch(
|
|
||||||
*this,
|
|
||||||
layer_index,
|
|
||||||
plane_index,
|
|
||||||
std::move(layer),
|
|
||||||
brush,
|
|
||||||
ortho);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Canvas::draw_merge_branch_orchestration(
|
|
||||||
int plane_index,
|
|
||||||
int layer_index,
|
|
||||||
const std::shared_ptr<Layer>& layer,
|
|
||||||
const Brush& brush,
|
|
||||||
const glm::mat4& ortho,
|
|
||||||
bool use_blend,
|
|
||||||
bool copy_blend_destination)
|
|
||||||
{
|
|
||||||
pp::panopainter::legacy_canvas_draw_merge_branch_orchestration(
|
|
||||||
*this,
|
|
||||||
plane_index,
|
|
||||||
layer_index,
|
|
||||||
layer,
|
|
||||||
brush,
|
|
||||||
ortho,
|
|
||||||
use_blend,
|
|
||||||
copy_blend_destination);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Canvas::draw_merge_final_plane_composite(
|
|
||||||
const glm::mat4& ortho,
|
|
||||||
bool draw_checkerboard)
|
|
||||||
{
|
|
||||||
pp::panopainter::legacy_canvas_draw_merge_final_plane_composite(
|
|
||||||
*this,
|
|
||||||
ortho,
|
|
||||||
draw_checkerboard);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Canvas::stroke_draw()
|
|
||||||
{
|
|
||||||
stroke_draw_live();
|
|
||||||
}
|
|
||||||
bool Canvas::point_trace(glm::vec2 loc, glm::vec3& ray_origin, glm::vec3& ray_dir,
|
|
||||||
glm::vec3& hit_pos, glm::vec2& fb_pos, glm::vec3& hit_normal, int& out_plane_id)
|
|
||||||
{
|
|
||||||
return pp::panopainter::legacy_canvas_point_trace(*this, loc, ray_origin, ray_dir, hit_pos, fb_pos, hit_normal, out_plane_id);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
bool Canvas::point_trace_plane(glm::vec2 loc, glm::vec3& hit_pos, glm::vec2& hit_fb_pos, int plane_id)
|
|
||||||
{
|
|
||||||
auto ln = (loc / zw(m_box)) * 2.f - 1.f;
|
|
||||||
auto p = m_plane_unproject[plane_id] * glm::vec4(ln, 1, 1);
|
|
||||||
if (p.w <= 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
bool Canvas::point_trace_plane(glm::vec2 loc, glm::vec3& ray_origin, glm::vec3& ray_dir,
|
|
||||||
glm::vec3& hit_pos, glm::vec3& hit_normal, glm::vec2& hit_fb_pos, int plane_id)
|
|
||||||
{
|
|
||||||
return pp::panopainter::legacy_canvas_point_trace_plane(*this, loc, ray_origin, ray_dir, hit_pos, hit_normal, hit_fb_pos, plane_id);
|
|
||||||
}
|
|
||||||
void Canvas::point_unproject(glm::vec2 loc, glm::vec4 vp, glm::mat4 camera, glm::mat4 proj,
|
|
||||||
glm::vec3& out_origin, glm::vec3& out_dir)
|
|
||||||
{
|
|
||||||
pp::panopainter::legacy_canvas_point_unproject(loc, vp, camera, proj, out_origin, out_dir);
|
|
||||||
}
|
|
||||||
void Canvas::point_unproject(glm::vec2 loc, glm::vec3& out_origin, glm::vec3& out_dir)
|
|
||||||
{
|
|
||||||
pp::panopainter::legacy_canvas_point_unproject(*this, loc, out_origin, out_dir);
|
|
||||||
}
|
|
||||||
glm::vec3 Canvas::point_trace(glm::vec2 loc)
|
|
||||||
{
|
|
||||||
return pp::panopainter::legacy_canvas_point_trace(*this, loc);
|
|
||||||
}
|
|
||||||
void Canvas::stroke_commit_timelapse()
|
|
||||||
{
|
|
||||||
pp::panopainter::legacy_canvas_stroke_commit_timelapse(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Canvas::draw_merge(bool draw_checkerboard, std::array<bool, 6> faces /*= SIXPLETTE(true)*/)
|
|
||||||
{
|
|
||||||
pp::panopainter::legacy_canvas_draw_merge(*this, draw_checkerboard, faces);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Canvas::stroke_update(glm::vec3 point, float pressure) { pp::panopainter::legacy_canvas_stroke_update(*this, point, pressure); }
|
|
||||||
void Canvas::stroke_start(glm::vec3 point, float pressure) { pp::panopainter::legacy_canvas_stroke_start(*this, point, pressure); }
|
|
||||||
void Canvas::destroy()
|
|
||||||
{
|
|
||||||
pp::panopainter::legacy_canvas_destroy(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Canvas::create(int width, int height)
|
|
||||||
{
|
|
||||||
return pp::panopainter::legacy_canvas_create(*this, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Canvas::clear_context()
|
|
||||||
{
|
|
||||||
pp::panopainter::legacy_canvas_clear_context(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Canvas::draw_objects_direct(std::function<void(const glm::mat4& camera, const glm::mat4& proj, int i)> observer, Layer& layer, int frame)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
draw_objects(observer, layer(), frame, save_history);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Canvas::project2Dpoints(std::vector<vertex_t>& vertices)
|
|
||||||
{
|
|
||||||
pp::panopainter::legacy_canvas_project_2d_points(*this, vertices);
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec3 Canvas::project2Dpoint(glm::vec2 pt)
|
|
||||||
{
|
|
||||||
return pp::panopainter::legacy_canvas_project_2d_point(*this, pt);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -118,6 +118,34 @@ void LegacyBrushPresetPanelUi::init(NodePanelBrushPreset& owner)
|
|||||||
owner.m_notification->SetVisibility(owner.m_container->m_children.size() == 0);
|
owner.m_notification->SetVisibility(owner.m_container->m_children.size() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kEventResult LegacyBrushPresetPanelUi::handle_event(NodePanelBrushPreset& owner, Event* event)
|
||||||
|
{
|
||||||
|
switch (event->m_type)
|
||||||
|
{
|
||||||
|
case kEventType::MouseLeave:
|
||||||
|
if (!owner.m_interacted)
|
||||||
|
break;
|
||||||
|
// else fall through
|
||||||
|
case kEventType::MouseUpL:
|
||||||
|
if (!owner.m_mouse_inside)
|
||||||
|
{
|
||||||
|
pp::panopainter::release_legacy_mouse_capture(owner);
|
||||||
|
if (owner.m_parent)
|
||||||
|
{
|
||||||
|
pp::panopainter::detach_legacy_node_from_parent(owner);
|
||||||
|
}
|
||||||
|
if (owner.on_popup_close)
|
||||||
|
{
|
||||||
|
owner.on_popup_close(&owner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return kEventResult::Available;
|
||||||
|
}
|
||||||
|
return kEventResult::Consumed;
|
||||||
|
}
|
||||||
|
|
||||||
void LegacyBrushPresetPanelUi::handle_click(NodePanelBrushPreset& owner, Node* target)
|
void LegacyBrushPresetPanelUi::handle_click(NodePanelBrushPreset& owner, Node* target)
|
||||||
{
|
{
|
||||||
const int idx = owner.m_container->get_child_index(target);
|
const int idx = owner.m_container->get_child_index(target);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ namespace pp::panopainter {
|
|||||||
class LegacyBrushPresetPanelUi final {
|
class LegacyBrushPresetPanelUi final {
|
||||||
public:
|
public:
|
||||||
static void init(NodePanelBrushPreset& owner);
|
static void init(NodePanelBrushPreset& owner);
|
||||||
|
static kEventResult handle_event(NodePanelBrushPreset& owner, Event* event);
|
||||||
static void handle_click(NodePanelBrushPreset& owner, Node* target);
|
static void handle_click(NodePanelBrushPreset& owner, Node* target);
|
||||||
static void add_brush(NodePanelBrushPreset& owner, std::shared_ptr<Brush> brush);
|
static void add_brush(NodePanelBrushPreset& owner, std::shared_ptr<Brush> brush);
|
||||||
static void added(NodePanelBrushPreset& owner);
|
static void added(NodePanelBrushPreset& owner);
|
||||||
|
|||||||
@@ -219,3 +219,28 @@ void legacy_canvas_draw_objects(
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace pp::panopainter
|
} // namespace pp::panopainter
|
||||||
|
|
||||||
|
void Canvas::draw_objects_direct(
|
||||||
|
std::function<void(const glm::mat4& camera, const glm::mat4& proj, int i)> observer,
|
||||||
|
Layer& layer,
|
||||||
|
int frame)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
draw_objects(std::move(observer), layer(), frame, save_history);
|
||||||
|
}
|
||||||
|
|||||||
@@ -177,3 +177,58 @@ void legacy_canvas_set_camera(Canvas& canvas, const CameraData& camera)
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace pp::panopainter
|
} // namespace pp::panopainter
|
||||||
|
|
||||||
|
bool Canvas::point_trace(
|
||||||
|
glm::vec2 loc,
|
||||||
|
glm::vec3& ray_origin,
|
||||||
|
glm::vec3& ray_dir,
|
||||||
|
glm::vec3& hit_pos,
|
||||||
|
glm::vec2& fb_pos,
|
||||||
|
glm::vec3& hit_normal,
|
||||||
|
int& out_plane_id)
|
||||||
|
{
|
||||||
|
return pp::panopainter::legacy_canvas_point_trace(*this, loc, ray_origin, ray_dir, hit_pos, fb_pos, hit_normal, out_plane_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Canvas::point_trace_plane(
|
||||||
|
glm::vec2 loc,
|
||||||
|
glm::vec3& ray_origin,
|
||||||
|
glm::vec3& ray_dir,
|
||||||
|
glm::vec3& hit_pos,
|
||||||
|
glm::vec3& hit_normal,
|
||||||
|
glm::vec2& hit_fb_pos,
|
||||||
|
int plane_id)
|
||||||
|
{
|
||||||
|
return pp::panopainter::legacy_canvas_point_trace_plane(*this, loc, ray_origin, ray_dir, hit_pos, hit_normal, hit_fb_pos, plane_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Canvas::point_unproject(
|
||||||
|
glm::vec2 loc,
|
||||||
|
glm::vec4 vp,
|
||||||
|
glm::mat4 camera,
|
||||||
|
glm::mat4 proj,
|
||||||
|
glm::vec3& out_origin,
|
||||||
|
glm::vec3& out_dir)
|
||||||
|
{
|
||||||
|
pp::panopainter::legacy_canvas_point_unproject(loc, vp, camera, proj, out_origin, out_dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Canvas::point_unproject(glm::vec2 loc, glm::vec3& out_origin, glm::vec3& out_dir)
|
||||||
|
{
|
||||||
|
pp::panopainter::legacy_canvas_point_unproject(*this, loc, out_origin, out_dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 Canvas::point_trace(glm::vec2 loc)
|
||||||
|
{
|
||||||
|
return pp::panopainter::legacy_canvas_point_trace(*this, loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Canvas::project2Dpoints(std::vector<vertex_t>& vertices)
|
||||||
|
{
|
||||||
|
pp::panopainter::legacy_canvas_project_2d_points(*this, vertices);
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 Canvas::project2Dpoint(glm::vec2 pt)
|
||||||
|
{
|
||||||
|
return pp::panopainter::legacy_canvas_project_2d_point(*this, pt);
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@@ -725,3 +726,71 @@ void legacy_canvas_render_shell_set_camera(Canvas& canvas, const CameraData& cam
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace pp::panopainter
|
} // namespace pp::panopainter
|
||||||
|
|
||||||
|
void Canvas::draw_merge_temporary_paint_branch(
|
||||||
|
int layer_index,
|
||||||
|
int plane_index,
|
||||||
|
std::shared_ptr<Layer> layer,
|
||||||
|
const Brush& brush,
|
||||||
|
const glm::mat4& ortho)
|
||||||
|
{
|
||||||
|
pp::panopainter::legacy_canvas_draw_merge_temporary_paint_branch(
|
||||||
|
*this,
|
||||||
|
layer_index,
|
||||||
|
plane_index,
|
||||||
|
std::move(layer),
|
||||||
|
brush,
|
||||||
|
ortho);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Canvas::draw_merge_branch_orchestration(
|
||||||
|
int plane_index,
|
||||||
|
int layer_index,
|
||||||
|
const std::shared_ptr<Layer>& layer,
|
||||||
|
const Brush& brush,
|
||||||
|
const glm::mat4& ortho,
|
||||||
|
bool use_blend,
|
||||||
|
bool copy_blend_destination)
|
||||||
|
{
|
||||||
|
pp::panopainter::legacy_canvas_draw_merge_branch_orchestration(
|
||||||
|
*this,
|
||||||
|
plane_index,
|
||||||
|
layer_index,
|
||||||
|
layer,
|
||||||
|
brush,
|
||||||
|
ortho,
|
||||||
|
use_blend,
|
||||||
|
copy_blend_destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Canvas::draw_merge_final_plane_composite(
|
||||||
|
const glm::mat4& ortho,
|
||||||
|
bool draw_checkerboard)
|
||||||
|
{
|
||||||
|
pp::panopainter::legacy_canvas_draw_merge_final_plane_composite(*this, ortho, draw_checkerboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Canvas::stroke_commit_timelapse()
|
||||||
|
{
|
||||||
|
pp::panopainter::legacy_canvas_stroke_commit_timelapse(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Canvas::draw_merge(bool draw_checkerboard, std::array<bool, 6> faces /*= SIXPLETTE(true)*/)
|
||||||
|
{
|
||||||
|
pp::panopainter::legacy_canvas_draw_merge(*this, draw_checkerboard, faces);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Canvas::destroy()
|
||||||
|
{
|
||||||
|
pp::panopainter::legacy_canvas_destroy(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Canvas::create(int width, int height)
|
||||||
|
{
|
||||||
|
return pp::panopainter::legacy_canvas_create(*this, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Canvas::clear_context()
|
||||||
|
{
|
||||||
|
pp::panopainter::legacy_canvas_clear_context(*this);
|
||||||
|
}
|
||||||
|
|||||||
@@ -612,3 +612,8 @@ void Canvas::stroke_draw_live()
|
|||||||
m_current_stroke = nullptr;
|
m_current_stroke = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Canvas::stroke_draw()
|
||||||
|
{
|
||||||
|
stroke_draw_live();
|
||||||
|
}
|
||||||
|
|||||||
@@ -334,3 +334,36 @@ void legacy_canvas_stroke_start(Canvas& canvas, glm::vec3 point, float pressure)
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace pp::panopainter
|
} // namespace pp::panopainter
|
||||||
|
|
||||||
|
void Canvas::stroke_end()
|
||||||
|
{
|
||||||
|
pp::panopainter::legacy_canvas_stroke_end(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Canvas::stroke_cancel()
|
||||||
|
{
|
||||||
|
pp::panopainter::legacy_canvas_stroke_cancel(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz)
|
||||||
|
{
|
||||||
|
pp::panopainter::legacy_canvas_stroke_draw_mix(*this, bb_min, bb_sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<std::vector<vertex_t>, 6> Canvas::stroke_draw_project(
|
||||||
|
std::array<vertex_t, 4>& B,
|
||||||
|
bool project_3d /*= false*/,
|
||||||
|
glm::mat4 mv /*= glm::mat4(1)*/) const
|
||||||
|
{
|
||||||
|
return pp::panopainter::legacy_canvas_stroke_draw_project(*this, B, project_3d, mv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Canvas::stroke_update(glm::vec3 point, float pressure)
|
||||||
|
{
|
||||||
|
pp::panopainter::legacy_canvas_stroke_update(*this, point, pressure);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Canvas::stroke_start(glm::vec3 point, float pressure)
|
||||||
|
{
|
||||||
|
pp::panopainter::legacy_canvas_stroke_start(*this, point, pressure);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,11 +1,192 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
|
||||||
#include "legacy_node_stroke_preview_draw_services.h"
|
#include "legacy_node_stroke_preview_draw_services.h"
|
||||||
|
#include "legacy_canvas_stroke_composite_services.h"
|
||||||
|
#include "legacy_canvas_stroke_execution_services.h"
|
||||||
|
#include "legacy_ui_gl_dispatch.h"
|
||||||
|
#include "renderer_gl/opengl_capabilities.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
namespace pp::panopainter {
|
namespace pp::panopainter {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
namespace stroke_preview_composite_slots {
|
||||||
|
constexpr std::uint32_t kBackground = 0U;
|
||||||
|
constexpr std::uint32_t kStroke = 1U;
|
||||||
|
constexpr std::uint32_t kDual = 3U;
|
||||||
|
constexpr std::uint32_t kPattern = 4U;
|
||||||
|
}
|
||||||
|
|
||||||
|
pp::panopainter::LegacyStrokeCompositeUniforms make_stroke_preview_mix_composite_uniforms(
|
||||||
|
const pp::panopainter::LegacyNodeStrokePreviewMixPassPlan::ShaderPlan& shader_plan) noexcept
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
.resolution = shader_plan.resolution,
|
||||||
|
.pattern = {
|
||||||
|
.scale = shader_plan.pattern_scale,
|
||||||
|
.invert = shader_plan.pattern_invert,
|
||||||
|
.brightness = shader_plan.pattern_brightness,
|
||||||
|
.contrast = shader_plan.pattern_contrast,
|
||||||
|
.depth = shader_plan.pattern_depth,
|
||||||
|
.blend_mode = shader_plan.pattern_blend_mode,
|
||||||
|
.offset = shader_plan.pattern_offset,
|
||||||
|
},
|
||||||
|
.mvp = glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f),
|
||||||
|
.layer_alpha = 1.0f,
|
||||||
|
.alpha_lock = false,
|
||||||
|
.mask_enabled = false,
|
||||||
|
.use_fragcoord = false,
|
||||||
|
.blend_mode = shader_plan.blend_mode,
|
||||||
|
.use_dual = shader_plan.use_dual,
|
||||||
|
.dual_blend_mode = shader_plan.dual_blend_mode,
|
||||||
|
.dual_alpha = shader_plan.dual_alpha,
|
||||||
|
.use_pattern = shader_plan.use_pattern,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pp::panopainter::LegacyCanvasStrokeMixPassRequest make_stroke_preview_mix_pass_execution_request(
|
||||||
|
const pp::panopainter::LegacyNodeStrokePreviewMixPassPlan::ShaderPlan& shader,
|
||||||
|
RTT& mixer_rtt,
|
||||||
|
const Brush& brush,
|
||||||
|
Sampler& linear_sampler,
|
||||||
|
Texture2D& background_texture,
|
||||||
|
Texture2D& stroke_texture,
|
||||||
|
Texture2D& dual_texture,
|
||||||
|
std::span<const pp::panopainter::LegacyCanvasStrokeMixPassPlane> mix_planes,
|
||||||
|
std::function<void()> draw_mix)
|
||||||
|
{
|
||||||
|
return pp::panopainter::make_legacy_canvas_stroke_mix_pass_request(
|
||||||
|
"NodeStrokePreview::stroke_draw_mix",
|
||||||
|
glm::vec2(static_cast<float>(mixer_rtt.getWidth()), static_cast<float>(mixer_rtt.getHeight())),
|
||||||
|
mix_planes,
|
||||||
|
[&] {
|
||||||
|
linear_sampler.bind(stroke_preview_composite_slots::kBackground);
|
||||||
|
linear_sampler.bind(stroke_preview_composite_slots::kStroke);
|
||||||
|
linear_sampler.bind(stroke_preview_composite_slots::kDual);
|
||||||
|
linear_sampler.bind(stroke_preview_composite_slots::kPattern);
|
||||||
|
pp::legacy::ui_gl::activate_texture_unit(stroke_preview_composite_slots::kBackground, "NodeStrokePreview");
|
||||||
|
background_texture.bind();
|
||||||
|
pp::legacy::ui_gl::activate_texture_unit(stroke_preview_composite_slots::kStroke, "NodeStrokePreview");
|
||||||
|
stroke_texture.bind();
|
||||||
|
pp::legacy::ui_gl::activate_texture_unit(stroke_preview_composite_slots::kDual, "NodeStrokePreview");
|
||||||
|
dual_texture.bind();
|
||||||
|
pp::legacy::ui_gl::activate_texture_unit(stroke_preview_composite_slots::kPattern, "NodeStrokePreview");
|
||||||
|
brush.m_pattern_texture ? brush.m_pattern_texture->bind() : pp::legacy::ui_gl::unbind_texture_2d("NodeStrokePreview");
|
||||||
|
},
|
||||||
|
[] {},
|
||||||
|
[&](int, const glm::mat4& plane_mvp) {
|
||||||
|
auto uniforms = make_stroke_preview_mix_composite_uniforms(shader);
|
||||||
|
uniforms.mvp = plane_mvp;
|
||||||
|
pp::panopainter::setup_legacy_stroke_composite_shader(uniforms);
|
||||||
|
},
|
||||||
|
[&](int) {
|
||||||
|
pp::legacy::ui_gl::activate_texture_unit(stroke_preview_composite_slots::kBackground, "NodeStrokePreview");
|
||||||
|
background_texture.bind();
|
||||||
|
},
|
||||||
|
[&](int) {
|
||||||
|
pp::legacy::ui_gl::activate_texture_unit(stroke_preview_composite_slots::kStroke, "NodeStrokePreview");
|
||||||
|
stroke_texture.bind();
|
||||||
|
},
|
||||||
|
[&](int) {
|
||||||
|
pp::legacy::ui_gl::activate_texture_unit(stroke_preview_composite_slots::kDual, "NodeStrokePreview");
|
||||||
|
dual_texture.bind();
|
||||||
|
},
|
||||||
|
std::move(draw_mix),
|
||||||
|
[&](int) {
|
||||||
|
pp::legacy::ui_gl::activate_texture_unit(stroke_preview_composite_slots::kDual, "NodeStrokePreview");
|
||||||
|
dual_texture.unbind();
|
||||||
|
},
|
||||||
|
[&](int) {
|
||||||
|
pp::legacy::ui_gl::activate_texture_unit(stroke_preview_composite_slots::kStroke, "NodeStrokePreview");
|
||||||
|
stroke_texture.unbind();
|
||||||
|
},
|
||||||
|
[&](int) {
|
||||||
|
pp::legacy::ui_gl::activate_texture_unit(stroke_preview_composite_slots::kBackground, "NodeStrokePreview");
|
||||||
|
background_texture.unbind();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
bool execute_legacy_node_stroke_preview_mix_pass(
|
||||||
|
const LegacyNodeStrokePreviewMixPassExecutionRequest& request)
|
||||||
|
{
|
||||||
|
if (!request.draw_mix) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto mix_pass = pp::panopainter::plan_legacy_node_stroke_preview_mix_pass(
|
||||||
|
pp::panopainter::LegacyNodeStrokePreviewMixPassRequest {
|
||||||
|
.resolution = request.preview_size,
|
||||||
|
.pattern_scale = request.brush.m_pattern_scale,
|
||||||
|
.pattern_flipx = request.brush.m_pattern_flipx,
|
||||||
|
.pattern_flipy = request.brush.m_pattern_flipy,
|
||||||
|
.pattern_invert = request.brush.m_pattern_invert,
|
||||||
|
.pattern_brightness = request.brush.m_pattern_brightness,
|
||||||
|
.pattern_contrast = request.brush.m_pattern_contrast,
|
||||||
|
.pattern_depth = request.brush.m_pattern_depth,
|
||||||
|
.pattern_rand_offset = request.brush.m_pattern_rand_offset,
|
||||||
|
.pattern_enabled = request.brush.m_pattern_enabled,
|
||||||
|
.pattern_eachsample = request.brush.m_pattern_eachsample,
|
||||||
|
.tip_wet = request.brush.m_tip_wet,
|
||||||
|
.tip_mix = request.brush.m_tip_mix,
|
||||||
|
.tip_noise = request.brush.m_tip_noise,
|
||||||
|
.dual_enabled = request.brush.m_dual_enabled,
|
||||||
|
.dual_blend_mode = request.brush.m_dual_blend_mode,
|
||||||
|
.pattern_blend_mode = request.brush.m_pattern_blend_mode,
|
||||||
|
.dual_opacity = request.brush.m_dual_opacity,
|
||||||
|
.blend_mode = request.brush.m_blend_mode,
|
||||||
|
});
|
||||||
|
const auto mix_planes = std::array {
|
||||||
|
pp::panopainter::LegacyCanvasStrokeMixPassPlane {
|
||||||
|
.index = 0,
|
||||||
|
.visible = true,
|
||||||
|
.has_target = true,
|
||||||
|
.opacity = 1.0f,
|
||||||
|
.mvp = glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
gl_state gl;
|
||||||
|
const auto mix_result = pp::panopainter::execute_legacy_canvas_stroke_mix_pass_with_setup(
|
||||||
|
[&] {
|
||||||
|
pp::legacy::ui_gl::apply_viewport(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
request.mixer_rtt.getWidth(),
|
||||||
|
request.mixer_rtt.getHeight(),
|
||||||
|
"NodeStrokePreview");
|
||||||
|
pp::legacy::ui_gl::set_capability(pp::renderer::gl::depth_test_state(), false, "NodeStrokePreview");
|
||||||
|
pp::legacy::ui_gl::set_capability(pp::renderer::gl::scissor_test_state(), true, "NodeStrokePreview");
|
||||||
|
pp::legacy::ui_gl::set_capability(pp::renderer::gl::blend_state(), false, "NodeStrokePreview");
|
||||||
|
pp::legacy::ui_gl::apply_scissor_rect(
|
||||||
|
static_cast<std::int32_t>(request.bb_min.x),
|
||||||
|
static_cast<std::int32_t>(request.bb_min.y),
|
||||||
|
static_cast<std::int32_t>(request.bb_sz.x),
|
||||||
|
static_cast<std::int32_t>(request.bb_sz.y),
|
||||||
|
"NodeStrokePreview");
|
||||||
|
gl.save();
|
||||||
|
request.mixer_rtt.bindFramebuffer();
|
||||||
|
},
|
||||||
|
[&] {
|
||||||
|
request.mixer_rtt.unbindFramebuffer();
|
||||||
|
gl.restore();
|
||||||
|
},
|
||||||
|
make_stroke_preview_mix_pass_execution_request(
|
||||||
|
mix_pass.shader,
|
||||||
|
request.mixer_rtt,
|
||||||
|
request.brush,
|
||||||
|
request.linear_sampler,
|
||||||
|
request.background_texture,
|
||||||
|
request.stroke_texture,
|
||||||
|
request.dual_texture,
|
||||||
|
mix_planes,
|
||||||
|
request.draw_mix));
|
||||||
|
return mix_result.ok;
|
||||||
|
}
|
||||||
|
|
||||||
bool has_valid_live_render_callbacks(const LegacyNodeStrokePreviewLiveRenderRequest& request)
|
bool has_valid_live_render_callbacks(const LegacyNodeStrokePreviewLiveRenderRequest& request)
|
||||||
{
|
{
|
||||||
return request.bind_dual_pass_textures &&
|
return request.bind_dual_pass_textures &&
|
||||||
@@ -18,8 +199,6 @@ bool has_valid_live_render_callbacks(const LegacyNodeStrokePreviewLiveRenderRequ
|
|||||||
request.draw_composite;
|
request.draw_composite;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
bool execute_legacy_node_stroke_preview_live_render_passes(
|
bool execute_legacy_node_stroke_preview_live_render_passes(
|
||||||
const LegacyNodeStrokePreviewLiveRenderRequest& request)
|
const LegacyNodeStrokePreviewLiveRenderRequest& request)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -45,6 +45,22 @@ struct LegacyNodeStrokePreviewLiveRenderRequest {
|
|||||||
std::function<void()> draw_composite;
|
std::function<void()> draw_composite;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LegacyNodeStrokePreviewMixPassExecutionRequest {
|
||||||
|
const Brush& brush;
|
||||||
|
glm::vec2 preview_size {};
|
||||||
|
RTT& mixer_rtt;
|
||||||
|
glm::vec2 bb_min {};
|
||||||
|
glm::vec2 bb_sz {};
|
||||||
|
Sampler& linear_sampler;
|
||||||
|
Texture2D& background_texture;
|
||||||
|
Texture2D& stroke_texture;
|
||||||
|
Texture2D& dual_texture;
|
||||||
|
std::function<void()> draw_mix;
|
||||||
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] bool execute_legacy_node_stroke_preview_mix_pass(
|
||||||
|
const LegacyNodeStrokePreviewMixPassExecutionRequest& request);
|
||||||
|
|
||||||
[[nodiscard]] bool execute_legacy_node_stroke_preview_live_render_passes(
|
[[nodiscard]] bool execute_legacy_node_stroke_preview_live_render_passes(
|
||||||
const LegacyNodeStrokePreviewLiveRenderRequest& request);
|
const LegacyNodeStrokePreviewLiveRenderRequest& request);
|
||||||
|
|
||||||
|
|||||||
@@ -213,31 +213,7 @@ void NodePanelBrushPreset::init()
|
|||||||
|
|
||||||
kEventResult NodePanelBrushPreset::handle_event(Event* e)
|
kEventResult NodePanelBrushPreset::handle_event(Event* e)
|
||||||
{
|
{
|
||||||
switch (e->m_type)
|
return pp::panopainter::LegacyBrushPresetPanelUi::handle_event(*this, e);
|
||||||
{
|
|
||||||
case kEventType::MouseLeave:
|
|
||||||
if (!m_interacted)
|
|
||||||
break;
|
|
||||||
// else fall through
|
|
||||||
case kEventType::MouseUpL:
|
|
||||||
if (!m_mouse_inside)
|
|
||||||
{
|
|
||||||
pp::panopainter::release_legacy_mouse_capture(*this);
|
|
||||||
if (m_parent)
|
|
||||||
{
|
|
||||||
pp::panopainter::detach_legacy_node_from_parent(*this);
|
|
||||||
}
|
|
||||||
if (on_popup_close)
|
|
||||||
{
|
|
||||||
on_popup_close(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return kEventResult::Available;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return kEventResult::Consumed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodePanelBrushPreset::handle_click(Node* target)
|
void NodePanelBrushPreset::handle_click(Node* target)
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
#include "canvas.h"
|
#include "canvas.h"
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
#include "legacy_canvas_draw_merge_services.h"
|
#include "legacy_canvas_draw_merge_services.h"
|
||||||
#include "legacy_canvas_stroke_composite_services.h"
|
|
||||||
#include "legacy_canvas_stroke_execution_services.h"
|
#include "legacy_canvas_stroke_execution_services.h"
|
||||||
#include "legacy_canvas_stroke_preview_services.h"
|
#include "legacy_canvas_stroke_preview_services.h"
|
||||||
#include "legacy_canvas_stroke_shader_services.h"
|
#include "legacy_canvas_stroke_shader_services.h"
|
||||||
@@ -69,13 +68,6 @@ void apply_stroke_preview_capability(std::uint32_t state, bool enabled)
|
|||||||
pp::legacy::ui_gl::set_capability(state, enabled, "NodeStrokePreview");
|
pp::legacy::ui_gl::set_capability(state, enabled, "NodeStrokePreview");
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace stroke_preview_composite_slots {
|
|
||||||
constexpr std::uint32_t kBackground = 0U;
|
|
||||||
constexpr std::uint32_t kStroke = 1U;
|
|
||||||
constexpr std::uint32_t kDual = 3U;
|
|
||||||
constexpr std::uint32_t kPattern = 4U;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace stroke_preview_live_slots {
|
namespace stroke_preview_live_slots {
|
||||||
constexpr std::uint32_t kTip = 0U;
|
constexpr std::uint32_t kTip = 0U;
|
||||||
constexpr std::uint32_t kDestination = 1U;
|
constexpr std::uint32_t kDestination = 1U;
|
||||||
@@ -84,122 +76,6 @@ constexpr std::uint32_t kMixer = 3U;
|
|||||||
constexpr std::uint32_t kReservedLinear = 4U;
|
constexpr std::uint32_t kReservedLinear = 4U;
|
||||||
}
|
}
|
||||||
|
|
||||||
pp::panopainter::LegacyNodeStrokePreviewMixPassRequest make_stroke_preview_mix_pass_request(
|
|
||||||
const Brush& brush,
|
|
||||||
glm::vec2 resolution) noexcept
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
.resolution = resolution,
|
|
||||||
.pattern_scale = brush.m_pattern_scale,
|
|
||||||
.pattern_flipx = brush.m_pattern_flipx,
|
|
||||||
.pattern_flipy = brush.m_pattern_flipy,
|
|
||||||
.pattern_invert = brush.m_pattern_invert,
|
|
||||||
.pattern_brightness = brush.m_pattern_brightness,
|
|
||||||
.pattern_contrast = brush.m_pattern_contrast,
|
|
||||||
.pattern_depth = brush.m_pattern_depth,
|
|
||||||
.pattern_rand_offset = brush.m_pattern_rand_offset,
|
|
||||||
.pattern_enabled = brush.m_pattern_enabled,
|
|
||||||
.pattern_eachsample = brush.m_pattern_eachsample,
|
|
||||||
.tip_wet = brush.m_tip_wet,
|
|
||||||
.tip_mix = brush.m_tip_mix,
|
|
||||||
.tip_noise = brush.m_tip_noise,
|
|
||||||
.dual_enabled = brush.m_dual_enabled,
|
|
||||||
.dual_blend_mode = brush.m_dual_blend_mode,
|
|
||||||
.pattern_blend_mode = brush.m_pattern_blend_mode,
|
|
||||||
.dual_opacity = brush.m_dual_opacity,
|
|
||||||
.blend_mode = brush.m_blend_mode,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pp::panopainter::LegacyStrokeCompositeUniforms make_stroke_preview_mix_composite_uniforms(
|
|
||||||
const pp::panopainter::LegacyNodeStrokePreviewMixPassPlan::ShaderPlan& shader_plan) noexcept
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
.resolution = shader_plan.resolution,
|
|
||||||
.pattern = {
|
|
||||||
.scale = shader_plan.pattern_scale,
|
|
||||||
.invert = shader_plan.pattern_invert,
|
|
||||||
.brightness = shader_plan.pattern_brightness,
|
|
||||||
.contrast = shader_plan.pattern_contrast,
|
|
||||||
.depth = shader_plan.pattern_depth,
|
|
||||||
.blend_mode = shader_plan.pattern_blend_mode,
|
|
||||||
.offset = shader_plan.pattern_offset,
|
|
||||||
},
|
|
||||||
.mvp = glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f),
|
|
||||||
.layer_alpha = 1.0f,
|
|
||||||
.alpha_lock = false,
|
|
||||||
.mask_enabled = false,
|
|
||||||
.use_fragcoord = false,
|
|
||||||
.blend_mode = shader_plan.blend_mode,
|
|
||||||
.use_dual = shader_plan.use_dual,
|
|
||||||
.dual_blend_mode = shader_plan.dual_blend_mode,
|
|
||||||
.dual_alpha = shader_plan.dual_alpha,
|
|
||||||
.use_pattern = shader_plan.use_pattern,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pp::panopainter::LegacyCanvasStrokeMixPassRequest make_stroke_preview_mix_pass_execution_request(
|
|
||||||
const pp::panopainter::LegacyNodeStrokePreviewMixPassPlan::ShaderPlan& shader,
|
|
||||||
RTT& mixer_rtt,
|
|
||||||
const Brush& brush,
|
|
||||||
Sampler& linear_sampler,
|
|
||||||
Texture2D& background_texture,
|
|
||||||
Texture2D& stroke_texture,
|
|
||||||
Texture2D& dual_texture,
|
|
||||||
std::span<const pp::panopainter::LegacyCanvasStrokeMixPassPlane> mix_planes,
|
|
||||||
std::function<void()> draw_mix)
|
|
||||||
{
|
|
||||||
return pp::panopainter::make_legacy_canvas_stroke_mix_pass_request(
|
|
||||||
"NodeStrokePreview::stroke_draw_mix",
|
|
||||||
glm::vec2(static_cast<float>(mixer_rtt.getWidth()), static_cast<float>(mixer_rtt.getHeight())),
|
|
||||||
mix_planes,
|
|
||||||
[&] {
|
|
||||||
linear_sampler.bind(stroke_preview_composite_slots::kBackground);
|
|
||||||
linear_sampler.bind(stroke_preview_composite_slots::kStroke);
|
|
||||||
linear_sampler.bind(stroke_preview_composite_slots::kDual);
|
|
||||||
linear_sampler.bind(stroke_preview_composite_slots::kPattern);
|
|
||||||
set_active_texture_unit(stroke_preview_composite_slots::kBackground);
|
|
||||||
background_texture.bind();
|
|
||||||
set_active_texture_unit(stroke_preview_composite_slots::kStroke);
|
|
||||||
stroke_texture.bind();
|
|
||||||
set_active_texture_unit(stroke_preview_composite_slots::kDual);
|
|
||||||
dual_texture.bind();
|
|
||||||
set_active_texture_unit(stroke_preview_composite_slots::kPattern);
|
|
||||||
brush.m_pattern_texture ? brush.m_pattern_texture->bind() : unbind_texture_2d();
|
|
||||||
},
|
|
||||||
[] {},
|
|
||||||
[&](int, const glm::mat4& plane_mvp) {
|
|
||||||
auto uniforms = make_stroke_preview_mix_composite_uniforms(shader);
|
|
||||||
uniforms.mvp = plane_mvp;
|
|
||||||
pp::panopainter::setup_legacy_stroke_composite_shader(uniforms);
|
|
||||||
},
|
|
||||||
[&](int) {
|
|
||||||
set_active_texture_unit(stroke_preview_composite_slots::kBackground);
|
|
||||||
background_texture.bind();
|
|
||||||
},
|
|
||||||
[&](int) {
|
|
||||||
set_active_texture_unit(stroke_preview_composite_slots::kStroke);
|
|
||||||
stroke_texture.bind();
|
|
||||||
},
|
|
||||||
[&](int) {
|
|
||||||
set_active_texture_unit(stroke_preview_composite_slots::kDual);
|
|
||||||
dual_texture.bind();
|
|
||||||
},
|
|
||||||
std::move(draw_mix),
|
|
||||||
[&](int) {
|
|
||||||
set_active_texture_unit(stroke_preview_composite_slots::kDual);
|
|
||||||
dual_texture.unbind();
|
|
||||||
},
|
|
||||||
[&](int) {
|
|
||||||
set_active_texture_unit(stroke_preview_composite_slots::kStroke);
|
|
||||||
stroke_texture.unbind();
|
|
||||||
},
|
|
||||||
[&](int) {
|
|
||||||
set_active_texture_unit(stroke_preview_composite_slots::kBackground);
|
|
||||||
background_texture.unbind();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void bind_stroke_preview_live_samplers(
|
void bind_stroke_preview_live_samplers(
|
||||||
Sampler& mipmap_sampler,
|
Sampler& mipmap_sampler,
|
||||||
Sampler& linear_sampler,
|
Sampler& linear_sampler,
|
||||||
@@ -308,49 +184,22 @@ void NodeStrokePreview::init_controls()
|
|||||||
void NodeStrokePreview::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz)
|
void NodeStrokePreview::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz)
|
||||||
{
|
{
|
||||||
const auto& b = m_brush;
|
const auto& b = m_brush;
|
||||||
const auto mix_pass = pp::panopainter::plan_legacy_node_stroke_preview_mix_pass(
|
const bool mix_ok = pp::panopainter::execute_legacy_node_stroke_preview_mix_pass(
|
||||||
make_stroke_preview_mix_pass_request(*b, m_size));
|
pp::panopainter::LegacyNodeStrokePreviewMixPassExecutionRequest {
|
||||||
const auto mix_planes = std::array {
|
.brush = *b,
|
||||||
pp::panopainter::LegacyCanvasStrokeMixPassPlane {
|
.preview_size = m_size,
|
||||||
.index = 0,
|
.mixer_rtt = m_rtt_mixer,
|
||||||
.visible = true,
|
.bb_min = bb_min,
|
||||||
.has_target = true,
|
.bb_sz = bb_sz,
|
||||||
.opacity = 1.0f,
|
.linear_sampler = m_sampler_linear,
|
||||||
.mvp = glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f),
|
.background_texture = m_tex_background,
|
||||||
},
|
.stroke_texture = m_tex,
|
||||||
};
|
.dual_texture = m_tex_dual,
|
||||||
gl_state gl;
|
.draw_mix = [this] {
|
||||||
const auto mix_result = pp::panopainter::execute_legacy_canvas_stroke_mix_pass_with_setup(
|
|
||||||
[&] {
|
|
||||||
apply_stroke_preview_viewport(0, 0, m_rtt_mixer.getWidth(), m_rtt_mixer.getHeight());
|
|
||||||
apply_stroke_preview_capability(pp::renderer::gl::depth_test_state(), false);
|
|
||||||
apply_stroke_preview_capability(pp::renderer::gl::scissor_test_state(), true);
|
|
||||||
apply_stroke_preview_capability(pp::renderer::gl::blend_state(), false);
|
|
||||||
apply_stroke_preview_scissor(
|
|
||||||
static_cast<std::int32_t>(bb_min.x),
|
|
||||||
static_cast<std::int32_t>(bb_min.y),
|
|
||||||
static_cast<std::int32_t>(bb_sz.x),
|
|
||||||
static_cast<std::int32_t>(bb_sz.y));
|
|
||||||
gl.save();
|
|
||||||
m_rtt_mixer.bindFramebuffer();
|
|
||||||
},
|
|
||||||
[&] {
|
|
||||||
m_rtt_mixer.unbindFramebuffer();
|
|
||||||
gl.restore();
|
|
||||||
},
|
|
||||||
make_stroke_preview_mix_pass_execution_request(
|
|
||||||
mix_pass.shader,
|
|
||||||
m_rtt_mixer,
|
|
||||||
*m_brush,
|
|
||||||
m_sampler_linear,
|
|
||||||
m_tex_background,
|
|
||||||
m_tex,
|
|
||||||
m_tex_dual,
|
|
||||||
mix_planes,
|
|
||||||
[this] {
|
|
||||||
m_plane.draw_fill();
|
m_plane.draw_fill();
|
||||||
}));
|
},
|
||||||
assert(mix_result.ok);
|
});
|
||||||
|
assert(mix_ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec4 NodeStrokePreview::stroke_draw_samples(
|
glm::vec4 NodeStrokePreview::stroke_draw_samples(
|
||||||
|
|||||||
Reference in New Issue
Block a user