Textures
This commit is contained in:
@@ -1,14 +1,10 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
layout(location = 0) in float vertexIndex;
|
layout(location = 0) in vec2 inUV;
|
||||||
layout(location = 1) in float depth;
|
|
||||||
layout(location = 0) out vec4 fragColor;
|
layout(location = 0) out vec4 fragColor;
|
||||||
|
|
||||||
|
layout(set = 2, binding = 0) uniform sampler2D texture_sampler;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
fragColor = vec4(
|
fragColor = texture(texture_sampler, inUV);
|
||||||
depth,
|
|
||||||
cos(vertexIndex * 0.5) * 0.25 + 0.75,
|
|
||||||
sin(vertexIndex * 0.5) * 0.25 + 0.75,
|
|
||||||
1.0
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
layout(location = 0) in vec3 inCoord;
|
layout(location = 0) in vec3 inCoord;
|
||||||
layout(location = 0) out float vertexIndex;
|
layout(location = 1) in vec2 inUV;
|
||||||
layout(location = 1) out float depth;
|
layout(location = 0) out vec2 outUV;
|
||||||
|
|
||||||
layout(set = 1, binding = 0) uniform Camera{
|
layout(set = 1, binding = 0) uniform Camera{
|
||||||
mat4 transform;
|
mat4 transform;
|
||||||
@@ -11,10 +11,7 @@ layout(set = 1, binding = 1) uniform Object{
|
|||||||
mat4 transform;
|
mat4 transform;
|
||||||
} object;
|
} object;
|
||||||
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vertexIndex = gl_VertexIndex;
|
gl_Position = vec4(inCoord, 1.0) * object.transform * camera.transform;
|
||||||
vec4 outPos = vec4(inCoord, 1.0) * object.transform * camera.transform;
|
outUV = inUV;
|
||||||
depth = outPos.z / outPos.w;
|
|
||||||
gl_Position = outPos;
|
|
||||||
}
|
}
|
||||||
|
@@ -8,50 +8,62 @@ const Graphics = @import("graphics.zig");
|
|||||||
const Game = @import("game.zig");
|
const Game = @import("game.zig");
|
||||||
|
|
||||||
const CUBE_MESH_DATA = [_]f32{
|
const CUBE_MESH_DATA = [_]f32{
|
||||||
-0.5, 0.5, -0.5,
|
-0.5, 0.5, -0.5, 0.0, 0.0,
|
||||||
0.5, 0.5, -0.5,
|
0.5, 0.5, -0.5, 0.0, 0.0,
|
||||||
-0.5, -0.5, -0.5,
|
-0.5, -0.5, -0.5, 0.0, 0.0,
|
||||||
0.5, -0.5, -0.5,
|
0.5, -0.5, -0.5, 0.0, 0.0,
|
||||||
-0.5, -0.5, -0.5,
|
-0.5, -0.5, -0.5, 0.0, 0.0,
|
||||||
0.5, 0.5, -0.5,
|
0.5, 0.5, -0.5, 0.0, 0.0,
|
||||||
0.5, 0.5, -0.5,
|
0.5, 0.5, -0.5, 0.0, 0.0,
|
||||||
0.5, 0.5, 0.5,
|
0.5, 0.5, 0.5, 0.0, 0.0,
|
||||||
0.5, -0.5, -0.5,
|
0.5, -0.5, -0.5, 0.0, 0.0,
|
||||||
0.5, -0.5, 0.5,
|
0.5, -0.5, 0.5, 0.0, 0.0,
|
||||||
0.5, -0.5, -0.5,
|
0.5, -0.5, -0.5, 0.0, 0.0,
|
||||||
0.5, 0.5, 0.5,
|
0.5, 0.5, 0.5, 0.0, 0.0,
|
||||||
0.5, 0.5, 0.5,
|
0.5, 0.5, 0.5, 0.0, 0.0,
|
||||||
-0.5, 0.5, 0.5,
|
-0.5, 0.5, 0.5, 0.0, 0.0,
|
||||||
0.5, -0.5, 0.5,
|
0.5, -0.5, 0.5, 0.0, 0.0,
|
||||||
-0.5, -0.5, 0.5,
|
-0.5, -0.5, 0.5, 0.0, 0.0,
|
||||||
0.5, -0.5, 0.5,
|
0.5, -0.5, 0.5, 0.0, 0.0,
|
||||||
-0.5, 0.5, 0.5,
|
-0.5, 0.5, 0.5, 0.0, 0.0,
|
||||||
-0.5, 0.5, 0.5,
|
-0.5, 0.5, 0.5, 0.0, 0.0,
|
||||||
-0.5, 0.5, -0.5,
|
-0.5, 0.5, -0.5, 0.0, 0.0,
|
||||||
-0.5, -0.5, 0.5,
|
-0.5, -0.5, 0.5, 0.0, 0.0,
|
||||||
-0.5, -0.5, -0.5,
|
-0.5, -0.5, -0.5, 0.0, 0.0,
|
||||||
-0.5, -0.5, 0.5,
|
-0.5, -0.5, 0.5, 0.0, 0.0,
|
||||||
-0.5, 0.5, -0.5,
|
-0.5, 0.5, -0.5, 0.0, 0.0,
|
||||||
-0.5, 0.5, 0.5,
|
-0.5, 0.5, 0.5, 0.0, 0.0,
|
||||||
0.5, 0.5, 0.5,
|
0.5, 0.5, 0.5, 0.0, 0.0,
|
||||||
-0.5, 0.5, -0.5,
|
-0.5, 0.5, -0.5, 0.0, 0.0,
|
||||||
0.5, 0.5, -0.5,
|
0.5, 0.5, -0.5, 0.0, 0.0,
|
||||||
-0.5, 0.5, -0.5,
|
-0.5, 0.5, -0.5, 0.0, 0.0,
|
||||||
0.5, 0.5, 0.5,
|
0.5, 0.5, 0.5, 0.0, 0.0,
|
||||||
-0.5, -0.5, -0.5,
|
-0.5, -0.5, -0.5, 0.0, 0.0,
|
||||||
0.5, -0.5, -0.5,
|
0.5, -0.5, -0.5, 0.0, 0.0,
|
||||||
-0.5, -0.5, 0.5,
|
-0.5, -0.5, 0.5, 0.0, 0.0,
|
||||||
0.5, -0.5, 0.5,
|
0.5, -0.5, 0.5, 0.0, 0.0,
|
||||||
-0.5, -0.5, 0.5,
|
-0.5, -0.5, 0.5, 0.0, 0.0,
|
||||||
0.5, -0.5, -0.5,
|
0.5, -0.5, -0.5, 0.0, 0.0,
|
||||||
};
|
};
|
||||||
const PLANE_MESH_DATA = [_]f32{
|
const PLANE_MESH_DATA = [_]f32{
|
||||||
-0.5, -0.5, 0,
|
-0.5, -0.5, 0, 0.0, 1.0,
|
||||||
0.5, 0.5, 0,
|
0.5, 0.5, 0, 1.0, 0.0,
|
||||||
-0.5, 0.5, 0,
|
-0.5, 0.5, 0, 0.0, 0.0,
|
||||||
0.5, 0.5, 0,
|
0.5, 0.5, 0, 1.0, 0.0,
|
||||||
-0.5, -0.5, 0,
|
-0.5, -0.5, 0, 0.0, 1.0,
|
||||||
0.5, -0.5, 0,
|
0.5, -0.5, 0, 1.0, 1.0,
|
||||||
|
};
|
||||||
|
// const TEXTURE_DATA = [_]u8{
|
||||||
|
// 255, 0, 0, 255,
|
||||||
|
// 0, 255, 0, 255,
|
||||||
|
// 0, 0, 255, 255,
|
||||||
|
// 0, 0, 0, 255,
|
||||||
|
// };
|
||||||
|
const TEXTURE_DATA = [_]u8{
|
||||||
|
255, 0, 0, 255,
|
||||||
|
0, 255, 0, 255,
|
||||||
|
0, 0, 255, 255,
|
||||||
|
0, 0, 0, 255,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const WorldTime = struct {
|
pub const WorldTime = struct {
|
||||||
@@ -72,6 +84,7 @@ pub const PlayerState = union(enum) {
|
|||||||
|
|
||||||
pub const Player = struct {
|
pub const Player = struct {
|
||||||
mesh: Graphics.Mesh,
|
mesh: Graphics.Mesh,
|
||||||
|
texture: Graphics.Texture,
|
||||||
transform: Transform,
|
transform: Transform,
|
||||||
position: @Vector(2, i32),
|
position: @Vector(2, i32),
|
||||||
state: PlayerState,
|
state: PlayerState,
|
||||||
@@ -83,12 +96,14 @@ pub const Player = struct {
|
|||||||
|
|
||||||
pub const Environment = struct {
|
pub const Environment = struct {
|
||||||
mesh: Graphics.Mesh,
|
mesh: Graphics.Mesh,
|
||||||
|
texture: Graphics.Texture,
|
||||||
transform: Transform,
|
transform: Transform,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn init(controller: *Controller, graphics: *Graphics) !void {
|
pub fn init(controller: *Controller, graphics: *Graphics) !void {
|
||||||
controller.addResource(Player{
|
controller.addResource(Player{
|
||||||
.mesh = try graphics.loadMesh(@ptrCast(&CUBE_MESH_DATA)),
|
.mesh = try graphics.loadMesh(@ptrCast(&CUBE_MESH_DATA)),
|
||||||
|
.texture = try graphics.loadTexture(2, 2, @ptrCast(&TEXTURE_DATA)),
|
||||||
.transform = .{},
|
.transform = .{},
|
||||||
.position = .{ 0, 0 },
|
.position = .{ 0, 0 },
|
||||||
.state = .idle,
|
.state = .idle,
|
||||||
@@ -98,6 +113,7 @@ pub fn init(controller: *Controller, graphics: *Graphics) !void {
|
|||||||
});
|
});
|
||||||
controller.addResource(Environment{
|
controller.addResource(Environment{
|
||||||
.mesh = try graphics.loadMesh(@ptrCast(&PLANE_MESH_DATA)),
|
.mesh = try graphics.loadMesh(@ptrCast(&PLANE_MESH_DATA)),
|
||||||
|
.texture = try graphics.loadTexture(2, 2, @ptrCast(&TEXTURE_DATA)),
|
||||||
.transform = .{
|
.transform = .{
|
||||||
.position = .{ 0, 0, -1 },
|
.position = .{ 0, 0, -1 },
|
||||||
.scale = @splat(5),
|
.scale = @splat(5),
|
||||||
@@ -259,10 +275,10 @@ pub fn draw(
|
|||||||
env.transform.rotation,
|
env.transform.rotation,
|
||||||
Transform.rotationByAxis(.{ 0, 0, 1 }, world_time.time.unitsSince(world_time.last_time) * std.math.pi),
|
Transform.rotationByAxis(.{ 0, 0, 1 }, world_time.time.unitsSince(world_time.last_time) * std.math.pi),
|
||||||
);
|
);
|
||||||
try graphics.drawMesh(env.mesh, env.transform);
|
try graphics.drawMesh(env.mesh, env.texture, env.transform);
|
||||||
try graphics.drawMesh(env.mesh, Transform{
|
try graphics.drawMesh(env.mesh, env.texture, Transform{
|
||||||
.position = .{ 0, 0, -0.5 },
|
.position = .{ 0, 0, -0.5 },
|
||||||
.scale = @splat(5),
|
.scale = @splat(5),
|
||||||
});
|
});
|
||||||
try graphics.drawMesh(player.mesh, player.transform);
|
try graphics.drawMesh(player.mesh, player.texture, player.transform);
|
||||||
}
|
}
|
||||||
|
@@ -11,6 +11,11 @@ pub const Mesh = struct {
|
|||||||
vertex_count: usize,
|
vertex_count: usize,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const Texture = struct {
|
||||||
|
texture: *sdl.GPUTexture,
|
||||||
|
sampler: *sdl.GPUSampler,
|
||||||
|
};
|
||||||
|
|
||||||
window: *sdl.Window,
|
window: *sdl.Window,
|
||||||
renderer: *sdl.Renderer,
|
renderer: *sdl.Renderer,
|
||||||
device: *sdl.GPUDevice,
|
device: *sdl.GPUDevice,
|
||||||
@@ -41,7 +46,7 @@ to_resize: ?[2]u32 = null,
|
|||||||
const VERTEX_BUFFER_DEFAULT_CAPACITY = 1024;
|
const VERTEX_BUFFER_DEFAULT_CAPACITY = 1024;
|
||||||
const VERTEX_BUFFER_GROWTH_MULTIPLIER = 2;
|
const VERTEX_BUFFER_GROWTH_MULTIPLIER = 2;
|
||||||
const TRANSFER_BUFFER_DEFAULT_CAPACITY = 1024;
|
const TRANSFER_BUFFER_DEFAULT_CAPACITY = 1024;
|
||||||
const BYTES_PER_VERTEX = 3 * 4;
|
const BYTES_PER_VERTEX = 5 * 4;
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
pub fn create() GameError!Self {
|
pub fn create() GameError!Self {
|
||||||
@@ -96,6 +101,7 @@ pub fn create() GameError!Self {
|
|||||||
.entrypoint = "main",
|
.entrypoint = "main",
|
||||||
.format = sdl.GPU_SHADERFORMAT_SPIRV,
|
.format = sdl.GPU_SHADERFORMAT_SPIRV,
|
||||||
.stage = sdl.GPU_SHADERSTAGE_FRAGMENT,
|
.stage = sdl.GPU_SHADERSTAGE_FRAGMENT,
|
||||||
|
.num_samplers = 1,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
errdefer sdl.ReleaseGPUShader(device, shader_frag);
|
errdefer sdl.ReleaseGPUShader(device, shader_frag);
|
||||||
@@ -132,18 +138,25 @@ pub fn create() GameError!Self {
|
|||||||
.vertex_input_state = .{
|
.vertex_input_state = .{
|
||||||
.vertex_buffer_descriptions = &.{
|
.vertex_buffer_descriptions = &.{
|
||||||
.slot = 0,
|
.slot = 0,
|
||||||
// 3 Coordinates * 4 Bytes
|
.pitch = 5 * 4,
|
||||||
.pitch = 3 * 4,
|
|
||||||
.input_rate = sdl.GPU_VERTEXINPUTRATE_VERTEX,
|
.input_rate = sdl.GPU_VERTEXINPUTRATE_VERTEX,
|
||||||
},
|
},
|
||||||
.num_vertex_buffers = 1,
|
.num_vertex_buffers = 1,
|
||||||
.vertex_attributes = &sdl.GPUVertexAttribute{
|
.vertex_attributes = &[2]sdl.GPUVertexAttribute{
|
||||||
.offset = 0,
|
sdl.GPUVertexAttribute{
|
||||||
.location = 0,
|
.offset = 0,
|
||||||
.format = sdl.GPU_VERTEXELEMENTFORMAT_FLOAT3,
|
.location = 0,
|
||||||
.buffer_slot = 0,
|
.format = sdl.GPU_VERTEXELEMENTFORMAT_FLOAT3,
|
||||||
|
.buffer_slot = 0,
|
||||||
|
},
|
||||||
|
sdl.GPUVertexAttribute{
|
||||||
|
.offset = 3 * 4,
|
||||||
|
.location = 1,
|
||||||
|
.format = sdl.GPU_VERTEXELEMENTFORMAT_FLOAT2,
|
||||||
|
.buffer_slot = 0,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
.num_vertex_attributes = 1,
|
.num_vertex_attributes = 2,
|
||||||
},
|
},
|
||||||
.primitive_type = sdl.GPU_PRIMITIVETYPE_TRIANGLELIST,
|
.primitive_type = sdl.GPU_PRIMITIVETYPE_TRIANGLELIST,
|
||||||
.rasterizer_state = presets.RASTERIZER_CULL,
|
.rasterizer_state = presets.RASTERIZER_CULL,
|
||||||
@@ -218,6 +231,64 @@ pub fn destroy(self: *Self) void {
|
|||||||
sdl.DestroyGPUDevice(self.device);
|
sdl.DestroyGPUDevice(self.device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn loadTexture(self: *Self, width: u32, height: u32, texture_bytes: []const u8) GameError!Texture {
|
||||||
|
const target_format = sdl.SDL_GetGPUSwapchainTextureFormat(self.device, self.window);
|
||||||
|
|
||||||
|
const texture = sdl.CreateGPUTexture(self.device, &sdl.GPUTextureCreateInfo{
|
||||||
|
.format = target_format,
|
||||||
|
.layer_count_or_depth = 1,
|
||||||
|
.width = width,
|
||||||
|
.height = height,
|
||||||
|
.num_levels = 1,
|
||||||
|
.sample_count = sdl.GPU_SAMPLECOUNT_1,
|
||||||
|
.usage = sdl.GPU_TEXTUREUSAGE_SAMPLER,
|
||||||
|
}) orelse return GameError.SdlError;
|
||||||
|
errdefer sdl.ReleaseGPUTexture(self.device, texture);
|
||||||
|
|
||||||
|
const command_buffer = sdl.AcquireGPUCommandBuffer(self.device) orelse return GameError.SdlError;
|
||||||
|
{
|
||||||
|
errdefer _ = sdl.CancelGPUCommandBuffer(command_buffer);
|
||||||
|
|
||||||
|
const copy_pass = sdl.BeginGPUCopyPass(command_buffer) orelse return GameError.SdlError;
|
||||||
|
defer sdl.EndGPUCopyPass(copy_pass);
|
||||||
|
|
||||||
|
const map: [*]u8 = @ptrCast(sdl.MapGPUTransferBuffer(self.device, self.transfer_buffer, false) orelse return GameError.SdlError);
|
||||||
|
@memcpy(map, texture_bytes);
|
||||||
|
sdl.UnmapGPUTransferBuffer(self.device, self.transfer_buffer);
|
||||||
|
|
||||||
|
sdl.UploadToGPUTexture(copy_pass, &sdl.GPUTextureTransferInfo{
|
||||||
|
.offset = 0,
|
||||||
|
.pixels_per_row = width,
|
||||||
|
.rows_per_layer = height,
|
||||||
|
.transfer_buffer = self.transfer_buffer,
|
||||||
|
}, &sdl.GPUTextureRegion{
|
||||||
|
.texture = texture,
|
||||||
|
.mip_level = 0,
|
||||||
|
.layer = 0,
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.z = 0,
|
||||||
|
.w = width,
|
||||||
|
.h = height,
|
||||||
|
.d = 1,
|
||||||
|
}, false);
|
||||||
|
}
|
||||||
|
if (!sdl.SubmitGPUCommandBuffer(command_buffer)) return GameError.SdlError;
|
||||||
|
|
||||||
|
const sampler = sdl.CreateGPUSampler(self.device, &sdl.GPUSamplerCreateInfo{
|
||||||
|
.address_mode_u = sdl.GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE,
|
||||||
|
.address_mode_v = sdl.GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE,
|
||||||
|
.address_mode_w = sdl.GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE,
|
||||||
|
.mag_filter = sdl.GPU_FILTER_NEAREST,
|
||||||
|
.min_filter = sdl.GPU_FILTER_LINEAR,
|
||||||
|
}) orelse return GameError.SdlError;
|
||||||
|
|
||||||
|
return Texture{
|
||||||
|
.texture = texture,
|
||||||
|
.sampler = sampler,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn loadMesh(self: *Self, mesh_bytes: []const u8) GameError!Mesh {
|
pub fn loadMesh(self: *Self, mesh_bytes: []const u8) GameError!Mesh {
|
||||||
std.debug.assert(mesh_bytes.len < self.transfer_buffer_capacity);
|
std.debug.assert(mesh_bytes.len < self.transfer_buffer_capacity);
|
||||||
|
|
||||||
@@ -359,10 +430,14 @@ pub fn beginDraw(self: *Self) GameError!bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drawMesh(self: *Self, mesh: Mesh, transform: Transform) GameError!void {
|
pub fn drawMesh(self: *Self, mesh: Mesh, texture: Texture, transform: Transform) GameError!void {
|
||||||
if (self.render_pass == null) return;
|
if (self.render_pass == null) return;
|
||||||
|
|
||||||
sdl.PushGPUVertexUniformData(self.command_buffer, 1, &transform.matrix(), 16 * 4);
|
sdl.PushGPUVertexUniformData(self.command_buffer, 1, &transform.matrix(), 16 * 4);
|
||||||
|
sdl.BindGPUFragmentSamplers(self.render_pass, 0, &sdl.GPUTextureSamplerBinding{
|
||||||
|
.texture = texture.texture,
|
||||||
|
.sampler = texture.sampler,
|
||||||
|
}, 1);
|
||||||
sdl.DrawGPUPrimitives(self.render_pass, @intCast(mesh.vertex_count), 1, @intCast(mesh.vertex_start), 0);
|
sdl.DrawGPUPrimitives(self.render_pass, @intCast(mesh.vertex_count), 1, @intCast(mesh.vertex_start), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user