Route paint render state through GL backend

This commit is contained in:
2026-06-04 22:19:54 +02:00
parent 24197c5f7e
commit d55f26d637
7 changed files with 304 additions and 73 deletions

View File

@@ -198,6 +198,74 @@ void unbind_texture_2d()
LOG("Canvas texture unbind dispatch failed because: %s", status.message);
}
void enable_opengl_state(std::uint32_t state) noexcept
{
glEnable(static_cast<GLenum>(state));
}
void disable_opengl_state(std::uint32_t state) noexcept
{
glDisable(static_cast<GLenum>(state));
}
void set_opengl_viewport(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height) noexcept
{
glViewport(static_cast<GLint>(x), static_cast<GLint>(y), static_cast<GLsizei>(width), static_cast<GLsizei>(height));
}
void set_opengl_scissor(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height) noexcept
{
glScissor(static_cast<GLint>(x), static_cast<GLint>(y), static_cast<GLsizei>(width), static_cast<GLsizei>(height));
}
void apply_canvas_viewport(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height)
{
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("Canvas viewport dispatch failed because: %s", status.message);
}
void apply_canvas_scissor(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height)
{
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("Canvas scissor dispatch failed because: %s", status.message);
}
void apply_canvas_capability(std::uint32_t state, bool enabled)
{
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("Canvas capability dispatch failed because: %s", status.message);
}
void gen_opengl_renderbuffers(std::uint32_t count, std::uint32_t* ids) noexcept
{
glGenRenderbuffers(static_cast<GLsizei>(count), reinterpret_cast<GLuint*>(ids));
@@ -427,12 +495,12 @@ void Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz)
m_mixer.bindFramebuffer();
glViewport(0, 0, m_mixer.getWidth(), m_mixer.getHeight());
glDisable(depth_test_state());
glEnable(scissor_test_state());
glDisable(blend_state());
apply_canvas_viewport(0, 0, m_mixer.getWidth(), m_mixer.getHeight());
apply_canvas_capability(depth_test_state(), false);
apply_canvas_capability(scissor_test_state(), true);
apply_canvas_capability(blend_state(), false);
glScissor(bb_min.x, bb_min.y, bb_sz.x, bb_sz.y);
apply_canvas_scissor(bb_min.x, bb_min.y, bb_sz.x, bb_sz.y);
auto layer_index = m_current_layer_idx;
for (int plane_index = 0; plane_index < 6; plane_index++)
@@ -718,7 +786,7 @@ void Canvas::stroke_draw()
const auto& dual_brush = m_dual_stroke->m_brush;
auto ortho_proj = glm::ortho(0.f, (float)m_width, 0.f, (float)m_height, -1.f, 1.f);
glViewport(0, 0, m_width, m_height);
apply_canvas_viewport(0, 0, m_width, m_height);
m_sampler_brush.bind(0);
m_sampler_nearest.bind(1);
@@ -733,7 +801,7 @@ void Canvas::stroke_draw()
const auto stroke_feedback = canvas_destination_feedback_plan(m_width, m_height);
const bool copy_stroke_destination = !stroke_feedback.reads_destination_color;
glDisable(blend_state());
apply_canvas_capability(blend_state(), false);
ShaderManager::use(kShader::Stroke);
ShaderManager::u_int(kShaderUniform::Tex, 0); // brush
if (copy_stroke_destination)
@@ -907,7 +975,7 @@ void Canvas::stroke_draw()
m_sampler_nearest.unbind();
m_sampler_stencil.unbind();
glViewport(vp[0], vp[1], vp[2], vp[3]);
apply_canvas_viewport(vp[0], vp[1], vp[2], vp[3]);
glClearColor(cc[0], cc[1], cc[2], cc[3]);
if (m_commit_delayed)
@@ -1032,8 +1100,8 @@ void Canvas::stroke_commit()
App::I->title_update();
// prepare common states
glViewport(0, 0, m_width, m_height);
glDisable(blend_state());
apply_canvas_viewport(0, 0, m_width, m_height);
apply_canvas_capability(blend_state(), false);
const auto& b = m_current_stroke->m_brush;
@@ -1190,8 +1258,8 @@ void Canvas::stroke_commit()
}
// restore viewport and clear color states
blend ? glEnable(blend_state()) : glDisable(blend_state());
glViewport(vp[0], vp[1], vp[2], vp[3]);
blend ? apply_canvas_capability(blend_state(), true) : apply_canvas_capability(blend_state(), false);
apply_canvas_viewport(vp[0], vp[1], vp[2], vp[3]);
glClearColor(cc[0], cc[1], cc[2], cc[3]);
set_active_texture_unit(0);
@@ -1226,7 +1294,7 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array<bool, 6> faces /*= SI
{
assert(App::I->is_render_thread());
glViewport(0, 0, m_width, m_height);
apply_canvas_viewport(0, 0, m_width, m_height);
auto ortho = glm::ortho<float>(-0.5f, 0.5f, -0.5f, 0.5f, -1.f, 1.f);
const auto& b = m_current_stroke->m_brush;
@@ -1239,7 +1307,7 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array<bool, 6> faces /*= SI
const bool copy_blend_destination = use_blend && !blend_gate.reads_destination_color;
// if not using shader blend, use gl rasterizer blend
glDisable(depth_test_state());
apply_canvas_capability(depth_test_state(), false);
for (int plane_index = 0; plane_index < 6; plane_index++)
{
@@ -1251,7 +1319,7 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array<bool, 6> faces /*= SI
if (use_blend)
{
glDisable(blend_state());
apply_canvas_capability(blend_state(), false);
m_layers_merge.rtt(plane_index).clear();
}
else
@@ -1263,7 +1331,7 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array<bool, 6> faces /*= SI
ShaderManager::u_mat4(kShaderUniform::MVP, ortho);
m_plane.draw_fill();
}
glEnable(blend_state());
apply_canvas_capability(blend_state(), true);
}
for (int layer_index = 0; layer_index < m_layers.size(); layer_index++)
@@ -1434,7 +1502,7 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array<bool, 6> faces /*= SI
// draw the grid behind the layers using a temporary copy
if (use_blend)
{
glEnable(blend_state());
apply_canvas_capability(blend_state(), true);
//draw the grid
if (draw_checkerboard)
@@ -1595,8 +1663,8 @@ void Canvas::layer_merge(int source_idx, int dest_idx) // m_layer index
App::I->render_task([&]
{
// prepare common states
glViewport(0, 0, m_width, m_height);
glDisable(blend_state());
apply_canvas_viewport(0, 0, m_width, m_height);
apply_canvas_capability(blend_state(), false);
for (int i = 0; i < 6; i++)
{
@@ -2017,7 +2085,7 @@ void Canvas::import_equirectangular_thread(std::string file_path, std::shared_pt
Plane plane;
plane.create<1>(2, 2);
draw_objects([&](const glm::mat4& camera, const glm::mat4& proj, int i) {
glDisable(depth_test_state());
apply_canvas_capability(depth_test_state(), false);
tex.update(img.m_data.get() + indices[i] * stride);
m_sampler.bind(0);
set_active_texture_unit(0);
@@ -2038,7 +2106,7 @@ void Canvas::import_equirectangular_thread(std::string file_path, std::shared_pt
Sphere sphere;
sphere.create<64, 64>(2.f);
draw_objects([&](const glm::mat4& camera, const glm::mat4& proj, int i) {
glDisable(depth_test_state());
apply_canvas_capability(depth_test_state(), false);
m_sampler.bind(0);
set_active_texture_unit(0);
tex.bind();
@@ -2174,9 +2242,9 @@ void Canvas::export_depth_thread(std::string file_name)
rtt.bindFramebuffer();
rtt.clear({ 0, 0, 0, 1 });
glEnable(blend_state());
glDisable(depth_test_state());
glViewport(0, 0, rtt.getWidth(), rtt.getHeight());
apply_canvas_capability(blend_state(), true);
apply_canvas_capability(depth_test_state(), false);
apply_canvas_viewport(0, 0, rtt.getWidth(), rtt.getHeight());
for (int plane_index = 0; plane_index < 6; plane_index++)
{
auto plane_mvp_z = proj * camera *
@@ -2209,9 +2277,9 @@ void Canvas::export_depth_thread(std::string file_name)
{
rtt.bindFramebuffer();
rtt.clear({ 0, 0, 0, 1 });
glEnable(blend_state());
glDisable(depth_test_state());
glViewport(0, 0, rtt.getWidth(), rtt.getHeight());
apply_canvas_capability(blend_state(), true);
apply_canvas_capability(depth_test_state(), false);
apply_canvas_viewport(0, 0, rtt.getWidth(), rtt.getHeight());
for (int layer_index = 0; layer_index < m_layers.size(); layer_index++)
{
for (int plane_index = 0; plane_index < 6; plane_index++)
@@ -2901,7 +2969,7 @@ Image Canvas::thumbnail_generate(int w, int h)
auto blend = glIsEnabled(blend_state());
// prepare common states
glViewport(0, 0, w, h);
apply_canvas_viewport(0, 0, w, h);
RTT fb;
fb.create(w, h);
@@ -2919,7 +2987,7 @@ Image Canvas::thumbnail_generate(int w, int h)
fb.clear({ 1, 1, 1, 0 });
for (int i = 0; i < 6; i++)
{
glDisable(blend_state());
apply_canvas_capability(blend_state(), false);
auto plane_mvp = proj * m_mv * m_plane_transform[i] * glm::translate(glm::vec3(0, 0, -1));
ShaderManager::use(kShader::TextureBlend);
@@ -2969,7 +3037,7 @@ Image Canvas::thumbnail_generate(int w, int h)
m_face_plane.draw_fill();
// now blend with the background
glEnable(blend_state());
apply_canvas_capability(blend_state(), true);
ShaderManager::use(kShader::Texture);
ShaderManager::u_int(kShaderUniform::Tex, 0);
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
@@ -2988,8 +3056,8 @@ Image Canvas::thumbnail_generate(int w, int h)
blendtex.destroy();
// restore viewport and clear color states
blend ? glEnable(blend_state()) : glDisable(blend_state());
glViewport(vp[0], vp[1], vp[2], vp[3]);
blend ? apply_canvas_capability(blend_state(), true) : apply_canvas_capability(blend_state(), false);
apply_canvas_viewport(vp[0], vp[1], vp[2], vp[3]);
glClearColor(cc[0], cc[1], cc[2], cc[3]);
set_active_texture_unit(0);
});
@@ -3036,8 +3104,8 @@ void Canvas::draw_objects_direct(std::function<void(const glm::mat4& camera, con
auto blend = glIsEnabled(blend_state());
// prepare common states
glViewport(0, 0, layer.w, layer.h);
glDisable(blend_state());
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);
@@ -3060,8 +3128,8 @@ void Canvas::draw_objects_direct(std::function<void(const glm::mat4& camera, con
delete_canvas_renderbuffer(rboID);
// restore viewport and clear color states
blend ? glEnable(blend_state()) : glDisable(blend_state());
glViewport(vp[0], vp[1], vp[2], vp[3]);
blend ? apply_canvas_capability(blend_state(), true) : apply_canvas_capability(blend_state(), false);
apply_canvas_viewport(vp[0], vp[1], vp[2], vp[3]);
glClearColor(cc[0], cc[1], cc[2], cc[3]);
set_active_texture_unit(0);
});
@@ -3079,8 +3147,8 @@ void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm:
auto blend = glIsEnabled(blend_state());
// prepare common states
glViewport(0, 0, layer.w, layer.h);
glDisable(blend_state());
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);
@@ -3166,8 +3234,8 @@ void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm:
rtt.destroy();
// restore viewport and clear color states
blend ? glEnable(blend_state()) : glDisable(blend_state());
glViewport(vp[0], vp[1], vp[2], vp[3]);
blend ? apply_canvas_capability(blend_state(), true) : apply_canvas_capability(blend_state(), false);
apply_canvas_viewport(vp[0], vp[1], vp[2], vp[3]);
glClearColor(cc[0], cc[1], cc[2], cc[3]);
set_active_texture_unit(0);
});

View File

@@ -1,8 +1,34 @@
#include "pch.h"
#include "hmd.h"
#include "log.h"
#include "renderer_gl/opengl_capabilities.h"
#include <array>
namespace {
void set_opengl_viewport(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height) noexcept
{
glViewport(static_cast<GLint>(x), static_cast<GLint>(y), static_cast<GLsizei>(width), static_cast<GLsizei>(height));
}
void apply_hmd_viewport(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height)
{
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("HMD viewport dispatch failed because: %s", status.message);
}
}
std::map<ViveController::kButton, ViveController::kButtonMask> ViveController::m_mask {
{ ViveController::kButton::Trigger, ViveController::kButtonMask::TriggerBit },
{ ViveController::kButton::Pad, ViveController::kButtonMask::PadBit },
@@ -181,7 +207,7 @@ void Vive::Draw()
{
m_eyes[eye].bindFramebuffer();
m_eyes[eye].clear();
glViewport(0, 0, m_eyes[eye].getWidth(), m_eyes[eye].getHeight());
apply_hmd_viewport(0, 0, m_eyes[eye].getWidth(), m_eyes[eye].getHeight());
if (on_draw)
on_draw(m_proj[eye], m_view[eye], m_pose);

View File

@@ -52,6 +52,50 @@ void unbind_texture_2d()
LOG("NodeCanvas texture unbind dispatch failed because: %s", status.message);
}
void enable_opengl_state(std::uint32_t state) noexcept
{
glEnable(static_cast<GLenum>(state));
}
void disable_opengl_state(std::uint32_t state) noexcept
{
glDisable(static_cast<GLenum>(state));
}
void set_opengl_viewport(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height) noexcept
{
glViewport(static_cast<GLint>(x), static_cast<GLint>(y), static_cast<GLsizei>(width), static_cast<GLsizei>(height));
}
void apply_node_canvas_viewport(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height)
{
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("NodeCanvas viewport dispatch failed because: %s", status.message);
}
void apply_node_canvas_capability(std::uint32_t state, bool enabled)
{
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("NodeCanvas capability dispatch failed because: %s", status.message);
}
pp::renderer::RenderDeviceFeatures node_canvas_stroke_composite_features() noexcept
{
return ShaderManager::render_device_features();
@@ -245,7 +289,7 @@ void NodeCanvas::draw()
auto depth = glIsEnabled(pp::renderer::gl::depth_test_state());
auto scissor = glIsEnabled(pp::renderer::gl::scissor_test_state());
glDisable(pp::renderer::gl::scissor_test_state());
apply_node_canvas_capability(pp::renderer::gl::scissor_test_state(), false);
glm::ivec4 c = (glm::ivec4)glm::vec4(box.x, (int)(vp[3] - box.y - box.w), box.z, box.w);
@@ -286,13 +330,13 @@ void NodeCanvas::draw()
m_rtt.bindFramebuffer();
glClearColor(1, 1, 0, 0);
glClear(pp::renderer::gl::framebuffer_color_buffer_mask());
glViewport(0, 0, m_rtt.getWidth(), m_rtt.getHeight());
apply_node_canvas_viewport(0, 0, m_rtt.getWidth(), m_rtt.getHeight());
}
else
{
glClearColor(1, 1, 1, 0);
glClear(pp::renderer::gl::framebuffer_color_buffer_mask());
glViewport(c.x + App::I->off_x, c.y + App::I->off_y, c.z, c.w);
apply_node_canvas_viewport(c.x + App::I->off_x, c.y + App::I->off_y, c.z, c.w);
}
// NOTE: draw_merge has been disabled for worst performance
@@ -301,7 +345,7 @@ void NodeCanvas::draw()
if (draw_merged)
{
glDisable(pp::renderer::gl::blend_state());
apply_node_canvas_capability(pp::renderer::gl::blend_state(), false);
// draw the grid
for (int plane_index = 0; plane_index < 6; plane_index++)
{
@@ -347,7 +391,7 @@ void NodeCanvas::draw()
if (use_blend)
{
glViewport(0, 0, m_cache_rtt.getWidth(), m_cache_rtt.getHeight());
apply_node_canvas_viewport(0, 0, m_cache_rtt.getWidth(), m_cache_rtt.getHeight());
m_cache_rtt.bindFramebuffer();
m_cache_rtt.clear({ 1, 1, 1, 0 });
}
@@ -369,8 +413,8 @@ void NodeCanvas::draw()
}
// if not using shader blend, use gl rasterizer blend
use_blend ? glDisable(pp::renderer::gl::blend_state()) : glEnable(pp::renderer::gl::blend_state());
glDisable(pp::renderer::gl::depth_test_state());
use_blend ? apply_node_canvas_capability(pp::renderer::gl::blend_state(), false) : apply_node_canvas_capability(pp::renderer::gl::blend_state(), true);
apply_node_canvas_capability(pp::renderer::gl::depth_test_state(), false);
const auto& b = m_canvas->m_current_stroke->m_brush;
@@ -589,15 +633,15 @@ void NodeCanvas::draw()
{
m_cache_rtt.unbindFramebuffer();
if (m_density != 1.f)
glViewport(0, 0, m_rtt.getWidth(), m_rtt.getHeight());
apply_node_canvas_viewport(0, 0, m_rtt.getWidth(), m_rtt.getHeight());
else
glViewport(c.x + App::I->off_x, c.y + App::I->off_y, c.z, c.w);
apply_node_canvas_viewport(c.x + App::I->off_x, c.y + App::I->off_y, c.z, c.w);
}
// draw the grid behind the layers using a temporary copy
if (use_blend)
{
glEnable(pp::renderer::gl::blend_state());
apply_node_canvas_capability(pp::renderer::gl::blend_state(), true);
//draw the grid
for (int plane_index = 0; plane_index < 6; plane_index++)
@@ -625,7 +669,7 @@ void NodeCanvas::draw()
}
}
glDisable(pp::renderer::gl::depth_test_state());
apply_node_canvas_capability(pp::renderer::gl::depth_test_state(), false);
if (m_canvas->m_smask_active || m_canvas->m_current_mode == kCanvasMode::Copy || m_canvas->m_current_mode == kCanvasMode::Cut)
{
@@ -641,7 +685,7 @@ void NodeCanvas::draw()
ShaderManager::u_int(kShaderUniform::Tex, 0);
ShaderManager::u_vec2(kShaderUniform::PatternOffset, m_outline_pan);
set_active_texture_unit(0);
glEnable(pp::renderer::gl::blend_state());
apply_node_canvas_capability(pp::renderer::gl::blend_state(), true);
//draw the cube faces
for (int plane_index = 0; plane_index < 6; plane_index++)
@@ -676,7 +720,7 @@ void NodeCanvas::draw()
glClearColor(1, 1, 1, 0);
glClear(pp::renderer::gl::framebuffer_color_buffer_mask());
glViewport(c.x + App::I->off_x, c.y + App::I->off_y, c.z, c.w);
apply_node_canvas_viewport(c.x + App::I->off_x, c.y + App::I->off_y, c.z, c.w);
// draw the canvas
m_sampler_nearest.bind(0);
@@ -689,10 +733,10 @@ void NodeCanvas::draw()
m_rtt.unbindTexture();
}
scissor ? glEnable(pp::renderer::gl::scissor_test_state()) : glDisable(pp::renderer::gl::scissor_test_state());
blend ? glEnable(pp::renderer::gl::blend_state()) : glDisable(pp::renderer::gl::blend_state());
depth ? glEnable(pp::renderer::gl::depth_test_state()) : glDisable(pp::renderer::gl::depth_test_state());
glViewport(vp[0], vp[1], vp[2], vp[3]);
scissor ? apply_node_canvas_capability(pp::renderer::gl::scissor_test_state(), true) : apply_node_canvas_capability(pp::renderer::gl::scissor_test_state(), false);
blend ? apply_node_canvas_capability(pp::renderer::gl::blend_state(), true) : apply_node_canvas_capability(pp::renderer::gl::blend_state(), false);
depth ? apply_node_canvas_capability(pp::renderer::gl::depth_test_state(), true) : apply_node_canvas_capability(pp::renderer::gl::depth_test_state(), false);
apply_node_canvas_viewport(vp[0], vp[1], vp[2], vp[3]);
glClearColor(cc[0], cc[1], cc[2], cc[3]);
}

View File

@@ -72,6 +72,74 @@ void unbind_texture_2d()
LOG("NodeStrokePreview texture unbind dispatch failed because: %s", status.message);
}
void enable_opengl_state(std::uint32_t state) noexcept
{
glEnable(static_cast<GLenum>(state));
}
void disable_opengl_state(std::uint32_t state) noexcept
{
glDisable(static_cast<GLenum>(state));
}
void set_opengl_viewport(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height) noexcept
{
glViewport(static_cast<GLint>(x), static_cast<GLint>(y), static_cast<GLsizei>(width), static_cast<GLsizei>(height));
}
void set_opengl_scissor(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height) noexcept
{
glScissor(static_cast<GLint>(x), static_cast<GLint>(y), static_cast<GLsizei>(width), static_cast<GLsizei>(height));
}
void apply_stroke_preview_viewport(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height)
{
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("NodeStrokePreview viewport dispatch failed because: %s", status.message);
}
void apply_stroke_preview_scissor(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height)
{
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("NodeStrokePreview scissor dispatch failed because: %s", status.message);
}
void apply_stroke_preview_capability(std::uint32_t state, bool enabled)
{
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("NodeStrokePreview capability dispatch failed because: %s", status.message);
}
}
std::atomic_int NodeStrokePreview::s_instances{ 0 };
@@ -155,12 +223,12 @@ void NodeStrokePreview::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2
m_rtt_mixer.bindFramebuffer();
glViewport(0, 0, m_rtt_mixer.getWidth(), m_rtt_mixer.getHeight());
glDisable(pp::renderer::gl::depth_test_state());
glEnable(pp::renderer::gl::scissor_test_state());
glDisable(pp::renderer::gl::blend_state());
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);
glScissor(
apply_stroke_preview_scissor(
static_cast<int>(bb_min.x),
static_cast<int>(bb_min.y),
static_cast<int>(bb_sz.x),
@@ -339,7 +407,7 @@ void NodeStrokePreview::draw_stroke_immediate()
glm::vec2 size = { m_rtt.getWidth(), m_rtt.getHeight() };
glm::mat4 ortho_proj = glm::ortho<float>(0, size.x, 0, size.y, -1, 1);
glViewport(0, 0, m_rtt.getWidth(), m_rtt.getHeight());
apply_stroke_preview_viewport(0, 0, m_rtt.getWidth(), m_rtt.getHeight());
m_rtt.bindFramebuffer();
m_rtt.clear();
m_sampler_mipmap.bind(0);
@@ -418,7 +486,7 @@ void NodeStrokePreview::draw_stroke_immediate()
if (b->m_pattern_flipx) patt_scale.x *= -1.f;
if (b->m_pattern_flipy) patt_scale.y *= -1.f;
glDisable(pp::renderer::gl::blend_state());
apply_stroke_preview_capability(pp::renderer::gl::blend_state(), false);
ShaderManager::use(kShader::Stroke);
ShaderManager::u_int(kShaderUniform::Tex, 0); // brush
const auto stroke_feedback = stroke_preview_destination_feedback_plan(m_rtt.getWidth(), m_rtt.getHeight());
@@ -600,7 +668,7 @@ void NodeStrokePreview::draw_stroke_immediate()
m_rtt.unbindFramebuffer();
glViewport(vp[0], vp[1], vp[2], vp[3]);
apply_stroke_preview_viewport(vp[0], vp[1], vp[2], vp[3]);
glClearColor(cc[0], cc[1], cc[2], cc[3]);
}