Move stroke preview render mapping to renderer gl

This commit is contained in:
2026-06-02 08:47:27 +02:00
parent dbaf50cb6e
commit 8a92bc973b
3 changed files with 85 additions and 38 deletions

View File

@@ -189,6 +189,9 @@ Known local toolchain state:
Legacy `util.cpp` OpenGL error naming and `gl_state` save/restore also Legacy `util.cpp` OpenGL error naming and `gl_state` save/restore also
consume backend-owned error codes, state queries, framebuffer targets, consume backend-owned error codes, state queries, framebuffer targets,
texture binding targets, and active texture units. texture binding targets, and active texture units.
`NodeStrokePreview` brush preview rendering also consumes backend-owned
depth/scissor/blend state, viewport/clear-color queries, active texture
units, 2D texture targets, copy targets, and sampler filters/wraps.
- `windows-msvc-vcpkg-headless` validates manifest install/configure/build/test - `windows-msvc-vcpkg-headless` validates manifest install/configure/build/test
for the current headless component matrix; see DEBT-0007 for remaining app for the current headless component matrix; see DEBT-0007 for remaining app
and platform triplet migration. and platform triplet migration.

View File

@@ -456,6 +456,9 @@ formats to `pp_renderer_gl`.
Legacy `util.cpp` OpenGL error naming and `gl_state` save/restore now delegate Legacy `util.cpp` OpenGL error naming and `gl_state` save/restore now delegate
error codes, state queries, framebuffer targets, texture binding targets, and error codes, state queries, framebuffer targets, texture binding targets, and
active texture units to `pp_renderer_gl`. active texture units to `pp_renderer_gl`.
`NodeStrokePreview` brush preview rendering now delegates depth/scissor/blend
state, viewport/clear-color queries, active texture units, 2D texture targets,
copy targets, and sampler filters/wraps to `pp_renderer_gl`.
The existing renderer classes are not yet fully The existing renderer classes are not yet fully
behind the renderer interfaces. behind the renderer interfaces.

View File

