254 lines
8 KiB
Zig
254 lines
8 KiB
Zig
|
|
//! ----------------------------------------------------
|
||
|
|
//! ----------------------------------------------------
|
||
|
|
|
||
|
|
const std = @import("std");
|
||
|
|
const sdl = @import("sdl");
|
||
|
|
const math = @import("math");
|
||
|
|
const Gfx = @import("gfx");
|
||
|
|
|
||
|
|
/// ----------------------------------------------------
|
||
|
|
/// ----------------------------------------------------
|
||
|
|
const UnlitMaterial = struct {
|
||
|
|
albedo: [4]f32 = .{ 1, 1, 1, 1 },
|
||
|
|
};
|
||
|
|
|
||
|
|
/// ----------------------------------------------------
|
||
|
|
/// ----------------------------------------------------
|
||
|
|
const Vertex = struct {
|
||
|
|
pos: [3]f32,
|
||
|
|
normal: [3]f32,
|
||
|
|
uv: [2]f32,
|
||
|
|
};
|
||
|
|
|
||
|
|
/// ----------------------------------------------------
|
||
|
|
/// ----------------------------------------------------
|
||
|
|
const vertices = [_]Vertex{
|
||
|
|
.{ .pos = .{ -0.5, -0.5, 0.5 }, .normal = .{ 0, 0, 1 }, .uv = .{ 0, 0 } },
|
||
|
|
.{ .pos = .{ 0.5, -0.5, 0.5 }, .normal = .{ 0, 0, 1 }, .uv = .{ 1, 0 } },
|
||
|
|
.{ .pos = .{ 0.5, 0.5, 0.5 }, .normal = .{ 0, 0, 1 }, .uv = .{ 1, 1 } },
|
||
|
|
.{ .pos = .{ -0.5, 0.5, 0.5 }, .normal = .{ 0, 0, 1 }, .uv = .{ 0, 1 } },
|
||
|
|
|
||
|
|
.{ .pos = .{ 0.5, -0.5, -0.5 }, .normal = .{ 0, 0, -1 }, .uv = .{ 0, 0 } },
|
||
|
|
.{ .pos = .{ -0.5, -0.5, -0.5 }, .normal = .{ 0, 0, -1 }, .uv = .{ 1, 0 } },
|
||
|
|
.{ .pos = .{ -0.5, 0.5, -0.5 }, .normal = .{ 0, 0, -1 }, .uv = .{ 1, 1 } },
|
||
|
|
.{ .pos = .{ 0.5, 0.5, -0.5 }, .normal = .{ 0, 0, -1 }, .uv = .{ 0, 1 } },
|
||
|
|
|
||
|
|
.{ .pos = .{ -0.5, -0.5, -0.5 }, .normal = .{ -1, 0, 0 }, .uv = .{ 0, 0 } },
|
||
|
|
.{ .pos = .{ -0.5, -0.5, 0.5 }, .normal = .{ -1, 0, 0 }, .uv = .{ 1, 0 } },
|
||
|
|
.{ .pos = .{ -0.5, 0.5, 0.5 }, .normal = .{ -1, 0, 0 }, .uv = .{ 1, 1 } },
|
||
|
|
.{ .pos = .{ -0.5, 0.5, -0.5 }, .normal = .{ -1, 0, 0 }, .uv = .{ 0, 1 } },
|
||
|
|
|
||
|
|
.{ .pos = .{ 0.5, -0.5, 0.5 }, .normal = .{ 1, 0, 0 }, .uv = .{ 0, 0 } },
|
||
|
|
.{ .pos = .{ 0.5, -0.5, -0.5 }, .normal = .{ 1, 0, 0 }, .uv = .{ 1, 0 } },
|
||
|
|
.{ .pos = .{ 0.5, 0.5, -0.5 }, .normal = .{ 1, 0, 0 }, .uv = .{ 1, 1 } },
|
||
|
|
.{ .pos = .{ 0.5, 0.5, 0.5 }, .normal = .{ 1, 0, 0 }, .uv = .{ 0, 1 } },
|
||
|
|
|
||
|
|
.{ .pos = .{ -0.5, 0.5, 0.5 }, .normal = .{ 0, 1, 0 }, .uv = .{ 0, 0 } },
|
||
|
|
.{ .pos = .{ 0.5, 0.5, 0.5 }, .normal = .{ 0, 1, 0 }, .uv = .{ 1, 0 } },
|
||
|
|
.{ .pos = .{ 0.5, 0.5, -0.5 }, .normal = .{ 0, 1, 0 }, .uv = .{ 1, 1 } },
|
||
|
|
.{ .pos = .{ -0.5, 0.5, -0.5 }, .normal = .{ 0, 1, 0 }, .uv = .{ 0, 1 } },
|
||
|
|
|
||
|
|
.{ .pos = .{ -0.5, -0.5, -0.5 }, .normal = .{ 0, -1, 0 }, .uv = .{ 0, 0 } },
|
||
|
|
.{ .pos = .{ 0.5, -0.5, -0.5 }, .normal = .{ 0, -1, 0 }, .uv = .{ 1, 0 } },
|
||
|
|
.{ .pos = .{ 0.5, -0.5, 0.5 }, .normal = .{ 0, -1, 0 }, .uv = .{ 1, 1 } },
|
||
|
|
.{ .pos = .{ -0.5, -0.5, 0.5 }, .normal = .{ 0, -1, 0 }, .uv = .{ 0, 1 } },
|
||
|
|
};
|
||
|
|
|
||
|
|
/// ----------------------------------------------------
|
||
|
|
/// ----------------------------------------------------
|
||
|
|
const indices = [_]u32{
|
||
|
|
0, 1, 2,
|
||
|
|
0, 2, 3,
|
||
|
|
|
||
|
|
4, 5, 6,
|
||
|
|
4, 6, 7,
|
||
|
|
|
||
|
|
8, 9, 10,
|
||
|
|
8, 10, 11,
|
||
|
|
|
||
|
|
12, 13, 14,
|
||
|
|
12, 14, 15,
|
||
|
|
|
||
|
|
16, 17, 18,
|
||
|
|
16, 18, 19,
|
||
|
|
|
||
|
|
20, 21, 22,
|
||
|
|
20, 22, 23,
|
||
|
|
};
|
||
|
|
|
||
|
|
/// ----------------------------------------------------
|
||
|
|
/// ----------------------------------------------------
|
||
|
|
const Camera = struct {
|
||
|
|
projection: math.Mat4x4,
|
||
|
|
view: math.Mat4x4,
|
||
|
|
};
|
||
|
|
|
||
|
|
/// ----------------------------------------------------
|
||
|
|
/// ----------------------------------------------------
|
||
|
|
const Model = struct {
|
||
|
|
matrix: math.Mat4x4,
|
||
|
|
};
|
||
|
|
|
||
|
|
/// ----------------------------------------------------
|
||
|
|
/// ----------------------------------------------------
|
||
|
|
pub fn main(init: std.process.Init) !void {
|
||
|
|
|
||
|
|
//
|
||
|
|
// DATA
|
||
|
|
//
|
||
|
|
|
||
|
|
var material: UnlitMaterial = .{ .albedo = .{ 1.0, 0.2, 0.2, 1.0 } };
|
||
|
|
const camera: Camera = .{
|
||
|
|
.projection = .perspective(std.math.degreesToRadians(90), 800.0 / 600.0, 0.01, 1000),
|
||
|
|
.view = .lookAt(.new(.{ 1, 1, -2 }), .new(.{ 0, 0, 1 }), .new(.{ 0, 1, 0 })),
|
||
|
|
};
|
||
|
|
const model: Model = .{
|
||
|
|
.matrix = math.Mat4x4.translate(
|
||
|
|
0,
|
||
|
|
0,
|
||
|
|
0,
|
||
|
|
)
|
||
|
|
.mul(math.Quat.fromEuler(.init(0, 0, 0)).toMat4())
|
||
|
|
.mul(math.Mat4x4.scale(
|
||
|
|
1,
|
||
|
|
1,
|
||
|
|
1,
|
||
|
|
)),
|
||
|
|
};
|
||
|
|
|
||
|
|
//
|
||
|
|
// SDL
|
||
|
|
//
|
||
|
|
|
||
|
|
// --- # ---
|
||
|
|
if (!sdl.SDL_Init(sdl.SDL_INIT_VIDEO)) return error.FailedToInitSDL;
|
||
|
|
defer sdl.SDL_Quit();
|
||
|
|
|
||
|
|
// --- # ---
|
||
|
|
const window = sdl.SDL_CreateWindow("NYXGFX", 800, 600, 0) orelse return error.FailedTomakeWindow;
|
||
|
|
defer sdl.SDL_DestroyWindow(window);
|
||
|
|
|
||
|
|
// --- # ---
|
||
|
|
const props = sdl.SDL_GetWindowProperties(window);
|
||
|
|
const display = sdl.SDL_GetPointerProperty(props, sdl.SDL_PROP_WINDOW_X11_DISPLAY_POINTER, null);
|
||
|
|
const xwindow = sdl.SDL_GetNumberProperty(props, sdl.SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
|
||
|
|
|
||
|
|
//
|
||
|
|
// GFX
|
||
|
|
//
|
||
|
|
|
||
|
|
// --- # ---
|
||
|
|
var gfx: Gfx = try .init(.{
|
||
|
|
.window = .{
|
||
|
|
.xlib = .{
|
||
|
|
.window = @intCast(xwindow),
|
||
|
|
.display = display.?,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
.backend = .vulkan,
|
||
|
|
}, init.gpa, init.io);
|
||
|
|
defer gfx.deinit();
|
||
|
|
|
||
|
|
errdefer gfx.deinit();
|
||
|
|
|
||
|
|
// --- # ---
|
||
|
|
const adapter = try gfx.makeAdapter(.{ .gpu_type = .any });
|
||
|
|
const surface = try gfx.makeSurface();
|
||
|
|
const device = try gfx.makeDevice(adapter, surface);
|
||
|
|
const swapchain = try gfx.makeSwapchain(adapter, device, surface);
|
||
|
|
|
||
|
|
// --- TEXTURES ---
|
||
|
|
const texture = try gfx.makeTexture(.{
|
||
|
|
.image = .{ .path = "examples/assets/textures/texture.jpg", .vertical_flip = true },
|
||
|
|
.sampler = .{ .min_filter = .linear, .address_u = .repeat },
|
||
|
|
}, adapter, device);
|
||
|
|
|
||
|
|
// --- BUFFERS ---
|
||
|
|
const vbuf = try gfx.makeBuffer(vertices, .vertex, adapter, device);
|
||
|
|
const ibuf = try gfx.makeBuffer(indices, .index, adapter, device);
|
||
|
|
|
||
|
|
// --- SHADERS ---
|
||
|
|
const simple_vert = try gfx.makeShader("examples/assets/shaders/compiled/3D.vert.spv", device);
|
||
|
|
const simple_frag = try gfx.makeShader("examples/assets/shaders/compiled/3D.frag.spv", device);
|
||
|
|
|
||
|
|
// --- PIPELINE ---
|
||
|
|
const pipeline = try gfx.makePipeline(.{
|
||
|
|
.vertex_attributes = &.{
|
||
|
|
.{ .location = 0, .format = .vec3, .offset = @offsetOf(Vertex, "pos") },
|
||
|
|
.{ .location = 1, .format = .vec3, .offset = @offsetOf(Vertex, "normal") },
|
||
|
|
.{ .location = 2, .format = .vec2, .offset = @offsetOf(Vertex, "uv") },
|
||
|
|
},
|
||
|
|
.vertex_binding = .{ .stride = @sizeOf(Vertex) },
|
||
|
|
|
||
|
|
.uniforms = &.{
|
||
|
|
.{ .name = "camera", .size = @sizeOf(Camera) },
|
||
|
|
.{ .name = "model", .size = @sizeOf(Model) },
|
||
|
|
},
|
||
|
|
|
||
|
|
.textures = &.{
|
||
|
|
texture,
|
||
|
|
},
|
||
|
|
|
||
|
|
.depth_format = .d32_sfloat,
|
||
|
|
|
||
|
|
.vert_shader = simple_vert,
|
||
|
|
.frag_shader = simple_frag,
|
||
|
|
|
||
|
|
.device = device,
|
||
|
|
.swapchain = swapchain,
|
||
|
|
});
|
||
|
|
|
||
|
|
// --- MISC ---
|
||
|
|
var event: sdl.SDL_Event = undefined;
|
||
|
|
var running: bool = true;
|
||
|
|
var i: f32 = 0;
|
||
|
|
|
||
|
|
while (running) {
|
||
|
|
// --- INPUTS ---
|
||
|
|
while (sdl.SDL_PollEvent(&event)) {
|
||
|
|
switch (event.type) {
|
||
|
|
sdl.SDL_EVENT_QUIT => running = false,
|
||
|
|
else => {},
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// --- ANIMATION ---
|
||
|
|
i += 0.001;
|
||
|
|
i = @mod(i, 1);
|
||
|
|
material.albedo[1] = i;
|
||
|
|
|
||
|
|
try pipeline.setUniform("camera", Camera{
|
||
|
|
.projection = camera.projection.transpose(),
|
||
|
|
.view = camera.view.transpose(),
|
||
|
|
});
|
||
|
|
try pipeline.setUniform("model", Model{
|
||
|
|
.matrix = model.matrix.transpose(),
|
||
|
|
});
|
||
|
|
|
||
|
|
// --- FRAME ---
|
||
|
|
try gfx.beginFrame(swapchain, device);
|
||
|
|
defer gfx.endFrame(swapchain, device) catch unreachable;
|
||
|
|
|
||
|
|
// --- NEW PASS ---
|
||
|
|
if (gfx.beginPass(swapchain, .{
|
||
|
|
.clear_color = .{ 0.01, 0.01, 0.01, 1.0 },
|
||
|
|
.depth_enabled = true,
|
||
|
|
})) |pass| {
|
||
|
|
defer pass.end();
|
||
|
|
|
||
|
|
try vbuf.bind();
|
||
|
|
try ibuf.bind();
|
||
|
|
|
||
|
|
try pipeline.bind();
|
||
|
|
pass.drawIndexed(indices.len, 1, 0, 0, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
// --- NEW PASS ---
|
||
|
|
if (gfx.beginPass(swapchain, .{
|
||
|
|
.load_op = .load,
|
||
|
|
})) |pass| {
|
||
|
|
defer pass.end();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|