tangled
alpha
login
or
join now
altagos.dev
/
rayray
this repo has no description
0
fork
atom
overview
issues
pulls
pipelines
added threaded image renderer + output as png
altagos.dev
2 years ago
99db8021
d38a4f73
+125
-9
5 changed files
expand all
collapse all
unified
split
.gitignore
build.zig
build.zig.zon
src
main.zig
rayray.zig
+1
.gitignore
···
1
1
/zig-cache
2
2
/zig-out
3
3
+
/out
+8
-1
build.zig
···
4
4
const target = b.standardTargetOptions(.{});
5
5
const optimize = b.standardOptimizeOption(.{});
6
6
7
7
+
const enable_spall = b.option(bool, "enable_spall", "Enable spall profiling") orelse false;
8
8
+
const spall = b.dependency("spall", .{
9
9
+
.enable = enable_spall,
10
10
+
});
11
11
+
7
12
const rayray = b.addModule("rayray", .{
8
13
.root_source_file = .{ .path = "src/rayray.zig" },
9
14
.target = target,
10
15
.optimize = optimize,
11
16
});
17
17
+
rayray.addImport("spall", spall.module("spall"));
18
18
+
12
19
addDeps(b, rayray);
13
20
14
21
const exe = b.addExecutable(.{
···
17
24
.target = target,
18
25
.optimize = optimize,
19
26
});
20
20
-
27
27
+
exe.root_module.addImport("spall", spall.module("spall"));
21
28
exe.root_module.addImport("rayray", rayray);
22
29
23
30
b.installArtifact(exe);
+6
-3
build.zig.zon
···
5
5
.dependencies = .{
6
6
// See `zig fetch --save <url>` for a command-line interface for adding dependencies.
7
7
.zigimg = .{
8
8
-
.url = "https://github.com/zigimg/zigimg/archive/2224f91ea4cf70f2254848657e308761b8cc8c5d.tar.gz",
9
9
-
// dumy hash, because zigimg does not contain a build.zig. zon
10
10
-
.hash = "122029f65edf3965d86f7d0741fe141bcc1d68b1f013fa7280bbfda4e87c6affc15f",
8
8
+
.url = "https://github.com/rockorager/zigimg/archive/19a49a7e44fb4b1c22341dfbd6566019de742055.tar.gz",
9
9
+
.hash = "1220ebfa8587cfd644995fc08e218dbb3ebd7344fb8e129ff02bc5a6d52a2325370d",
10
10
+
},
11
11
+
.spall = .{
12
12
+
.url = "https://git.sr.ht/~altagos/zig-spall/archive/7cae52aa2d1a519006e0c90fbd179cf7fcac0c83.tar.gz",
13
13
+
.hash = "1220753b2f9e7c4f3fb6cdc8fc275cc9073904ea7032a1f5596aa776a857de69f72c",
11
14
},
12
15
13
16
// libs folder
+22
-1
src/main.zig
···
1
1
+
const std = @import("std");
2
2
+
3
3
+
const spall = @import("spall");
4
4
+
1
5
const Raytracer = @import("rayray").Raytracer;
2
6
3
7
pub fn main() !void {
4
4
-
const raytracer = Raytracer.init();
8
8
+
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
9
9
+
defer arena.deinit();
10
10
+
const allocator = arena.allocator();
11
11
+
12
12
+
try spall.init("./out/trace.spall");
13
13
+
defer spall.deinit();
14
14
+
15
15
+
spall.init_thread();
16
16
+
defer spall.deinit_thread();
17
17
+
18
18
+
const s = spall.trace(@src(), "Main", .{});
19
19
+
20
20
+
var raytracer = try Raytracer.init(allocator);
5
21
defer raytracer.deinit();
22
22
+
23
23
+
const img = try raytracer.render();
24
24
+
25
25
+
s.end();
26
26
+
try img.writeToFilePath("./out/out.png", .{ .png = .{} });
6
27
}
+88
-4
src/rayray.zig
···
1
1
const std = @import("std");
2
2
3
3
+
const spall = @import("spall");
4
4
+
const zigimg = @import("zigimg");
5
5
+
const color = zigimg.color;
6
6
+
3
7
pub const Raytracer = struct {
4
8
const Self = @This();
5
9
6
10
allocator: std.mem.Allocator,
7
11
8
8
-
pub fn init(allocator: std.mem.Allocator) Self {
12
12
+
camera: Camera,
13
13
+
14
14
+
pub fn init(allocator: std.mem.Allocator) !Self {
9
15
return .{
10
16
.allocator = allocator,
17
17
+
.camera = try Camera.init(allocator, 256 * 10, 256 * 10),
11
18
};
12
19
}
13
20
···
15
22
_ = self;
16
23
}
17
24
18
18
-
pub fn render(self: *Self) void {
19
19
-
_ = self;
25
25
+
pub fn render(self: *Self) !zigimg.Image {
26
26
+
const s = spall.trace(@src(), "render", .{});
27
27
+
defer s.end();
28
28
+
29
29
+
const rows: usize = try std.Thread.getCpuCount();
30
30
+
const row_height = @divTrunc(self.camera.height, rows);
31
31
+
const num_threads = blk: {
32
32
+
if (self.camera.height % rows == 0) {
33
33
+
break :blk rows;
34
34
+
}
35
35
+
break :blk rows + 1;
36
36
+
};
37
37
+
std.debug.print("rows: {}, row_height: {}, num_threads: {}", .{ rows, row_height, num_threads });
38
38
+
39
39
+
const threads = try self.allocator.alloc(std.Thread, num_threads);
40
40
+
defer self.allocator.free(threads);
41
41
+
42
42
+
for (0..num_threads) |row| {
43
43
+
const t = try std.Thread.spawn(.{}, r, .{ &self.camera, row, row_height });
44
44
+
threads[row] = t;
45
45
+
}
46
46
+
47
47
+
for (threads) |t| {
48
48
+
t.join();
49
49
+
}
50
50
+
51
51
+
return self.camera.image;
52
52
+
}
53
53
+
54
54
+
fn r(camera: *Camera, row: usize, height: usize) void {
55
55
+
spall.init_thread();
56
56
+
defer spall.deinit_thread();
57
57
+
58
58
+
const s = spall.trace(@src(), "thread {}", .{row});
59
59
+
defer s.end();
60
60
+
61
61
+
for (0..height) |iy| {
62
62
+
const y = iy + height * row;
63
63
+
if (y >= camera.height) break;
64
64
+
65
65
+
for (0..camera.width) |x| {
66
66
+
@setRuntimeSafety(false);
67
67
+
if (iy <= height - 5) {
68
68
+
camera.setPixel(x, y, color.Rgba32.initRgba(
69
69
+
@intCast(x),
70
70
+
@intCast(y),
71
71
+
0,
72
72
+
255,
73
73
+
)) catch break;
74
74
+
} else {
75
75
+
camera.setPixel(x, y, color.Rgba32.initRgba(
76
76
+
0,
77
77
+
0,
78
78
+
255,
79
79
+
255,
80
80
+
)) catch break;
81
81
+
}
82
82
+
}
83
83
+
}
20
84
}
21
85
};
22
86
23
23
-
pub const Camera = struct {};
87
87
+
pub const Camera = struct {
88
88
+
width: usize,
89
89
+
height: usize,
90
90
+
image: zigimg.Image,
91
91
+
92
92
+
pub fn init(allocator: std.mem.Allocator, width: usize, height: usize) !Camera {
93
93
+
const img = try zigimg.Image.create(allocator, width, height, zigimg.PixelFormat.rgba32);
94
94
+
95
95
+
return Camera{
96
96
+
.width = width,
97
97
+
.height = height,
98
98
+
.image = img,
99
99
+
};
100
100
+
}
101
101
+
102
102
+
pub fn setPixel(self: *Camera, x: usize, y: usize, c: color.Rgba32) !void {
103
103
+
if (x >= self.width or y >= self.height) return error.OutOfBounds;
104
104
+
const i = x + self.width * y;
105
105
+
self.image.pixels.rgba32[i] = c;
106
106
+
}
107
107
+
};