Skip to content

Commit

Permalink
RenderOperation now receives the region
Browse files Browse the repository at this point in the history
A shader that supports being embedded in a scroll view needs the region
of the context, not just the clip rect and origin.
  • Loading branch information
ecton committed Nov 23, 2024
1 parent 57f0c06 commit 5e2819a
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 28 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 5 additions & 8 deletions examples/shaders.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use std::borrow::Cow;

use cushy::figures::units::Px;
use cushy::figures::Rect;
use cushy::kludgine::{wgpu, RenderingGraphics};
use cushy::widget::MakeWidget;
use cushy::widgets::Canvas;
use cushy::{Run, SimpleRenderOperation};
use kludgine::{wgpu, RenderingGraphics};

static TRIANGLE_SHADER: &str = r#"
@vertex
Expand Down Expand Up @@ -68,13 +70,8 @@ impl SimpleRenderOperation for TriangleShader {
Self { pipeline }
}

fn render(
&self,
origin: figures::Point<figures::units::Px>,
_opacity: f32,
graphics: &mut RenderingGraphics<'_, '_>,
) {
println!("Render to {origin:?} clipped to {:?}", graphics.clip_rect());
fn render(&self, region: Rect<Px>, _opacity: f32, graphics: &mut RenderingGraphics<'_, '_>) {
println!("Render to {region:?} clipped to {:?}", graphics.clip_rect());
graphics.pass_mut().set_pipeline(&self.pipeline);
graphics.pass_mut().draw(0..3, 0..1);
}
Expand Down
59 changes: 40 additions & 19 deletions src/graphics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,15 +316,15 @@ impl<'clip, 'gfx, 'pass> Graphics<'clip, 'gfx, 'pass> {
where
Op::DrawInfo: Default,
{
let origin = self.region.origin;
let region = self.region;
self.renderer
.draw::<CushyRenderOp<Op>>((<Op::DrawInfo>::default(), origin));
.draw::<CushyRenderOp<Op>>((<Op::DrawInfo>::default(), region));
}

/// Draws `Op` with the given context.
pub fn draw_with<Op: RenderOperation>(&mut self, context: Op::DrawInfo) {
let origin = self.region.origin;
self.renderer.draw::<CushyRenderOp<Op>>((context, origin));
let region = self.region;
self.renderer.draw::<CushyRenderOp<Op>>((context, region));
}

/// Returns a reference to the font system used to render.
Expand Down Expand Up @@ -382,7 +382,7 @@ impl<'gfx, 'pass> DerefMut for RenderContext<'_, 'gfx, 'pass> {

#[derive(Debug)]
struct Prepared<T> {
origin: Point<Px>,
region: Rect<Px>,
data: T,
}

Expand All @@ -392,7 +392,7 @@ impl<Op> kludgine::drawing::RenderOperation for CushyRenderOp<Op>
where
Op: RenderOperation,
{
type DrawInfo = (Op::DrawInfo, Point<Px>);
type DrawInfo = (Op::DrawInfo, Rect<Px>);
type Prepared = Prepared<Op::Prepared>;

fn new(graphics: &mut kludgine::Graphics<'_>) -> Self {
Expand All @@ -401,12 +401,12 @@ where

fn prepare(
&mut self,
(context, origin): Self::DrawInfo,
(context, region): Self::DrawInfo,
graphics: &mut kludgine::Graphics<'_>,
) -> Self::Prepared {
Prepared {
origin,
data: self.0.prepare(context, origin, graphics),
region,
data: self.0.prepare(context, region, graphics),
}
}

Expand All @@ -417,7 +417,7 @@ where
graphics: &mut RenderingGraphics<'_, 'pass>,
) {
self.0
.render(&prepared.data, prepared.origin, opacity, graphics);
.render(&prepared.data, prepared.region, opacity, graphics);
}
}

Expand Down Expand Up @@ -630,19 +630,33 @@ pub trait RenderOperation: Send + Sync + 'static {
/// Returns a new instance of this render operation.
fn new(graphics: &mut kludgine::Graphics<'_>) -> Self;

/// Prepares this operation to be rendered at `origin` in `graphics`.
/// Prepares this operation to be rendered in `region` in `graphics`.
///
/// This operation's will automatically be clipped to the available space
/// for the context it is being drawn to. The render operation should
/// project itself into `region` and only use the clip rect as an
/// optimization. To test that this is handled correctly, try placing
/// whatever is being rendered in a `Scroll` widget and ensure that as the
/// contents are clipped, the visible area shows the correct contents.
fn prepare(
&mut self,
context: Self::DrawInfo,
origin: Point<Px>,
region: Rect<Px>,
graphics: &mut kludgine::Graphics<'_>,
) -> Self::Prepared;

/// Render `preprared` to `graphics` at `origin` with `opacity`.
/// Render `preprared` to `graphics` at `region` with `opacity`.
///
/// This operation's will automatically be clipped to the available space
/// for the context it is being drawn to. The render operation should
/// project itself into `region` and only use the clip rect as an
/// optimization. To test that this is handled correctly, try placing
/// whatever is being rendered in a `Scroll` widget and ensure that as the
/// contents are clipped, the visible area shows the correct contents.
fn render(
&self,
prepared: &Self::Prepared,
origin: Point<Px>,
region: Rect<Px>,
opacity: f32,
graphics: &mut RenderingGraphics<'_, '_>,
);
Expand All @@ -653,8 +667,15 @@ pub trait SimpleRenderOperation: Send + Sync + 'static {
/// Returns a new instance of this render operation.
fn new(graphics: &mut kludgine::Graphics<'_>) -> Self;

/// Render to `graphics` at `origin` with `opacity`.
fn render(&self, origin: Point<Px>, opacity: f32, graphics: &mut RenderingGraphics<'_, '_>);
/// Render to `graphics` at `rect` with `opacity`.
///
/// This operation's will automatically be clipped to the available space
/// for the context it is being drawn to. The render operation should
/// project itself into `region` and only use the clip rect as an
/// optimization. To test that this is handled correctly, try placing
/// whatever is being rendered in a `Scroll` widget and ensure that as the
/// contents are clipped, the visible area shows the correct contents.
fn render(&self, region: Rect<Px>, opacity: f32, graphics: &mut RenderingGraphics<'_, '_>);
}

impl<T> RenderOperation for T
Expand All @@ -671,18 +692,18 @@ where
fn prepare(
&mut self,
_context: Self::DrawInfo,
_origin: Point<Px>,
_origin: Rect<Px>,
_graphics: &mut kludgine::Graphics<'_>,
) -> Self::Prepared {
}

fn render(
&self,
_prepared: &Self::Prepared,
origin: Point<Px>,
region: Rect<Px>,
opacity: f32,
graphics: &mut RenderingGraphics<'_, '_>,
) {
self.render(origin, opacity, graphics);
self.render(region, opacity, graphics);
}
}

0 comments on commit 5e2819a

Please sign in to comment.