Automatically calculate draw_texture scale from image resolution by default (closes #65)
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is passing
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			This commit is contained in:
		
							parent
							
								
									a63eefd7d4
								
							
						
					
					
						commit
						13c58bf106
					
				
							
								
								
									
										81
									
								
								build.zig
									
									
									
									
									
								
							
							
						
						
									
										81
									
								
								build.zig
									
									
									
									
									
								
							@ -12,29 +12,29 @@ const Project = struct {
 | 
			
		||||
	optimize: std.builtin.OptimizeMode,
 | 
			
		||||
	imports: ImportList,
 | 
			
		||||
 | 
			
		||||
	pub fn demos_step(self: *const Project, b: *std.Build) *std.Build.Step {
 | 
			
		||||
		const Demos = struct {
 | 
			
		||||
			step: std.Build.Step,
 | 
			
		||||
			project: *const Project,
 | 
			
		||||
 | 
			
		||||
			const Self = @This();
 | 
			
		||||
 | 
			
		||||
			fn make(step: *std.Build.Step, _: std.Progress.Node) anyerror!void {
 | 
			
		||||
				const demos: *const Self = @fieldParentPtr("step", step);
 | 
			
		||||
	pub fn find_demos(self: Project, step: *std.Build.Step) void {
 | 
			
		||||
		const absolute_path = step.owner.path("demos/").getPath(step.owner);
 | 
			
		||||
				var dir = try std.fs.openDirAbsolute(absolute_path, .{.iterate = true});
 | 
			
		||||
 | 
			
		||||
		var dir = std.fs.openDirAbsolute(absolute_path, .{.iterate = true}) catch |open_error| {
 | 
			
		||||
			std.log.warn("failed to open demos directory at {s} with error {s}, skipping...", .{
 | 
			
		||||
				absolute_path,
 | 
			
		||||
				@errorName(open_error),
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			return;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		defer {
 | 
			
		||||
			dir.close();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
				var entries = try dir.walk(step.owner.allocator);
 | 
			
		||||
		var entries = dir.walk(step.owner.allocator) catch @panic("OOM");
 | 
			
		||||
 | 
			
		||||
		defer {
 | 
			
		||||
			entries.deinit();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
				while (try entries.next()) |entry| {
 | 
			
		||||
		while (entries.next() catch @panic("I/O failure")) |entry| {
 | 
			
		||||
			if (entry.kind != .file or !std.mem.endsWith(u8, entry.path, ".zig")) {
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
@ -43,46 +43,30 @@ const Project = struct {
 | 
			
		||||
			var path_buffer = [_:0]u8{0} ** 255;
 | 
			
		||||
 | 
			
		||||
			const demo = step.owner.addExecutable(.{
 | 
			
		||||
						.name = try std.fmt.bufPrint(&path_buffer, "{s}.out", .{std.fs.path.stem(entry.basename)}),
 | 
			
		||||
				.name = std.fmt.bufPrint(&path_buffer, "{s}.out", .{std.fs.path.stem(entry.basename)}) catch {
 | 
			
		||||
					@panic("a demo file name is too long");
 | 
			
		||||
				},
 | 
			
		||||
 | 
			
		||||
				.root_source_file = step.owner.path(source_path),
 | 
			
		||||
						.target = demos.project.target,
 | 
			
		||||
						.optimize = demos.project.optimize,
 | 
			
		||||
				.target = self.target,
 | 
			
		||||
				.optimize = self.optimize,
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
					for (demos.project.imports.items) |import| {
 | 
			
		||||
			for (self.imports.items) |import| {
 | 
			
		||||
				demo.root_module.addImport(import.name, import.module);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
					step.owner.installArtifact(demo);
 | 
			
		||||
			step.dependOn(&step.owner.addInstallArtifact(demo, .{
 | 
			
		||||
				.dest_dir = .{
 | 
			
		||||
					.override = .{.custom = "../demos"},
 | 
			
		||||
				},
 | 
			
		||||
			}).step);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
				step.state = .success;
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		const demos = b.allocator.create(Demos) catch {
 | 
			
		||||
			@panic("OOM");
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		demos.* = .{
 | 
			
		||||
			.step = std.Build.Step.init(.{
 | 
			
		||||
				.id = .custom,
 | 
			
		||||
				.name = "demos",
 | 
			
		||||
				.makeFn = Demos.make,
 | 
			
		||||
				.owner = b,
 | 
			
		||||
			}),
 | 
			
		||||
 | 
			
		||||
			.project = self,
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		return &demos.step;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pub fn find_tests(self: Project, b: *std.Build) !void {
 | 
			
		||||
		const tests = b.step("tests", "Build and run tests");
 | 
			
		||||
 | 
			
		||||
	pub fn find_tests(self: Project, step: *std.Build.Step) void {
 | 
			
		||||
		for (self.imports.items) |import| {
 | 
			
		||||
			tests.dependOn(&b.addRunArtifact(b.addTest(.{
 | 
			
		||||
			step.dependOn(&step.owner.addRunArtifact(step.owner.addTest(.{
 | 
			
		||||
				.root_source_file = import.module.root_source_file.?,
 | 
			
		||||
				.target = self.target,
 | 
			
		||||
				.optimize = self.optimize,
 | 
			
		||||
@ -177,11 +161,7 @@ const Project = struct {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub fn build(b: *std.Build) !void {
 | 
			
		||||
	const project = b.allocator.create(Project) catch {
 | 
			
		||||
		@panic("OOM");
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	project.* = .{
 | 
			
		||||
	var project = Project{
 | 
			
		||||
		.imports = ImportList.init(b.allocator),
 | 
			
		||||
		.target = b.standardTargetOptions(.{}),
 | 
			
		||||
		.optimize = b.standardOptimizeOption(.{}),
 | 
			
		||||
@ -274,7 +254,6 @@ pub fn build(b: *std.Build) !void {
 | 
			
		||||
 | 
			
		||||
	gfx_module.link_libc = true;
 | 
			
		||||
 | 
			
		||||
	b.step("demos", "Build demos").dependOn(project.demos_step(b));
 | 
			
		||||
 | 
			
		||||
	try project.find_tests(b);
 | 
			
		||||
	project.find_demos(b.step("demos", "Build demos"));
 | 
			
		||||
	project.find_tests(b.step("tests", "Build and run tests"));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -50,15 +50,14 @@ fn render(commands: gfx.Commands, effects: ona.Write(Effects), app: ona.Read(ona
 | 
			
		||||
	const display_width: f32 = @floatFromInt(display.state.width);
 | 
			
		||||
	const display_height: f32 = @floatFromInt(display.state.height);
 | 
			
		||||
 | 
			
		||||
	const display_transform = gfx.Transform2D{
 | 
			
		||||
		.origin = .{display_width / 2, display_height / 2},
 | 
			
		||||
		.xbasis = .{display_width, 0},
 | 
			
		||||
		.ybasis = .{0, display_height},
 | 
			
		||||
	};
 | 
			
		||||
	const display_transform = gfx.transform_2d(.{
 | 
			
		||||
		.translation = .{display_width / 2, display_height / 2},
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	try commands.draw_texture(.{
 | 
			
		||||
		.texture = .default,
 | 
			
		||||
		.transform = display_transform,
 | 
			
		||||
		.resolution = .{display.state.width, display.state.height},
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	try commands.set_effect(.{
 | 
			
		||||
@ -72,7 +71,6 @@ fn render(commands: gfx.Commands, effects: ona.Write(Effects), app: ona.Read(ona
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	try commands.set_target(.{
 | 
			
		||||
		.texture = null,
 | 
			
		||||
		.clear_color = null,
 | 
			
		||||
		.clear_depth = null,
 | 
			
		||||
		.clear_stencil = null,
 | 
			
		||||
 | 
			
		||||
@ -48,7 +48,7 @@ fn update(visuals: ona.Write(Visuals), events: ona.Receive(hid.Event), display:
 | 
			
		||||
	const random = visuals.state.random.random();
 | 
			
		||||
	const width: f32 = @floatFromInt(display.state.width);
 | 
			
		||||
	const height: f32 = @floatFromInt(display.state.height);
 | 
			
		||||
	const icon_scale = .{64, 64};
 | 
			
		||||
	const icon_scale = .{8, 8};
 | 
			
		||||
 | 
			
		||||
	for (events.messages()) |event| {
 | 
			
		||||
		switch (event) {
 | 
			
		||||
@ -56,7 +56,7 @@ fn update(visuals: ona.Write(Visuals), events: ona.Receive(hid.Event), display:
 | 
			
		||||
				try visuals.state.spawned_keyboards.push_grow(.{
 | 
			
		||||
					.lifetime_seconds = 2.5 + (5 * random.float(f32)),
 | 
			
		||||
 | 
			
		||||
					.transform = gfx.Transform2D.from_simplified(.{
 | 
			
		||||
					.transform = gfx.transform_2d(.{
 | 
			
		||||
						.translation = .{width * random.float(f32), height},
 | 
			
		||||
						.rotation = std.math.pi * random.float(f32),
 | 
			
		||||
						.scale = icon_scale,
 | 
			
		||||
@ -68,7 +68,7 @@ fn update(visuals: ona.Write(Visuals), events: ona.Receive(hid.Event), display:
 | 
			
		||||
				try visuals.state.spawned_mouses.push_grow(.{
 | 
			
		||||
					.lifetime_seconds = 2.5 + (5 * random.float(f32)),
 | 
			
		||||
 | 
			
		||||
					.transform = gfx.Transform2D.from_simplified(.{
 | 
			
		||||
					.transform = gfx.transform_2d(.{
 | 
			
		||||
						.translation = visuals.state.mouse_position,
 | 
			
		||||
						.rotation = std.math.pi * random.float(f32),
 | 
			
		||||
						.scale = icon_scale,
 | 
			
		||||
 | 
			
		||||
@ -178,6 +178,7 @@ pub const Commands = struct {
 | 
			
		||||
	pub const DrawTextureCommand = struct {
 | 
			
		||||
		texture: Texture,
 | 
			
		||||
		transform: Transform2D,
 | 
			
		||||
		resolution: ?@Vector(2, u16) = null,
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	pub const SetEffectCommand = struct {
 | 
			
		||||
@ -357,13 +358,34 @@ pub const Transform2D = extern struct {
 | 
			
		||||
 | 
			
		||||
	pub const Vector = @Vector(2, f32);
 | 
			
		||||
 | 
			
		||||
	pub fn from_simplified(simplified: Simplified) Transform2D {
 | 
			
		||||
		const rotation_skew = simplified.rotation + simplified.skew;
 | 
			
		||||
	pub fn scaled(self: Transform2D, scale: Vector) Transform2D {
 | 
			
		||||
		var transform = self;
 | 
			
		||||
		const scale_x, const scale_y = scale;
 | 
			
		||||
 | 
			
		||||
		transform.xbasis *= @splat(scale_x);
 | 
			
		||||
        transform.ybasis *= @splat(scale_y);
 | 
			
		||||
 | 
			
		||||
		return transform;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pub fn transformed(self: Transform2D, other: Transform2D) Transform2D {
 | 
			
		||||
		const xbasis_x, const xbasis_y = other.xbasis;
 | 
			
		||||
		const ybasis_x, const ybasis_y = other.ybasis;
 | 
			
		||||
		const origin_x, const origin_y = other.origin;
 | 
			
		||||
 | 
			
		||||
		return .{
 | 
			
		||||
			.xbasis = simplified.scale * Vector{std.math.cos(simplified.rotation), std.math.sin(simplified.rotation)},
 | 
			
		||||
			.ybasis = simplified.scale * Vector{-std.math.sin(rotation_skew), std.math.cos(rotation_skew)},
 | 
			
		||||
			.origin = simplified.translation,
 | 
			
		||||
			.xbasis =
 | 
			
		||||
				(self.xbasis * @as(Vector, @splat(xbasis_x))) +
 | 
			
		||||
				(self.ybasis * @as(Vector, @splat(xbasis_y))),
 | 
			
		||||
 | 
			
		||||
			.ybasis =
 | 
			
		||||
				(self.xbasis * @as(Vector, @splat(ybasis_x))) +
 | 
			
		||||
				(self.ybasis * @as(Vector, @splat(ybasis_y))),
 | 
			
		||||
 | 
			
		||||
			.origin =
 | 
			
		||||
				(self.xbasis * @as(Vector, @splat(origin_x))) +
 | 
			
		||||
				(self.ybasis * @as(Vector, @splat(origin_y))) +
 | 
			
		||||
				self.origin,
 | 
			
		||||
		};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -586,3 +608,21 @@ pub fn synchronize(exclusive: ona.Exclusive(&.{Assets, Display})) !void {
 | 
			
		||||
		assets.frame_rendered.set();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn transform_2d(simplified: Transform2D.Simplified) Transform2D {
 | 
			
		||||
	const rotation_skew = simplified.rotation + simplified.skew;
 | 
			
		||||
 | 
			
		||||
	return .{
 | 
			
		||||
		.xbasis = simplified.scale * Transform2D.Vector{
 | 
			
		||||
			std.math.cos(simplified.rotation),
 | 
			
		||||
			std.math.sin(simplified.rotation),
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		.ybasis = simplified.scale * Transform2D.Vector{
 | 
			
		||||
			-std.math.sin(rotation_skew),
 | 
			
		||||
			std.math.cos(rotation_skew),
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		.origin = simplified.translation,
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -96,8 +96,13 @@ const Frame = struct {
 | 
			
		||||
			try self.texture_batch_buffers.push_grow(instance_buffer);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const texture = resources.get_texture(command.texture).?;
 | 
			
		||||
 | 
			
		||||
		_ = sokol.gfx.appendBuffer(self.texture_batch_buffers.get().?.*, sokol.gfx.asRange(&DrawTexture{
 | 
			
		||||
			.transform = command.transform,
 | 
			
		||||
			.transform = command.transform.scaled(@floatFromInt(command.resolution orelse .{
 | 
			
		||||
				texture.width,
 | 
			
		||||
				texture.height,
 | 
			
		||||
			})),
 | 
			
		||||
		}));
 | 
			
		||||
 | 
			
		||||
		self.drawn_count += 1;
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@ layout (location = 3) in vec2 instance_ybasis;
 | 
			
		||||
layout (location = 4) in vec2 instance_origin;
 | 
			
		||||
layout (location = 5) in vec4 instance_tint;
 | 
			
		||||
layout (location = 6) in float instance_depth;
 | 
			
		||||
layout (location = 7) in vec4 instance_rect;
 | 
			
		||||
layout (location = 7) in vec4 instance_clip;
 | 
			
		||||
 | 
			
		||||
layout (location = 0) out vec4 color;
 | 
			
		||||
layout (location = 1) out vec2 uv;
 | 
			
		||||
@ -20,10 +20,10 @@ layout (binding = 0) uniform View {
 | 
			
		||||
void main() {
 | 
			
		||||
	const vec2 world_position = instance_origin + mesh_xy.x * instance_xbasis + mesh_xy.y * instance_ybasis;
 | 
			
		||||
	const vec2 projected_position = (projection_matrix * vec4(world_position, 0, 1)).xy;
 | 
			
		||||
	const vec2 rect_size = instance_rect.zw - instance_rect.xy;
 | 
			
		||||
	const vec2 rect_size = instance_clip.zw - instance_clip.xy;
 | 
			
		||||
	const vec4 screen_position = vec4(projected_position, instance_depth, 1.0);
 | 
			
		||||
 | 
			
		||||
	gl_Position = screen_position;
 | 
			
		||||
	color = instance_tint;
 | 
			
		||||
	uv = instance_rect.xy + (mesh_uv * rect_size);
 | 
			
		||||
	uv = instance_clip.xy + (mesh_uv * rect_size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user