first commit

This commit is contained in:
Daniel Ledda
2023-04-12 21:49:48 +02:00
parent 658b5d693a
commit 993531655f
23 changed files with 7804 additions and 3462 deletions

9
src/c.zig Normal file
View File

@@ -0,0 +1,9 @@
pub usingnamespace @cImport({
@cInclude("glad/glad.h");
@cInclude("GLFW/glfw3.h");
@cDefine("STB_IMAGE_IMPLEMENTATION", "");
@cDefine("TINYOBJ_LOADER_C_IMPLEMENTATION", "");
@cInclude("loaders/stb_image.h");
@cInclude("loaders/tinyobj.h");
});

43
src/gfx/Color.zig Normal file
View File

@@ -0,0 +1,43 @@
fn hue_to_rgb(p: f32, q: f32, t: f32) f32 {
if (t < 0) {
t += 1;
} else if (t > 1) {
t -= 1;
}
if (t < 1.0 / 6) return p + (q - p) * 6 * t;
if (t < 1.0 / 2) return q;
if (t < 2.0 / 3) return p + (q - p) * (2.0 / 3 - t) * 6;
return p;
}
fn hsl_to_hex(h: f32, s: f32, l: f32) @Vector(3, f32) {
h /= 360;
s /= 100;
l /= 100;
const r: f32;
const g: f32;
const b: f32;
if (s == 0) {
r = l;
g = l;
b = l;
} else {
const q = if (l < 0.5) l * (1 + s) else l + s - l * s;
const p = 2 * l - q;
r = hue_to_rgb(p, q, h + 1.0 / 3);
g = hue_to_rgb(p, q, h);
b = hue_to_rgb(p, q, h - 1.0 / 3);
}
return @Vector(3, f32){ r, g, b };
}
pub fn color_from_index(index: i32) @Vector(3, f32) {
const color_wheel_cycle = @floor(index / 6.0);
const darkness_cycle = @floor(index / 12.0);
const spacing = (360.0 / 6.0);
const offset = if (color_wheel_cycle == 0) 0 else spacing / (color_wheel_cycle + 2);
const hue = spacing * (index % 6) + offset;
const saturation = 100.0f;
const lightness = 1.0f / (2 + darkness_cycle) * 100;
return hsl_to_hex(hue, saturation, lightness);
}

94
src/gfx/Mesh.zig Normal file
View File

