implement sprite scaling

This commit is contained in:
Alessandro Mauri 2025-10-23 22:30:18 +02:00
parent c63d08c462
commit 793fd1aa28
5 changed files with 33 additions and 18 deletions

View File

@ -145,7 +145,7 @@ fn void? Ctx.checkbox_id(&ctx, Id id, String description, bool* active, String t
if (*active) {
Sprite* sprite = ctx.sprite_atlas.get(tick_sprite)!;
Id tex_id = ctx.sprite_atlas.id;
ctx.push_sprite(sprite.rect().center_to(check_bounds), sprite.uv(), tex_id, parent.z_index, type: sprite.type)!;
ctx.push_sprite(check_bounds, sprite.uv(), tex_id, parent.z_index, type: sprite.type)!;
}
} else {
if (*active) {

View File

@ -4,9 +4,9 @@ struct ElemSprite {
Id id;
}
macro Ctx.sprite(&ctx, String name, ...)
=> ctx.sprite_id(@compute_id($vasplat), name);
fn void? Ctx.sprite_id(&ctx, Id id, String name)
macro Ctx.sprite(&ctx, String name, short size = 0, ...)
=> ctx.sprite_id(@compute_id($vasplat), name, size);
fn void? Ctx.sprite_id(&ctx, Id id, String name, short size = 0)
{
id = ctx.gen_id(id)!;
Elem* parent, elem;
@ -16,11 +16,26 @@ fn void? Ctx.sprite_id(&ctx, Id id, String name)
Sprite* sprite = ctx.sprite_atlas.get(name)!;
elem.sprite.id = ctx.get_sprite_atlas_id(name);
elem.layout.w = elem.layout.children.w = @exact(sprite.w);
elem.layout.h = elem.layout.children.h = @exact(sprite.h);
// scale the sprite so that the biggest dimension becomes "size"
short width = sprite.w;
short height = sprite.h;
if (size > 0) {
if (sprite.w >= sprite.h) {
width = size;
height = (short)(size * (float)height/width);
} else {
width = (short)(size * (float)width/height);
height = size;
}
}
elem.layout.w = elem.layout.children.w = @exact(width);
elem.layout.h = elem.layout.children.h = @exact(height);
elem.layout.content_offset = style.margin + style.border + style.padding;
update_parent_size(elem, parent);
Id tex_id = ctx.sprite_atlas.id;
return ctx.push_sprite(elem.bounds, sprite.uv(), tex_id, parent.z_index, type: sprite.type)!;
Rect content_bounds = elem.bounds.pad(elem.layout.content_offset);
return ctx.push_sprite(content_bounds, sprite.uv(), tex_id, parent.z_index, type: sprite.type)!;
}

View File

@ -64,7 +64,7 @@ void sprite_main()
{
ivec2 ts = textureSize(sprite_atlas, 0);
vec2 fts = vec2(ts);
vec2 real_uv = in_uv / fts;
vec2 real_uv = in_uv.xy / fts;
fragColor = texture(sprite_atlas, real_uv);
}
@ -74,7 +74,7 @@ void font_main()
{
ivec2 ts = textureSize(font_atlas, 0);
vec2 fts = vec2(ts);
vec2 real_uv = in_uv / fts;
vec2 real_uv = in_uv.xy / fts;
vec4 opacity = texture(font_atlas, real_uv);
fragColor = vec4(in_color.rgb, in_color.a*opacity.r);
@ -85,7 +85,7 @@ void font_main()
void msdf_main() {
ivec2 ts = textureSize(sprite_atlas, 0);
vec2 fts = vec2(ts);
vec2 real_uv = in_uv / fts;
vec2 real_uv = in_uv.xy / fts;
vec3 msd = texture(sprite_atlas, real_uv).rgb;
float sd = median(msd.r, msd.g, msd.b);

View File

@ -10,7 +10,7 @@ layout(set = 1, binding = 0) uniform Viewport {
// inputs
layout(location = 0) in ivec2 in_position;
layout(location = 1) in ivec4 in_attr; // quad x,y,w,h
layout(location = 2) in ivec2 in_uv;
layout(location = 2) in ivec4 in_uv;
layout(location = 3) in uvec4 in_color;
layout(location = 4) in uint in_type;
@ -35,7 +35,7 @@ void main()
out_color = vec4(in_color) / 255.0;
// uv output. only useful if the type is SPRITE
vec2 px_uv = in_uv.xy + in_position.xy * in_attr.zw;
vec2 px_uv = in_uv.xy + in_position.xy * in_uv.zw;
out_uv = vec2(px_uv);
// quad size and radius output, only useful if type is RECT

View File

@ -55,7 +55,7 @@ struct QuadAttributes {
short x, y, w, h;
}
struct uv {
short u, v;
short u, v, w, h;
}
uint color;
uint type;
@ -483,7 +483,7 @@ fn void Renderer.create_pipeline(&self, String shader_name, PipelineType type)
}
},
.num_vertex_buffers = 2,
// the description of each vertex
// the description of each vertex, quad and bindings
.vertex_attributes = (GPUVertexAttribute[]){
{ // at location zero there is the position of the vertex
.location = 0,
@ -500,7 +500,7 @@ fn void Renderer.create_pipeline(&self, String shader_name, PipelineType type)
{ // at location two there are the per-quad uv coordinates
.location = 2,
.buffer_slot = 1,
.format = GPU_VERTEXELEMENTFORMAT_SHORT2,
.format = GPU_VERTEXELEMENTFORMAT_SHORT4,
.offset = QuadAttributes.uv.offsetof,
},
{ // at location three there is the quad color
@ -713,11 +713,11 @@ const uint TYPE_FONT = 1;
const uint TYPE_SPRITE = 2;
const uint TYPE_MSDF = 3;
fn bool Renderer.push_sprite(&self, short x, short y, short w, short h, short u, short v, uint color = 0xffffffff, uint type)
fn bool Renderer.push_sprite(&self, short x, short y, short w, short h, short u, short v, short sw, short sh, uint color = 0xffffffff, uint type)
{
QuadAttributes qa = {
.pos = {.x = x, .y = y, .w = w, .h = h},
.uv = {.u = u, .v = v},
.uv = {.u = u, .v = v, .w = sw, .h = sh},
.color = color,
.type = type,
};
@ -980,7 +980,7 @@ fn void Renderer.render_ugui(&self, CmdQueue* queue)
} else {
unreachable("unrecognized command type");
}
self.push_sprite(s.rect.x, s.rect.y, s.texture_rect.w, s.texture_rect.h, s.texture_rect.x, s.texture_rect.y, s.hue.to_uint(), type);
self.push_sprite(s.rect.x, s.rect.y, s.rect.w, s.rect.h, s.texture_rect.x, s.texture_rect.y, s.texture_rect.w, s.texture_rect.h, s.hue.to_uint(), type);
}
}
self.upload_quads();