cleanup graphics.zig
This commit is contained in:
parent
ddb012d3df
commit
0ac0cd0c37
@ -660,10 +660,19 @@ pub fn setTexture(id: Texture.Id, opts: SetTextureOptions) void {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Apply premultiply, will need scratch buffer
|
var scratch = std.heap.ArenaAllocator.init(self.gpa);
|
||||||
assert(opts.premultiplied);
|
|
||||||
|
|
||||||
var mipchain = opts.mipchain;
|
var mipchain = opts.mipchain;
|
||||||
|
if (!opts.premultiplied) {
|
||||||
|
var new_mipchain = mipchain.clone(scratch.allocator()) catch |e| {
|
||||||
|
log.warn("Failed to clone mipmap: {}", .{e});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
new_mipchain.premultiplyAlpha();
|
||||||
|
|
||||||
|
mipchain = new_mipchain;
|
||||||
|
}
|
||||||
|
|
||||||
var image_data: sg.ImageData = .{};
|
var image_data: sg.ImageData = .{};
|
||||||
assert(mipchain.length() <= image_data.mip_levels.len);
|
assert(mipchain.length() <= image_data.mip_levels.len);
|
||||||
@ -917,12 +926,7 @@ pub fn setSprite(id: Sprite.Id, opts: SetSpriteOptions) void {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
next_mipchain.copyFromRect(
|
next_mipchain.copyFromRect(opts.mipchain, 0, 0, .initTrunc(rect));
|
||||||
opts.mipchain,
|
|
||||||
0, 0,
|
|
||||||
@trunc(rect.pos.x), @trunc(rect.pos.y),
|
|
||||||
@trunc(rect.size.x), @trunc(rect.size.y)
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
next_mipchain = opts.mipchain.clone(next_arena.allocator()) catch |e| {
|
next_mipchain = opts.mipchain.clone(next_arena.allocator()) catch |e| {
|
||||||
log.warn("Failed to clone mipchain: {}", .{e});
|
log.warn("Failed to clone mipchain: {}", .{e});
|
||||||
@ -931,9 +935,7 @@ pub fn setSprite(id: Sprite.Id, opts: SetSpriteOptions) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!opts.premultiplied) {
|
if (!opts.premultiplied) {
|
||||||
for (0..next_mipchain.length()) |index| {
|
next_mipchain.premultiplyAlpha();
|
||||||
next_mipchain.getLevel(index).premultiplyAlpha();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var prev_size: ?Vec2 = null;
|
var prev_size: ?Vec2 = null;
|
||||||
@ -1043,6 +1045,9 @@ fn repackSpritesheetIfNeeded(id: Spritesheet.Id) void {
|
|||||||
// TODO: This function is a bit large, there are some easy things that could be moved to separate function.
|
// TODO: This function is a bit large, there are some easy things that could be moved to separate function.
|
||||||
// e.g. extruding padding.
|
// e.g. extruding padding.
|
||||||
fn rebuildSpritesheetTextureIfNeeded(id: Spritesheet.Id) void {
|
fn rebuildSpritesheetTextureIfNeeded(id: Spritesheet.Id) void {
|
||||||
|
// TODO: Allow generating mipmaps
|
||||||
|
// https://github.com/floooh/sokol/issues/102#issuecomment-2926566603
|
||||||
|
|
||||||
const self = &g_state;
|
const self = &g_state;
|
||||||
const spritesheet = self.spritesheets.get(id) orelse return;
|
const spritesheet = self.spritesheets.get(id) orelse return;
|
||||||
if (!spritesheet.needs_texture_rebuild) {
|
if (!spritesheet.needs_texture_rebuild) {
|
||||||
@ -1095,36 +1100,22 @@ fn rebuildSpritesheetTextureIfNeeded(id: Spritesheet.Id) void {
|
|||||||
);
|
);
|
||||||
level.copyFrom(sprite_level, x, y);
|
level.copyFrom(sprite_level, x, y);
|
||||||
|
|
||||||
|
// TODO: Make `edge_extrusion` amount configurable
|
||||||
|
var edge_extrusion: u32 = 0;
|
||||||
if (padding > 0) {
|
if (padding > 0) {
|
||||||
for (0..sprite_level.width) |ox| {
|
edge_extrusion = 1;
|
||||||
const pixel = level.getPixel(x+ox, y);
|
|
||||||
for (0..padding) |i| {
|
|
||||||
@memcpy(level.getPixel(x+ox, y-(i+1)), pixel);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (0..sprite_level.width) |ox| {
|
if (edge_extrusion > 0) {
|
||||||
const pixel = level.getPixel(x+ox, y+sprite_level.height-1);
|
level.extrudeEdge(
|
||||||
for (0..padding) |i| {
|
.{
|
||||||
@memcpy(level.getPixel(x+ox, y+sprite_level.height+i), pixel);
|
.x = x,
|
||||||
}
|
.y = y,
|
||||||
}
|
.width = sprite_level.width,
|
||||||
|
.height = sprite_level.height,
|
||||||
for (0..sprite_level.height) |oy| {
|
},
|
||||||
const pixel = level.getPixel(x, y+oy);
|
edge_extrusion
|
||||||
for (0..padding) |i| {
|
);
|
||||||
@memcpy(level.getPixel(x-(i+1), y+oy), pixel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (0..sprite_level.height) |oy| {
|
|
||||||
const pixel = level.getPixel(x+sprite_level.width-1, y+oy);
|
|
||||||
for (0..padding) |i| {
|
|
||||||
@memcpy(level.getPixel(x+sprite_level.width+i, y+oy), pixel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Add padding to corners.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1301,6 +1292,22 @@ pub const Image = struct {
|
|||||||
height: u32,
|
height: u32,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const Rect = struct {
|
||||||
|
x: u32,
|
||||||
|
y: u32,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
|
||||||
|
fn initTrunc(r: Math.Rect) Image.Rect {
|
||||||
|
return .{
|
||||||
|
.x = @trunc(r.pos.x),
|
||||||
|
.y = @trunc(r.pos.y),
|
||||||
|
.width = @trunc(r.size.x),
|
||||||
|
.height = @trunc(r.size.y),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
pub fn initAlloc(gpa: Allocator, opts: InitOptions) !Image {
|
pub fn initAlloc(gpa: Allocator, opts: InitOptions) !Image {
|
||||||
const pixel_count = opts.width * opts.height;
|
const pixel_count = opts.width * opts.height;
|
||||||
const pixel_size = opts.format.pixelSize();
|
const pixel_size = opts.format.pixelSize();
|
||||||
@ -1385,15 +1392,12 @@ pub const Image = struct {
|
|||||||
source: Image,
|
source: Image,
|
||||||
cx: u32,
|
cx: u32,
|
||||||
cy: u32,
|
cy: u32,
|
||||||
source_cx: u32,
|
source_rect: Image.Rect,
|
||||||
source_cy: u32,
|
|
||||||
source_width: u32,
|
|
||||||
source_height: u32,
|
|
||||||
) void {
|
) void {
|
||||||
assert(source.format == self.format);
|
assert(source.format == self.format);
|
||||||
|
|
||||||
for (0..source_height) |oy| {
|
for (0..source_rect.height) |oy| {
|
||||||
const source_y = source_cy+oy;
|
const source_y = source_rect.y+oy;
|
||||||
const dest_y = cy+oy;
|
const dest_y = cy+oy;
|
||||||
if (dest_y >= self.height) {
|
if (dest_y >= self.height) {
|
||||||
continue;
|
continue;
|
||||||
@ -1402,8 +1406,8 @@ pub const Image = struct {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (0..source_width) |ox| {
|
for (0..source_rect.width) |ox| {
|
||||||
const source_x = source_cx+ox;
|
const source_x = source_rect.x+ox;
|
||||||
const dest_x = cx+ox;
|
const dest_x = cx+ox;
|
||||||
if (dest_x >= self.width) {
|
if (dest_x >= self.width) {
|
||||||
continue;
|
continue;
|
||||||
@ -1426,7 +1430,39 @@ pub const Image = struct {
|
|||||||
cx: u32,
|
cx: u32,
|
||||||
cy: u32,
|
cy: u32,
|
||||||
) void {
|
) void {
|
||||||
self.copyFromRect(source, cx, cy, 0, 0, source.width, source.height);
|
self.copyFromRect(source, cx, cy, .{ .x = 0, .y = 0, .width = source.width, .height = source.height});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn extrudeEdge(self: Image, rect: Image.Rect, size: u32) void {
|
||||||
|
for (0..rect.width) |ox| {
|
||||||
|
const pixel = self.getPixel(rect.x+ox, rect.y);
|
||||||
|
for (0..size) |i| {
|
||||||
|
@memcpy(self.getPixel(rect.x+ox, rect.y-(i+1)), pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (0..rect.width) |ox| {
|
||||||
|
const pixel = self.getPixel(rect.x+ox, rect.y+rect.height-1);
|
||||||
|
for (0..size) |i| {
|
||||||
|
@memcpy(self.getPixel(rect.x+ox, rect.y+rect.height+i), pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (0..rect.height) |oy| {
|
||||||
|
const pixel = self.getPixel(rect.x, rect.y+oy);
|
||||||
|
for (0..size) |i| {
|
||||||
|
@memcpy(self.getPixel(rect.x-(i+1), rect.y+oy), pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (0..rect.height) |oy| {
|
||||||
|
const pixel = self.getPixel(rect.x+rect.width-1, rect.y+oy);
|
||||||
|
for (0..size) |i| {
|
||||||
|
@memcpy(self.getPixel(rect.x+rect.width+i, rect.y+oy), pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add padding to corners.
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1562,10 +1598,7 @@ pub const Mipchain = struct {
|
|||||||
source: Mipchain,
|
source: Mipchain,
|
||||||
cx: u32,
|
cx: u32,
|
||||||
cy: u32,
|
cy: u32,
|
||||||
source_cx: u32,
|
source_rect: Image.Rect,
|
||||||
source_cy: u32,
|
|
||||||
source_width: u32,
|
|
||||||
source_height: u32,
|
|
||||||
) void {
|
) void {
|
||||||
assert(self.length() == source.length());
|
assert(self.length() == source.length());
|
||||||
|
|
||||||
@ -1576,13 +1609,21 @@ pub const Mipchain = struct {
|
|||||||
source_level,
|
source_level,
|
||||||
cx >> @intCast(index),
|
cx >> @intCast(index),
|
||||||
cy >> @intCast(index),
|
cy >> @intCast(index),
|
||||||
source_cx >> @intCast(index),
|
.{
|
||||||
source_cy >> @intCast(index),
|
.x = source_rect.x >> @intCast(index),
|
||||||
source_width >> @intCast(index),
|
.y = source_rect.y >> @intCast(index),
|
||||||
source_height >> @intCast(index),
|
.width = source_rect.width >> @intCast(index),
|
||||||
|
.height = source_rect.height >> @intCast(index),
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn premultiplyAlpha(self: Mipchain) void {
|
||||||
|
for (0..self.length()) |index| {
|
||||||
|
self.getLevel(index).premultiplyAlpha();
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Texture = struct {
|
pub const Texture = struct {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user