add texture sampling

This commit is contained in:
Rokas Puzonas 2026-07-06 22:15:34 +03:00
parent 1d9f1cfa6a
commit 40bbfff775
3 changed files with 111 additions and 44 deletions

View File

@ -26,20 +26,21 @@ pub fn init(self: *App, plt: Platform.Init) !?u8 {
pub fn frame(self: *App, plt: *Platform.Frame) !void { pub fn frame(self: *App, plt: *Platform.Frame) !void {
const gfx = plt.gfx; const gfx = plt.gfx;
const input = plt.input;
const dt = plt.deltaTime(); const dt = plt.deltaTime();
var dir: Vec2 = .init(0, 0); var dir: Vec2 = .init(0, 0);
if (plt.input.isKeyDown(.S)) { if (input.isKeyDown(.S)) {
dir.y += 1; dir.y += 1;
} }
if (plt.input.isKeyDown(.W)) { if (input.isKeyDown(.W)) {
dir.y -= 1; dir.y -= 1;
} }
if (plt.input.isKeyDown(.D)) { if (input.isKeyDown(.D)) {
dir.x += 1; dir.x += 1;
} }
if (plt.input.isKeyDown(.A)) { if (input.isKeyDown(.A)) {
dir.x -= 1; dir.x -= 1;
} }
dir = dir.normalized(); dir = dir.normalized();

View File

@ -18,46 +18,52 @@ const shd = @import("shader");
const max_quads = 2048; const max_quads = 2048;
pub const System = struct { pub const System = struct {
shader: sg.Shader,
pipeline: sg.Pipeline, pipeline: sg.Pipeline,
bindings: sg.Bindings, bindings: sg.Bindings,
pub fn init(self: *System, logger: sg.Logger) void { default_image: sg.Image,
self.* = @This(){ default_view: sg.View,
.pipeline = .{}, default_sampler: sg.Sampler,
.bindings = .{},
};
pub fn init(self: *System, logger: sg.Logger) void {
sg.setup(.{ sg.setup(.{
.environment = sglue.environment(), .environment = sglue.environment(),
.logger = logger .logger = logger
}); });
self.bindings.vertex_buffers[0] = sg.makeBuffer(.{
.size = @sizeOf(Quad) * max_quads,
.usage = .{ .vertex_buffer = true, .dynamic_update = true },
.label = "quad-vertices"
});
const index_count = max_quads * 6;
var indices: [index_count]u16 = undefined;
for (0..max_quads) |i| {
indices[6*i + 0] = @intCast(4*i + 0);
indices[6*i + 1] = @intCast(4*i + 1);
indices[6*i + 2] = @intCast(4*i + 2);
indices[6*i + 3] = @intCast(4*i + 1);
indices[6*i + 4] = @intCast(4*i + 3);
indices[6*i + 5] = @intCast(4*i + 2);
}
self.bindings.index_buffer = sg.makeBuffer(.{
.data = sg.asRange(&indices),
.usage = .{ .index_buffer = true, },
.label = "indices"
});
const shader = sg.makeShader(shd.mainShaderDesc(sg.queryBackend())); const shader = sg.makeShader(shd.mainShaderDesc(sg.queryBackend()));
self.pipeline = sg.makePipeline(.{ assert(shader.id != sg.invalid_id);
var pixels: [8 * 8 * 4]u8 = undefined;
@memset(&pixels, 0xFF);
var image_data: sg.ImageData = .{};
image_data.mip_levels[0] = sg.asRange(&pixels);
const default_image = sg.makeImage(.{
.type = ._2D,
.width = 8,
.height = 8,
.num_mipmaps = 1,
.pixel_format = .RGBA8,
.data = image_data,
.label = "default-texture"
});
assert(default_image.id != sg.invalid_id);
const default_view = sg.makeView(.{
.texture = .{ .image = default_image },
.label = "default-view"
});
assert(default_view.id != sg.invalid_id);
const default_sampler = sg.makeSampler(.{
.min_filter = .NEAREST,
.mag_filter = .NEAREST,
.label = "default-sampler"
});
assert(default_sampler.id != sg.invalid_id);
const pipeline = sg.makePipeline(.{
.primitive_type = .TRIANGLES, .primitive_type = .TRIANGLES,
.index_type = .UINT16, .index_type = .UINT16,
.colors = init: { .colors = init: {
@ -79,15 +85,60 @@ pub const System = struct {
.layout = init: { .layout = init: {
var l = sg.VertexLayoutState{}; var l = sg.VertexLayoutState{};
l.attrs[shd.ATTR_main_position].format = .FLOAT2; l.attrs[shd.ATTR_main_position].format = .FLOAT2;
l.attrs[shd.ATTR_main_texcoord0].format = .FLOAT2;
l.attrs[shd.ATTR_main_color0].format = .FLOAT4; l.attrs[shd.ATTR_main_color0].format = .FLOAT4;
break :init l; break :init l;
}, },
.label = "main-pipeline" .label = "main-pipeline"
}); });
assert(pipeline.id != sg.invalid_id);
var bindings: sg.Bindings = .{};
{
bindings.vertex_buffers[0] = sg.makeBuffer(.{
.size = @sizeOf(Quad) * max_quads,
.usage = .{ .vertex_buffer = true, .dynamic_update = true },
.label = "quad-vertices"
});
const index_count = max_quads * 6;
var indices: [index_count]u16 = undefined;
for (0..max_quads) |i| {
indices[6*i + 0] = @intCast(4*i + 0);
indices[6*i + 1] = @intCast(4*i + 1);
indices[6*i + 2] = @intCast(4*i + 2);
indices[6*i + 3] = @intCast(4*i + 1);
indices[6*i + 4] = @intCast(4*i + 3);
indices[6*i + 5] = @intCast(4*i + 2);
}
bindings.index_buffer = sg.makeBuffer(.{
.data = sg.asRange(&indices),
.usage = .{ .index_buffer = true, },
.label = "indices"
});
bindings.views[shd.VIEW_tex] = default_view;
bindings.samplers[shd.SMP_smp] = default_sampler;
}
self.* = @This(){
.shader = shader,
.pipeline = pipeline,
.bindings = bindings,
.default_image = default_image,
.default_view = default_view,
.default_sampler = default_sampler
};
} }
pub fn deinit(self: System) void { pub fn deinit(self: System) void {
_ = self; // autofix sg.destroyPipeline(self.pipeline);
sg.destroyShader(self.shader);
sg.destroyImage(self.default_image);
sg.destroyView(self.default_view);
sg.destroySampler(self.default_sampler);
sg.shutdown(); sg.shutdown();
} }
@ -168,19 +219,23 @@ pub const Interface = struct {
self.drawQuad(Quad{ self.drawQuad(Quad{
Vertex{ Vertex{
.position = pos, .position = pos,
.color = color_vec4 .color = color_vec4,
.texcoord = .init(0, 0)
}, },
Vertex{ Vertex{
.position = pos.add(.{ .x = size.x, .y = 0 }), .position = pos.add(.{ .x = size.x, .y = 0 }),
.color = color_vec4 .color = color_vec4,
.texcoord = .init(1, 0)
}, },
Vertex{ Vertex{
.position = pos.add(.{ .x = 0, .y = size.y }), .position = pos.add(.{ .x = 0, .y = size.y }),
.color = color_vec4 .color = color_vec4,
.texcoord = .init(0, 1)
}, },
Vertex{ Vertex{
.position = pos.add(size), .position = pos.add(size),
.color = color_vec4 .color = color_vec4,
.texcoord = .init(1, 1)
}, },
}); });
} }
@ -196,19 +251,23 @@ pub const Interface = struct {
drawQuad(Quad{ drawQuad(Quad{
Vertex{ Vertex{
.position = top_right, .position = top_right,
.color = color .color = color,
.texcoord = .init(0, 0)
}, },
Vertex{ Vertex{
.position = top_left, .position = top_left,
.color = color .color = color,
.texcoord = .init(1, 0)
}, },
Vertex{ Vertex{
.position = bottom_right, .position = bottom_right,
.color = color .color = color,
.texcoord = .init(0, 1)
}, },
Vertex{ Vertex{
.position = bottom_left, .position = bottom_left,
.color = color .color = color,
.texcoord = .init(1, 1)
}, },
}); });
} }
@ -216,6 +275,7 @@ pub const Interface = struct {
pub const Vertex = extern struct { pub const Vertex = extern struct {
position: Vec2, position: Vec2,
texcoord: Vec2,
color: Vec4, color: Vec4,
}; };

View File

@ -4,8 +4,10 @@
/* main vertex shader */ /* main vertex shader */
@vs vs @vs vs
in vec2 position; in vec2 position;
in vec2 texcoord0;
in vec4 color0; in vec4 color0;
out vec4 color; out vec4 color;
out vec4 uv;
layout(binding = 0) uniform vs_params { layout(binding = 0) uniform vs_params {
mat4 view; mat4 view;
@ -15,16 +17,20 @@ layout(binding = 0) uniform vs_params {
void main() { void main() {
gl_Position = projection * view * vec4(position, 0, 1); gl_Position = projection * view * vec4(position, 0, 1);
color = color0; color = color0;
uv = vec4(texcoord0, 0.0, 1.0);
} }
@end @end
/* main fragment shader */ /* main fragment shader */
@fs fs @fs fs
layout(binding=0) uniform texture2D tex;
layout(binding=0) uniform sampler smp;
in vec4 color; in vec4 color;
in vec4 uv;
out vec4 frag_color; out vec4 frag_color;
void main() { void main() {
frag_color = color; frag_color = texture(sampler2D(tex, smp), uv.xy) * color;
} }
@end @end