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
consume backend-owned error codes, state queries, framebuffer targets,
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
for the current headless component matrix; see DEBT-0007 for remaining app
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
error codes, state queries, framebuffer targets, texture binding targets, and
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
behind the renderer interfaces.

View File

@@ -6,6 +6,7 @@
#include "bezier.h"
#include "canvas.h"
#include "app.h"
#include "renderer_gl/opengl_capabilities.h"
std::atomic_int NodeStrokePreview::s_instances{ 0 };
std::atomic_bool NodeStrokePreview::s_running{ false };
@@ -71,7 +72,7 @@ void NodeStrokePreview::restore_context()
NodeBorder::restore_context();
init_controls();
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();
}
@@ -89,11 +90,15 @@ 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(GL_DEPTH_TEST);
glEnable(GL_SCISSOR_TEST);
glDisable(GL_BLEND);
glDisable(pp::renderer::gl::depth_test_state());
glEnable(pp::renderer::gl::scissor_test_state());
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;
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);
m_sampler_linear.bind(0);
glActiveTexture(GL_TEXTURE0);
glActiveTexture(pp::renderer::gl::active_texture_unit(0U));
m_tex_background.bind();
glActiveTexture(GL_TEXTURE1);
glActiveTexture(pp::renderer::gl::active_texture_unit(1U));
m_rtt.bindTexture();
glActiveTexture(GL_TEXTURE3);
glActiveTexture(pp::renderer::gl::active_texture_unit(3U));
m_tex_dual.bind();
glActiveTexture(GL_TEXTURE4);
glActiveTexture(pp::renderer::gl::active_texture_unit(4U));
b->m_pattern_texture ?
b->m_pattern_texture->bind() :
glBindTexture(GL_TEXTURE_2D, 0);
glBindTexture(pp::renderer::gl::texture_2d_target(), 0);
m_plane.draw_fill();
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)
{
glActiveTexture(GL_TEXTURE1);
glActiveTexture(pp::renderer::gl::active_texture_unit(1U));
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)
{
// 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);
}
@@ -186,7 +191,7 @@ glm::vec4 NodeStrokePreview::stroke_draw_samples(std::array<vertex_t, 4>& P, Tex
if (!ShaderManager::ext_framebuffer_fetch)
{
glActiveTexture(GL_TEXTURE1);
glActiveTexture(pp::renderer::gl::active_texture_unit(1U));
blend_tex.unbind();
}
@@ -259,8 +264,8 @@ void NodeStrokePreview::draw_stroke_immediate()
GLint vp[4];
GLfloat cc[4];
glGetIntegerv(GL_VIEWPORT, vp);
glGetFloatv(GL_COLOR_CLEAR_VALUE, cc);
glGetIntegerv(pp::renderer::gl::viewport_query(), vp);
glGetFloatv(pp::renderer::gl::color_clear_value_query(), cc);
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_flipy) patt_scale.y *= -1.f;
glDisable(GL_BLEND);
glDisable(pp::renderer::gl::blend_state());
ShaderManager::use(kShader::Stroke);
ShaderManager::u_int(kShaderUniform::Tex, 0); // brush
if (!ShaderManager::ext_framebuffer_fetch)
@@ -373,10 +378,10 @@ void NodeStrokePreview::draw_stroke_immediate()
ShaderManager::u_float(kShaderUniform::MixAlpha, 0);
ShaderManager::u_float(kShaderUniform::Wet, 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->bind() :
glBindTexture(GL_TEXTURE_2D, 0);
glBindTexture(pp::renderer::gl::texture_2d_target(), 0);
auto frames_dual = stroke_draw_compute(m_dual_stroke, zoom);
for (auto& f : frames_dual)
{
@@ -387,9 +392,17 @@ void NodeStrokePreview::draw_stroke_immediate()
}
// copy raw stroke to tex
glActiveTexture(GL_TEXTURE1);
glActiveTexture(pp::renderer::gl::active_texture_unit(1U));
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
@@ -402,7 +415,15 @@ void NodeStrokePreview::draw_stroke_immediate()
m_plane.draw_fill();
//m_rtt.clear({ .3f, .3f, .3f, 1.f });
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
@@ -412,19 +433,19 @@ void NodeStrokePreview::draw_stroke_immediate()
ShaderManager::u_float(kShaderUniform::Wet, b->m_tip_wet);
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();
if (!ShaderManager::ext_framebuffer_fetch)
{
glActiveTexture(GL_TEXTURE1);
glActiveTexture(pp::renderer::gl::active_texture_unit(1U));
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->bind() :
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE3);
b->m_tip_mix > 0.f ? m_rtt_mixer.bindTexture() : glBindTexture(GL_TEXTURE_2D, 0);
glBindTexture(pp::renderer::gl::texture_2d_target(), 0);
glActiveTexture(pp::renderer::gl::active_texture_unit(3U));
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);
m_rtt.clear();
for (auto& f : frames)
@@ -443,13 +464,21 @@ void NodeStrokePreview::draw_stroke_immediate()
ShaderManager::u_float(kShaderUniform::Opacity, f.opacity);
/*auto rect =*/ stroke_draw_samples(f.shapes, m_tex);
}
glActiveTexture(GL_TEXTURE3);
glActiveTexture(pp::renderer::gl::active_texture_unit(3U));
m_rtt_mixer.unbindTexture();
// copy raw stroke to tex
glActiveTexture(GL_TEXTURE1);
glActiveTexture(pp::renderer::gl::active_texture_unit(1U));
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
@@ -483,21 +512,29 @@ void NodeStrokePreview::draw_stroke_immediate()
m_sampler_linear.bind(3);
m_sampler_linear_repeat.bind(4);
glActiveTexture(GL_TEXTURE0);
glActiveTexture(pp::renderer::gl::active_texture_unit(0U));
m_tex_background.bind();
glActiveTexture(GL_TEXTURE1);
glActiveTexture(pp::renderer::gl::active_texture_unit(1U));
m_tex.bind();
glActiveTexture(GL_TEXTURE3);
glActiveTexture(pp::renderer::gl::active_texture_unit(3U));
m_tex_dual.bind();
glActiveTexture(GL_TEXTURE4);
glActiveTexture(pp::renderer::gl::active_texture_unit(4U));
b->m_pattern_texture ?
b->m_pattern_texture->bind() :
glBindTexture(GL_TEXTURE_2D, 0);
glBindTexture(pp::renderer::gl::texture_2d_target(), 0);
m_plane.draw_fill();
// copy the result to the actual preview
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();
@@ -538,9 +575,13 @@ void NodeStrokePreview::draw_stroke()
BT_SetTerminate();
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.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();
while (s_running)
{