mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
experimental renderer for widgets with custom materials
- rename `shader` to `material` in `fyrox-ui`
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
|
||||
#![allow(missing_docs)] // TODO
|
||||
|
||||
use crate::material::Material;
|
||||
use crate::scene::camera::Camera;
|
||||
use crate::{
|
||||
core::{
|
||||
@@ -76,6 +77,7 @@ use crate::{
|
||||
use fxhash::{FxBuildHasher, FxHashMap, FxHasher};
|
||||
use fyrox_core::algebra::Point3;
|
||||
use fyrox_graph::{SceneGraph, SceneGraphNode};
|
||||
use fyrox_graphics::gpu_program::{SamplerFallback, ShaderResourceDefinition};
|
||||
use std::{
|
||||
fmt::{Debug, Formatter},
|
||||
hash::{Hash, Hasher},
|
||||
@@ -363,6 +365,49 @@ pub fn write_shader_values<T: ByteStorage>(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_texture_binding(
|
||||
server: &dyn GraphicsServer,
|
||||
material: &Material,
|
||||
resource_definition: &ShaderResourceDefinition,
|
||||
fallback_resources: &FallbackResources,
|
||||
fallback: SamplerFallback,
|
||||
texture_cache: &mut TextureCache,
|
||||
) -> ResourceBinding {
|
||||
let fallback = fallback_resources.sampler_fallback(fallback);
|
||||
let fallback = (fallback, &fallback_resources.linear_wrap_sampler);
|
||||
|
||||
let texture_sampler_pair =
|
||||
if let Some(binding) = material.binding_ref(resource_definition.name.clone()) {
|
||||
if let material::MaterialResourceBinding::Texture(binding) = binding {
|
||||
binding
|
||||
.value
|
||||
.as_ref()
|
||||
.and_then(|t| {
|
||||
texture_cache
|
||||
.get(server, t)
|
||||
.map(|t| (&t.gpu_texture, &t.gpu_sampler))
|
||||
})
|
||||
.unwrap_or(fallback)
|
||||
} else {
|
||||
Log::err(format!(
|
||||
"Unable to use texture binding {}, types mismatch! Expected \
|
||||
{:?} got {:?}",
|
||||
resource_definition.name, resource_definition.kind, binding
|
||||
));
|
||||
|
||||
fallback
|
||||
}
|
||||
} else {
|
||||
fallback
|
||||
};
|
||||
|
||||
ResourceBinding::texture(
|
||||
texture_sampler_pair.0,
|
||||
texture_sampler_pair.1,
|
||||
resource_definition.binding,
|
||||
)
|
||||
}
|
||||
|
||||
impl RenderDataBundle {
|
||||
/// Writes all the required uniform data of the bundle to uniform memory allocator.
|
||||
pub fn write_uniforms(
|
||||
@@ -597,43 +642,13 @@ impl RenderDataBundle {
|
||||
}
|
||||
_ => match resource_definition.kind {
|
||||
ShaderResourceKind::Texture { fallback, .. } => {
|
||||
let fallback = render_context.fallback_resources.sampler_fallback(fallback);
|
||||
let fallback = (
|
||||
material_bindings.push(make_texture_binding(
|
||||
server,
|
||||
material,
|
||||
resource_definition,
|
||||
render_context.fallback_resources,
|
||||
fallback,
|
||||
&render_context.fallback_resources.linear_wrap_sampler,
|
||||
);
|
||||
|
||||
let texture_sampler_pair = if let Some(binding) =
|
||||
material.binding_ref(resource_definition.name.clone())
|
||||
{
|
||||
if let material::MaterialResourceBinding::Texture(binding) = binding {
|
||||
binding
|
||||
.value
|
||||
.as_ref()
|
||||
.and_then(|t| {
|
||||
render_context
|
||||
.texture_cache
|
||||
.get(server, t)
|
||||
.map(|t| (&t.gpu_texture, &t.gpu_sampler))
|
||||
})
|
||||
.unwrap_or(fallback)
|
||||
} else {
|
||||
Log::err(format!(
|
||||
"Unable to use texture binding {}, types mismatch! Expected \
|
||||
{:?} got {:?}",
|
||||
resource_definition.name, resource_definition.kind, binding
|
||||
));
|
||||
|
||||
fallback
|
||||
}
|
||||
} else {
|
||||
fallback
|
||||
};
|
||||
|
||||
material_bindings.push(ResourceBinding::texture(
|
||||
texture_sampler_pair.0,
|
||||
texture_sampler_pair.1,
|
||||
resource_definition.binding,
|
||||
render_context.texture_cache,
|
||||
));
|
||||
}
|
||||
ShaderResourceKind::PropertyGroup(_) => {
|
||||
|
||||
@@ -1369,6 +1369,7 @@ impl Renderer {
|
||||
fallback_resources: &self.fallback_resources,
|
||||
texture_cache: &mut self.texture_cache,
|
||||
uniform_buffer_cache: &mut self.uniform_buffer_cache,
|
||||
render_pass_cache: &mut self.shader_cache,
|
||||
})?;
|
||||
|
||||
// Finally register texture in the cache so it will become available as texture in deferred/forward
|
||||
@@ -1856,6 +1857,7 @@ impl Renderer {
|
||||
fallback_resources: &self.fallback_resources,
|
||||
texture_cache: &mut self.texture_cache,
|
||||
uniform_buffer_cache: &mut self.uniform_buffer_cache,
|
||||
render_pass_cache: &mut self.shader_cache,
|
||||
})?;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,9 +32,13 @@ use crate::{
|
||||
brush::Brush,
|
||||
draw::{CommandTexture, DrawingContext},
|
||||
},
|
||||
material::{Material, MaterialResource},
|
||||
renderer::{
|
||||
bundle::{self, make_texture_binding},
|
||||
cache::{
|
||||
shader::{binding, property, PropertyGroup, RenderMaterial, RenderPassContainer},
|
||||
shader::{
|
||||
binding, property, PropertyGroup, RenderMaterial, RenderPassContainer, ShaderCache,
|
||||
},
|
||||
uniform::UniformBufferCache,
|
||||
},
|
||||
framework::{
|
||||
@@ -53,6 +57,13 @@ use crate::{
|
||||
},
|
||||
resource::texture::{Texture, TextureKind, TexturePixelKind, TextureResource},
|
||||
};
|
||||
use fyrox_core::arrayvec::ArrayVec;
|
||||
use fyrox_graphics::{
|
||||
framebuffer::{ResourceBindGroup, ResourceBinding},
|
||||
gpu_program::ShaderResourceKind,
|
||||
uniform::StaticUniformBuffer,
|
||||
};
|
||||
use fyrox_resource::untyped::UntypedResource;
|
||||
use uuid::Uuid;
|
||||
|
||||
/// User interface renderer allows you to render drawing context in specified render target.
|
||||
@@ -82,6 +93,26 @@ pub struct UiRenderContext<'a, 'b, 'c> {
|
||||
pub texture_cache: &'a mut TextureCache,
|
||||
/// A reference to the cache of uniform buffers.
|
||||
pub uniform_buffer_cache: &'a mut UniformBufferCache,
|
||||
/// A reference to the render pass cache.
|
||||
pub render_pass_cache: &'a mut ShaderCache,
|
||||
}
|
||||
|
||||
fn try_get_render_pass<'a>(
|
||||
server: &dyn GraphicsServer,
|
||||
material: Option<&UntypedResource>,
|
||||
render_pass_cache: &'a mut ShaderCache,
|
||||
) -> Option<(MaterialResource, &'a RenderPassContainer)> {
|
||||
if let Some(material) = material {
|
||||
if let Some(material) = material.try_cast::<Material>() {
|
||||
let material_data_guard = material.data_ref();
|
||||
if let Some(material_data) = material_data_guard.as_loaded_ref() {
|
||||
let rp = render_pass_cache.get(server, material_data.shader())?;
|
||||
drop(material_data_guard);
|
||||
return Some((material, rp));
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
impl UiRenderer {
|
||||
@@ -163,6 +194,7 @@ impl UiRenderer {
|
||||
fallback_resources,
|
||||
texture_cache,
|
||||
uniform_buffer_cache,
|
||||
render_pass_cache,
|
||||
} = args;
|
||||
|
||||
let mut statistics = RenderPassStatistics::default();
|
||||
@@ -176,12 +208,6 @@ impl UiRenderer {
|
||||
let resolution = Vector2::new(frame_width, frame_height);
|
||||
|
||||
for cmd in drawing_context.get_commands() {
|
||||
let mut diffuse_texture = (
|
||||
&fallback_resources.white_dummy,
|
||||
&fallback_resources.linear_wrap_sampler,
|
||||
);
|
||||
let mut is_font_texture = false;
|
||||
|
||||
let mut clip_bounds = cmd.clip_bounds;
|
||||
clip_bounds.position.x = clip_bounds.position.x.floor();
|
||||
clip_bounds.position.y = clip_bounds.position.y.floor();
|
||||
@@ -231,72 +257,6 @@ impl UiRenderer {
|
||||
});
|
||||
}
|
||||
|
||||
match &cmd.texture {
|
||||
CommandTexture::Font {
|
||||
font,
|
||||
page_index,
|
||||
height,
|
||||
} => {
|
||||
if let Some(font) = font.state().data() {
|
||||
let page_size = font.page_size() as u32;
|
||||
if let Some(page) = font
|
||||
.atlases
|
||||
.get_mut(height)
|
||||
.and_then(|atlas| atlas.pages.get_mut(*page_index))
|
||||
{
|
||||
if page.texture.is_none() || page.modified {
|
||||
if let Some(details) = Texture::from_bytes(
|
||||
TextureKind::Rectangle {
|
||||
width: page_size,
|
||||
height: page_size,
|
||||
},
|
||||
TexturePixelKind::R8,
|
||||
page.pixels.clone(),
|
||||
) {
|
||||
page.texture = Some(
|
||||
TextureResource::new_ok(
|
||||
Uuid::new_v4(),
|
||||
ResourceKind::Embedded,
|
||||
details,
|
||||
)
|
||||
.into(),
|
||||
);
|
||||
page.modified = false;
|
||||
}
|
||||
}
|
||||
if let Some(texture) = texture_cache.get(
|
||||
server,
|
||||
&page
|
||||
.texture
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.try_cast::<Texture>()
|
||||
.unwrap(),
|
||||
) {
|
||||
diffuse_texture = (&texture.gpu_texture, &texture.gpu_sampler);
|
||||
}
|
||||
is_font_texture = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
CommandTexture::Texture(texture) => {
|
||||
if let Some(texture) = texture_cache.get(server, texture) {
|
||||
diffuse_texture = (&texture.gpu_texture, &texture.gpu_sampler);
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
let mut raw_stops = [0.0; 16];
|
||||
let mut raw_colors = [Vector4::default(); 16];
|
||||
let bounds_max = cmd.bounds.right_bottom_corner();
|
||||
|
||||
let (gradient_origin, gradient_end) = match cmd.brush {
|
||||
Brush::Solid(_) => (Vector2::default(), Vector2::default()),
|
||||
Brush::LinearGradient { from, to, .. } => (from, to),
|
||||
Brush::RadialGradient { center, .. } => (center, Vector2::default()),
|
||||
};
|
||||
|
||||
let params = DrawParameters {
|
||||
cull_face: None,
|
||||
color_write: ColorMask::all(true),
|
||||
@@ -311,76 +271,219 @@ impl UiRenderer {
|
||||
scissor_box,
|
||||
};
|
||||
|
||||
let solid_color = match cmd.brush {
|
||||
Brush::Solid(color) => color,
|
||||
_ => Color::WHITE,
|
||||
let element_range = ElementRange::Specific {
|
||||
offset: cmd.triangles.start,
|
||||
count: cmd.triangles.end - cmd.triangles.start,
|
||||
};
|
||||
let gradient_colors = match cmd.brush {
|
||||
Brush::Solid(_) => &raw_colors,
|
||||
Brush::LinearGradient { ref stops, .. }
|
||||
| Brush::RadialGradient { ref stops, .. } => {
|
||||
for (i, point) in stops.iter().enumerate() {
|
||||
raw_colors[i] = point.color.as_frgba();
|
||||
|
||||
if let Some((material, render_pass_container)) =
|
||||
try_get_render_pass(server, cmd.material.as_ref(), render_pass_cache)
|
||||
{
|
||||
let render_pass = render_pass_container.get(&ImmutableString::new("Forward"))?;
|
||||
|
||||
let mut resource_bindings = ArrayVec::<ResourceBinding, 32>::new();
|
||||
|
||||
let material = material.data_ref();
|
||||
let shader = material.shader();
|
||||
let shader = shader.data_ref();
|
||||
|
||||
for resource in shader.definition.resources.iter() {
|
||||
// Ignore built-in groups.
|
||||
if resource.is_built_in() {
|
||||
continue;
|
||||
}
|
||||
&raw_colors
|
||||
}
|
||||
};
|
||||
let gradient_stops = match cmd.brush {
|
||||
Brush::Solid(_) => &raw_stops,
|
||||
Brush::LinearGradient { ref stops, .. }
|
||||
| Brush::RadialGradient { ref stops, .. } => {
|
||||
for (i, point) in stops.iter().enumerate() {
|
||||
raw_stops[i] = point.stop;
|
||||
|
||||
match resource.kind {
|
||||
ShaderResourceKind::Texture { fallback, .. } => {
|
||||
resource_bindings.push(make_texture_binding(
|
||||
server,
|
||||
&material,
|
||||
resource,
|
||||
fallback_resources,
|
||||
fallback,
|
||||
texture_cache,
|
||||
))
|
||||
}
|
||||
ShaderResourceKind::PropertyGroup(ref shader_property_group) => {
|
||||
let mut buf = StaticUniformBuffer::<16384>::new();
|
||||
|
||||
if let Some(material_property_group) =
|
||||
material.property_group_ref(resource.name.clone())
|
||||
{
|
||||
bundle::write_with_material(
|
||||
shader_property_group,
|
||||
material_property_group,
|
||||
|c, n| c.property_ref(n.clone()).map(|p| p.as_ref()),
|
||||
&mut buf,
|
||||
);
|
||||
} else {
|
||||
// No respective resource bound in the material, use shader defaults. This is very
|
||||
// important, because some drivers will crash if uniform buffer has insufficient
|
||||
// data.
|
||||
bundle::write_shader_values(shader_property_group, &mut buf)
|
||||
}
|
||||
|
||||
resource_bindings.push(ResourceBinding::buffer(
|
||||
&uniform_buffer_cache.write(buf)?,
|
||||
resource.binding,
|
||||
Default::default(),
|
||||
));
|
||||
}
|
||||
}
|
||||
&raw_stops
|
||||
}
|
||||
};
|
||||
let brush_type = match cmd.brush {
|
||||
Brush::Solid(_) => 0,
|
||||
Brush::LinearGradient { .. } => 1,
|
||||
Brush::RadialGradient { .. } => 2,
|
||||
};
|
||||
let gradient_point_count = match cmd.brush {
|
||||
Brush::Solid(_) => 0,
|
||||
Brush::LinearGradient { ref stops, .. }
|
||||
| Brush::RadialGradient { ref stops, .. } => stops.len() as i32,
|
||||
};
|
||||
|
||||
let properties = PropertyGroup::from([
|
||||
property("worldViewProjection", &ortho),
|
||||
property("solidColor", &solid_color),
|
||||
property("gradientColors", gradient_colors.as_slice()),
|
||||
property("gradientStops", gradient_stops.as_slice()),
|
||||
property("gradientOrigin", &gradient_origin),
|
||||
property("gradientEnd", &gradient_end),
|
||||
property("resolution", &resolution),
|
||||
property("boundsMin", &cmd.bounds.position),
|
||||
property("boundsMax", &bounds_max),
|
||||
property("isFont", &is_font_texture),
|
||||
property("opacity", &cmd.opacity),
|
||||
property("brushType", &brush_type),
|
||||
property("gradientPointCount", &gradient_point_count),
|
||||
]);
|
||||
statistics += frame_buffer.draw(
|
||||
&self.geometry_buffer,
|
||||
viewport,
|
||||
&render_pass.program,
|
||||
¶ms,
|
||||
&[ResourceBindGroup {
|
||||
bindings: &resource_bindings,
|
||||
}],
|
||||
element_range,
|
||||
)?;
|
||||
} else {
|
||||
// Render with standard material.
|
||||
let mut diffuse_texture = (
|
||||
&fallback_resources.white_dummy,
|
||||
&fallback_resources.linear_wrap_sampler,
|
||||
);
|
||||
let mut is_font_texture = false;
|
||||
|
||||
let material = RenderMaterial::from([
|
||||
binding("diffuseTexture", diffuse_texture),
|
||||
binding("properties", &properties),
|
||||
]);
|
||||
match &cmd.texture {
|
||||
CommandTexture::Font {
|
||||
font,
|
||||
page_index,
|
||||
height,
|
||||
} => {
|
||||
if let Some(font) = font.state().data() {
|
||||
let page_size = font.page_size() as u32;
|
||||
if let Some(page) = font
|
||||
.atlases
|
||||
.get_mut(height)
|
||||
.and_then(|atlas| atlas.pages.get_mut(*page_index))
|
||||
{
|
||||
if page.texture.is_none() || page.modified {
|
||||
if let Some(details) = Texture::from_bytes(
|
||||
TextureKind::Rectangle {
|
||||
width: page_size,
|
||||
height: page_size,
|
||||
},
|
||||
TexturePixelKind::R8,
|
||||
page.pixels.clone(),
|
||||
) {
|
||||
page.texture = Some(
|
||||
TextureResource::new_ok(
|
||||
Uuid::new_v4(),
|
||||
ResourceKind::Embedded,
|
||||
details,
|
||||
)
|
||||
.into(),
|
||||
);
|
||||
page.modified = false;
|
||||
}
|
||||
}
|
||||
if let Some(texture) = texture_cache.get(
|
||||
server,
|
||||
&page
|
||||
.texture
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.try_cast::<Texture>()
|
||||
.unwrap(),
|
||||
) {
|
||||
diffuse_texture = (&texture.gpu_texture, &texture.gpu_sampler);
|
||||
}
|
||||
is_font_texture = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
CommandTexture::Texture(texture) => {
|
||||
if let Some(texture) = texture_cache.get(server, texture) {
|
||||
diffuse_texture = (&texture.gpu_texture, &texture.gpu_sampler);
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
statistics += self.render_passes.run_pass(
|
||||
1,
|
||||
&ImmutableString::new("Primary"),
|
||||
frame_buffer,
|
||||
&self.geometry_buffer,
|
||||
viewport,
|
||||
&material,
|
||||
uniform_buffer_cache,
|
||||
ElementRange::Specific {
|
||||
offset: cmd.triangles.start,
|
||||
count: cmd.triangles.end - cmd.triangles.start,
|
||||
},
|
||||
Some(¶ms),
|
||||
)?;
|
||||
let mut raw_stops = [0.0; 16];
|
||||
let mut raw_colors = [Vector4::default(); 16];
|
||||
let bounds_max = cmd.bounds.right_bottom_corner();
|
||||
|
||||
let (gradient_origin, gradient_end) = match cmd.brush {
|
||||
Brush::Solid(_) => (Vector2::default(), Vector2::default()),
|
||||
Brush::LinearGradient { from, to, .. } => (from, to),
|
||||
Brush::RadialGradient { center, .. } => (center, Vector2::default()),
|
||||
};
|
||||
|
||||
let solid_color = match cmd.brush {
|
||||
Brush::Solid(color) => color,
|
||||
_ => Color::WHITE,
|
||||
};
|
||||
let gradient_colors = match cmd.brush {
|
||||
Brush::Solid(_) => &raw_colors,
|
||||
Brush::LinearGradient { ref stops, .. }
|
||||
| Brush::RadialGradient { ref stops, .. } => {
|
||||
for (i, point) in stops.iter().enumerate() {
|
||||
raw_colors[i] = point.color.as_frgba();
|
||||
}
|
||||
&raw_colors
|
||||
}
|
||||
};
|
||||
let gradient_stops = match cmd.brush {
|
||||
Brush::Solid(_) => &raw_stops,
|
||||
Brush::LinearGradient { ref stops, .. }
|
||||
| Brush::RadialGradient { ref stops, .. } => {
|
||||
for (i, point) in stops.iter().enumerate() {
|
||||
raw_stops[i] = point.stop;
|
||||
}
|
||||
&raw_stops
|
||||
}
|
||||
};
|
||||
let brush_type = match cmd.brush {
|
||||
Brush::Solid(_) => 0,
|
||||
Brush::LinearGradient { .. } => 1,
|
||||
Brush::RadialGradient { .. } => 2,
|
||||
};
|
||||
let gradient_point_count = match cmd.brush {
|
||||
Brush::Solid(_) => 0,
|
||||
Brush::LinearGradient { ref stops, .. }
|
||||
| Brush::RadialGradient { ref stops, .. } => stops.len() as i32,
|
||||
};
|
||||
|
||||
let properties = PropertyGroup::from([
|
||||
property("worldViewProjection", &ortho),
|
||||
property("solidColor", &solid_color),
|
||||
property("gradientColors", gradient_colors.as_slice()),
|
||||
property("gradientStops", gradient_stops.as_slice()),
|
||||
property("gradientOrigin", &gradient_origin),
|
||||
property("gradientEnd", &gradient_end),
|
||||
property("resolution", &resolution),
|
||||
property("boundsMin", &cmd.bounds.position),
|
||||
property("boundsMax", &bounds_max),
|
||||
property("isFont", &is_font_texture),
|
||||
property("opacity", &cmd.opacity),
|
||||
property("brushType", &brush_type),
|
||||
property("gradientPointCount", &gradient_point_count),
|
||||
]);
|
||||
|
||||
let material = RenderMaterial::from([
|
||||
binding("diffuseTexture", diffuse_texture),
|
||||
binding("properties", &properties),
|
||||
]);
|
||||
|
||||
statistics += self.render_passes.run_pass(
|
||||
1,
|
||||
&ImmutableString::new("Primary"),
|
||||
frame_buffer,
|
||||
&self.geometry_buffer,
|
||||
viewport,
|
||||
&material,
|
||||
uniform_buffer_cache,
|
||||
element_range,
|
||||
Some(¶ms),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(statistics)
|
||||
|
||||
+10
-10
@@ -132,7 +132,7 @@ pub struct Command {
|
||||
pub brush: Brush,
|
||||
pub texture: CommandTexture,
|
||||
pub triangles: Range<usize>,
|
||||
pub shader: Option<UntypedResource>,
|
||||
pub material: Option<UntypedResource>,
|
||||
pub opacity: f32,
|
||||
/// A set of triangles that defines clipping region.
|
||||
pub clipping_geometry: Option<ClippingGeometry>,
|
||||
@@ -786,7 +786,7 @@ pub struct DrawingContext {
|
||||
command_buffer: Vec<Command>,
|
||||
pub transform_stack: TransformStack,
|
||||
opacity_stack: Vec<f32>,
|
||||
shader_stack: Vec<UntypedResource>,
|
||||
material_stack: Vec<UntypedResource>,
|
||||
triangles_to_commit: usize,
|
||||
pub style: StyleResource,
|
||||
/// Amount of time (in seconds) that passed from creation of the engine. Keep in mind, that
|
||||
@@ -838,7 +838,7 @@ impl DrawingContext {
|
||||
transform_stack: Default::default(),
|
||||
style,
|
||||
elapsed_time: 0.0,
|
||||
shader_stack: Default::default(),
|
||||
material_stack: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -848,7 +848,7 @@ impl DrawingContext {
|
||||
self.triangle_buffer.clear();
|
||||
self.command_buffer.clear();
|
||||
self.opacity_stack.clear();
|
||||
self.shader_stack.clear();
|
||||
self.material_stack.clear();
|
||||
self.opacity_stack.push(1.0);
|
||||
self.triangles_to_commit = 0;
|
||||
}
|
||||
@@ -876,12 +876,12 @@ impl DrawingContext {
|
||||
self.opacity_stack.pop().unwrap();
|
||||
}
|
||||
|
||||
pub fn push_shader(&mut self, shader: UntypedResource) {
|
||||
self.shader_stack.push(shader)
|
||||
pub fn push_material(&mut self, shader: UntypedResource) {
|
||||
self.material_stack.push(shader)
|
||||
}
|
||||
|
||||
pub fn pop_shader(&mut self) {
|
||||
self.shader_stack.pop().unwrap();
|
||||
pub fn pop_material(&mut self) {
|
||||
self.material_stack.pop().unwrap();
|
||||
}
|
||||
|
||||
pub fn triangle_points(
|
||||
@@ -938,14 +938,14 @@ impl DrawingContext {
|
||||
let bounds = self.bounds_of(triangles.clone());
|
||||
|
||||
let opacity = *self.opacity_stack.last().unwrap();
|
||||
let shader = self.shader_stack.last().cloned();
|
||||
let shader = self.material_stack.last().cloned();
|
||||
self.command_buffer.push(Command {
|
||||
clip_bounds,
|
||||
bounds,
|
||||
brush,
|
||||
texture,
|
||||
triangles,
|
||||
shader,
|
||||
material: shader,
|
||||
opacity,
|
||||
clipping_geometry,
|
||||
});
|
||||
|
||||
+4
-4
@@ -976,8 +976,8 @@ fn draw_node(
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(shader) = node.shader.as_ref() {
|
||||
drawing_context.push_shader(shader.clone());
|
||||
if let Some(shader) = node.material.as_ref() {
|
||||
drawing_context.push_material(shader.clone());
|
||||
}
|
||||
|
||||
let pushed = if !is_node_enabled(nodes, node_handle) {
|
||||
@@ -1022,8 +1022,8 @@ fn draw_node(
|
||||
|
||||
drawing_context.transform_stack.pop();
|
||||
|
||||
if node.shader.as_ref().is_some() {
|
||||
drawing_context.pop_shader();
|
||||
if node.material.as_ref().is_some() {
|
||||
drawing_context.pop_material();
|
||||
}
|
||||
|
||||
if pushed {
|
||||
|
||||
@@ -892,8 +892,8 @@ pub struct Widget {
|
||||
/// handle to get a corresponding widget from resource.
|
||||
#[reflect(read_only)]
|
||||
pub resource: Option<Resource<UserInterface>>,
|
||||
/// A shader, that should be used when rendering the widget.
|
||||
pub shader: InheritableVariable<Option<UntypedResource>>,
|
||||
/// A material, that should be used when rendering the widget.
|
||||
pub material: InheritableVariable<Option<UntypedResource>>,
|
||||
/// Handle to a widget in a user interface resource from which this node was instantiated from.
|
||||
#[reflect(hidden)]
|
||||
pub original_handle_in_resource: Handle<UiNode>,
|
||||
@@ -1894,8 +1894,8 @@ pub struct WidgetBuilder {
|
||||
pub tab_stop: bool,
|
||||
/// A flag, that indicates that the widget accepts user input.
|
||||
pub accepts_input: bool,
|
||||
/// A shader that will be used for rendering.
|
||||
pub shader: Option<UntypedResource>,
|
||||
/// A material that will be used for rendering.
|
||||
pub material: Option<UntypedResource>,
|
||||
}
|
||||
|
||||
impl Default for WidgetBuilder {
|
||||
@@ -1945,7 +1945,7 @@ impl WidgetBuilder {
|
||||
tab_index: None,
|
||||
tab_stop: false,
|
||||
accepts_input: false,
|
||||
shader: None,
|
||||
material: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2208,9 +2208,9 @@ impl WidgetBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets a shader which will be used for rendering of this widget.
|
||||
pub fn with_shader(mut self, shader: UntypedResource) -> Self {
|
||||
self.shader = Some(shader);
|
||||
/// Sets a material which will be used for rendering of this widget.
|
||||
pub fn with_material(mut self, material: UntypedResource) -> Self {
|
||||
self.material = Some(material);
|
||||
self
|
||||
}
|
||||
|
||||
@@ -2282,7 +2282,7 @@ impl WidgetBuilder {
|
||||
id: self.id,
|
||||
is_resource_instance_root: false,
|
||||
resource: None,
|
||||
shader: self.shader.into(),
|
||||
material: self.material.into(),
|
||||
original_handle_in_resource: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user