BlendMode

Enum BlendMode 

Source
pub enum BlendMode {
    Replace,
    Alpha,
    PremultipliedAlpha,
    Additive,
    Multiply,
    Custom(BlendState),
}
Expand description

Predefined blend modes for common use cases.

Use these to configure how source and destination colors are combined during rendering.

Variants§

§

Replace

No blending - source completely replaces destination.

§

Alpha

Standard alpha blending for transparent content.

Formula: src.rgb * src.a + dst.rgb * (1 - src.a)

Use for: Transparent UI over game content, sprites with transparency.

§

PremultipliedAlpha

Premultiplied alpha blending.

Formula: src.rgb + dst.rgb * (1 - src.a)

Use for: Blitting framebuffers with premultiplied alpha, compositing.

§

Additive

Additive blending - colors are added together.

Formula: src.rgb + dst.rgb

Use for: Glow effects, particles, light sources.

§

Multiply

Multiplicative blending.

Formula: src.rgb * dst.rgb

Use for: Shadows, color tinting.

§

Custom(BlendState)

Custom blend state for advanced use cases.

Implementations§

Source§

impl BlendMode

Source

pub fn to_blend_state(self) -> Option<BlendState>

Convert to wgpu BlendState.

Source

pub fn to_color_target_state(self, format: TextureFormat) -> ColorTargetState

Create a color target state with this blend mode.

Examples found in repository?
examples/renderer_api.rs (line 134)
28fn main() {
29    logging::init();
30
31    run_app(|ctx| {
32        let graphics_ctx = GraphicsContext::new_sync();
33        let renderer = Renderer::new(graphics_ctx);
34
35        let window = ctx
36            .create_window(WindowDescriptor {
37                title: "Renderer API Example".to_string(),
38                size: Some(PhysicalSize::new(800.0, 600.0)),
39                ..Default::default()
40            })
41            .expect("Failed to create window");
42
43        let window = RenderableWindow::new_with_descriptor(
44            window,
45            graphics_ctx,
46            WindowContextDescriptor {
47                format: Some(wgpu::TextureFormat::Bgra8UnormSrgb),
48                ..Default::default()
49            },
50        );
51
52        let window_id = window.id();
53
54        // Create shader using Renderer API
55        let shader = renderer.create_shader(Some("Color Shader"), SHADER_SOURCE);
56
57        // Create texture using Renderer helper
58        let texture_data = create_gradient_texture();
59        let texture = renderer.create_texture_2d(
60            Some("Gradient Texture"),
61            256,
62            256,
63            wgpu::TextureFormat::Rgba8UnormSrgb,
64            wgpu::TextureUsages::TEXTURE_BINDING,
65            &texture_data,
66        );
67
68        let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default());
69        let sampler = renderer.create_linear_sampler(Some("Linear Sampler"));
70
71        // Create bind group using Renderer API
72        let bind_group_layout = renderer.create_bind_group_layout(
73            Some("Texture Bind Group Layout"),
74            &[
75                wgpu::BindGroupLayoutEntry {
76                    binding: 0,
77                    visibility: wgpu::ShaderStages::FRAGMENT,
78                    ty: wgpu::BindingType::Texture {
79                        multisampled: false,
80                        view_dimension: wgpu::TextureViewDimension::D2,
81                        sample_type: wgpu::TextureSampleType::Float { filterable: true },
82                    },
83                    count: None,
84                },
85                wgpu::BindGroupLayoutEntry {
86                    binding: 1,
87                    visibility: wgpu::ShaderStages::FRAGMENT,
88                    ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
89                    count: None,
90                },
91            ],
92        );
93
94        let bind_group = renderer.create_bind_group(
95            Some("Texture Bind Group"),
96            &bind_group_layout,
97            &[
98                wgpu::BindGroupEntry {
99                    binding: 0,
100                    resource: wgpu::BindingResource::TextureView(&texture_view),
101                },
102                wgpu::BindGroupEntry {
103                    binding: 1,
104                    resource: wgpu::BindingResource::Sampler(&sampler),
105                },
106            ],
107        );
108
109        let pipeline_layout = renderer.create_pipeline_layout(
110            Some("Render Pipeline Layout"),
111            &[&bind_group_layout],
112            &[],
113        );
114
115        // Create pipeline using Renderer API with BlendMode
116        let pipeline = renderer.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
117            label: Some("Render Pipeline"),
118            layout: Some(&pipeline_layout),
119            vertex: wgpu::VertexState {
120                module: &shader,
121                entry_point: Some("vs_main"),
122                buffers: &[wgpu::VertexBufferLayout {
123                    array_stride: 4 * 4,
124                    step_mode: wgpu::VertexStepMode::Vertex,
125                    attributes: &wgpu::vertex_attr_array![0 => Float32x2, 1 => Float32x2],
126                }],
127                compilation_options: wgpu::PipelineCompilationOptions::default(),
128            },
129            fragment: Some(wgpu::FragmentState {
130                module: &shader,
131                entry_point: Some("fs_main"),
132                // Use BlendMode for transparent rendering
133                targets: &[Some(
134                    BlendMode::Alpha.to_color_target_state(wgpu::TextureFormat::Rgba8UnormSrgb),
135                )],
136                compilation_options: wgpu::PipelineCompilationOptions::default(),
137            }),
138            primitive: wgpu::PrimitiveState {
139                topology: wgpu::PrimitiveTopology::TriangleList,
140                strip_index_format: None,
141                front_face: wgpu::FrontFace::Ccw,
142                cull_mode: Some(wgpu::Face::Back),
143                polygon_mode: wgpu::PolygonMode::Fill,
144                unclipped_depth: false,
145                conservative: false,
146            },
147            depth_stencil: None,
148            multisample: wgpu::MultisampleState {
149                count: 1,
150                mask: !0,
151                alpha_to_coverage_enabled: false,
152            },
153            multiview: None,
154            cache: None,
155        });
156
157        #[rustfmt::skip]
158        let vertices: &[f32] = &[
159            -0.8, -0.8,  0.0, 1.0,
160             0.8, -0.8,  1.0, 1.0,
161             0.8,  0.8,  1.0, 0.0,
162            -0.8, -0.8,  0.0, 1.0,
163             0.8,  0.8,  1.0, 0.0,
164            -0.8,  0.8,  0.0, 0.0,
165        ];
166
167        // Create vertex buffer using Renderer helper
168        let vertex_buffer = renderer.create_vertex_buffer(Some("Vertex Buffer"), vertices);
169
170        // Create offscreen framebuffer using the new Framebuffer abstraction
171        let offscreen_fb = Framebuffer::builder(400, 300)
172            .format(wgpu::TextureFormat::Rgba8UnormSrgb)
173            .label("Offscreen FB")
174            .build(graphics_ctx);
175
176        // Create blit shader and pipeline for rendering framebuffer to surface
177        let blit_shader = renderer.create_shader(Some("Blit Shader"), BLIT_SHADER_SOURCE);
178
179        let blit_bind_group_layout = renderer.create_bind_group_layout(
180            Some("Blit Bind Group Layout"),
181            &[
182                wgpu::BindGroupLayoutEntry {
183                    binding: 0,
184                    visibility: wgpu::ShaderStages::FRAGMENT,
185                    ty: wgpu::BindingType::Texture {
186                        multisampled: false,
187                        view_dimension: wgpu::TextureViewDimension::D2,
188                        sample_type: wgpu::TextureSampleType::Float { filterable: true },
189                    },
190                    count: None,
191                },
192                wgpu::BindGroupLayoutEntry {
193                    binding: 1,
194                    visibility: wgpu::ShaderStages::FRAGMENT,
195                    ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
196                    count: None,
197                },
198            ],
199        );
200
201        let blit_bind_group = renderer.create_bind_group(
202            Some("Blit Bind Group"),
203            &blit_bind_group_layout,
204            &[
205                wgpu::BindGroupEntry {
206                    binding: 0,
207                    resource: wgpu::BindingResource::TextureView(offscreen_fb.color_view()),
208                },
209                wgpu::BindGroupEntry {
210                    binding: 1,
211                    resource: wgpu::BindingResource::Sampler(&sampler),
212                },
213            ],
214        );
215
216        let blit_pipeline_layout = renderer.create_pipeline_layout(
217            Some("Blit Pipeline Layout"),
218            &[&blit_bind_group_layout],
219            &[],
220        );
221
222        let blit_pipeline = renderer.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
223            label: Some("Blit Pipeline"),
224            layout: Some(&blit_pipeline_layout),
225            vertex: wgpu::VertexState {
226                module: &blit_shader,
227                entry_point: Some("vs_main"),
228                buffers: &[],
229                compilation_options: wgpu::PipelineCompilationOptions::default(),
230            },
231            fragment: Some(wgpu::FragmentState {
232                module: &blit_shader,
233                entry_point: Some("fs_main"),
234                // Use PremultipliedAlpha for framebuffer blitting
235                targets: &[Some(
236                    BlendMode::PremultipliedAlpha
237                        .to_color_target_state(wgpu::TextureFormat::Bgra8UnormSrgb),
238                )],
239                compilation_options: wgpu::PipelineCompilationOptions::default(),
240            }),
241            primitive: wgpu::PrimitiveState {
242                topology: wgpu::PrimitiveTopology::TriangleList,
243                ..Default::default()
244            },
245            depth_stencil: None,
246            multisample: wgpu::MultisampleState::default(),
247            multiview: None,
248            cache: None,
249        });
250
251        tracing::info!("Renderer initialized successfully");
252        tracing::info!("Device: {:?}", renderer.context().info());
253
254        Box::new(RendererApp {
255            context: graphics_ctx,
256            renderer,
257            window,
258            window_id,
259            pipeline,
260            bind_group,
261            vertex_buffer,
262            offscreen_fb,
263            blit_pipeline,
264            blit_bind_group,
265            time: 0.0,
266        })
267    });
268}

Trait Implementations§

Source§

impl Clone for BlendMode

Source§

fn clone(&self) -> BlendMode

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for BlendMode

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for BlendMode

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl From<BlendMode> for Option<BlendState>

Source§

fn from(mode: BlendMode) -> Self

Converts to this type from the input type.
Source§

impl From<BlendState> for BlendMode

Source§

fn from(state: BlendState) -> Self

Converts to this type from the input type.
Source§

impl Hash for BlendMode

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for BlendMode

Source§

fn eq(&self, other: &BlendMode) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Copy for BlendMode

Source§

impl Eq for BlendMode

Source§

impl StructuralPartialEq for BlendMode

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,