make surface example more interesting, optimise memory filling

This commit is contained in:
koniifer 2024-10-15 21:11:06 +01:00
parent fc06820332
commit 0ebb1f200e
4 changed files with 47 additions and 85 deletions

View file

@ -4,23 +4,6 @@
framebuffer := @as(^Color, idk) framebuffer := @as(^Color, idk)
// init := fn(): void {
// width := dt.get(int, "framebuffer/fb0/width\0")
// height := dt.get(int, "framebuffer/fb0/height\0")
// pixels := width * height
// back_buffer := memory.alloc(Color, pixels * @bitcast(@sizeof(Color)))
// ctx = Context.{
// fb: dt.get(^Color, "framebuffer/fb0/ptr\0"),
// bb: back_buffer,
// buf: back_buffer,
// width,
// height,
// pixels,
// double_buffer: true,
// }
// return
// }
init := fn(double_buffer: bool): Surface { init := fn(double_buffer: bool): Surface {
framebuffer = dt.get(^Color, "framebuffer/fb0/ptr\0") framebuffer = dt.get(^Color, "framebuffer/fb0/ptr\0")
width := dt.get(int, "framebuffer/fb0/width\0") width := dt.get(int, "framebuffer/fb0/width\0")
@ -49,37 +32,22 @@ put_pixel := fn(surface: Surface, pos: Vec2(int), color: Color): void {
return return
} }
// put_filled_rect := fn(surface: Surface, pos: Vec2(int), tr: Vec2(int), color: Color): void {
// start_idx := @inline(screenidx, surface, pos.x, pos.y)
// end_idx := @inline(screenidx, surface, pos.x, pos.y + tr.y)
// loop if start_idx >= end_idx break else {
// @inline(memory.set, Color, &color, surface.buf + start_idx, @bitcast(tr.x))
// start_idx += surface.width
// }
// return
// }
put_filled_rect := fn(surface: Surface, pos: Vec2(int), tr: Vec2(int), color: Color): void { put_filled_rect := fn(surface: Surface, pos: Vec2(int), tr: Vec2(int), color: Color): void {
top_start_idx := @inline(screenidx, surface, pos.x, pos.y) top_start_idx := surface.buf + @inline(screenidx, surface, pos.x, pos.y)
bottom_start_idx := @inline(screenidx, surface, pos.x, pos.y + tr.y - 1) bottom_start_idx := surface.buf + @inline(screenidx, surface, pos.x, pos.y + tr.y - 1)
rows_to_fill := tr.y / 2 rows_to_fill := tr.y
top_cursor := 0
bottom_cursor := (tr.y - 1) * surface.width loop if rows_to_fill <= 1 break else {
i := 0 @inline(memory.set, Color, &color, top_start_idx, @bitcast(tr.x))
loop if i == rows_to_fill break else { @inline(memory.set, Color, &color, bottom_start_idx, @bitcast(tr.x))
@inline(memory.set, Color, &color, surface.buf + top_start_idx, @bitcast(tr.x))
@inline(memory.set, Color, &color, surface.buf + bottom_start_idx, @bitcast(tr.x))
top_start_idx += surface.width top_start_idx += surface.width
bottom_start_idx -= surface.width bottom_start_idx -= surface.width
i += 1 rows_to_fill -= 2
} }
if tr.y % 2 != 0 { if rows_to_fill == 1 {
middle_idx := @inline(screenidx, surface, pos.x, pos.y + rows_to_fill) @inline(memory.set, Color, &color, top_start_idx, @bitcast(tr.x))
@inline(memory.set, Color, &color, surface.buf + middle_idx, @bitcast(tr.x))
} }
return return
@ -168,40 +136,26 @@ put_line := fn(surface: Surface, p0: Vec2(int), p1: Vec2(int), color: Color): vo
return return
} }
// put_surface := fn(surface: Surface, top: Surface, pos: Vec2(int)): void {
// start_idx := @inline(screenidx, surface, pos.x, pos.y)
// end_idx := @inline(screenidx, surface, pos.x, pos.y + top.height)
// cursor := top.width * top.height
// loop if start_idx >= end_idx break else {
// @inline(memory.copy, Color, top.buf + cursor, surface.buf + start_idx, @intcast(top.width))
// start_idx += surface.width
// cursor -= top.width
// }
// return
// }
put_surface := fn(surface: Surface, top: Surface, pos: Vec2(int)): void { put_surface := fn(surface: Surface, top: Surface, pos: Vec2(int)): void {
top_start_idx := @inline(screenidx, surface, pos.x, pos.y) top_start_idx := surface.buf + @inline(screenidx, surface, pos.x, pos.y)
bottom_start_idx := @inline(screenidx, surface, pos.x, pos.y + top.height - 1) bottom_start_idx := surface.buf + @inline(screenidx, surface, pos.x, pos.y + top.height - 1)
rows_to_copy := top.height / 2 rows_to_copy := top.height
top_cursor := 0 top_cursor := top.buf
bottom_cursor := top.width * (top.height - 1) bottom_cursor := top.buf + top.width * (top.height - 1)
i := 0
loop if i == rows_to_copy break else { loop if rows_to_copy <= 1 break else {
@inline(memory.copy, Color, top.buf + top_cursor, surface.buf + top_start_idx, @intcast(top.width)) @inline(memory.copy, Color, top_cursor, top_start_idx, @bitcast(top.width))
@inline(memory.copy, Color, top.buf + bottom_cursor, surface.buf + bottom_start_idx, @intcast(top.width)) @inline(memory.copy, Color, bottom_cursor, bottom_start_idx, @bitcast(top.width))
top_start_idx += surface.width top_start_idx += surface.width
bottom_start_idx -= surface.width bottom_start_idx -= surface.width
top_cursor += top.width top_cursor += top.width
bottom_cursor -= top.width bottom_cursor -= top.width
i += 1 rows_to_copy -= 2
} }
if top.height % 2 != 0 { if rows_to_copy == 1 {
middle_idx := @inline(screenidx, surface, pos.x, pos.y + rows_to_copy) @inline(memory.copy, Color, top_cursor, top_start_idx, @bitcast(top.width))
@inline(memory.copy, Color, top.buf + top_cursor, surface.buf + middle_idx, @intcast(top.width))
} }
return return

View file

@ -1,30 +1,37 @@
.{Vec2} := @use("../../../../libraries/stn/src/lib.hb").math .{Vec2} := @use("../../../../libraries/stn/src/lib.hb").math;
.{random} := @use("../../../../libraries/stn/src/lib.hb")
render := @use("../../../../libraries/render/src/lib.hb") render := @use("../../../../libraries/render/src/lib.hb")
/* expected result: /* expected result:
the lines example bounces around the screen */ the square example bounces around the screen */
example := fn(): void { example := fn(): void {
screen := render.init(true) screen := render.init(true)
image := render.new_surface(341, 256) image := render.new_surface(341, 256)
vel := Vec2(int).(-1, -1)
p0 := Vec2(int).(0, 0)
p1 := Vec2(int).(0, image.height)
render.clear(image, .(100, 50, 0, 255))
loop if p0.y >= image.height break else {
render.put_line(image, p0, p1, .(255, 180, 100, 255))
render.put_line(image, .(image.width, image.height) - p0, .(image.width, image.height) - p1, .(255, 180, 100, 255))
p0.y += image.height >> 6
p1.x += image.width >> 6
}
vel := Vec2(int).(1, 1)
pos := Vec2(int).(100, 100) pos := Vec2(int).(100, 100)
vel_inner := Vec2(int).(1, 1)
pos_inner := Vec2(int).(10, 10)
color := @as(render.Color, @intcast(random.range(int, 0, 0xFFFFFF)))
loop { loop {
render.clear(image, render.black)
render.clear(screen, render.black)
render.put_filled_rect(image, pos_inner, .(100, 100), color)
render.put_rect(image, .(0, 0), .(image.width - 1, image.height - 1), render.white)
render.put_surface(screen, image, pos) render.put_surface(screen, image, pos)
render.sync(screen) render.sync(screen)
render.clear(screen, render.black)
if pos_inner.x == 0 | pos_inner.x == image.width - 100 {
vel_inner.x = -vel_inner.x
color = @as(render.Color, @intcast(random.range(int, 0, 0xFFFFFF)))
}
if pos_inner.y == 0 | pos_inner.y == image.height - 100 {
vel_inner.y = -vel_inner.y
color = @as(render.Color, @intcast(random.range(int, 0, 0xFFFFFF)))
}
if pos.x == 0 | pos.x == screen.width - image.width { if pos.x == 0 | pos.x == screen.width - image.width {
vel.x = -vel.x vel.x = -vel.x
@ -34,6 +41,7 @@ example := fn(): void {
} }
pos += vel pos += vel
pos_inner += vel_inner
} }
return return
} }

View file

@ -1,4 +1,4 @@
.{example} := @use("./examples/image.hb") .{example} := @use("./examples/surface.hb")
main := fn(): void { main := fn(): void {
@inline(example) @inline(example)