repo: hackvr-turbo action: commit revision: path_from: revision_from: 7668423d34c6fc09f53c5fed590670318f1a1bd3: path_to: revision_to:
commit 7668423d34c6fc09f53c5fed590670318f1a1bd3 Author: Felix (xq) QueißnerDate: Sat Jul 4 02:27:50 2020 +0200 Basic rendering, no translation/rotation yet. diff --git a/.gitmodules b/.gitmodules
--- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "lib/zlm"] path = lib/zlm url = https://github.com/ziglibs/zlm +[submodule "lib/zgl"] + path = lib/zgl + url = https://github.com/ziglibs/zgl diff --git a/LICENSE b/LICENSE
--- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -MIT License Copyright (c)+MIT License Copyright (c) 2020 Felix Queißner Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/build.zig b/build.zig
--- a/build.zig
+++ b/build.zig
@@ -19,6 +19,11 @@ const zlm = std.build.Pkg{
.path = "lib/zlm/zlm.zig",
};
+const zgl = std.build.Pkg{
+ .name = "zgl",
+ .path = "lib/zgl/zgl.zig",
+};
+
pub fn build(b: *std.build.Builder) void {
// Standard target options allows the person running `zig build` to choose
// what target to build for. Here we do not override the defaults, which
@@ -39,6 +44,7 @@ pub fn build(b: *std.build.Builder) void {
exe.addPackage(hackvr);
exe.addPackage(zlm);
+ exe.addPackage(zgl);
exe.install();
diff --git a/lib/hackvr/lib.zig b/lib/hackvr/lib.zig
--- a/lib/hackvr/lib.zig
+++ b/lib/hackvr/lib.zig
@@ -158,10 +158,16 @@ pub fn applyEventToState(state: *State, event: parsing.Event) !void {
};
},
.move => |cmd| {
- // semantics unclear
+ var iter = state.findGroups(cmd.selector.groups);
+ while (iter.next()) |*grp| {
+ // semantics unclear
+ }
},
.rotate => |cmd| {
- // semantics unclear
+ var iter = state.findGroups(cmd.selector.groups);
+ while (iter.next()) |*grp| {
+ // semantics unclear
+ }
},
else => {
std.debug.print("Event {} not implemented yet!\n", .{@as(parsing.EventType, event)});
diff --git a/lib/zgl b/lib/zgl
new file mode 160000
index 0000000000000000000000000000000000000000..c37cf0cfbeeab94cc07121ce3c817cc6813c15fd
--- /dev/null
+++ b/lib/zgl
@@ -0,0 +1 @@
+Subproject commit c37cf0cfbeeab94cc07121ce3c817cc6813c15fd
diff --git a/notes/chatlog.txt b/notes/chatlog.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6ee868e0934a228d0aec0fb92240d054bff940a4
--- /dev/null
+++ b/notes/chatlog.txt
@@ -0,0 +1,48 @@
+ merpkz hat die Verbindung getrennt (Ping timeout: 20 seconds).
+ rotation /should/ be group-relative, but I don't have the code for that in my version yet
+ those movements are absolute
+ if you put a + before them, they're relative
+ rotate 0 90 0 #sets rotation to 90
+ rotate 0 45 0 #sets rotation to 45, not 90 + 45
+ rotate 0 +45 0 #sets rotation to 45 more than what it was
+ rotate 0 +-45 0 #sets rotation to 45 less than what it was
+ and those 0s are absolutes too
+ so if there was a rotation on the x or z before any of those, they'd get reset to 0
+ the moves are in the global directions probably
+ and they set absolute too
+ unless using + before the values
+ if you do "forward" it is the group's positive z after rotation
+ so you can have something loop on: "rotate 0 +5 0" and "move forward" and it'll walk in a circle
+ "circle"
+ n-gon of 360/5 sides or something
+ thanks for clarification :)
+ so move forward is relative, but move +0 +0 +1 is absolute *grin*
+ I'm kind of AFK doing cleaning, so leave questions and I'll answer when I check my screen.
+ (so to speak: without rotation)
+ but makes implementation easier for me :
+ *girn*
+ no fancy transforms
+ this allows me to display the maze soonish *joy*
+ the fancy transforms can usually be done by building up multiple commands.
+ om mani padme hum
+ ...
+ someone said something about an "Abort, Retry, Fail" keychain
+ but made me think of other situtations where those three options would apply.
+ > your fetus has Fetal Alcohol Syndrome.
+ > Abort, Retry, Fail
+ *cough*
+ anyway
+* epoch wanders off again
+* ice hat die Verbindung getrennt (Ping timeout: 20 seconds).
+* ice (~ice@loud.house) ist beigetreten.
+* SegFault gibt Channel-Operator-Status an ice
+ hackvr over gemini.
+ not just static either
+ gemini-get gemini://gemini.thebackupbox.net/hackvr-stream | hackvr | tr '\n' '\0' | uriescape | tr '\n' '\0' | xargs -0 -I{} gemini-get 'gemini://gemini.thebackupbox.net/hackvr-input?{}'
+-except/#default- hxxini://gemini.thebackupbox.net/hackvr-stream https://epo.k.vu/9a4d
+-except/#default- title:
+ or whatever it is
+ similar would work for http
+ as long as the protocol can stay open forever.
+ still not sure if gemini will support that
+ solderpunk liked that idea of doing tail -f over gemini though
\ No newline at end of file
diff --git a/src/main.zig b/src/main.zig
--- a/src/main.zig
+++ b/src/main.zig
@@ -1,11 +1,11 @@
const std = @import("std");
+const zlm = @import("zlm");
const hackvr = @import("hackvr");
+const gl = @import("zgl");
const c = @cImport({
- @cInclude("epoxy/gl.h");
@cInclude("SDL.h");
- // @cInclude("SDL_opengl.h");
});
const SdlError = error{SdlFailure};
@@ -28,7 +28,48 @@ const cli_options = CliOptions{
.multisampling = null,
};
+fn parseColor(comptime col: []const u8) zlm.Vec3 {
+ std.debug.assert(col.len == 7);
+ std.debug.assert(col[0] == '#');
+ return zlm.Vec3{
+ .x = @intToFloat(f32, std.fmt.parseInt(u8, col[1..3], 16) catch unreachable) / 255.0,
+ .y = @intToFloat(f32, std.fmt.parseInt(u8, col[3..5], 16) catch unreachable) / 255.0,
+ .z = @intToFloat(f32, std.fmt.parseInt(u8, col[5..7], 16) catch unreachable) / 255.0,
+ };
+}
+
+// https://lospec.com/palette-list/dawnbringer-16
+const palette = [_]zlm.Vec3{
+ parseColor("#140c1c"),
+ parseColor("#442434"),
+ parseColor("#30346d"),
+ parseColor("#4e4a4e"),
+ parseColor("#854c30"),
+ parseColor("#346524"),
+ parseColor("#d04648"),
+ parseColor("#757161"),
+ parseColor("#597dce"),
+ parseColor("#d27d2c"),
+ parseColor("#8595a1"),
+ parseColor("#6daa2c"),
+ parseColor("#d2aa99"),
+ parseColor("#6dc2ca"),
+ parseColor("#dad45e"),
+ parseColor("#deeed6"),
+};
+
+const Vertex = extern struct {
+ position: zlm.Vec3,
+ color: zlm.Vec3,
+};
+
pub fn main() anyerror!void {
+ var gpa_backing = std.testing.LeakCountAllocator.init(std.heap.c_allocator);
+ defer {
+ gpa_backing.validate() catch |err| {};
+ }
+ const gpa = &gpa_backing.allocator;
+
if (c.SDL_Init(c.SDL_INIT_EVERYTHING) < 0) {
return makeSdlError();
}
@@ -58,7 +99,123 @@ pub fn main() anyerror!void {
try sdlCheck(c.SDL_GL_MakeCurrent(window, context));
- c.glDebugMessageCallback(openGlDebugCallback, null);
+ try gl.debugMessageCallback({}, openGlDebugCallback);
+
+ var state = hackvr.State.init(std.testing.allocator);
+ defer state.deinit();
+
+ var parser = hackvr.parsing.Parser.init();
+
+ // Good enough for now, should be changed later!
+ {
+ var src: []const u8 = @embedFile("../lib/hackvr/data/test.hackvr");
+ while (src.len > 0) {
+ var item = try parser.push(src);
+ switch (item) {
+ // should never be reached as the test.hackvr is a complete file, terminated by a LF
+ .needs_data => unreachable,
+
+ // should never be reached as the test.hackvr file is correct
+ .parse_error => unreachable,
+
+ .event => |ev| {
+ src = ev.rest;
+ try hackvr.applyEventToState(&state, ev.event);
+ },
+ }
+ }
+ }
+
+ var vao = try gl.createVertexArray();
+ defer vao.delete();
+
+ try vao.enableVertexAttribute(0);
+ try vao.enableVertexAttribute(1);
+
+ try vao.attribFormat(
+ 0,
+ 3,
+ .float,
+ false,
+ @byteOffsetOf(Vertex, "position"),
+ );
+ try vao.attribFormat(
+ 1,
+ 3,
+ .float,
+ false,
+ @byteOffsetOf(Vertex, "color"),
+ );
+
+ try vao.attribBinding(0, 0);
+ try vao.attribBinding(1, 0);
+
+ var vertex_buffer = try gl.createBuffer();
+ defer vertex_buffer.delete();
+
+ var vertex_list = std.ArrayList(Vertex).init(gpa);
+ defer vertex_list.deinit();
+
+ try vao.vertexBuffer(0, vertex_buffer, 0, @sizeOf(Vertex));
+
+ var shader_program = try gl.createProgram();
+ defer shader_program.delete();
+
+ {
+ var vertex_shader = try gl.createShader(.vertex);
+ defer vertex_shader.delete();
+
+ var fragment_shader = try gl.createShader(.fragment);
+ defer fragment_shader.delete();
+
+ try vertex_shader.source(1, &[_][]const u8{
+ @embedFile("./shader/flat.vert"),
+ });
+
+ try fragment_shader.source(1, &[_][]const u8{
+ @embedFile("./shader/flat.frag"),
+ });
+
+ try vertex_shader.compile();
+ if ((try vertex_shader.get(.compile_status)) == 0) {
+ const compile_log = try vertex_shader.getCompileLog(gpa);
+ defer gpa.free(compile_log);
+
+ std.debug.print("failed to compile vertex shader:\n{}\n", .{compile_log});
+ return;
+ }
+
+ try fragment_shader.compile();
+ if ((try fragment_shader.get(.compile_status)) == 0) {
+ const compile_log = try fragment_shader.getCompileLog(gpa);
+ defer gpa.free(compile_log);
+
+ std.debug.print("failed to compile fragment shader:\n{}\n", .{compile_log});
+ return;
+ }
+
+ try shader_program.attach(vertex_shader);
+ defer shader_program.detach(vertex_shader);
+
+ try shader_program.attach(fragment_shader);
+ defer shader_program.detach(fragment_shader);
+
+ try shader_program.link();
+ if ((try shader_program.get(.link_status)) == 0) {
+ const link_log = try shader_program.getCompileLog(gpa);
+ defer gpa.free(link_log);
+
+ std.debug.print("failed to compile fragment shader:\n{}\n", .{link_log});
+ return;
+ }
+ }
+
+ const transform_loc = (try shader_program.uniformLocation("uTransform")) orelse {
+ std.log.crit(.Exe, "Failed to query uniform uTransform!\n", .{});
+ return;
+ };
+
+ try gl.enable(.depth_test);
mainLoop: while (true) {
// process events
@@ -72,10 +229,71 @@ pub fn main() anyerror!void {
}
}
+ // Render scene from HackVR dataset
{
- // render
- c.glClearColor(1.0, 0.0, 0.0, 1.0);
- c.glClear(c.GL_COLOR_BUFFER_BIT);
+ vertex_list.shrink(0);
+
+ var groups = state.iterator();
+ while (groups.next()) |group| {
+ for (group.shapes.items) |shape| {
+ if (shape.points.len < 3) {
+ std.debug.print("count: {}\n", .{shape.points.len});
+ } else {
+ // Simple fan-out triangulation.
+ // Not beautiful, but very simple
+ var i: usize = 2;
+ while (i < shape.points.len) {
+ try vertex_list.append(Vertex{
+ .position = shape.points[0],
+ .color = palette[shape.attributes.color],
+ });
+ try vertex_list.append(Vertex{
+ .position = shape.points[i - 1],
+ .color = palette[shape.attributes.color],
+ });
+ try vertex_list.append(Vertex{
+ .position = shape.points[i],
+ .color = palette[shape.attributes.color],
+ });
+
+ i += 1;
+ }
+ }
+ }
+ }
+ }
+
+ try gl.namedBufferData(vertex_buffer, Vertex, vertex_list.items, .dynamic_draw);
+
+ const mat_proj = zlm.Mat4.createPerspective(1.0, 16.0 / 9.0, 0.1, 10000.0);
+ const mat_view = zlm.Mat4.createLookAt(
+ .{ .x = -20, .y = 0, .z = 0 },
+ .{ .x = 0, .y = 0, .z = 0 },
+ .{ .x = 0, .y = 1, .z = 0 },
+ );
+
+ const mat_view_proj = zlm.Mat4.mul(mat_view, mat_proj);
+
+ // render graphics
+ {
+ try gl.clearColor(0.0, 0.0, 0.3, 1.0);
+ try gl.clearDepth(1.0);
+ try gl.clear(.{
+ .color = true,
+ .depth = true,
+ });
+
+ try vao.bind();
+ try shader_program.use();
+
+ try gl.programUniformMatrix4(
+ shader_program,
+ transform_loc,
+ false,
+ @ptrCast([*]const [4][4]f32, &mat_view_proj.fields)[0..1],
+ );
+
+ try gl.drawArrays(.triangles, 0, vertex_list.items.len);
c.SDL_GL_SwapWindow(window);
c.SDL_Delay(10);
@@ -84,24 +302,20 @@ pub fn main() anyerror!void {
}
fn openGlDebugCallback(
- source: c.GLenum,
- msg_type: c.GLenum,
- id: c.GLuint,
- severity: c.GLenum,
- length: c.GLsizei,
- message: [*c]const c.GLchar,
- userParam: ?*const c_void,
-) callconv(.C) void {
- const msg_fmt = "{}\n";
- const msg_arg = .{
- message.?[0..@intCast(usize, length)],
- };
+ source: gl.DebugSource,
+ msg_type: gl.DebugMessageType,
+ id: usize,
+ severity: gl.DebugSeverity,
+ message: []const u8,
+) void {
+ const msg_fmt = "[{}/{}] {}\n";
+ const msg_arg = .{ @tagName(source), @tagName(msg_type), message };
switch (severity) {
- c.GL_DEBUG_SEVERITY_HIGH => std.log.err(.OpenGL, msg_fmt, msg_arg),
- c.GL_DEBUG_SEVERITY_MEDIUM => std.log.warn(.OpenGL, msg_fmt, msg_arg),
- c.GL_DEBUG_SEVERITY_LOW => std.log.notice(.OpenGL, msg_fmt, msg_arg),
- c.GL_DEBUG_SEVERITY_NOTIFICATION => std.log.notice(.OpenGL, msg_fmt, msg_arg),
+ .high => std.log.crit(.OpenGL, msg_fmt, msg_arg),
+ .medium => std.log.err(.OpenGL, msg_fmt, msg_arg),
+ .low => std.log.warn(.OpenGL, msg_fmt, msg_arg),
+ .notification => std.log.notice(.OpenGL, msg_fmt, msg_arg),
else => std.log.crit(.OpenGL, msg_fmt, msg_arg),
}
}
diff --git a/src/shader/flat.frag b/src/shader/flat.frag
new file mode 100644
index 0000000000000000000000000000000000000000..5c6ddd46d636e44dba774d3b8da825221017db28
--- /dev/null
+++ b/src/shader/flat.frag
@@ -0,0 +1,7 @@
+#version 330
+
+layout(location = 0) out vec4 fColor;
+
+in vec3 color;
+
+void main() { fColor = vec4(color, 1.0); }
\ No newline at end of file
diff --git a/src/shader/flat.vert b/src/shader/flat.vert
new file mode 100644
index 0000000000000000000000000000000000000000..184f764e3bd870c7c21caeda93f0d38c0729d797
--- /dev/null
+++ b/src/shader/flat.vert
@@ -0,0 +1,13 @@
+#version 330
+
+layout(location = 0) in vec3 vPosition;
+layout(location = 1) in vec3 vColor;
+
+out vec3 color;
+
+uniform mat4 uTransform;
+
+void main() {
+ gl_Position = uTransform * vec4(vPosition, 1);
+ color = vColor;
+}
\ No newline at end of file
-----END OF PAGE-----