@@ -0,0 +1,94 @@
const std = @import("std");
const c = @import("../c.zig");
const djleddaGeom = @import("djleddaGeom.zig");
pub const Mesh = struct {
vao: c_uint,
vbo_xyz: c_uint,
vbo_uv: c_uint,
vbo_norm: c_uint,
ebo: c_uint,
num_indices: c_uint,
pub fn from_shape(shape: *const djleddaGeom.Shape) void {
const mesh = Mesh{};
mesh.num_indices = shape.indices.len;
c.glGenVertexArrays(1, &mesh.vao);
c.glGenBuffers(1, &mesh.vbo_xyz);
c.glGenBuffers(1, &mesh.vbo_uv);
c.glGenBuffers(1, &mesh.ebo);
c.glBindVertexArray(mesh.vao);
c.glBindBuffer(c.GL_ARRAY_BUFFER, mesh.vbo_xyz);
c.glBufferData(c.GL_ARRAY_BUFFER, shape.xyz.ptr * @sizeOf(float), shape.xyz, c.GL_STATIC_DRAW);
c.glVertexAttribPointer(0, 3, c.GL_FLOAT, c.GL_FALSE, 3 * @sizeOf(f32), @as(*void, 0));
c.glEnableVertexAttribArray(0);
c.glBindBuffer(c.GL_ARRAY_BUFFER, mesh.vbo_uv);
c.glBufferData(c.GL_ARRAY_BUFFER, shape.uv.ptr * @sizeOf(f32), shape.uv, c.GL_STATIC_DRAW);
c.glVertexAttribPointer(1, 2, c.GL_FLOAT, c.GL_FALSE, 2 * @sizeOf(f32), @as(*void, 0));
c.glEnableVertexAttribArray(1);
c.glBindBuffer(c.GL_ELEMENT_ARRAY_BUFFER, mesh.ebo);
c.glBufferData(c.GL_ELEMENT_ARRAY_BUFFER, shape.indices.len * @sizeOf(c_uint), shape.indices.ptr, c.GL_STATIC_DRAW);
}
// pub fn init(obj_file: *[]const u8) void {
// const reader = c.tinyobj.ObjReader();
// const success = reader.ParseFromFile(obj_file);
// std.debug.print("{}\n", .{reader.Error()});
//
// const attrib = reader.GetAttrib();
//
// const indices_t = reader.GetShapes().at(0).mesh.indices;
// const indices = ArrayList(c_uint)(indices_t.size());
//
// const vertices = ArrayList()(3*indices_t.size());
// const normals = ArrayList()(3*indices_t.size());
// const texcoords = ArrayList()(2*indices_t.size());
//
// for (int i = 0; i < indices_t.size(); i++) {
// const vertex_data = indices_t[i];
// vertices[3*i] = attrib.vertices[3*vertex_data.vertex_index];
// vertices[3*i+1] = attrib.vertices[3*vertex_data.vertex_index + 1];
// vertices[3*i+2] = attrib.vertices[3*vertex_data.vertex_index + 2];
//
// normals[3*i] = attrib.normals[3*vertex_data.normal_index];
// normals[3*i+1] = attrib.normals[3*vertex_data.normal_index + 1];
// normals[3*i+2] = attrib.normals[3*vertex_data.normal_index + 2];
//
// texcoords[2*i] = attrib.texcoords[2*vertex_data.texcoord_index];
// texcoords[2*i+1] = attrib.texcoords[2*vertex_data.texcoord_index + 1];
//
// indices[i] = i;
// }
//
// num_indices = indices_t.size();
// glGenVertexArrays(1, &vao);
// glGenBuffers(1, &vbo_xyz);
// glGenBuffers(1, &vbo_uv);
// glGenBuffers(1, &vbo_norm);
// //glGenBuffers(1, &ebo);
//
// glBindVertexArray(vao);
//
// glBindBuffer(GL_ARRAY_BUFFER, vbo_xyz);
// glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW);
// glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
// glEnableVertexAttribArray(0);
//
// glBindBuffer(GL_ARRAY_BUFFER, vbo_uv);
// glBufferData(GL_ARRAY_BUFFER, texcoords.size() * sizeof(float), texcoords.data(), GL_STATIC_DRAW);
// glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
// glEnableVertexAttribArray(1);
//
// glBindBuffer(GL_ARRAY_BUFFER, vbo_norm);
// glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(float), normals.data(), GL_STATIC_DRAW);
// glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
// glEnableVertexAttribArray(2);
//
// //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
// //glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW);
// }
};

56
src/gfx/Shader.zig Normal file
View File

