Use hand texture as render background
This commit is contained in:
441
src/render.rs
441
src/render.rs
@@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
matrix::{MatrixLayout, build_view_projection, glyph_world_position},
|
||||
model::{Instance, InstanceRaw, Model, ModelVertex, Vertex},
|
||||
resources,
|
||||
model::{AlphaMode, InstanceRaw, ModelVertex, Vertex},
|
||||
resources, texture,
|
||||
};
|
||||
use eframe::{
|
||||
egui,
|
||||
@@ -69,20 +69,86 @@ pub struct BackgroundRenderResources {
|
||||
layout: MatrixLayout,
|
||||
rows: u32,
|
||||
cols: u32,
|
||||
surface_is_srgb: bool,
|
||||
uniform: MatrixUniform,
|
||||
uniform_buffer: wgpu::Buffer,
|
||||
uniform_bind_group: wgpu::BindGroup,
|
||||
|
||||
background_pipeline: wgpu::RenderPipeline,
|
||||
hand_image_pipeline: wgpu::RenderPipeline,
|
||||
glyph_pipeline: wgpu::RenderPipeline,
|
||||
dot_pipeline: wgpu::RenderPipeline,
|
||||
model_pipeline: wgpu::RenderPipeline,
|
||||
hand_image_bind_group: wgpu::BindGroup,
|
||||
hand_image_texture: texture::Texture,
|
||||
|
||||
model: Option<Model>,
|
||||
model_instance_buffer: wgpu::Buffer,
|
||||
glyph_vertex_buffer: wgpu::Buffer,
|
||||
glyph_instance_buffer: wgpu::Buffer,
|
||||
glyph_instances: Vec<GlyphInstance>,
|
||||
render_options: RenderOptions,
|
||||
}
|
||||
|
||||
struct ModelPipelines {
|
||||
opaque: ModelCullPipelines,
|
||||
mask: ModelCullPipelines,
|
||||
blend: ModelCullPipelines,
|
||||
}
|
||||
|
||||
struct ModelCullPipelines {
|
||||
single_sided: wgpu::RenderPipeline,
|
||||
double_sided: wgpu::RenderPipeline,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
struct RenderOptions {
|
||||
debug_mode: u32,
|
||||
ambient_enabled: bool,
|
||||
tone_mapping_enabled: bool,
|
||||
exposure: f32,
|
||||
}
|
||||
|
||||
impl RenderOptions {
|
||||
fn from_env() -> Self {
|
||||
let debug_mode = std::env::var("ESKIN_MATERIAL_DEBUG")
|
||||
.ok()
|
||||
.and_then(|value| value.parse().ok())
|
||||
.unwrap_or(0);
|
||||
let ambient_enabled = env_bool("ESKIN_AMBIENT", true);
|
||||
let tone_mapping_enabled = env_bool("ESKIN_TONEMAP", true);
|
||||
let exposure = std::env::var("ESKIN_EXPOSURE")
|
||||
.ok()
|
||||
.and_then(|value| value.parse().ok())
|
||||
.unwrap_or(1.0);
|
||||
|
||||
log::warn!(
|
||||
"render options material_debug={debug_mode} ambient_enabled={ambient_enabled} tone_mapping_enabled={tone_mapping_enabled} exposure={exposure:.3}"
|
||||
);
|
||||
|
||||
Self {
|
||||
debug_mode,
|
||||
ambient_enabled,
|
||||
tone_mapping_enabled,
|
||||
exposure,
|
||||
}
|
||||
}
|
||||
|
||||
fn as_uniform(self) -> [f32; 4] {
|
||||
[
|
||||
self.debug_mode as f32,
|
||||
if self.ambient_enabled { 1.0 } else { 0.0 },
|
||||
if self.tone_mapping_enabled { 1.0 } else { 0.0 },
|
||||
self.exposure,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
fn env_bool(name: &str, default: bool) -> bool {
|
||||
std::env::var(name)
|
||||
.ok()
|
||||
.map(|value| {
|
||||
let value = value.to_ascii_lowercase();
|
||||
matches!(value.as_str(), "1" | "true" | "yes" | "on")
|
||||
})
|
||||
.unwrap_or(default)
|
||||
}
|
||||
|
||||
impl BackgroundRenderResources {
|
||||
@@ -94,7 +160,40 @@ impl BackgroundRenderResources {
|
||||
cols: u32,
|
||||
) -> Self {
|
||||
let layout = MatrixLayout::new(rows, cols);
|
||||
let uniform = MatrixUniform::new(1.0, 1.0, build_view_projection(1.0, &layout));
|
||||
let surface_is_srgb = target_format.is_srgb();
|
||||
let render_options = RenderOptions::from_env();
|
||||
log::warn!("wgpu target surface format: {target_format:?}, srgb={surface_is_srgb}");
|
||||
let hand_image_texture = match resources::load_texture("hand.png", device, _queue) {
|
||||
Ok(texture) => texture,
|
||||
Err(err) => {
|
||||
log::warn!("failed to load hand.png background: {err:#}");
|
||||
texture::Texture::from_rgba8(
|
||||
device,
|
||||
_queue,
|
||||
&[0, 0, 0, 255],
|
||||
1,
|
||||
1,
|
||||
"Fallback Hand Background Texture",
|
||||
)
|
||||
.expect("fallback hand texture should be valid")
|
||||
}
|
||||
};
|
||||
log::warn!(
|
||||
"using hand.png as render background: {}x{}",
|
||||
hand_image_texture.width,
|
||||
hand_image_texture.height
|
||||
);
|
||||
let uniform = MatrixUniform::new(
|
||||
1.0,
|
||||
1.0,
|
||||
build_view_projection(1.0, &layout),
|
||||
surface_is_srgb,
|
||||
render_options,
|
||||
[
|
||||
hand_image_texture.width as f32,
|
||||
hand_image_texture.height as f32,
|
||||
],
|
||||
);
|
||||
let uniform_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("Pressure Matrix Uniform Buffer"),
|
||||
contents: bytemuck::cast_slice(&[uniform]),
|
||||
@@ -140,9 +239,9 @@ impl BackgroundRenderResources {
|
||||
// source: wgpu::ShaderSource::Wgsl(include_str!("../static/wgsl/shader.wgsl").into()),
|
||||
// });
|
||||
|
||||
let texture_bind_group_layout =
|
||||
let hand_image_bind_group_layout =
|
||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: Some("model_texture_bind_group_layout"),
|
||||
label: Some("hand_image_bind_group_layout"),
|
||||
entries: &[
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
@@ -163,11 +262,132 @@ impl BackgroundRenderResources {
|
||||
],
|
||||
});
|
||||
|
||||
let hand_image_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
label: Some("hand_image_bind_group"),
|
||||
layout: &hand_image_bind_group_layout,
|
||||
entries: &[
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::TextureView(&hand_image_texture.view),
|
||||
},
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: wgpu::BindingResource::Sampler(&hand_image_texture.sampler),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
let texture_bind_group_layout =
|
||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: Some("model_texture_bind_group_layout"),
|
||||
entries: &[
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Texture {
|
||||
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
||||
view_dimension: wgpu::TextureViewDimension::D2,
|
||||
multisampled: false,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 2,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Buffer {
|
||||
ty: wgpu::BufferBindingType::Uniform,
|
||||
has_dynamic_offset: false,
|
||||
min_binding_size: None,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 3,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Texture {
|
||||
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
||||
view_dimension: wgpu::TextureViewDimension::D2,
|
||||
multisampled: false,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 4,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 5,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Texture {
|
||||
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
||||
view_dimension: wgpu::TextureViewDimension::D2,
|
||||
multisampled: false,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 6,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 7,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Texture {
|
||||
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
||||
view_dimension: wgpu::TextureViewDimension::D2,
|
||||
multisampled: false,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 8,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 9,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Texture {
|
||||
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
||||
view_dimension: wgpu::TextureViewDimension::D2,
|
||||
multisampled: false,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 10,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
|
||||
count: None,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("Pressure Matrix Pipeline Layout"),
|
||||
bind_group_layouts: &[Some(&uniform_bind_group_layout)],
|
||||
immediate_size: 0,
|
||||
});
|
||||
let hand_image_pipeline_layout =
|
||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("Hand Image Pipeline Layout"),
|
||||
bind_group_layouts: &[
|
||||
Some(&uniform_bind_group_layout),
|
||||
Some(&hand_image_bind_group_layout),
|
||||
],
|
||||
immediate_size: 0,
|
||||
});
|
||||
let model_pipeline_layout =
|
||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("Hand Model Pipeline Layout"),
|
||||
@@ -180,32 +400,14 @@ impl BackgroundRenderResources {
|
||||
|
||||
let background_pipeline =
|
||||
create_background_pipeline(device, target_format, &shader, &pipeline_layout);
|
||||
let hand_image_pipeline =
|
||||
create_hand_image_pipeline(device, target_format, &shader, &hand_image_pipeline_layout);
|
||||
let glyph_pipeline =
|
||||
create_glyph_pipeline(device, target_format, &shader, &pipeline_layout);
|
||||
let dot_pipeline = create_dot_pipeline(device, target_format, &shader, &pipeline_layout);
|
||||
|
||||
let model_pipeline =
|
||||
create_model_pipeline(device, target_format, &shader, &model_pipeline_layout);
|
||||
|
||||
let model =
|
||||
match resources::load_model("hand.obj", device, _queue, &texture_bind_group_layout) {
|
||||
Ok(model) => Some(model),
|
||||
Err(err) => {
|
||||
log::warn!("failed to load hand.obj: {err:#}");
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
let model_instance = Instance::new(
|
||||
glam::Vec3::new(0.0, -2.0, 12.0),
|
||||
glam::Quat::from_rotation_y(0.65) * glam::Quat::from_rotation_x(-0.35),
|
||||
)
|
||||
.to_raw();
|
||||
let model_instance_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("Hand Model Instance Buffer"),
|
||||
contents: bytemuck::cast_slice(&[model_instance]),
|
||||
usage: wgpu::BufferUsages::VERTEX,
|
||||
});
|
||||
let _model_pipelines =
|
||||
create_model_pipelines(device, target_format, &shader, &model_pipeline_layout);
|
||||
|
||||
let glyph_vertices = [
|
||||
GlyphVertex {
|
||||
@@ -235,25 +437,36 @@ impl BackgroundRenderResources {
|
||||
layout,
|
||||
rows,
|
||||
cols,
|
||||
surface_is_srgb,
|
||||
uniform,
|
||||
uniform_buffer,
|
||||
uniform_bind_group,
|
||||
background_pipeline,
|
||||
hand_image_pipeline,
|
||||
glyph_pipeline,
|
||||
dot_pipeline,
|
||||
model_pipeline,
|
||||
model,
|
||||
model_instance_buffer,
|
||||
hand_image_bind_group,
|
||||
hand_image_texture,
|
||||
glyph_vertex_buffer,
|
||||
glyph_instance_buffer,
|
||||
glyph_instances,
|
||||
render_options,
|
||||
}
|
||||
}
|
||||
|
||||
fn prepare(&mut self, queue: &wgpu::Queue, width: f32, height: f32, pressure: &PressureFrame) {
|
||||
let aspect = width / height.max(1.0);
|
||||
self.uniform =
|
||||
MatrixUniform::new(width, height, build_view_projection(aspect, &self.layout));
|
||||
self.uniform = MatrixUniform::new(
|
||||
width,
|
||||
height,
|
||||
build_view_projection(aspect, &self.layout),
|
||||
self.surface_is_srgb,
|
||||
self.render_options,
|
||||
[
|
||||
self.hand_image_texture.width as f32,
|
||||
self.hand_image_texture.height as f32,
|
||||
],
|
||||
);
|
||||
queue.write_buffer(
|
||||
&self.uniform_buffer,
|
||||
0,
|
||||
@@ -280,6 +493,10 @@ impl BackgroundRenderResources {
|
||||
render_pass.set_pipeline(&self.background_pipeline);
|
||||
render_pass.draw(0..3, 0..1);
|
||||
|
||||
render_pass.set_pipeline(&self.hand_image_pipeline);
|
||||
render_pass.set_bind_group(1, &self.hand_image_bind_group, &[]);
|
||||
render_pass.draw(0..6, 0..1);
|
||||
|
||||
match active_mode {
|
||||
ActiveMode::Finger(mode) => self.paint_finger(render_pass, mode),
|
||||
ActiveMode::Hand(mode) => self.paint_hand(render_pass, mode),
|
||||
@@ -303,20 +520,7 @@ impl BackgroundRenderResources {
|
||||
|
||||
fn paint_hand(&self, render_pass: &mut wgpu::RenderPass<'_>, mode: &HandGatewayMode) {
|
||||
let _range = mode.range.clone();
|
||||
|
||||
if let Some(model) = &self.model {
|
||||
render_pass.set_pipeline(&self.model_pipeline);
|
||||
render_pass.set_vertex_buffer(1, self.model_instance_buffer.slice(..));
|
||||
for mesh in &model.meshes {
|
||||
if let Some(material) = model.materials.get(mesh.material) {
|
||||
render_pass.set_bind_group(1, &material.bind_group, &[]);
|
||||
}
|
||||
render_pass.set_vertex_buffer(0, mesh.vertex_buffer.slice(..));
|
||||
render_pass
|
||||
.set_index_buffer(mesh.index_buffer.slice(..), wgpu::IndexFormat::Uint32);
|
||||
render_pass.draw_indexed(0..mesh.num_elements, 0, 0..1);
|
||||
}
|
||||
}
|
||||
let _ = render_pass;
|
||||
}
|
||||
|
||||
fn visible_instance_count(&self, rows: u32, cols: u32) -> u32 {
|
||||
@@ -358,6 +562,39 @@ fn create_background_pipeline(
|
||||
})
|
||||
}
|
||||
|
||||
fn create_hand_image_pipeline(
|
||||
device: &wgpu::Device,
|
||||
target_format: &wgpu::TextureFormat,
|
||||
shader: &wgpu::ShaderModule,
|
||||
layout: &wgpu::PipelineLayout,
|
||||
) -> wgpu::RenderPipeline {
|
||||
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: Some("Hand Image Background Pipeline"),
|
||||
layout: Some(layout),
|
||||
vertex: wgpu::VertexState {
|
||||
module: shader,
|
||||
entry_point: Some("vs_hand_image"),
|
||||
compilation_options: Default::default(),
|
||||
buffers: &[],
|
||||
},
|
||||
fragment: Some(wgpu::FragmentState {
|
||||
module: shader,
|
||||
entry_point: Some("fs_hand_image"),
|
||||
compilation_options: Default::default(),
|
||||
targets: &[Some(wgpu::ColorTargetState {
|
||||
format: *target_format,
|
||||
blend: Some(wgpu::BlendState::ALPHA_BLENDING),
|
||||
write_mask: wgpu::ColorWrites::ALL,
|
||||
})],
|
||||
}),
|
||||
primitive: wgpu::PrimitiveState::default(),
|
||||
depth_stencil: None,
|
||||
multisample: wgpu::MultisampleState::default(),
|
||||
multiview_mask: None,
|
||||
cache: None,
|
||||
})
|
||||
}
|
||||
|
||||
fn create_glyph_pipeline(
|
||||
device: &wgpu::Device,
|
||||
target_format: &wgpu::TextureFormat,
|
||||
@@ -391,14 +628,88 @@ fn create_glyph_pipeline(
|
||||
})
|
||||
}
|
||||
|
||||
fn create_model_pipelines(
|
||||
device: &wgpu::Device,
|
||||
target_format: &wgpu::TextureFormat,
|
||||
shader: &wgpu::ShaderModule,
|
||||
layout: &wgpu::PipelineLayout,
|
||||
) -> ModelPipelines {
|
||||
ModelPipelines {
|
||||
opaque: ModelCullPipelines {
|
||||
single_sided: create_model_pipeline(
|
||||
device,
|
||||
target_format,
|
||||
shader,
|
||||
layout,
|
||||
AlphaMode::Opaque,
|
||||
false,
|
||||
),
|
||||
double_sided: create_model_pipeline(
|
||||
device,
|
||||
target_format,
|
||||
shader,
|
||||
layout,
|
||||
AlphaMode::Opaque,
|
||||
true,
|
||||
),
|
||||
},
|
||||
mask: ModelCullPipelines {
|
||||
single_sided: create_model_pipeline(
|
||||
device,
|
||||
target_format,
|
||||
shader,
|
||||
layout,
|
||||
AlphaMode::Mask,
|
||||
false,
|
||||
),
|
||||
double_sided: create_model_pipeline(
|
||||
device,
|
||||
target_format,
|
||||
shader,
|
||||
layout,
|
||||
AlphaMode::Mask,
|
||||
true,
|
||||
),
|
||||
},
|
||||
blend: ModelCullPipelines {
|
||||
single_sided: create_model_pipeline(
|
||||
device,
|
||||
target_format,
|
||||
shader,
|
||||
layout,
|
||||
AlphaMode::Blend,
|
||||
false,
|
||||
),
|
||||
double_sided: create_model_pipeline(
|
||||
device,
|
||||
target_format,
|
||||
shader,
|
||||
layout,
|
||||
AlphaMode::Blend,
|
||||
true,
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn create_model_pipeline(
|
||||
device: &wgpu::Device,
|
||||
target_format: &wgpu::TextureFormat,
|
||||
shader: &wgpu::ShaderModule,
|
||||
layout: &wgpu::PipelineLayout,
|
||||
alpha_mode: AlphaMode,
|
||||
double_sided: bool,
|
||||
) -> wgpu::RenderPipeline {
|
||||
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: Some("Hand Model Pipeline"),
|
||||
label: Some(&format!(
|
||||
"Hand Model {} {} Pipeline",
|
||||
alpha_mode.as_str(),
|
||||
if double_sided {
|
||||
"Double Sided"
|
||||
} else {
|
||||
"Single Sided"
|
||||
}
|
||||
)),
|
||||
layout: Some(layout),
|
||||
vertex: wgpu::VertexState {
|
||||
module: shader,
|
||||
@@ -412,10 +723,11 @@ fn create_model_pipeline(
|
||||
compilation_options: Default::default(),
|
||||
targets: &[Some(wgpu::ColorTargetState {
|
||||
format: *target_format,
|
||||
blend: Some(wgpu::BlendState {
|
||||
color: wgpu::BlendComponent::REPLACE,
|
||||
alpha: wgpu::BlendComponent::REPLACE,
|
||||
}),
|
||||
blend: if alpha_mode == AlphaMode::Blend {
|
||||
Some(wgpu::BlendState::ALPHA_BLENDING)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
write_mask: wgpu::ColorWrites::ALL,
|
||||
})],
|
||||
}),
|
||||
@@ -423,7 +735,11 @@ fn create_model_pipeline(
|
||||
topology: wgpu::PrimitiveTopology::TriangleList,
|
||||
strip_index_format: None,
|
||||
front_face: wgpu::FrontFace::Ccw,
|
||||
cull_mode: None,
|
||||
cull_mode: if double_sided {
|
||||
None
|
||||
} else {
|
||||
Some(wgpu::Face::Back)
|
||||
},
|
||||
polygon_mode: wgpu::PolygonMode::Fill,
|
||||
unclipped_depth: false,
|
||||
conservative: false,
|
||||
@@ -524,15 +840,26 @@ struct MatrixUniform {
|
||||
viewport: [f32; 4],
|
||||
glyph: [f32; 4],
|
||||
color: [f32; 4],
|
||||
render_options: [f32; 4],
|
||||
image: [f32; 4],
|
||||
}
|
||||
|
||||
impl MatrixUniform {
|
||||
fn new(width: f32, height: f32, view_proj: [[f32; 4]; 4]) -> Self {
|
||||
fn new(
|
||||
width: f32,
|
||||
height: f32,
|
||||
view_proj: [[f32; 4]; 4],
|
||||
surface_is_srgb: bool,
|
||||
render_options: RenderOptions,
|
||||
image_size: [f32; 2],
|
||||
) -> Self {
|
||||
Self {
|
||||
view_proj,
|
||||
viewport: [width.max(1.0), height.max(1.0), 0.0, 0.0],
|
||||
glyph: [16.0, 0.0, 0.0, 0.0],
|
||||
color: [0.05, 0.92, 0.32, 1.0],
|
||||
color: [0.05, 0.92, 0.32, if surface_is_srgb { 1.0 } else { 0.0 }],
|
||||
render_options: render_options.as_uniform(),
|
||||
image: [image_size[0].max(1.0), image_size[1].max(1.0), 0.0, 0.0],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user