Simplify build.zig, support installing multiple asset outputs
This commit is contained in:
parent
672bce7fe6
commit
756f4fa6f9
131
build.zig
131
build.zig
@ -146,12 +146,12 @@ pub fn build(b: *Build) void {
|
||||
}
|
||||
|
||||
const asset_extensions = [_][]const u8{
|
||||
".obj",
|
||||
".glsl",
|
||||
".prog",
|
||||
".png",
|
||||
".jpg",
|
||||
".exr",
|
||||
"obj",
|
||||
"glsl",
|
||||
"prog",
|
||||
"png",
|
||||
"jpg",
|
||||
"exr",
|
||||
};
|
||||
|
||||
// Find all assets and cook them using assetc
|
||||
@ -168,107 +168,40 @@ fn buildAssets(b: *std.Build, install_assetc_step: *Step, step: *Step, assetc: *
|
||||
defer walker.deinit();
|
||||
|
||||
while (try walker.next()) |entry| {
|
||||
if (std.mem.endsWith(u8, entry.basename, ".obj")) {
|
||||
const run_assetc = b.addRunArtifact(assetc);
|
||||
gen_asset_manifest.addAssetListFile(run_assetc.captureStdOut());
|
||||
run_assetc.step.dependOn(install_assetc_step);
|
||||
const ext_with_dot = std.fs.path.extension(entry.basename);
|
||||
if (ext_with_dot.len == 0) continue;
|
||||
|
||||
run_assetc.addPathDir(b.pathFromRoot("libs/ispc_texcomp/lib"));
|
||||
const ext = ext_with_dot[1..];
|
||||
|
||||
run_assetc.addFileArg(.{ .path = b.pathJoin(&.{ path, entry.path }) });
|
||||
const out_name = try std.mem.concat(
|
||||
b.allocator,
|
||||
u8,
|
||||
&.{ std.fs.path.stem(entry.basename), ".mesh" },
|
||||
);
|
||||
const compiled_file = run_assetc.addOutputFileArg(out_name);
|
||||
|
||||
const out_path = b.pathJoin(&.{
|
||||
path,
|
||||
std.fs.path.dirname(entry.path) orelse "",
|
||||
out_name,
|
||||
});
|
||||
const install_asset = b.addInstallFileWithDir(
|
||||
compiled_file,
|
||||
.prefix,
|
||||
out_path,
|
||||
);
|
||||
step.dependOn(&install_asset.step);
|
||||
var is_known_ext = false;
|
||||
for (asset_extensions) |known_ext| {
|
||||
if (std.mem.eql(u8, known_ext, ext)) {
|
||||
is_known_ext = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!is_known_ext) continue;
|
||||
|
||||
if (std.mem.endsWith(u8, entry.basename, ".glsl")) {
|
||||
const run_assetc = b.addRunArtifact(assetc);
|
||||
run_assetc.step.dependOn(install_assetc_step);
|
||||
const run_assetc = b.addRunArtifact(assetc);
|
||||
gen_asset_manifest.addAssetListFile(run_assetc.captureStdOut());
|
||||
run_assetc.step.dependOn(install_assetc_step);
|
||||
|
||||
gen_asset_manifest.addAssetListFile(run_assetc.captureStdOut());
|
||||
run_assetc.addPathDir(b.pathFromRoot("libs/ispc_texcomp/lib"));
|
||||
|
||||
run_assetc.addPathDir(b.pathFromRoot("libs/ispc_texcomp/lib"));
|
||||
// First argument, input path relative to base assets dir
|
||||
run_assetc.addArg(b.dupe(entry.path));
|
||||
// Absolute input file arg, this will add it to step deps, cache and all that good stuff
|
||||
run_assetc.addFileArg(.{ .path = b.pathJoin(&.{ path, entry.path }) });
|
||||
|
||||
run_assetc.addFileArg(.{ .path = b.pathJoin(&.{ path, entry.path }) });
|
||||
const compiled_file = run_assetc.addOutputFileArg(b.dupe(entry.basename));
|
||||
// Generated output dir. Output asset(s) will be placed there at the same relative path as input
|
||||
const result_dir = run_assetc.addOutputFileArg("assets");
|
||||
|
||||
const out_path = b.pathJoin(&.{
|
||||
path,
|
||||
entry.path,
|
||||
});
|
||||
const install_asset = b.addInstallFileWithDir(
|
||||
compiled_file,
|
||||
.prefix,
|
||||
out_path,
|
||||
);
|
||||
step.dependOn(&install_asset.step);
|
||||
}
|
||||
|
||||
// Shader program
|
||||
if (std.mem.endsWith(u8, entry.basename, ".prog")) {
|
||||
const run_assetc = b.addRunArtifact(assetc);
|
||||
run_assetc.step.dependOn(install_assetc_step);
|
||||
|
||||
gen_asset_manifest.addAssetListFile(run_assetc.captureStdOut());
|
||||
|
||||
run_assetc.addPathDir(b.pathFromRoot("libs/ispc_texcomp/lib"));
|
||||
|
||||
run_assetc.addFileArg(.{ .path = b.pathJoin(&.{ path, entry.path }) });
|
||||
const compiled_file = run_assetc.addOutputFileArg(b.dupe(entry.basename));
|
||||
|
||||
const out_path = b.pathJoin(&.{
|
||||
path,
|
||||
entry.path,
|
||||
});
|
||||
const install_asset = b.addInstallFileWithDir(
|
||||
compiled_file,
|
||||
.prefix,
|
||||
out_path,
|
||||
);
|
||||
step.dependOn(&install_asset.step);
|
||||
}
|
||||
|
||||
if (std.mem.endsWith(u8, entry.basename, ".png") or std.mem.endsWith(u8, entry.basename, ".jpg") or std.mem.endsWith(u8, entry.basename, ".exr")) {
|
||||
const run_assetc = b.addRunArtifact(assetc);
|
||||
run_assetc.step.dependOn(install_assetc_step);
|
||||
run_assetc.addPathDir(b.pathFromRoot("libs/ispc_texcomp/lib"));
|
||||
gen_asset_manifest.addAssetListFile(run_assetc.captureStdOut());
|
||||
|
||||
run_assetc.addFileArg(.{ .path = b.pathJoin(&.{ path, entry.path }) });
|
||||
const out_name = try std.mem.concat(
|
||||
b.allocator,
|
||||
u8,
|
||||
&.{ std.fs.path.stem(entry.basename), ".tex" },
|
||||
);
|
||||
const compiled_file = run_assetc.addOutputFileArg(out_name);
|
||||
|
||||
const out_path = b.pathJoin(&.{
|
||||
path,
|
||||
std.fs.path.dirname(entry.path) orelse "",
|
||||
out_name,
|
||||
});
|
||||
const install_asset = b.addInstallFileWithDir(
|
||||
compiled_file,
|
||||
.prefix,
|
||||
out_path,
|
||||
);
|
||||
step.dependOn(&install_asset.step);
|
||||
}
|
||||
const install_assets = b.addInstallDirectory(.{
|
||||
.source_dir = result_dir,
|
||||
.install_dir = .prefix,
|
||||
.install_subdir = path,
|
||||
});
|
||||
step.dependOn(&install_assets.step);
|
||||
}
|
||||
|
||||
return asset_manifest_file;
|
||||
|
@ -119,7 +119,7 @@ pub fn begin(self: *Render) void {
|
||||
gl.clearColor(0.0, 0.0, 0.0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
|
||||
gl.useProgram(self.assetman.resolveShaderProgram(a.ShaderPrograms.mesh).program);
|
||||
gl.useProgram(self.assetman.resolveShaderProgram(a.ShaderPrograms.shaders.mesh).program);
|
||||
gl.bindVertexArray(self.mesh_vao);
|
||||
|
||||
if (self.gl_fences[self.tripple_buffer_index]) |fence| {
|
||||
|
@ -55,7 +55,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
|
||||
// Random bytes to make WriteFile unique. Refresh this with
|
||||
// new random bytes when GenerateAssetManifest implementation is modified
|
||||
// in a non-backwards-compatible way.
|
||||
man.hash.add(@as(u32, 0xd767ee68));
|
||||
man.hash.add(@as(u32, 0xd767ee71));
|
||||
|
||||
// TODO: sort generated asset lists to make sure cache is predictable
|
||||
|
||||
@ -195,14 +195,14 @@ const NestedAssetDef = union(enum) {
|
||||
var iter = try std.fs.path.componentIterator(path.getPath());
|
||||
const filename = iter.last().?.name;
|
||||
_ = iter.first();
|
||||
// Skip first one because it's always "assets"
|
||||
_ = iter.next();
|
||||
|
||||
var current = &self.path;
|
||||
|
||||
while (iter.next()) |comp| {
|
||||
std.log.debug("NestedAssetDef comp next {s}\n", .{comp.name});
|
||||
if (comp.name.ptr == filename.ptr) break;
|
||||
const gop = try current.getOrPut(allocator, comp.name);
|
||||
std.log.debug("NestedAssetDef put path {s}\n", .{comp.name});
|
||||
if (!gop.found_existing) {
|
||||
gop.value_ptr.* = NestedAssetDef{ .path = .{} };
|
||||
}
|
||||
@ -216,6 +216,7 @@ const NestedAssetDef = union(enum) {
|
||||
}
|
||||
try gop.value_ptr.put(allocator, .{ .simple = sub_path }, asset_list_entry);
|
||||
} else {
|
||||
std.log.debug("NestedAssetDef put filename {s}\n", .{std.fs.path.stem(filename)});
|
||||
try current.put(allocator, std.fs.path.stem(filename), NestedAssetDef{
|
||||
.asset = asset_list_entry,
|
||||
});
|
||||
|
@ -38,40 +38,51 @@ pub fn resolveAssetTypeByExtension(path: []const u8) ?AssetType {
|
||||
pub fn main() !void {
|
||||
const allocator = std.heap.c_allocator;
|
||||
const argv = std.os.argv;
|
||||
if (argv.len < 3) {
|
||||
std.log.err("usage assetc <basedir> <input> <output>\n", .{});
|
||||
if (argv.len < 4) {
|
||||
std.log.err("usage assetc <rel_path> <input> <output>\n", .{});
|
||||
return error.MissingArgs;
|
||||
}
|
||||
|
||||
const input = argv[argv.len - 2];
|
||||
const output = std.mem.span(argv[argv.len - 1]);
|
||||
const rel_input = std.mem.span(argv[argv.len - 3]);
|
||||
const abs_input = std.mem.span(argv[argv.len - 2]);
|
||||
const output_dir_path = std.mem.span(argv[argv.len - 1]);
|
||||
|
||||
var cwd_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
|
||||
const cwd_path = try std.os.getcwd(&cwd_buf);
|
||||
|
||||
const build_root_rel_input = try std.fs.path.relative(allocator, cwd_path, std.mem.span(input));
|
||||
const cwd_rel_input = try std.fs.path.relative(allocator, cwd_path, abs_input);
|
||||
const cwd_rel_output_dir = try std.fs.path.relative(allocator, cwd_path, output_dir_path);
|
||||
|
||||
const asset_type = resolveAssetTypeByExtension(std.mem.span(input)) orelse return error.UnknownAssetType;
|
||||
// Generated output dir
|
||||
var output_dir = blk: {
|
||||
var base_output_dir = try std.fs.cwd().makeOpenPath(cwd_rel_output_dir, .{});
|
||||
defer base_output_dir.close();
|
||||
|
||||
break :blk try base_output_dir.makeOpenPath(std.fs.path.dirname(rel_input) orelse ".", .{});
|
||||
};
|
||||
defer output_dir.close();
|
||||
|
||||
const asset_type = resolveAssetTypeByExtension(abs_input) orelse return error.UnknownAssetType;
|
||||
|
||||
switch (asset_type) {
|
||||
.Mesh => try processMesh(allocator, input, output),
|
||||
.Shader => try std.fs.copyFileAbsolute(std.mem.span(input), output, .{}),
|
||||
.ShaderProgram => try processShaderProgram(allocator, std.mem.span(input), output),
|
||||
.Texture => try processTexture(allocator, input, output, false),
|
||||
.Mesh => try processMesh(allocator, abs_input, output_dir),
|
||||
.Shader => try std.fs.Dir.copyFile(std.fs.cwd(), abs_input, output_dir, std.fs.path.basename(rel_input), .{}),
|
||||
.ShaderProgram => try processShaderProgram(allocator, abs_input, output_dir),
|
||||
.Texture => try processTexture(allocator, abs_input, output_dir, false),
|
||||
}
|
||||
|
||||
const out_writer = std.io.getStdOut().writer();
|
||||
|
||||
try asset_list.writeAssetListEntryText(out_writer, .{
|
||||
.type = asset_type,
|
||||
.src_path = .{ .simple = build_root_rel_input },
|
||||
.dst_path = output,
|
||||
.src_path = .{ .simple = cwd_rel_input }, // TODO: remove assets prefix
|
||||
.dst_path = cwd_rel_output_dir,
|
||||
});
|
||||
}
|
||||
|
||||
fn processMesh(allocator: std.mem.Allocator, input: [*:0]const u8, output: []const u8) !void {
|
||||
fn processMesh(allocator: std.mem.Allocator, input: []const u8, output_dir: std.fs.Dir) !void {
|
||||
const maybe_scene: ?*const c.aiScene = @ptrCast(c.aiImportFile(
|
||||
input,
|
||||
input.ptr,
|
||||
c.aiProcess_CalcTangentSpace | c.aiProcess_Triangulate | c.aiProcess_JoinIdenticalVertices | c.aiProcess_SortByPType | c.aiProcess_GenNormals,
|
||||
));
|
||||
if (maybe_scene == null) {
|
||||
@ -152,7 +163,9 @@ fn processMesh(allocator: std.mem.Allocator, input: [*:0]const u8, output: []con
|
||||
.indices = indices,
|
||||
};
|
||||
|
||||
const out_file = try std.fs.createFileAbsolute(output, .{});
|
||||
const out_name = try changeExtensionAlloc(allocator, input, AssetType.Mesh.ext());
|
||||
|
||||
const out_file = try output_dir.createFile(out_name, .{});
|
||||
defer out_file.close();
|
||||
var buf_writer = std.io.bufferedWriter(out_file.writer());
|
||||
|
||||
@ -164,7 +177,7 @@ fn processMesh(allocator: std.mem.Allocator, input: [*:0]const u8, output: []con
|
||||
try buf_writer.flush();
|
||||
}
|
||||
|
||||
fn processShaderProgram(allocator: std.mem.Allocator, absolute_input: []const u8, output: []const u8) !void {
|
||||
fn processShaderProgram(allocator: std.mem.Allocator, absolute_input: []const u8, output_dir: std.fs.Dir) !void {
|
||||
var cwd_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
|
||||
const cwd_path = try std.os.getcwd(&cwd_buf);
|
||||
|
||||
@ -198,7 +211,7 @@ fn processShaderProgram(allocator: std.mem.Allocator, absolute_input: []const u8
|
||||
return error.InvalidShaderPath;
|
||||
}
|
||||
|
||||
const out_file = try std.fs.createFileAbsolute(output, .{});
|
||||
const out_file = try output_dir.createFile(std.fs.path.basename(absolute_input), .{});
|
||||
defer out_file.close();
|
||||
var buf_writer = std.io.bufferedWriter(out_file.writer());
|
||||
|
||||
@ -212,11 +225,11 @@ const MipLevel = struct {
|
||||
out_data: []const u8 = &.{},
|
||||
};
|
||||
|
||||
fn processTexture(allocator: std.mem.Allocator, input: [*:0]const u8, output: []const u8, hdr: bool) !void {
|
||||
fn processTexture(allocator: std.mem.Allocator, input: []const u8, output_dir: std.fs.Dir, hdr: bool) !void {
|
||||
_ = hdr; // autofix
|
||||
|
||||
// For tex.norm.png - this will be ".norm"
|
||||
const sub_ext = std.fs.path.extension(std.fs.path.stem(std.mem.span(input)));
|
||||
const sub_ext = std.fs.path.extension(std.fs.path.stem(input));
|
||||
const format = if (std.mem.eql(u8, sub_ext, ".norm")) formats.Texture.Format.bc5 else formats.Texture.Format.bc7;
|
||||
|
||||
var width_int: c_int = undefined;
|
||||
@ -224,7 +237,7 @@ fn processTexture(allocator: std.mem.Allocator, input: [*:0]const u8, output: []
|
||||
var comps: c_int = undefined;
|
||||
|
||||
c.stbi_set_flip_vertically_on_load(1);
|
||||
const rgba_data_c = c.stbi_load(input, &width_int, &height_int, &comps, 4);
|
||||
const rgba_data_c = c.stbi_load(input.ptr, &width_int, &height_int, &comps, 4);
|
||||
if (rgba_data_c == null) {
|
||||
return error.ImageLoadError;
|
||||
}
|
||||
@ -308,7 +321,8 @@ fn processTexture(allocator: std.mem.Allocator, input: [*:0]const u8, output: []
|
||||
},
|
||||
.data = out_data,
|
||||
};
|
||||
const out_file = try std.fs.createFileAbsolute(output, .{});
|
||||
const out_name = try changeExtensionAlloc(allocator, input, AssetType.Texture.ext());
|
||||
const out_file = try output_dir.createFile(out_name, .{});
|
||||
defer out_file.close();
|
||||
var buf_writer = std.io.bufferedWriter(out_file.writer());
|
||||
|
||||
@ -508,3 +522,10 @@ inline fn storeColorVec4(pixel: []u8, vec: @Vector(4, f32)) void {
|
||||
pixel[2] = @intFromFloat(out[2]);
|
||||
pixel[3] = @intFromFloat(out[3]);
|
||||
}
|
||||
|
||||
fn changeExtensionAlloc(allocator: std.mem.Allocator, input: []const u8, new_ext: []const u8) ![]u8 {
|
||||
const input_basename = std.fs.path.basename(input);
|
||||
const ext = std.fs.path.extension(input_basename);
|
||||
const name_without_ext = input_basename[0 .. input_basename.len - ext.len];
|
||||
return try std.mem.concat(allocator, u8, &.{ name_without_ext, ".", new_ext });
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user