zig sample:

* generate a gradient image and draw it
* rbga8 color helpers and some const tweaks
This commit is contained in:
Reuben Dunnington 2023-10-01 14:56:32 -04:00
parent c31c81bd9c
commit 024a528afa
Signed by: rdunnington
GPG Key ID: 3D57C8938EA08E90
2 changed files with 87 additions and 21 deletions

View File

@ -1,6 +1,8 @@
const std = @import("std");
const oc = @import("orca");
const lerp = std.math.lerp;
const Vec2 = oc.Vec2;
const Mat2x3 = oc.Mat2x3;
const Str8 = oc.Str8;
@ -9,6 +11,7 @@ var surface: oc.Surface = undefined;
var canvas: oc.Canvas = undefined;
var font: oc.Font = undefined;
var orca_image: oc.Image = undefined;
var gradient_image: oc.Image = undefined;
var counter: u32 = 0;
var last_seconds: f64 = 0;
@ -42,6 +45,41 @@ export fn oc_on_init() void {
orca_image = oc.Image.createFromPath(surface, Str8.fromSlice("/orca_jumping.jpg"), false);
oc.assert(oc.Image.nil().isNil() == true, "nil image should be nil", .{}, @src());
oc.assert(orca_image.isNil() == false, "created image should not be nil", .{}, @src());
// generate a gradient and upload it to an image
{
const width = 256;
const height = 128;
const tl = oc.Color{ .r = 70.0 / 255.0, .g = 13.0 / 255.0, .b = 108.0 / 255.0 };
const bl = oc.Color{ .r = 251.0 / 255.0, .g = 167.0 / 255.0, .b = 87.0 / 255.0 };
const tr = oc.Color{ .r = 48.0 / 255.0, .g = 164.0 / 255.0, .b = 219.0 / 255.0 };
const br = oc.Color{ .r = 151.0 / 255.0, .g = 222.0 / 255.0, .b = 150.0 / 255.0 };
var pixels: [width * height]u32 = undefined;
for (0..height) |y| {
for (0..width) |x| {
const h: f32 = @floatFromInt(height - 1);
const w: f32 = @floatFromInt(width - 1);
const y_norm: f32 = @as(f32, @floatFromInt(y)) / h;
const x_norm: f32 = @as(f32, @floatFromInt(x)) / w;
const tl_weight = (1 - x_norm) * (1 - y_norm);
const bl_weight = (1 - x_norm) * y_norm;
const tr_weight = x_norm * (1 - y_norm);
const br_weight = x_norm * y_norm;
const r: f32 = tl_weight * tl.r + bl_weight * bl.r + tr_weight * tr.r + br_weight * br.r;
const g: f32 = tl_weight * tl.g + bl_weight * bl.g + tr_weight * tr.g + br_weight * br.g;
const b: f32 = tl_weight * tl.b + bl_weight * bl.b + tr_weight * tr.b + br_weight * br.b;
const color = oc.Color{ .r = r, .g = g, .b = b, .a = 1.0 };
pixels[y * width + x] = color.toRgba8();
}
}
gradient_image = oc.Image.create(surface, width, height);
gradient_image.uploadRegionRgba8(oc.Rect.xywh(0, 0, width, height), @ptrCast((&pixels).ptr));
}
}
export fn oc_on_resize(width: u32, height: u32) void {
@ -106,9 +144,9 @@ export fn oc_on_frame_refresh() void {
oc.Canvas.roundedRectangleFill(90, 0, 10, 10, 3);
oc.Canvas.roundedRectangleStroke(110, 0, 10, 10, 3);
const green = oc.Color{ .Flat = .{ .r = 0.05, .g = 1, .b = 0.05, .a = 1 } };
const green = oc.Color{ .r = 0.05, .g = 1, .b = 0.05, .a = 1 };
oc.Canvas.setColor(green);
oc.assert(std.meta.eql(oc.Canvas.getColor().Flat, green.Flat), "color should be green", .{}, @src());
oc.assert(std.meta.eql(oc.Canvas.getColor(), green), "color should be green", .{}, @src());
oc.Canvas.setTolerance(1);
oc.Canvas.setJoint(.Bevel);
@ -204,18 +242,32 @@ export fn oc_on_frame_refresh() void {
}
{
const trans = Mat2x3.translate(0, 200);
const scale = Mat2x3.scaleUniform(0.25);
Mat2x3.push(Mat2x3.mul_m(trans, scale));
defer Mat2x3.pop();
const orca_size = orca_image.size();
const size = orca_image.size();
{
const trans = Mat2x3.translate(0, 200);
const scale = Mat2x3.scaleUniform(0.25);
Mat2x3.push(Mat2x3.mul_m(trans, scale));
defer Mat2x3.pop();
orca_image.draw(oc.Rect.xywh(0, 0, size.x, size.y));
orca_image.draw(oc.Rect.xywh(0, 0, orca_size.x, orca_size.y));
var half_size = orca_image.size();
half_size.x /= 2;
orca_image.drawRegion(oc.Rect.xywh(0, 0, half_size.x, half_size.y), oc.Rect.xywh(size.x + 10, 0, half_size.x, half_size.y));
var half_size = orca_size;
half_size.x /= 2;
orca_image.drawRegion(oc.Rect.xywh(0, 0, half_size.x, half_size.y), oc.Rect.xywh(orca_size.x + 10, 0, half_size.x, half_size.y));
}
{
const x_offset = orca_size.x * 0.25 + orca_size.x * 0.25 * 0.5 + 5;
const gradient_size = gradient_image.size();
const trans = Mat2x3.translate(x_offset, 200);
const scale = Mat2x3.scaleUniform((orca_size.y * 0.25) / gradient_size.y);
Mat2x3.push(Mat2x3.mul_m(trans, scale));
defer Mat2x3.pop();
gradient_image.draw(oc.Rect.xywh(0, 0, gradient_size.x, gradient_size.y));
}
}
surface.select();
@ -231,3 +283,7 @@ fn fatal(err: anyerror, source: std.builtin.SourceLocation) noreturn {
oc.abort("Caught fatal {}", .{err}, source);
unreachable;
}
fn oneMinusLerp(a: anytype, b: anytype, t: anytype) @TypeOf(a, b, t) {
return 1.0 - lerp(a, b, t);
}

View File

@ -1596,12 +1596,12 @@ pub const Image = extern struct {
extern fn oc_image_nil() Image;
extern fn oc_image_is_nil(image: Image) bool;
extern fn oc_image_create(surface: Surface, width: u32, height: u32) Image;
extern fn oc_image_create_from_rgba8(surface: Surface, width: u32, height: u32, pixels: [*]u8) Image;
extern fn oc_image_create_from_rgba8(surface: Surface, width: u32, height: u32, pixels: [*]const u8) Image;
extern fn oc_image_create_from_memory(surface: Surface, mem: Str8, flip: bool) Image;
extern fn oc_image_create_from_file(surface: Surface, file: File, flip: bool) Image;
extern fn oc_image_create_from_path(surface: Surface, path: Str8, flip: bool) Image;
extern fn oc_image_destroy(image: Image) void;
extern fn oc_image_upload_region_rgba8(image: Image, region: Rect, pixels: [*]u8) void;
extern fn oc_image_upload_region_rgba8(image: Image, region: Rect, pixels: [*]const u8) void;
extern fn oc_image_size(image: Image) Vec2;
extern fn oc_image_draw(image: Image, rect: Rect) void;
extern fn oc_image_draw_region(image: Image, srcRegion: Rect, dstRegion: Rect) void;
@ -1638,14 +1638,24 @@ pub const Rect = extern union {
}
};
pub const Color = extern union {
Flat: extern struct {
r: f32,
g: f32,
b: f32,
a: f32,
},
Array: [4]f32,
pub const Color = extern struct {
r: f32 = 1.0,
g: f32 = 1.0,
b: f32 = 1.0,
a: f32 = 1.0,
pub fn toArray(color: *Color) *[4]f32 {
return @ptrCast(color);
}
pub fn toRgba8(color: *const Color) u32 {
var c: u32 = 0;
c |= @as(u32, @intFromFloat(color.r * 255.0));
c |= @as(u32, @intFromFloat(color.g * 255.0)) << 8;
c |= @as(u32, @intFromFloat(color.b * 255.0)) << 16;
c |= @as(u32, @intFromFloat(color.a * 255.0)) << 24;
return c;
}
};
//------------------------------------------------------------------------------------------