repo: hackvr-turbo
action: commit
revision: 
path_from: 
revision_from: 2b0a7c57cd1f11c4c0250196ebad2fc895e8a3ff:
path_to: 
revision_to: 
git.thebackupbox.net
hackvr-turbo
git clone git://git.thebackupbox.net/hackvr-turbo
commit 2b0a7c57cd1f11c4c0250196ebad2fc895e8a3ff
Author: Felix (xq) Queißner 
Date:   Sat Jul 11 16:03:55 2020 +0200

    Improves color parsing.

diff --git a/src/main.zig b/src/main.zig
index 1d3aa53e426f60611bc5237efb3252899f2efcd6..
index ..b3dac5908eb09ee00eb88b379638ebde0be61527 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -39,6 +39,104 @@ const Resolution = struct {
     }
 };

+const Color = extern struct {
+    const Self = @This();
+
+    pub const black = parse("#FFFFFF") catch unreachable;
+    pub const white = parse("#FFFFFF") catch unreachable;
+    pub const red = parse("#FF0000") catch unreachable;
+    pub const green = parse("#00FF00") catch unreachable;
+    pub const blue = parse("#0000FF") catch unreachable;
+    pub const magenta = parse("#FF00FF") catch unreachable;
+    pub const cyan = parse("#00FFFF") catch unreachable;
+    pub const yellow = parse("#FF00FF") catch unreachable;
+
+    red: f32,
+    green: f32,
+    blue: f32,
+    alpha: f32 = 1.0,
+
+    /// Supported formats:
+    /// - `RGB`
+    /// - `#RGB`
+    /// - `RGBA`
+    /// - `RRGGBB`
+    /// - `#RRGGBB`
+    /// - `RRGGBBAA`
+    /// - `#RRGGBBAA`
+    pub fn parse(col: []const u8) !Self {
+        switch (col.len) {
+            3 => {
+                return Self{
+                    .red = @intToFloat(f32, try std.fmt.parseInt(u8, col[0..1], 16)) / 15.0,
+                    .green = @intToFloat(f32, try std.fmt.parseInt(u8, col[1..2], 16)) / 15.0,
+                    .blue = @intToFloat(f32, try std.fmt.parseInt(u8, col[2..3], 16)) / 15.0,
+                };
+            },
+            4 => {
+                return if (col[0] == '#')
+                    Self{
+                        .red = @intToFloat(f32, try std.fmt.parseInt(u8, col[1..2], 16)) / 15.0,
+                        .green = @intToFloat(f32, try std.fmt.parseInt(u8, col[2..3], 16)) / 15.0,
+                        .blue = @intToFloat(f32, try std.fmt.parseInt(u8, col[3..4], 16)) / 15.0,
+                    }
+                else
+                    Self{
+                        .red = @intToFloat(f32, try std.fmt.parseInt(u8, col[0..1], 16)) / 15.0,
+                        .green = @intToFloat(f32, try std.fmt.parseInt(u8, col[1..2], 16)) / 15.0,
+                        .blue = @intToFloat(f32, try std.fmt.parseInt(u8, col[2..3], 16)) / 15.0,
+                        .alpha = @intToFloat(f32, try std.fmt.parseInt(u8, col[3..4], 16)) / 15.0,
+                    };
+            },
+            5 => {
+                if (col[0] != '#')
+                    return error.InvalidFormat;
+                return Self{
+                    .red = @intToFloat(f32, try std.fmt.parseInt(u8, col[1..2], 16)) / 15.0,
+                    .green = @intToFloat(f32, try std.fmt.parseInt(u8, col[2..3], 16)) / 15.0,
+                    .blue = @intToFloat(f32, try std.fmt.parseInt(u8, col[3..4], 16)) / 15.0,
+                    .alpha = @intToFloat(f32, try std.fmt.parseInt(u8, col[4..5], 16)) / 15.0,
+                };
+            },
+            6 => {
+                return Self{
+                    .red = @intToFloat(f32, try std.fmt.parseInt(u8, col[0..2], 16)) / 255.0,
+                    .green = @intToFloat(f32, try std.fmt.parseInt(u8, col[2..4], 16)) / 255.0,
+                    .blue = @intToFloat(f32, try std.fmt.parseInt(u8, col[4..6], 16)) / 255.0,
+                };
+            },
+            7 => {
+                if (col[0] != '#')
+                    return error.InvalidFormat;
+                return Self{
+                    .red = @intToFloat(f32, try std.fmt.parseInt(u8, col[1..3], 16)) / 255.0,
+                    .green = @intToFloat(f32, try std.fmt.parseInt(u8, col[3..5], 16)) / 255.0,
+                    .blue = @intToFloat(f32, try std.fmt.parseInt(u8, col[5..7], 16)) / 255.0,
+                };
+            },
+            8 => {
+                return Self{
+                    .red = @intToFloat(f32, try std.fmt.parseInt(u8, col[0..2], 16)) / 255.0,
+                    .green = @intToFloat(f32, try std.fmt.parseInt(u8, col[2..4], 16)) / 255.0,
+                    .blue = @intToFloat(f32, try std.fmt.parseInt(u8, col[4..6], 16)) / 255.0,
+                    .alpha = @intToFloat(f32, try std.fmt.parseInt(u8, col[6..8], 16)) / 255.0,
+                };
+            },
+            9 => {
+                if (col[0] != '#')
+                    return error.InvalidFormat;
+                return Self{
+                    .red = @intToFloat(f32, try std.fmt.parseInt(u8, col[1..3], 16)) / 255.0,
+                    .green = @intToFloat(f32, try std.fmt.parseInt(u8, col[3..5], 16)) / 255.0,
+                    .blue = @intToFloat(f32, try std.fmt.parseInt(u8, col[5..7], 16)) / 255.0,
+                    .alpha = @intToFloat(f32, try std.fmt.parseInt(u8, col[7..9], 16)) / 255.0,
+                };
+            },
+            else => return error.InvalidFormat,
+        }
+    }
+};
+
 const CliOptions = struct {
     resolution: Resolution = Resolution{
         .width = 1280,
@@ -46,47 +144,39 @@ const CliOptions = struct {
     },
     fullscreen: bool = false,
     multisampling: ?u7 = null,
+    background: Color = Color.parse("#000020") catch unreachable,

     pub const shorthands = .{
         .f = "fullscreen",
         .r = "resolution",
         .m = "multisampling",
+        .b = "background",
     };
 };

-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 palette = [_]Color{
+    Color.parse("#140c1c") catch unreachable,
+    Color.parse("#442434") catch unreachable,
+    Color.parse("#30346d") catch unreachable,
+    Color.parse("#4e4a4e") catch unreachable,
+    Color.parse("#854c30") catch unreachable,
+    Color.parse("#346524") catch unreachable,
+    Color.parse("#d04648") catch unreachable,
+    Color.parse("#757161") catch unreachable,
+    Color.parse("#597dce") catch unreachable,
+    Color.parse("#d27d2c") catch unreachable,
+    Color.parse("#8595a1") catch unreachable,
+    Color.parse("#6daa2c") catch unreachable,
+    Color.parse("#d2aa99") catch unreachable,
+    Color.parse("#6dc2ca") catch unreachable,
+    Color.parse("#dad45e") catch unreachable,
+    Color.parse("#deeed6") catch unreachable,
 };

 const Vertex = extern struct {
     position: zlm.Vec3,
-    color: zlm.Vec3,
+    color: Color,
 };

 fn getGroupTransform(state: hackvr.State, group: hackvr.Group) zlm.Mat4 {
@@ -165,7 +255,7 @@ pub fn main() !void {
     );
     vao.attribFormat(
         1,
-        3,
+        4,
         .float,
         false,
         @byteOffsetOf(Vertex, "color"),
@@ -520,21 +610,21 @@ pub fn main() !void {
                         while (i < shape.points.len) {
                             try outline_list.append(Vertex{
                                 .position = shape.points[i - 1],
-                                .color = zlm.Vec3.one,
+                                .color = Color.white,
                             });
                             try outline_list.append(Vertex{
                                 .position = shape.points[i],
-                                .color = zlm.Vec3.one,
+                                .color = Color.white,
                             });
                             i += 1;
                         }
                         try outline_list.append(Vertex{
                             .position = shape.points[0],
-                            .color = zlm.Vec3.one,
+                            .color = Color.white,
                         });
                         try outline_list.append(Vertex{
                             .position = shape.points[shape.points.len - 1],
-                            .color = zlm.Vec3.one,
+                            .color = Color.white,
                         });
                     }
                 }
@@ -773,7 +863,12 @@ pub fn main() !void {

         // render graphics
         {
-            gl.clearColor(0.0, 0.0, 0.3, 1.0);
+            gl.clearColor(
+                cli.options.background.red,
+                cli.options.background.green,
+                cli.options.background.blue,
+                1.0,
+            );
             gl.clearDepth(1.0);
             gl.clear(.{
                 .color = true,
@@ -913,90 +1008,6 @@ fn rayTriangleIntersect(ro: zlm.Vec3, rd: zlm.Vec3, v0: zlm.Vec3, v1: zlm.Vec3,
     // return vec3( t, u, v );
 }

-// fn rayTriangleIntersect(ro: zlm.Vec3, rd: zlm.Vec3, v0: zlm.Vec3, v1: zlm.Vec3, v2: zlm.Vec3) ?f32 {
-//     const a = v0.sub(v1);
-//     const b = v2.sub(v1);
-//     const p = v0.sub(ro);
-//     const n = b.cross(a);
-//     const q = p.cross(rd);
-
-//     const idet = 1.0 / rd.dot(n);
-
-//     const u = q.dot(b) * idet;
-//     const v = q.dot(a) * idet;
-//     const t = n.dot(p) * idet;
-
-//     if (t < 0) {
-//         return null;
-//     }
-
-//     if (u < 0 or u > 1 or v < 0 or (u + v) > 1) {
-//         return null;
-//     }
-
-//     return t;
-// }
-
-// fn rayTriangleIntersect(orig: zlm.Vec3, dir: zlm.Vec3, v0: zlm.Vec3, v1: zlm.Vec3, v2: zlm.Vec3) ?f32 {
-//     const kEpsilon = 1e-10;
-
-//     // compute plane's normal
-//     const v0v1 = v1.sub(v0);
-//     const v0v2 = v2.sub(v0);
-//     // no need to normalize
-//     const N = v0v1.cross(v0v2); // N
-//     const area2 = N.length();
-
-//     // Step 1: finding P
-
-//     // check if ray and plane are parallel ?
-//     const NdotRayDirection = N.dot(dir);
-//     if (std.math.absFloat(NdotRayDirection) < kEpsilon) { // almost 0
-//         return null; // they are parallel so they don't intersect !
-//     }
-
-//     // compute d parameter using equation 2
-//     const d = N.dot(v0);
-
-//     // compute t (equation 3)
-//     const t = (N.dot(orig) + d) / NdotRayDirection;
-//     // check if the triangle is in behind the ray
-//     if (t < 0) {
-//         return null; // the triangle is behind
-//     }
-
-//     // compute the intersection point using equation 1
-//     const P = orig.add(dir.scale(t));
-
-//     // Step 2: inside-outside test
-
-//     // edge 0
-//     const edge0 = v1.sub(v0);
-//     const vp0 = P.sub(v0);
-//     const C0 = edge0.cross(vp0); // vector perpendicular to triangle's plane
-//     const side_0 = (N.dot(C0) < 0);
-//     if (side_0)
-//         return null;
-
-//     // edge 1
-//     const edge1 = v2.sub(v1);
-//     const vp1 = P.sub(v1);
-//     const C1 = edge1.cross(vp1);
-//     const side_1 = (N.dot(C1) < 0);
-//     if (side_1)
-//         return null;
-
-//     // edge 2
-//     const edge2 = v0.sub(v2);
-//     const vp2 = P.sub(v2);
-//     const C2 = edge2.cross(vp2);
-//     const side_2 = (N.dot(C2) < 0);
-//     if (side_2)
-//         return null;
-
-//     return t; // this ray hits the triangle
-// }
-
 fn invertMatrix(mat: zlm.Mat4) ?zlm.Mat4 {
     const m = @bitCast([16]f32, mat.fields);
     var inv: [16]f32 = undefined;

-----END OF PAGE-----