Textures
This commit is contained in:
@@ -1,14 +1,10 @@
|
||||
#version 450
|
||||
|
||||
layout(location = 0) in float vertexIndex;
|
||||
layout(location = 1) in float depth;
|
||||
layout(location = 0) in vec2 inUV;
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
|
||||
layout(set = 2, binding = 0) uniform sampler2D texture_sampler;
|
||||
|
||||
void main() {
|
||||
fragColor = vec4(
|
||||
depth,
|
||||
cos(vertexIndex * 0.5) * 0.25 + 0.75,
|
||||
sin(vertexIndex * 0.5) * 0.25 + 0.75,
|
||||
1.0
|
||||
);
|
||||
fragColor = texture(texture_sampler, inUV);
|
||||
}
|
||||
|
@@ -1,8 +1,8 @@
|
||||
#version 450
|
||||
|
||||
layout(location = 0) in vec3 inCoord;
|
||||
layout(location = 0) out float vertexIndex;
|
||||
layout(location = 1) out float depth;
|
||||
layout(location = 1) in vec2 inUV;
|
||||
layout(location = 0) out vec2 outUV;
|
||||
|
||||
layout(set = 1, binding = 0) uniform Camera{
|
||||
mat4 transform;
|
||||
@@ -11,10 +11,7 @@ layout(set = 1, binding = 1) uniform Object{
|
||||
mat4 transform;
|
||||
} object;
|
||||
|
||||
|
||||
void main() {
|
||||
vertexIndex = gl_VertexIndex;
|
||||
vec4 outPos = vec4(inCoord, 1.0) * object.transform * camera.transform;
|
||||
depth = outPos.z / outPos.w;
|
||||
gl_Position = outPos;
|
||||
gl_Position = vec4(inCoord, 1.0) * object.transform * camera.transform;
|
||||
outUV = inUV;
|
||||
}
|
||||
|
@@ -8,50 +8,62 @@ const Graphics = @import("graphics.zig");
|
||||
const Game = @import("game.zig");
|
||||
|
||||
const CUBE_MESH_DATA = [_]f32{
|
||||
-0.5, 0.5, -0.5,
|
||||
0.5, 0.5, -0.5,
|
||||
-0.5, -0.5, -0.5,
|
||||
0.5, -0.5, -0.5,
|
||||
-0.5, -0.5, -0.5,
|
||||
0.5, 0.5, -0.5,
|
||||
0.5, 0.5, -0.5,
|
||||
0.5, 0.5, 0.5,
|
||||
0.5, -0.5, -0.5,
|
||||
0.5, -0.5, 0.5,
|
||||
0.5, -0.5, -0.5,
|
||||
0.5, 0.5, 0.5,
|
||||
0.5, 0.5, 0.5,
|
||||
-0.5, 0.5, 0.5,
|
||||
0.5, -0.5, 0.5,
|
||||
-0.5, -0.5, 0.5,
|
||||
0.5, -0.5, 0.5,
|
||||
-0.5, 0.5, 0.5,
|
||||
-0.5, 0.5, 0.5,
|
||||
-0.5, 0.5, -0.5,
|
||||
-0.5, -0.5, 0.5,
|
||||
-0.5, -0.5, -0.5,
|
||||
-0.5, -0.5, 0.5,
|
||||
-0.5, 0.5, -0.5,
|
||||
-0.5, 0.5, 0.5,
|
||||
0.5, 0.5, 0.5,
|
||||
-0.5, 0.5, -0.5,
|
||||
0.5, 0.5, -0.5,
|
||||
-0.5, 0.5, -0.5,
|
||||
0.5, 0.5, 0.5,
|
||||
-0.5, -0.5, -0.5,
|
||||
0.5, -0.5, -0.5,
|
||||
-0.5, -0.5, 0.5,
|
||||
0.5, -0.5, 0.5,
|
||||
-0.5, -0.5, 0.5,
|
||||
0.5, -0.5, -0.5,
|
||||
-0.5, 0.5, -0.5, 0.0, 0.0,
|
||||
0.5, 0.5, -0.5, 0.0, 0.0,
|
||||
-0.5, -0.5, -0.5, 0.0, 0.0,
|
||||
0.5, -0.5, -0.5, 0.0, 0.0,
|
||||
-0.5, -0.5, -0.5, 0.0, 0.0,
|
||||
0.5, 0.5, -0.5, 0.0, 0.0,
|
||||
0.5, 0.5, -0.5, 0.0, 0.0,
|
||||
0.5, 0.5, 0.5, 0.0, 0.0,
|
||||
0.5, -0.5, -0.5, 0.0, 0.0,
|
||||
0.5, -0.5, 0.5, 0.0, 0.0,
|
||||
0.5, -0.5, -0.5, 0.0, 0.0,
|
||||
0.5, 0.5, 0.5, 0.0, 0.0,
|
||||
0.5, 0.5, 0.5, 0.0, 0.0,
|
||||
-0.5, 0.5, 0.5, 0.0, 0.0,
|
||||
0.5, -0.5, 0.5, 0.0, 0.0,
|
||||
-0.5, -0.5, 0.5, 0.0, 0.0,
|
||||
0.5, -0.5, 0.5, 0.0, 0.0,
|
||||
-0.5, 0.5, 0.5, 0.0, 0.0,
|
||||
-0.5, 0.5, 0.5, 0.0, 0.0,
|
||||
-0.5, 0.5, -0.5, 0.0, 0.0,
|
||||
-0.5, -0.5, 0.5, 0.0, 0.0,
|
||||
-0.5, -0.5, -0.5, 0.0, 0.0,
|
||||
-0.5, -0.5, 0.5, 0.0, 0.0,
|
||||
-0.5, 0.5, -0.5, 0.0, 0.0,
|
||||
-0.5, 0.5, 0.5, 0.0, 0.0,
|
||||
0.5, 0.5, 0.5, 0.0, 0.0,
|
||||
-0.5, 0.5, -0.5, 0.0, 0.0,
|
||||
0.5, 0.5, -0.5, 0.0, 0.0,
|
||||
-0.5, 0.5, -0.5, 0.0, 0.0,
|
||||
0.5, 0.5, 0.5, 0.0, 0.0,
|
||||
-0.5, -0.5, -0.5, 0.0, 0.0,
|
||||
0.5, -0.5, -0.5, 0.0, 0.0,
|
||||
-0.5, -0.5, 0.5, 0.0, 0.0,
|
||||
0.5, -0.5, 0.5, 0.0, 0.0,
|
||||
-0.5, -0.5, 0.5, 0.0, 0.0,
|
||||
0.5, -0.5, -0.5, 0.0, 0.0,
|
||||
};
|
||||
const PLANE_MESH_DATA = [_]f32{
|
||||
-0.5, -0.5, 0,
|
||||
0.5, 0.5, 0,
|
||||
-0.5, 0.5, 0,
|
||||
0.5, 0.5, 0,
|
||||
-0.5, -0.5, 0,
|
||||
0.5, -0.5, 0,
|
||||
-0.5, -0.5, 0, 0.0, 1.0,
|
||||
0.5, 0.5, 0, 1.0, 0.0,
|
||||
-0.5, 0.5, 0, 0.0, 0.0,
|
||||
0.5, 0.5, 0, 1.0, 0.0,
|
||||
-0.5, -0.5, 0, 0.0, 1.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 {
|
||||
@@ -72,6 +84,7 @@ pub const PlayerState = union(enum) {
|
||||
|
||||
pub const Player = struct {
|
||||
mesh: Graphics.Mesh,
|
||||
texture: Graphics.Texture,
|
||||
transform: Transform,
|
||||
position: @Vector(2, i32),
|
||||
state: PlayerState,
|
||||
@@ -83,12 +96,14 @@ pub const Player = struct {
|
||||
|
||||
pub const Environment = struct {
|
||||
mesh: Graphics.Mesh,
|
||||
texture: Graphics.Texture,
|
||||
transform: Transform,
|
||||
};
|
||||
|
||||
pub fn init(controller: *Controller, graphics: *Graphics) !void {
|
||||
controller.addResource(Player{
|
||||
.mesh = try graphics.loadMesh(@ptrCast(&CUBE_MESH_DATA)),
|
||||
.texture = try graphics.loadTexture(2, 2, @ptrCast(&TEXTURE_DATA)),
|
||||
.transform = .{},
|
||||
.position = .{ 0, 0 },
|
||||
.state = .idle,
|
||||
@@ -98,6 +113,7 @@ pub fn init(controller: *Controller, graphics: *Graphics) !void {
|
||||
});
|
||||
controller.addResource(Environment{
|
||||
.mesh = try graphics.loadMesh(@ptrCast(&PLANE_MESH_DATA)),
|
||||
.texture = try graphics.loadTexture(2, 2, @ptrCast(&TEXTURE_DATA)),
|
||||
.transform = .{
|
||||
.position = .{ 0, 0, -1 },
|
||||
.scale = @splat(5),
|
||||
@@ -259,10 +275,10 @@ pub fn draw(
|
||||
env.transform.rotation,
|
||||
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, Transform{
|
||||
try graphics.drawMesh(env.mesh, env.texture, env.transform);
|
||||
try graphics.drawMesh(env.mesh, env.texture, Transform{
|
||||
.position = .{ 0, 0, -0.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,
|
||||
};
|
||||
|
||||
pub const Texture = struct {
|
||||
texture: *sdl.GPUTexture,
|
||||
sampler: *sdl.GPUSampler,
|
||||
};
|
||||
|
||||
window: *sdl.Window,
|
||||
renderer: *sdl.Renderer,
|
||||
device: *sdl.GPUDevice,
|
||||
@@ -41,7 +46,7 @@ to_resize: ?[2]u32 = null,
|
||||
const VERTEX_BUFFER_DEFAULT_CAPACITY = 1024;
|
||||
const VERTEX_BUFFER_GROWTH_MULTIPLIER = 2;
|
||||
const TRANSFER_BUFFER_DEFAULT_CAPACITY = 1024;
|
||||
const BYTES_PER_VERTEX = 3 * 4;
|
||||
const BYTES_PER_VERTEX = 5 * 4;
|
||||
|
||||
const Self = @This();
|
||||
pub fn create() GameError!Self {
|
||||
@@ -96,6 +101,7 @@ pub fn create() GameError!Self {
|
||||
.entrypoint = "main",
|
||||
.format = sdl.GPU_SHADERFORMAT_SPIRV,
|
||||
.stage = sdl.GPU_SHADERSTAGE_FRAGMENT,
|
||||
.num_samplers = 1,
|
||||
},
|
||||
);
|
||||
errdefer sdl.ReleaseGPUShader(device, shader_frag);
|
||||
@@ -132,18 +138,25 @@ pub fn create() GameError!Self {
|
||||
.vertex_input_state = .{
|
||||
.vertex_buffer_descriptions = &.{
|
||||
.slot = 0,
|
||||
// 3 Coordinates * 4 Bytes
|
||||
.pitch = 3 * 4,
|
||||
.pitch = 5 * 4,
|
||||
.input_rate = sdl.GPU_VERTEXINPUTRATE_VERTEX,
|
||||
},
|
||||
.num_vertex_buffers = 1,
|
||||
.vertex_attributes = &sdl.GPUVertexAttribute{
|
||||
.vertex_attributes = &[2]sdl.GPUVertexAttribute{
|
||||
sdl.GPUVertexAttribute{
|
||||
.offset = 0,
|
||||
.location = 0,
|
||||
.format = sdl.GPU_VERTEXELEMENTFORMAT_FLOAT3,
|
||||
.buffer_slot = 0,
|
||||
},
|
||||
.num_vertex_attributes = 1,
|
||||
sdl.GPUVertexAttribute{
|
||||
.offset = 3 * 4,
|
||||
.location = 1,
|
||||
.format = sdl.GPU_VERTEXELEMENTFORMAT_FLOAT2,
|
||||
.buffer_slot = 0,
|
||||
},
|
||||
},
|
||||
.num_vertex_attributes = 2,
|
||||
},
|
||||
.primitive_type = sdl.GPU_PRIMITIVETYPE_TRIANGLELIST,
|
||||
.rasterizer_state = presets.RASTERIZER_CULL,
|
||||
@@ -218,6 +231,64 @@ pub fn destroy(self: *Self) void {
|
||||
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 {
|
||||
std.debug.assert(mesh_bytes.len < self.transfer_buffer_capacity);
|
||||
|
||||
@@ -359,10 +430,14 @@ pub fn beginDraw(self: *Self) GameError!bool {
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user