@@ -0,0 +1,56 @@
const c = @import("../c.zig");
const std = @import("std");
const ShaderType = enum(u32) {
fragment = c.GL_FRAGMENT_SHADER,
vertex = c.GL_VERTEX_SHADER,
};
fn create_shader(file_path: []const u8, shader_type: ShaderType, info_log: *[]const u8, allocator: *std.mem.Allocator) c_uint {
const file = try std.fs.openFileAbsolute(file_path);
const file_reader = file.reader(file);
const shader_code = std.ArrayList(u8);
shader_code.initCapacity(allocator, 1024);
defer allocator.free(shader_code);
file_reader.readAllArrayList(shader_code, 1024 * 1024);
const vertex_shader = c.glCreateShader(shader_type);
c.glShaderSource(vertex_shader, 1, &shader_code.items, c.NULL);
c.glCompileShader(vertex_shader);
const success: i32 = undefined;
c.glGetShaderiv(vertex_shader, c.GL_COMPILE_STATUS, &success);
if (success != 0) {
c.glGetShaderInfoLog(vertex_shader, 512, c.NULL, info_log);
const shader_type_name = if (shader_type == ShaderType.fragment) "FRAGMENT" else "VERTEX";
std.debug.print("ERROR::SHADER::{}::COMPILATION_FAILED\n{}\n", .{ shader_type_name, info_log });
}
return vertex_shader;
}
const Shader = struct {
prog_id: c_uint,
pub fn init(self: Shader, vertex_path: *[]const u8, fragment_path: *[]const u8, allocator: *std.mem.Allocator) void {
const info_log = [512]u8{};
const vertex_shader = create_shader(vertex_path, ShaderType.vertex, &info_log, allocator);
const fragment_shader = create_shader(fragment_path, ShaderType.fragment, &info_log, allocator);
self.prog_id = c.glCreateProgram();
c.glAttachShader(self.prog_id, vertex_shader);
c.glAttachShader(self.prog_id, fragment_shader);
c.glLinkProgram(self.prog_id);
const success: c_uint = undefined;
c.glGetProgramiv(self.prog_id, c.GL_LINK_STATUS, &success);
if (!success) {
c.glGetProgramInfoLog(self.prog_id, 512, c.NULL, &info_log);
std.debug.print("ERROR::SHADER::PROGRAM::LINK_FAILED\n{}\n", .{info_log});
}
c.glDeleteShader(vertex_shader);
c.glDeleteShader(fragment_shader);
}
};

57
src/gfx/djleddaGeom.zig Normal file
View File

@@ -0,0 +1,57 @@
// Buffer layout:
// X, Y, Z, U, V
pub const Shape = struct {
indices: []c_uint,
uv: []f32,
xyz: []f32,
};
const triangle_vertices = []f32{
-0.5, -0.5, 0.0, 1.0, 1.0,
0.5, -0.5, 0.0, 0.5, 0.5,
0.0, 0.5, 0.0, 0.0, 0.0,
};
const triangle_indices = []c_uint{ 0, 1, 2 };
const cube_vertices = []f32{ -0.5, -0.5, -0.5, 0.0, 0.0, 0.5, -0.5, -0.5, 1.0, 0.0, 0.5, 0.5, -0.5, 1.0, 1.0, 0.5, 0.5, -0.5, 1.0, 1.0, -0.5, 0.5, -0.5, 0.0, 1.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, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 1.0, 0.5, 0.5, 0.5, 1.0, 1.0, -0.5, 0.5, 0.5, 0.0, 1.0, -0.5, -0.5, 0.5, 0.0, 0.0, -0.5, 0.5, 0.5, 1.0, 0.0, -0.5, 0.5, -0.5, 1.0, 1.0, -0.5, -0.5, -0.5, 0.0, 1.0, -0.5, -0.5, -0.5, 0.0, 1.0, -0.5, -0.5, 0.5, 0.0, 0.0, -0.5, 0.5, 0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 0.0, 0.5, 0.5, -0.5, 1.0, 1.0, 0.5, -0.5, -0.5, 0.0, 1.0, 0.5, -0.5, -0.5, 0.0, 1.0, 0.5, -0.5, 0.5, 0.0, 0.0, 0.5, 0.5, 0.5, 1.0, 0.0, -0.5, -0.5, -0.5, 0.0, 1.0, 0.5, -0.5, -0.5, 1.0, 1.0, 0.5, -0.5, 0.5, 1.0, 0.0, 0.5, -0.5, 0.5, 1.0, 0.0, -0.5, -0.5, 0.5, 0.0, 0.0, -0.5, -0.5, -0.5, 0.0, 1.0, -0.5, 0.5, -0.5, 0.0, 1.0, 0.5, 0.5, -0.5, 1.0, 1.0, 0.5, 0.5, 0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 0.0, -0.5, 0.5, 0.5, 0.0, 0.0, -0.5, 0.5, -0.5, 0.0, 1.0 };
const cube_indices = []c_uint{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 };
const square_xyz = []f32{
0.5, 0.5, 0.0,
0.5, -0.5, 0.0,
-0.5, -0.5, 0.0,
-0.5, 0.5, 0.0,
};
const square_uv = []f32{
1.0, 1.0,
1.0, 0.0,
0.0, 0.0,
0.0, 1.0,
};
const square_indices = []c_uint{
0, 1, 3,
1, 2, 3,
};
pub const TRIANGLE = Shape{
.indices = triangle_indices,
.uv = triangle_vertices,
.xyz = triangle_vertices,
};
pub const SQUARE = Shape{
.indices = square_indices,
.uv = square_uv,
.xyz = square_xyz,
};
pub const CUBE = Shape{
.indices = cube_indices,
.uv = triangle_vertices,
.xyz = triangle_vertices,
};

View File

@@ -1,6 +1,5 @@
#include <bitset>
#include <array>
#include <glm/ext/matrix_transform.hpp>
#include <span>
#include <cstdint>
#include <iostream>
@@ -10,6 +9,7 @@
#include <optional>
#include "glad/glad.h"
#include <glm/ext/matrix_transform.hpp>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtx/quaternion.hpp>

402
src/main.zig Normal file
View File

@@ -0,0 +1,402 @@
const std = @import("std");
const c = @import("c.zig");
const zm = @import("zm");
const Mesh = @import("gfx/Mesh.zig").Mesh;
const ArrayList = std.ArrayList;
fn print_mat(matrix: *const zm.Mat) void {
std.debug.print("{}, {}, {}, {}\n", .{ matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3] });
std.debug.print("{}, {}, {}, {}\n", .{ matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3] });
std.debug.print("{}, {}, {}, {}\n", .{ matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3] });
std.debug.print("{}, {}, {}, {}\n", .{ matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3] });
}
const Camera = struct {
view: zm.Mat = .{ zm.f32x4s(0.0), zm.f32x4s(0.0), zm.f32x4s(0.0), zm.f32x4s(0.0) },
proj: zm.Mat,
pos: zm.Vec = zm.f32x4s(0.0),
up: zm.Vec = zm.f32x4s(0.0),
target: zm.Vec,
pub fn init(self: Camera, aspect_ratio: f32) void {
self.proj = zm.perspectiveFovRh(std.math.degreesToRadians(45.0), aspect_ratio, 0.1, 100.0);
}
pub fn new(aspect_ratio: f32) Camera {
const cam = Camera{};
init(cam, aspect_ratio);
return cam;
}
pub fn look_at(self: Camera, x: f32, y: f32, z: f32) void {
self.target = zm.f32x4(x, y, z, 0.0);
self.view = zm.lookAtRh(self.pos, self.target, self.up);
}
pub fn set_up(self: Camera, up_x: f32, up_y: f32, up_z: f32) void {
self.up = zm.f32x4(up_x, up_y, up_z, 0.0);
}
};
const GlobalAppState = struct {
current_polycube: i32,
last_polycube_visible: i32,
active_shader: ?*Shader,
polycubes: ArrayList(Polycube),
};
const app_state: GlobalAppState = .{};
const WindowDims = struct {
width: u32,
height: u32,
};
const Entity = struct {
mesh: *Mesh,
tex: *Texture,
visible: bool,
scene_graph_node: i32,
};
const SceneGraphNode = struct {
local: zm.Mat,
world: zm.Mat,
translation: zm.Vec,
rotation: zm.Quat,
scale: zm.Vec,
children: ArrayList(i32),
entity: ?i32,
pub fn reset(self: SceneGraphNode) void {
self.scale = zm.f32x4(1.0, 1.0, 1.0, 0.0);
self.translation = zm.f32x4s(0.0);
self.rotation = zm.f32x4s(0.0);
}
pub fn init(self: SceneGraphNode) void {
self.reset();
self.local = zm.identity();
self.world = self.local;
}
pub fn update_local(self: SceneGraphNode) void {
const scaling = zm.scaling(self.scale);
const translation = zm.translation(self.translation);
const rotation = zm.quatToMat(self.rotation);
self.local = zm.mul(zm.mul(translation, rotation), scaling);
self.local = scaling(
zm.translate(
zm.identity(),
self.translation
) * toMat4(self.rotation),
self.scale
);
}
};
const Polycube = struct {
graph_node: i32,
color: zm.Vec,
pub fn show(self: Polycube) void {
const node = get_scene_graph_node(self.graph_node);
for (node.children.items) |child_id| {
const child_node = get_scene_graph_node(child_id);
if (child_node.entity) |entity_id| {
get_entity(entity_id).visible = true;
}
}
}
pub fn hide(self: Polycube) void {
const node = get_scene_graph_node(self.graph_node);
for (node.children.items) |child_id| {
const child_node = get_scene_graph_node(child_id);
if (child_node.entity) |entity_id| {
get_entity(entity_id).visible = false;
}
}
}
pub fn get_centre(self: Polycube) zm.Vec {
const centre = zm.Vec(0.0);
for (get_scene_graph_node(self.graph_node).children.items) |child_id| {
centre += get_scene_graph_node(child_id).translation;
}
centre /= get_scene_graph_node(self.graph_node).children.size();
return centre;
}
};
const Frame = struct {
width: i32,
height: i32,
x: i32,
y: i32,
cam: *Camera,
pub fn new(camera: *Camera, width: i32, height: i32) Frame {
const frame = Frame{};
camera.init(@as(f32, width) / @as(f32, height));
frame.cam = camera;
return frame;
}
};
fn framebuffer_size_callback(width: i32, height: i32) void {
c.glViewport(0, 0, width, height);
}
fn init_window_and_gl(window_dims: *WindowDims) ?*c.GLFWwindow {
c.glfwInit();
c.glfwWindowHint(c.GLFW_CONTEXT_VERSION_MAJOR, 4);
c.glfwWindowHint(c.GLFW_CONTEXT_VERSION_MINOR, 6);
c.glfwWindowHint(c.GLFW_OPENGL_PROFILE, c.GLFW_OPENGL_CORE_PROFILE);
const window = c.glfwCreateWindow(window_dims.width, window_dims.height, "Somaesque", c.NULL, c.NULL);
if (window == c.NULL) {
std.debug.print("Failed to create GLFW window");
c.glfwTerminate();
return null;
}
c.glfwMakeContextCurrent(window);
if (!c.gladLoadGLLoader(@as(c.GLADloadproc, c.glfwGetProcAddress))) {
std.debug.print("Failed to initialize GLAD");
return null;
}
c.glViewport(0, 0, 800, 600);
c.glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
c.glEnable(c.GL_DEPTH_TEST);
return window;
}
fn gl_update_viewport(window_dims: *WindowDims, frame: *Frame) void {
c.glViewport(frame.x, window_dims.height - frame.y - frame.height, frame.width, frame.height);
}
const cube_mesh = Mesh{};
const wall_tex = Texture{};
const entities = ArrayList(Entity);
const scene_graph_nodes = ArrayList(SceneGraphNode);
fn process_input(window: *c.GLFWwindow) void {
const static = struct {
wireframe: bool = false,
last_frame_state_press_enter: bool = false,
last_frame_state_press: bool = false,
};
if (c.glfwGetKey(window, c.GLFW_KEY_ESCAPE) == c.GLFW_PRESS) {
c.glfwSetWindowShouldClose(window, true);
}
if (c.glfwGetKey(window, c.GLFW_KEY_SPACE) == c.GLFW_PRESS and !static.last_frame_state_press) {
c.glPolygonMode(c.GL_FRONT_AND_BACK, if (!static.wireframe) c.GL_LINE else c.GL_FILL);
static.wireframe = !static.wireframe;
static.last_frame_state_press = true;
} else if (c.glfwGetKey(window, c.GLFW_KEY_SPACE) == c.GLFW_RELEASE) {
static.last_frame_state_press = false;
}
if (c.glfwGetKey(window, c.GLFW_KEY_ENTER) == c.GLFW_PRESS and !static.last_frame_state_press_enter) {
if (app_state.current_polycube == 6) {
app_state.current_polycube = 0;
} else {
app_state.current_polycube += 1;
}
static.last_frame_state_press_enter = true;
} else if (c.glfwGetKey(window, c.GLFW_KEY_ENTER) == c.GLFW_RELEASE) {
static.last_frame_state_press_enter = false;
}
}
fn new_entity() i32 {
entities.append(.{});
scene_graph_nodes.append(.{});
entities.items[entities.items.len - 1].scene_graph_node = scene_graph_nodes.items.len;
scene_graph_nodes.items[scene_graph_nodes.items.len - 1].entity = entities.items.len;
return entities.items.len;
}
fn get_entity(id: i32) ?*Entity {
if (entities.items[id - 1]) {
return &entities.items[id - 1];
}
return null;
}
fn get_scene_graph_node(id: i32) *SceneGraphNode {
if (scene_graph_nodes.items[id - 1]) {
return &scene_graph_nodes.items[id - 1];
}
return null;
}
fn new_graph_node() i32 {
scene_graph_nodes.append(.{});
return scene_graph_nodes.items.len;
}
fn draw_entity(entity: *Entity) void {
const modelUniformLoc = c.glGetUniformLocation(app_state.active_shader.prog_id, "model");
c.glUniformMatrix4fv(modelUniformLoc, 1, c.GL_FALSE, &get_scene_graph_node(entity.scene_graph_node).world);
c.glBindTexture(c.GL_TEXTURE_2D, entity.tex.tex_id);
c.glBindVertexArray(entity.mesh.vao);
c.glDrawArrays(c.GL_TRIANGLES, 0, entity.mesh.num_indices);
//c.glDrawElements(c.GL_TRIANGLES, entity.mesh.num_indices, c.GL_UNSIGNED_INT, 0);
}
fn create_polycube_from_repr(repr: *Voxel.Space) Polycube {
const polycube_id = new_graph_node();
get_scene_graph_node(polycube_id).init();
var x: usize = 1;
var y: usize = 1;
var z: usize = 1;
while (x < repr.dim_x) : (x += 1) {
while (y < repr.dim_y) : (y += 1) {
while (z < repr.dim_z) : (z += 1) {
if (Voxel.filledAt(repr, x, y, z)) {
const polycube_segment = get_entity(new_entity());
polycube_segment.mesh = &cube_mesh;
polycube_segment.tex = &wall_tex;
const graph_node = get_scene_graph_node(polycube_segment.scene_graph_node);
graph_node.init();
graph_node.translation = zm.f32x4(
-((repr.dim_z - 1)/2.0) + z,
((repr.dim_x - 1)/2.0) - x,
-((repr.dim_y - 1)/2.0) + y,
0.0,
);
graph_node.update_local();
get_scene_graph_node(polycube_id).children.append(polycube_segment.scene_graph_node);
}
}
}
}
const result = Polycube{
.graph_node = polycube_id,
.color = zm.f32x4s(1.0),
};
return result;
}
fn recalculate_scene_graph(top: *SceneGraphNode) void {
if (top.children.size() == 0) {
return;
}
for (top.children.items) |child_id| {
const graph_node = get_scene_graph_node(child_id);
graph_node.update_local();
graph_node.world = zm.mul(top.world, graph_node.local);
recalculate_scene_graph(graph_node);
}
}
pub fn main() void {
const window_dims = WindowDims{ 800, 600 };
const window = init_window_and_gl(&window_dims);
if (window == null) {
return -1;
}
app_state = GlobalAppState{
.current_polycube=0,
.last_polycube_visible=6,
.active_shader=null,
.polycubes={},
};
const phong_shader = Shader{};
phong_shader.init("../assets/shaders/phong-solid.vertex.glsl", "../assets/shaders/phong-solid.fragment.glsl");
app_state.active_shader = &phong_shader;
cube_mesh.init("../assets/models/c000000.obj");
wall_tex.init("../assets/textures/brick-wall.jpg");
const little_frame = Frame{ .width=80, .height=60, .x=20, .y=20 };
const big_frame = Frame{ .width=800, .height=600, .x=0, .y=0 };
const main_cam = Camera{};
const other_cam = Camera{};
little_frame.init(&other_cam);
big_frame.init(&main_cam);
const frames = [_]*Frame{ &big_frame, &little_frame };
const root_node = SceneGraphNode{};
root_node.init();
var i: usize = 0;
while (i < SomaSolve.STD_SOMA.items.len) : (i += 1) {
const voxel_space = voxel.Space{ SomaSolve.STD_SOMA[i], 3, 3, 3 };
voxel.cullEmptySpace(&voxel_space);
const polycube = create_polycube_from_repr(&voxel_space);
polycube.color = color.color_from_index(i);
app_state.polycubes.append(polycube);
root_node.children.append(app_state.polycubes.items[app_state.polycubes.items.len - 1].graph_node);
}
main_cam.pos = zm.f32x4(4.0, 4.0, 4.0, 0.0);
main_cam.look_at(0.0, 0.0, 0.0);
const light_pos = zm.f32x4(6.0, 6.0, 6.0, 0.0);
c.glUseProgram(app_state.active_shader.prog_id);
const view_loc = c.glGetUniformLocation(app_state.active_shader.prog_id, "view");
const proj_loc = c.glGetUniformLocation(app_state.active_shader.prog_id, "projection");
const light_pos_loc = c.glGetUniformLocation(app_state.active_shader.prog_id, "light_pos");
c.glUniform3fv(light_pos_loc, 1, &light_pos);
c.glUniformMatrix4fv(proj_loc, 1, GL_FALSE, &main_cam.proj);
c.glUniformMatrix4fv(view_loc, 1, GL_FALSE, &main_cam.view);
var last_frame = c.glfwGetTime();
var time_delta = 1.0/60.0;
while (!c.glfwWindowShouldClose(window)) {
time_delta = c.glfwGetTime() - last_frame;
process_input(window);
if (app_state.last_polycube_visible != app_state.current_polycube) {
app_state.polycubes[app_state.last_polycube_visible].hide();
app_state.polycubes[app_state.current_polycube].show();
app_state.last_polycube_visible = app_state.current_polycube;
}
c.glClearColor(0.0, 0.0, 0.0, 1.0);
c.glClear(c.GL_DEPTH_BUFFER_BIT | c.GL_COLOR_BUFFER_BIT);
c.gl_update_viewport(&window_dims, &big_frame);
const current_polycube = &app_state.polycubes[app_state.current_polycube];
c.get_scene_graph_node(current_polycube.graph_node).rotation = zm.quatFromRollPitchYaw(0.0, c.glfwGetTime() / 2.0, 0.0);
c.glBindVertexArray(cube_mesh.vao);
//glBindTexture(GL_TEXTURE_2D, entity.tex->tex_id);
recalculate_scene_graph(&root_node);
const model_uniform_loc = c.glGetUniformLocation(app_state.active_shader.prog_id, "model");
const solid_color_loc = c.glGetUniformLocation(app_state.active_shader.prog_id, "solid_color");
c.glUniform3fv(solid_color_loc, 1, &current_polycube.color);
while (entities.items) |entity| {
if (entity.visible) {
c.glUniformMatrix4fv(model_uniform_loc, 1, c.GL_FALSE, &get_scene_graph_node(entity.scene_graph_node).world);
c.glDrawArrays(c.GL_TRIANGLES, 0, entity.mesh.num_indices);
//glDrawElements(GL_TRIANGLES, entity->mesh->num_indices, GL_UNSIGNED_INT, 0);
}
}
c.glfwSwapBuffers(window);
c.glfwPollEvents();
}
c.glfwTerminate();
return 0;
}
//test "simple test" {
// var list = std.ArrayList(i32).init(std.testing.allocator);
// defer list.deinit(); // try commenting this out and see if zig detects the memory leak!
// try list.append(42);
// try std.testing.expectEqual(@as(i32, 42), list.pop());
//}