Zig bindings for orca (still WIP) #140
|
@ -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);
|
||||
}
|
||||
|
|
30
src/orca.zig
30
src/orca.zig
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue