Skip to content

Commit

Permalink
Canvas2D: added scissor rect support
Browse files Browse the repository at this point in the history
  • Loading branch information
nadult committed Jan 8, 2025
1 parent 348629c commit 5cd4938
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 6 deletions.
10 changes: 8 additions & 2 deletions include/fwk/gfx/canvas_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ class Canvas2D {
void setMaterial(const SimpleMaterial &);
SimpleMaterial getMaterial() const;

void setScissorRect(Maybe<IRect>);
Maybe<IRect> getScissorRect() const;

void pushViewMatrix();
void popViewMatrix();
void mulViewMatrix(const Matrix4 &);
Expand Down Expand Up @@ -79,12 +82,14 @@ class Canvas2D {

private:
struct Group {
Group(int first_index, int pipeline_index)
: first_index(first_index), num_indices(0), pipeline_index(pipeline_index) {}
Group(int first_index, int pipeline_index, int scissor_rect_index)
: first_index(first_index), num_indices(0), pipeline_index(pipeline_index),
scissor_rect_index(scissor_rect_index) {}

PVImageView texture;
int first_index, num_indices;
int pipeline_index;
int scissor_rect_index;
};

int getPipeline(const SimplePipelineSetup &);
Expand All @@ -99,6 +104,7 @@ class Canvas2D {
vector<SimplePipelineSetup> m_pipelines;
vector<Matrix4> m_group_matrices;
vector<Group> m_groups;
vector<IRect> m_scissor_rects;

PodVector<float3> m_positions;
PodVector<TexCoord> m_tex_coords;
Expand Down
4 changes: 2 additions & 2 deletions include/fwk/gfx/drawing.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,20 @@ struct SimpleDrawCall {

// Vertex data:
// indices, tex_coords, normals & colors are optional

VBufferSpan<u32> indices;
VBufferSpan<float3> vertices;
VBufferSpan<float2> tex_coords;
VBufferSpan<IColor> colors;

// Instance data:

struct Instance {
PVImageView texture;
int pipeline_index;
int first_index, num_vertices;
int scissor_rect_index;
};
VBufferSpan<Matrix4> instance_matrices;
vector<IRect> scissor_rects;
vector<Instance> instances;
vector<PVPipeline> pipelines;
};
Expand Down
21 changes: 20 additions & 1 deletion src/gfx/canvas_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace fwk {
Canvas2D::Canvas2D(const IRect &viewport, Orient2D orient)
: m_matrix_stack(projectionMatrix2D(viewport, orient), viewMatrix2D(viewport, float2(0, 0))),
m_viewport(viewport) {
m_groups.emplace_back(0, getPipeline({}));
m_groups.emplace_back(0, getPipeline({}), -1);
m_group_matrices.emplace_back(m_matrix_stack.fullMatrix());
}

Expand Down Expand Up @@ -81,10 +81,12 @@ Ex<SimpleDrawCall> Canvas2D::genDrawCall(ShaderCompiler &compiler, VulkanDevice
instance.pipeline_index = group.pipeline_index + (skip_first_pipeline ? -1 : 0);
instance.num_vertices = group.num_indices;
instance.first_index = group.first_index;
instance.scissor_rect_index = group.scissor_rect_index;
}

auto setups = subSpan(m_pipelines, skip_first_pipeline ? 1 : 0);
dc.pipelines = EX_PASS(SimpleDrawCall::makePipelines(compiler, device, render_pass, setups));
dc.scissor_rects = m_scissor_rects;
return dc;
}

Expand Down Expand Up @@ -160,6 +162,23 @@ SimpleMaterial Canvas2D::getMaterial() const {
return SimpleMaterial{group.texture, IColor(m_cur_color), pipe.flags, pipe.blending_mode};
}

void Canvas2D::setScissorRect(Maybe<IRect> rect) {
if(getScissorRect() == rect)
return;
splitGroup();
int scissor_index = -1;
if(rect) {
scissor_index = m_scissor_rects.size();
m_scissor_rects.emplace_back(*rect);
}
m_groups.back().scissor_rect_index = scissor_index;
}

Maybe<IRect> Canvas2D::getScissorRect() const {
int index = m_groups.back().scissor_rect_index;
return index == -1 ? Maybe<IRect>() : m_scissor_rects[index];
}

void Canvas2D::pushViewMatrix() {
m_matrix_stack.pushViewMatrix();
if(!splitGroup())
Expand Down
12 changes: 11 additions & 1 deletion src/gfx/drawing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ void SimpleDrawCall::render(VulkanDevice &device) {
cmds.bindIndices(indices);

uint instance_id = 0;
for(auto &instance : instances) {
for(int i = 0; i < instances.size(); i++) {
auto &instance = instances[i];

if(instance.pipeline_index != prev_pipeline_idx) {
cmds.bind(pipelines[instance.pipeline_index]);
prev_pipeline_idx = instance.pipeline_index;
Expand All @@ -137,12 +139,20 @@ void SimpleDrawCall::render(VulkanDevice &device) {
cmds.bindDS(1).set(0, {{sampler, instance.texture}});
prev_tex = instance.texture;
}
if(i == 0 || instance.scissor_rect_index != instances[i - 1].scissor_rect_index) {
Maybe<IRect> scissor_rect;
if(instance.scissor_rect_index != -1)
scissor_rect = scissor_rects[instance.scissor_rect_index];
cmds.setScissor(scissor_rect);
}

if(indices)
cmds.drawIndexed(instance.num_vertices, 1, instance.first_index, instance_id++);
else
cmds.draw(instance.num_vertices, 1, instance.first_index, instance_id++);
}

cmds.setScissor(none);
}

/*
Expand Down

0 comments on commit 5cd4938

Please sign in to comment.