@@ -6,6 +6,7 @@
#include "bezier.h" #include "bezier.h"
#include "canvas.h" #include "canvas.h"
#include "app.h" #include "app.h"
#include "renderer_gl/opengl_capabilities.h"
std::atomic_int NodeStrokePreview::s_instances{ 0 }; std::atomic_int NodeStrokePreview::s_instances{ 0 };
std::atomic_bool NodeStrokePreview::s_running{ false }; std::atomic_bool NodeStrokePreview::s_running{ false };
@@ -71,7 +72,7 @@ void NodeStrokePreview::restore_context()
NodeBorder::restore_context(); NodeBorder::restore_context();
init_controls(); init_controls();
if (m_size.x > 0 && m_size.y > 0) if (m_size.x > 0 && m_size.y > 0)
m_tex_preview.create(m_size.x, m_size.y); m_tex_preview.create(static_cast<int>(m_size.x), static_cast<int>(m_size.y));
draw_stroke(); draw_stroke();
} }
@@ -89,11 +90,15 @@ void NodeStrokePreview::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2
m_rtt_mixer.bindFramebuffer(); m_rtt_mixer.bindFramebuffer();
glViewport(0, 0, m_rtt_mixer.getWidth(), m_rtt_mixer.getHeight()); glViewport(0, 0, m_rtt_mixer.getWidth(), m_rtt_mixer.getHeight());
glDisable(GL_DEPTH_TEST); glDisable(pp::renderer::gl::depth_test_state());
glEnable(GL_SCISSOR_TEST); glEnable(pp::renderer::gl::scissor_test_state());
glDisable(GL_BLEND); glDisable(pp::renderer::gl::blend_state());
glScissor(bb_min.x, bb_min.y, bb_sz.x, bb_sz.y); glScissor(
static_cast<int>(bb_min.x),
static_cast<int>(bb_min.y),
static_cast<int>(bb_sz.x),
static_cast<int>(bb_sz.y));
const auto& b = m_brush; const auto& b = m_brush;
glm::vec2 patt_scale = glm::vec2(b->m_pattern_scale); glm::vec2 patt_scale = glm::vec2(b->m_pattern_scale);
@@ -126,16 +131,16 @@ void NodeStrokePreview::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2
ShaderManager::u_float(kShaderUniform::DualAlpha, b->m_dual_opacity); ShaderManager::u_float(kShaderUniform::DualAlpha, b->m_dual_opacity);
m_sampler_linear.bind(0); m_sampler_linear.bind(0);
glActiveTexture(GL_TEXTURE0); glActiveTexture(pp::renderer::gl::active_texture_unit(0U));
m_tex_background.bind(); m_tex_background.bind();
glActiveTexture(GL_TEXTURE1); glActiveTexture(pp::renderer::gl::active_texture_unit(1U));
m_rtt.bindTexture(); m_rtt.bindTexture();
glActiveTexture(GL_TEXTURE3); glActiveTexture(pp::renderer::gl::active_texture_unit(3U));
m_tex_dual.bind(); m_tex_dual.bind();
glActiveTexture(GL_TEXTURE4); glActiveTexture(pp::renderer::gl::active_texture_unit(4U));
b->m_pattern_texture ? b->m_pattern_texture ?
b->m_pattern_texture->bind() : b->m_pattern_texture->bind() :
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(pp::renderer::gl::texture_2d_target(), 0);
m_plane.draw_fill(); m_plane.draw_fill();
m_rtt_mixer.unbindFramebuffer(); m_rtt_mixer.unbindFramebuffer();
@@ -146,7 +151,7 @@ glm::vec4 NodeStrokePreview::stroke_draw_samples(std::array<vertex_t, 4>& P, Tex
{ {
if (!ShaderManager::ext_framebuffer_fetch) if (!ShaderManager::ext_framebuffer_fetch)
{ {
glActiveTexture(GL_TEXTURE1); glActiveTexture(pp::renderer::gl::active_texture_unit(1U));
blend_tex.bind(); // bg, copy of framebuffer (copied before drawing) blend_tex.bind(); // bg, copy of framebuffer (copied before drawing)
} }
@@ -167,7 +172,7 @@ glm::vec4 NodeStrokePreview::stroke_draw_samples(std::array<vertex_t, 4>& P, Tex
if (!ShaderManager::ext_framebuffer_fetch) if (!ShaderManager::ext_framebuffer_fetch)
{ {
// this is also used by the mixer // this is also used by the mixer
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, tex_pos.x, tex_pos.y, glCopyTexSubImage2D(pp::renderer::gl::texture_2d_target(), 0, tex_pos.x, tex_pos.y,
tex_pos.x, tex_pos.y, tex_sz.x, tex_sz.y); tex_pos.x, tex_pos.y, tex_sz.x, tex_sz.y);
} }
@@ -186,7 +191,7 @@ glm::vec4 NodeStrokePreview::stroke_draw_samples(std::array<vertex_t, 4>& P, Tex
if (!ShaderManager::ext_framebuffer_fetch) if (!ShaderManager::ext_framebuffer_fetch)
{ {
glActiveTexture(GL_TEXTURE1); glActiveTexture(pp::renderer::gl::active_texture_unit(1U));
blend_tex.unbind(); blend_tex.unbind();
} }
@@ -259,8 +264,8 @@ void NodeStrokePreview::draw_stroke_immediate()
GLint vp[4]; GLint vp[4];
GLfloat cc[4]; GLfloat cc[4];
glGetIntegerv(GL_VIEWPORT, vp); glGetIntegerv(pp::renderer::gl::viewport_query(), vp);
glGetFloatv(GL_COLOR_CLEAR_VALUE, cc); glGetFloatv(pp::renderer::gl::color_clear_value_query(), cc);
float zoom = root()->m_zoom; float zoom = root()->m_zoom;
@@ -345,7 +350,7 @@ void NodeStrokePreview::draw_stroke_immediate()
if (b->m_pattern_flipx) patt_scale.x *= -1.f; if (b->m_pattern_flipx) patt_scale.x *= -1.f;
if (b->m_pattern_flipy) patt_scale.y *= -1.f; if (b->m_pattern_flipy) patt_scale.y *= -1.f;
glDisable(GL_BLEND); glDisable(pp::renderer::gl::blend_state());
ShaderManager::use(kShader::Stroke); ShaderManager::use(kShader::Stroke);
ShaderManager::u_int(kShaderUniform::Tex, 0); // brush ShaderManager::u_int(kShaderUniform::Tex, 0); // brush
if (!ShaderManager::ext_framebuffer_fetch) if (!ShaderManager::ext_framebuffer_fetch)
@@ -373,10 +378,10 @@ void NodeStrokePreview::draw_stroke_immediate()
ShaderManager::u_float(kShaderUniform::MixAlpha, 0); ShaderManager::u_float(kShaderUniform::MixAlpha, 0);
ShaderManager::u_float(kShaderUniform::Wet, 0); ShaderManager::u_float(kShaderUniform::Wet, 0);
ShaderManager::u_float(kShaderUniform::Noise, 0); ShaderManager::u_float(kShaderUniform::Noise, 0);
glActiveTexture(GL_TEXTURE0); glActiveTexture(pp::renderer::gl::active_texture_unit(0U));
dual_brush->m_tip_texture ? dual_brush->m_tip_texture ?
dual_brush->m_tip_texture->bind() : dual_brush->m_tip_texture->bind() :
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(pp::renderer::gl::texture_2d_target(), 0);
auto frames_dual = stroke_draw_compute(m_dual_stroke, zoom); auto frames_dual = stroke_draw_compute(m_dual_stroke, zoom);
for (auto& f : frames_dual) for (auto& f : frames_dual)
{ {
@@ -387,9 +392,17 @@ void NodeStrokePreview::draw_stroke_immediate()
} }
// copy raw stroke to tex // copy raw stroke to tex
glActiveTexture(GL_TEXTURE1); glActiveTexture(pp::renderer::gl::active_texture_unit(1U));
m_tex_dual.bind(); m_tex_dual.bind();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, size.x, size.y); glCopyTexSubImage2D(
pp::renderer::gl::texture_2d_target(),
0,
0,
0,
0,
0,
static_cast<int>(size.x),
static_cast<int>(size.y));
} }
// CHEKCERBOARD // CHEKCERBOARD
@@ -402,7 +415,15 @@ void NodeStrokePreview::draw_stroke_immediate()
m_plane.draw_fill(); m_plane.draw_fill();
//m_rtt.clear({ .3f, .3f, .3f, 1.f }); //m_rtt.clear({ .3f, .3f, .3f, 1.f });
m_tex_background.bind(); m_tex_background.bind();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, size.x, size.y); glCopyTexSubImage2D(
pp::renderer::gl::texture_2d_target(),
0,
0,
0,
0,
0,
static_cast<int>(size.x),
static_cast<int>(size.y));
// DRAW MAIN BRUSH // DRAW MAIN BRUSH
@@ -412,19 +433,19 @@ void NodeStrokePreview::draw_stroke_immediate()
ShaderManager::u_float(kShaderUniform::Wet, b->m_tip_wet); ShaderManager::u_float(kShaderUniform::Wet, b->m_tip_wet);
ShaderManager::u_float(kShaderUniform::Noise, b->m_tip_noise); ShaderManager::u_float(kShaderUniform::Noise, b->m_tip_noise);
glActiveTexture(GL_TEXTURE0); glActiveTexture(pp::renderer::gl::active_texture_unit(0U));
b->m_tip_texture->bind(); b->m_tip_texture->bind();
if (!ShaderManager::ext_framebuffer_fetch) if (!ShaderManager::ext_framebuffer_fetch)
{ {
glActiveTexture(GL_TEXTURE1); glActiveTexture(pp::renderer::gl::active_texture_unit(1U));
m_tex.bind(); // tmp swap for blending m_tex.bind(); // tmp swap for blending
} }
glActiveTexture(GL_TEXTURE2); glActiveTexture(pp::renderer::gl::active_texture_unit(2U));
b->m_pattern_texture ? b->m_pattern_texture ?
b->m_pattern_texture->bind() : b->m_pattern_texture->bind() :
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(pp::renderer::gl::texture_2d_target(), 0);
glActiveTexture(GL_TEXTURE3); glActiveTexture(pp::renderer::gl::active_texture_unit(3U));
b->m_tip_mix > 0.f ? m_rtt_mixer.bindTexture() : glBindTexture(GL_TEXTURE_2D, 0); b->m_tip_mix > 0.f ? m_rtt_mixer.bindTexture() : glBindTexture(pp::renderer::gl::texture_2d_target(), 0);
auto frames = stroke_draw_compute(m_stroke, zoom); auto frames = stroke_draw_compute(m_stroke, zoom);
m_rtt.clear(); m_rtt.clear();
for (auto& f : frames) for (auto& f : frames)
@@ -443,13 +464,21 @@ void NodeStrokePreview::draw_stroke_immediate()
ShaderManager::u_float(kShaderUniform::Opacity, f.opacity); ShaderManager::u_float(kShaderUniform::Opacity, f.opacity);
/*auto rect =*/ stroke_draw_samples(f.shapes, m_tex); /*auto rect =*/ stroke_draw_samples(f.shapes, m_tex);
} }
glActiveTexture(GL_TEXTURE3); glActiveTexture(pp::renderer::gl::active_texture_unit(3U));
m_rtt_mixer.unbindTexture(); m_rtt_mixer.unbindTexture();
// copy raw stroke to tex // copy raw stroke to tex
glActiveTexture(GL_TEXTURE1); glActiveTexture(pp::renderer::gl::active_texture_unit(1U));
m_tex.bind(); m_tex.bind();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, size.x, size.y); glCopyTexSubImage2D(
pp::renderer::gl::texture_2d_target(),
0,
0,
0,
0,
0,
static_cast<int>(size.x),
static_cast<int>(size.y));
// COMPOSITE // COMPOSITE
@@ -483,21 +512,29 @@ void NodeStrokePreview::draw_stroke_immediate()
m_sampler_linear.bind(3); m_sampler_linear.bind(3);
m_sampler_linear_repeat.bind(4); m_sampler_linear_repeat.bind(4);
glActiveTexture(GL_TEXTURE0); glActiveTexture(pp::renderer::gl::active_texture_unit(0U));
m_tex_background.bind(); m_tex_background.bind();
glActiveTexture(GL_TEXTURE1); glActiveTexture(pp::renderer::gl::active_texture_unit(1U));
m_tex.bind(); m_tex.bind();
glActiveTexture(GL_TEXTURE3); glActiveTexture(pp::renderer::gl::active_texture_unit(3U));
m_tex_dual.bind(); m_tex_dual.bind();
glActiveTexture(GL_TEXTURE4); glActiveTexture(pp::renderer::gl::active_texture_unit(4U));
b->m_pattern_texture ? b->m_pattern_texture ?
b->m_pattern_texture->bind() : b->m_pattern_texture->bind() :
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(pp::renderer::gl::texture_2d_target(), 0);
m_plane.draw_fill(); m_plane.draw_fill();
// copy the result to the actual preview // copy the result to the actual preview
m_tex_preview.bind(); m_tex_preview.bind();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, size.x, size.y); glCopyTexSubImage2D(
pp::renderer::gl::texture_2d_target(),
0,
0,
0,
0,
0,
static_cast<int>(size.x),
static_cast<int>(size.y));
m_rtt.unbindFramebuffer(); m_rtt.unbindFramebuffer();
@@ -538,9 +575,13 @@ void NodeStrokePreview::draw_stroke()
BT_SetTerminate(); BT_SetTerminate();
m_sampler_linear.create(); m_sampler_linear.create();
m_sampler_linear_repeat.create(GL_LINEAR, GL_REPEAT); m_sampler_linear_repeat.create(
pp::renderer::gl::linear_texture_filter(),
pp::renderer::gl::repeat_texture_wrap());
m_sampler_mipmap.create(); m_sampler_mipmap.create();
m_sampler_mipmap.set_filter(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR); m_sampler_mipmap.set_filter(
pp::renderer::gl::linear_mipmap_linear_texture_filter(),
pp::renderer::gl::linear_texture_filter());
m_brush_shape.create(); m_brush_shape.create();
while (s_running) while (s_running)
{ {