Get glyphs sort of rendering
This commit is contained in:
parent
28b84c081d
commit
e5d586a942
5 changed files with 37 additions and 24 deletions
|
@ -51,7 +51,16 @@ fn compile_metal_shaders() {
|
||||||
println!("cargo:rerun-if-changed={}", shader_path);
|
println!("cargo:rerun-if-changed={}", shader_path);
|
||||||
|
|
||||||
let output = Command::new("xcrun")
|
let output = Command::new("xcrun")
|
||||||
.args(&["-sdk", "macosx", "metal", "-c", shader_path, "-o"])
|
.args(&[
|
||||||
|
"-sdk",
|
||||||
|
"macosx",
|
||||||
|
"metal",
|
||||||
|
"-gline-tables-only",
|
||||||
|
"-MO",
|
||||||
|
"-c",
|
||||||
|
shader_path,
|
||||||
|
"-o",
|
||||||
|
])
|
||||||
.arg(&air_output_path)
|
.arg(&air_output_path)
|
||||||
.output()
|
.output()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -278,7 +278,7 @@ impl Renderer {
|
||||||
.or_insert_with(Vec::new)
|
.or_insert_with(Vec::new)
|
||||||
.push(shaders::GPUISprite {
|
.push(shaders::GPUISprite {
|
||||||
origin: (glyph.origin * scene.scale_factor()).to_float2(),
|
origin: (glyph.origin * scene.scale_factor()).to_float2(),
|
||||||
size: (bounds.size().to_f32() * scene.scale_factor()).to_float2(),
|
size: bounds.size().to_float2(),
|
||||||
atlas_origin: bounds.origin().to_float2(),
|
atlas_origin: bounds.origin().to_float2(),
|
||||||
color: glyph.color.to_uchar4(),
|
color: glyph.color.to_uchar4(),
|
||||||
});
|
});
|
||||||
|
@ -293,18 +293,15 @@ impl Renderer {
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
ctx.command_encoder.set_vertex_bytes(
|
ctx.command_encoder.set_vertex_bytes(
|
||||||
shaders::GPUISpriteVertexInputIndex_GPUISpriteVertexInputIndexUniforms as u64,
|
shaders::GPUISpriteVertexInputIndex_GPUISpriteVertexInputIndexViewportSize as u64,
|
||||||
mem::size_of::<shaders::GPUIUniforms>() as u64,
|
mem::size_of::<shaders::vector_float2>() as u64,
|
||||||
[shaders::GPUIUniforms {
|
[ctx.drawable_size.to_float2()].as_ptr() as *const c_void,
|
||||||
viewport_size: ctx.drawable_size.to_float2(),
|
);
|
||||||
}]
|
ctx.command_encoder.set_vertex_bytes(
|
||||||
.as_ptr() as *const c_void,
|
shaders::GPUISpriteVertexInputIndex_GPUISpriteVertexInputIndexAtlasSize as u64,
|
||||||
|
mem::size_of::<shaders::vector_float2>() as u64,
|
||||||
|
[self.sprite_cache.atlas_size().to_float2()].as_ptr() as *const c_void,
|
||||||
);
|
);
|
||||||
|
|
||||||
let buffer_contents = unsafe {
|
|
||||||
(self.instances.contents() as *mut u8).offset(*offset as isize)
|
|
||||||
as *mut shaders::GPUISprite
|
|
||||||
};
|
|
||||||
|
|
||||||
for (atlas_id, sprites) in sprites_by_atlas {
|
for (atlas_id, sprites) in sprites_by_atlas {
|
||||||
align_offset(offset);
|
align_offset(offset);
|
||||||
|
@ -327,6 +324,9 @@ impl Renderer {
|
||||||
);
|
);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let buffer_contents = (self.instances.contents() as *mut u8)
|
||||||
|
.offset(*offset as isize)
|
||||||
|
as *mut shaders::GPUISprite;
|
||||||
std::ptr::copy_nonoverlapping(sprites.as_ptr(), buffer_contents, sprites.len());
|
std::ptr::copy_nonoverlapping(sprites.as_ptr(), buffer_contents, sprites.len());
|
||||||
}
|
}
|
||||||
self.instances.did_modify_range(NSRange {
|
self.instances.did_modify_range(NSRange {
|
||||||
|
@ -430,10 +430,7 @@ mod shaders {
|
||||||
|
|
||||||
impl ToFloat2 for Vector2I {
|
impl ToFloat2 for Vector2I {
|
||||||
fn to_float2(&self) -> vector_float2 {
|
fn to_float2(&self) -> vector_float2 {
|
||||||
let mut output = self.y() as vector_float2;
|
self.to_f32().to_float2()
|
||||||
output <<= 32;
|
|
||||||
output |= self.x() as vector_float2;
|
|
||||||
output
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,8 @@ typedef struct {
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GPUISpriteVertexInputIndexVertices = 0,
|
GPUISpriteVertexInputIndexVertices = 0,
|
||||||
GPUISpriteVertexInputIndexSprites = 1,
|
GPUISpriteVertexInputIndexSprites = 1,
|
||||||
GPUISpriteVertexInputIndexUniforms = 2,
|
GPUISpriteVertexInputIndexViewportSize = 2,
|
||||||
|
GPUISpriteVertexInputIndexAtlasSize = 3,
|
||||||
} GPUISpriteVertexInputIndex;
|
} GPUISpriteVertexInputIndex;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -151,13 +151,14 @@ vertex SpriteFragmentInput sprite_vertex(
|
||||||
uint sprite_id [[instance_id]],
|
uint sprite_id [[instance_id]],
|
||||||
constant float2 *unit_vertices [[buffer(GPUISpriteVertexInputIndexVertices)]],
|
constant float2 *unit_vertices [[buffer(GPUISpriteVertexInputIndexVertices)]],
|
||||||
constant GPUISprite *sprites [[buffer(GPUISpriteVertexInputIndexSprites)]],
|
constant GPUISprite *sprites [[buffer(GPUISpriteVertexInputIndexSprites)]],
|
||||||
constant GPUIUniforms *uniforms [[buffer(GPUISpriteVertexInputIndexUniforms)]]
|
constant float2 *viewport_size [[buffer(GPUISpriteVertexInputIndexViewportSize)]],
|
||||||
|
constant float2 *atlas_size [[buffer(GPUISpriteVertexInputIndexAtlasSize)]]
|
||||||
) {
|
) {
|
||||||
float2 unit_vertex = unit_vertices[unit_vertex_id];
|
float2 unit_vertex = unit_vertices[unit_vertex_id];
|
||||||
GPUISprite sprite = sprites[sprite_id];
|
GPUISprite sprite = sprites[sprite_id];
|
||||||
float2 position = unit_vertex * sprite.size + sprite.origin;
|
float2 position = unit_vertex * sprite.size + sprite.origin;
|
||||||
float2 atlas_position = unit_vertex * sprite.size + sprite.atlas_origin;
|
float4 device_position = to_device_position(position, *viewport_size);
|
||||||
float4 device_position = to_device_position(position, uniforms->viewport_size);
|
float2 atlas_position = (unit_vertex * sprite.size + sprite.atlas_origin) / *atlas_size;
|
||||||
|
|
||||||
return SpriteFragmentInput {
|
return SpriteFragmentInput {
|
||||||
device_position,
|
device_position,
|
||||||
|
@ -172,6 +173,7 @@ fragment float4 sprite_fragment(
|
||||||
) {
|
) {
|
||||||
constexpr sampler atlas_sampler(mag_filter::linear, min_filter::linear);
|
constexpr sampler atlas_sampler(mag_filter::linear, min_filter::linear);
|
||||||
float4 color = input.color;
|
float4 color = input.color;
|
||||||
color.a *= atlas.sample(atlas_sampler, input.atlas_position).r;
|
float4 mask = atlas.sample(atlas_sampler, input.atlas_position);
|
||||||
|
color.a *= mask.a;
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,10 @@ impl SpriteCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn atlas_size(&self) -> Vector2I {
|
||||||
|
self.atlas_size
|
||||||
|
}
|
||||||
|
|
||||||
pub fn render_glyph(
|
pub fn render_glyph(
|
||||||
&mut self,
|
&mut self,
|
||||||
font_id: FontId,
|
font_id: FontId,
|
||||||
|
@ -64,12 +68,12 @@ impl SpriteCache {
|
||||||
|
|
||||||
let atlas = atlasses.last_mut().unwrap();
|
let atlas = atlasses.last_mut().unwrap();
|
||||||
if let Some(bounds) = atlas.try_insert(size, &mask) {
|
if let Some(bounds) = atlas.try_insert(size, &mask) {
|
||||||
Some((atlasses.len() - 1, bounds))
|
Some((atlasses.len() - 1, RectI::new(bounds.origin(), size)))
|
||||||
} else {
|
} else {
|
||||||
let mut atlas = Atlas::new(device, atlas_size);
|
let mut atlas = Atlas::new(device, atlas_size);
|
||||||
let bounds = atlas.try_insert(size, &mask).unwrap();
|
let bounds = atlas.try_insert(size, &mask).unwrap();
|
||||||
atlasses.push(atlas);
|
atlasses.push(atlas);
|
||||||
Some((atlasses.len() - 1, bounds))
|
Some((atlasses.len() - 1, RectI::new(bounds.origin(), size)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.clone()
|
.clone()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue