aboutsummaryrefslogtreecommitdiff
path: root/mons_exe
diff options
context:
space:
mode:
Diffstat (limited to 'mons_exe')
-rw-r--r--mons_exe/CMakeLists.txt36
-rw-r--r--mons_exe/embed/shaders/basic.vert.glsl26
-rw-r--r--mons_exe/embed/shaders/basic_lit.frag.glsl27
-rwxr-xr-xmons_exe/embed_headers.sh10
-rw-r--r--mons_exe/include/embedded/shaders/basic.vert.glsl.h64
-rw-r--r--mons_exe/include/embedded/shaders/basic_lit.frag.glsl.h65
-rw-r--r--mons_exe/include/input.h113
-rw-r--r--mons_exe/src/input.c0
-rw-r--r--mons_exe/src/main.c247
9 files changed, 588 insertions, 0 deletions
diff --git a/mons_exe/CMakeLists.txt b/mons_exe/CMakeLists.txt
new file mode 100644
index 0000000..103d1d4
--- /dev/null
+++ b/mons_exe/CMakeLists.txt
@@ -0,0 +1,36 @@
+cmake_minimum_required(VERSION 3.14)
+project(mons_exe LANGUAGES C)
+set(CMAKE_C_STANDARD 99)
+set(CMAKE_EXPORT_COMPILE_COMMANDS true)
+set(CMAKE_BUILD_TYPE "Debug")
+
+add_custom_target(hexdump_embeds
+ ./embed_headers.sh
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+)
+
+add_executable(mons_exe
+ ./src/main.c
+ ./src/input.c
+)
+
+target_include_directories(mons_exe PUBLIC
+ "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/include"
+ "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
+)
+target_compile_options(mons_exe PRIVATE -coverage)
+target_link_options(mons_exe PRIVATE -coverage)
+target_link_libraries(mons_exe PUBLIC mons_3d mons_gltf X11)
+add_dependencies(mons_exe hexdump_embeds)
+
+include(CTest)
+
+function(TESTCASE NAME)
+ add_executable(test_${NAME} ./tests/${NAME}.c)
+ target_link_libraries(test_${NAME} PUBLIC mons_exe)
+ add_test(
+ NAME ${NAME}
+ COMMAND $<TARGET_FILE:test_${NAME}>
+ )
+endfunction()
+
diff --git a/mons_exe/embed/shaders/basic.vert.glsl b/mons_exe/embed/shaders/basic.vert.glsl
new file mode 100644
index 0000000..8164120
--- /dev/null
+++ b/mons_exe/embed/shaders/basic.vert.glsl
@@ -0,0 +1,26 @@
+#version 460 core
+layout (location = 0) in vec3 aPos;
+layout (location = 1) in vec3 aNormal;
+layout (location = 2) in vec4 aTangent;
+layout (location = 3) in vec2 aTexCoord;
+
+out vec3 Normal;
+out vec2 TexCoord;
+out vec3 FragPos;
+out mat3 TBN;
+
+uniform mat4 transform;
+uniform mat4 view;
+uniform mat4 projection;
+
+void main() {
+ gl_Position = projection * view * transform * vec4(aPos, 1.0);
+ FragPos = vec3(transform * vec4(aPos, 1.0));
+ Normal = mat3(transpose(inverse(transform))) * aNormal;
+ TexCoord = aTexCoord;
+
+ vec3 T = normalize(vec3(transform * vec4(aTangent.xyz, 0.0)));
+ vec3 N = normalize(vec3(transform * vec4(aNormal, 0.0)));
+ vec3 B = aTangent.w * cross(N, T);
+ TBN = mat3(T,B,N);
+}
diff --git a/mons_exe/embed/shaders/basic_lit.frag.glsl b/mons_exe/embed/shaders/basic_lit.frag.glsl
new file mode 100644
index 0000000..467174c
--- /dev/null
+++ b/mons_exe/embed/shaders/basic_lit.frag.glsl
@@ -0,0 +1,27 @@
+#version 460 core
+out vec4 FragColor;
+
+in vec3 Normal;
+in vec2 TexCoord;
+in vec3 FragPos;
+in mat3 TBN;
+
+uniform float ambient_strength;
+uniform sampler2D base_texture;
+uniform sampler2D normal_texture;
+
+uniform vec4 light_color;
+uniform vec3 light_position;
+
+void main() {
+ vec4 base_color = texture(base_texture, TexCoord);
+ vec3 normal = texture(normal_texture, TexCoord).rgb;
+ normal = normal * 2.0 - 1.0;
+ normal = normalize(TBN * normal);
+ vec3 light_direction = normalize(light_position - FragPos);
+ float diff = max(dot(normal, light_direction), 0.0);
+ vec4 diffuse_color = diff * light_color;
+ vec4 ambient_color = ambient_strength * light_color;
+
+ FragColor = (ambient_color + diffuse_color) * base_color;
+}
diff --git a/mons_exe/embed_headers.sh b/mons_exe/embed_headers.sh
new file mode 100755
index 0000000..fdbea13
--- /dev/null
+++ b/mons_exe/embed_headers.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+rm -rf ./include/embedded/
+for file in $(find ./embed -type f); do
+ basepath="${file#*/*/}"
+ basedir="${basepath%/*}"
+ mkdir -p "./include/embedded/$basedir"
+ echo "Generating ./include/embedded/$basepath.h"
+ xxd -i "$file" "./include/embedded/$basepath.h"
+done
diff --git a/mons_exe/include/embedded/shaders/basic.vert.glsl.h b/mons_exe/include/embedded/shaders/basic.vert.glsl.h
new file mode 100644
index 0000000..932d8e1
--- /dev/null
+++ b/mons_exe/include/embedded/shaders/basic.vert.glsl.h
@@ -0,0 +1,64 @@
+unsigned char __embed_shaders_basic_vert_glsl[] = {
+ 0x23, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x34, 0x36, 0x30,
+ 0x20, 0x63, 0x6f, 0x72, 0x65, 0x0a, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74,
+ 0x20, 0x28, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d,
+ 0x20, 0x30, 0x29, 0x20, 0x69, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20,
+ 0x61, 0x50, 0x6f, 0x73, 0x3b, 0x0a, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74,
+ 0x20, 0x28, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d,
+ 0x20, 0x31, 0x29, 0x20, 0x69, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20,
+ 0x61, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x3b, 0x0a, 0x6c, 0x61, 0x79,
+ 0x6f, 0x75, 0x74, 0x20, 0x28, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x20, 0x3d, 0x20, 0x32, 0x29, 0x20, 0x69, 0x6e, 0x20, 0x76, 0x65,
+ 0x63, 0x34, 0x20, 0x61, 0x54, 0x61, 0x6e, 0x67, 0x65, 0x6e, 0x74, 0x3b,
+ 0x0a, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x20, 0x28, 0x6c, 0x6f, 0x63,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x33, 0x29, 0x20, 0x69,
+ 0x6e, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x61, 0x54, 0x65, 0x78, 0x43,
+ 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x20, 0x76,
+ 0x65, 0x63, 0x33, 0x20, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x3b, 0x0a,
+ 0x6f, 0x75, 0x74, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x54, 0x65, 0x78,
+ 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x6f, 0x75, 0x74, 0x20, 0x76,
+ 0x65, 0x63, 0x33, 0x20, 0x46, 0x72, 0x61, 0x67, 0x50, 0x6f, 0x73, 0x3b,
+ 0x0a, 0x6f, 0x75, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x33, 0x20, 0x54, 0x42,
+ 0x4e, 0x3b, 0x0a, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20,
+ 0x6d, 0x61, 0x74, 0x34, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f,
+ 0x72, 0x6d, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20,
+ 0x6d, 0x61, 0x74, 0x34, 0x20, 0x76, 0x69, 0x65, 0x77, 0x3b, 0x0a, 0x75,
+ 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x20,
+ 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a,
+ 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29,
+ 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f,
+ 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x70, 0x72, 0x6f,
+ 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x2a, 0x20, 0x76, 0x69,
+ 0x65, 0x77, 0x20, 0x2a, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f,
+ 0x72, 0x6d, 0x20, 0x2a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x61, 0x50,
+ 0x6f, 0x73, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20,
+ 0x20, 0x20, 0x46, 0x72, 0x61, 0x67, 0x50, 0x6f, 0x73, 0x20, 0x3d, 0x20,
+ 0x76, 0x65, 0x63, 0x33, 0x28, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f,
+ 0x72, 0x6d, 0x20, 0x2a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x61, 0x50,
+ 0x6f, 0x73, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x3b, 0x0a, 0x20,
+ 0x20, 0x20, 0x20, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x20, 0x3d, 0x20,
+ 0x6d, 0x61, 0x74, 0x33, 0x28, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f,
+ 0x73, 0x65, 0x28, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x65, 0x28, 0x74,
+ 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x29, 0x29, 0x29, 0x20,
+ 0x2a, 0x20, 0x61, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x3b, 0x0a, 0x20,
+ 0x20, 0x20, 0x20, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x20,
+ 0x3d, 0x20, 0x61, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x3b,
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65,
+ 0x63, 0x33, 0x20, 0x54, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61,
+ 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x76, 0x65, 0x63, 0x33, 0x28, 0x74, 0x72,
+ 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x2a, 0x20, 0x76, 0x65,
+ 0x63, 0x34, 0x28, 0x61, 0x54, 0x61, 0x6e, 0x67, 0x65, 0x6e, 0x74, 0x2e,
+ 0x78, 0x79, 0x7a, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x29, 0x29, 0x3b,
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x4e, 0x20,
+ 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28,
+ 0x76, 0x65, 0x63, 0x33, 0x28, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f,
+ 0x72, 0x6d, 0x20, 0x2a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x61, 0x4e,
+ 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x29,
+ 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20,
+ 0x42, 0x20, 0x3d, 0x20, 0x61, 0x54, 0x61, 0x6e, 0x67, 0x65, 0x6e, 0x74,
+ 0x2e, 0x77, 0x20, 0x2a, 0x20, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x28, 0x4e,
+ 0x2c, 0x20, 0x54, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x54, 0x42,
+ 0x4e, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x33, 0x28, 0x54, 0x2c, 0x42,
+ 0x2c, 0x4e, 0x29, 0x3b, 0x0a, 0x7d, 0x0a
+};
+unsigned int __embed_shaders_basic_vert_glsl_len = 727;
diff --git a/mons_exe/include/embedded/shaders/basic_lit.frag.glsl.h b/mons_exe/include/embedded/shaders/basic_lit.frag.glsl.h
new file mode 100644
index 0000000..766f7b5
--- /dev/null
+++ b/mons_exe/include/embedded/shaders/basic_lit.frag.glsl.h
@@ -0,0 +1,65 @@
+unsigned char __embed_shaders_basic_lit_frag_glsl[] = {
+ 0x23, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x34, 0x36, 0x30,
+ 0x20, 0x63, 0x6f, 0x72, 0x65, 0x0a, 0x6f, 0x75, 0x74, 0x20, 0x76, 0x65,
+ 0x63, 0x34, 0x20, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72,
+ 0x3b, 0x0a, 0x0a, 0x69, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x4e,
+ 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x3b, 0x0a, 0x69, 0x6e, 0x20, 0x76, 0x65,
+ 0x63, 0x32, 0x20, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x3b,
+ 0x0a, 0x69, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x46, 0x72, 0x61,
+ 0x67, 0x50, 0x6f, 0x73, 0x3b, 0x0a, 0x69, 0x6e, 0x20, 0x6d, 0x61, 0x74,
+ 0x33, 0x20, 0x54, 0x42, 0x4e, 0x3b, 0x0a, 0x0a, 0x75, 0x6e, 0x69, 0x66,
+ 0x6f, 0x72, 0x6d, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x6d,
+ 0x62, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x6e, 0x67,
+ 0x74, 0x68, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20,
+ 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x62, 0x61,
+ 0x73, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x3b, 0x0a,
+ 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70,
+ 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c,
+ 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x3b, 0x0a, 0x0a, 0x75,
+ 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20,
+ 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3b,
+ 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x76, 0x65, 0x63,
+ 0x33, 0x20, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x69,
+ 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20,
+ 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20,
+ 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63,
+ 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75,
+ 0x72, 0x65, 0x28, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74,
+ 0x75, 0x72, 0x65, 0x2c, 0x20, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72,
+ 0x64, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33,
+ 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x74, 0x65,
+ 0x78, 0x74, 0x75, 0x72, 0x65, 0x28, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c,
+ 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x54, 0x65,
+ 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x29, 0x2e, 0x72, 0x67, 0x62, 0x3b,
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x20,
+ 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x20, 0x2a, 0x20, 0x32,
+ 0x2e, 0x30, 0x20, 0x2d, 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20,
+ 0x20, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x6e,
+ 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x54, 0x42, 0x4e,
+ 0x20, 0x2a, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x29, 0x3b, 0x0a,
+ 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x6c, 0x69, 0x67,
+ 0x68, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+ 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65,
+ 0x28, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74,
+ 0x69, 0x6f, 0x6e, 0x20, 0x2d, 0x20, 0x46, 0x72, 0x61, 0x67, 0x50, 0x6f,
+ 0x73, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61,
+ 0x74, 0x20, 0x64, 0x69, 0x66, 0x66, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x78,
+ 0x28, 0x64, 0x6f, 0x74, 0x28, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x2c,
+ 0x20, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x3b,
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x64, 0x69,
+ 0x66, 0x66, 0x75, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20,
+ 0x3d, 0x20, 0x64, 0x69, 0x66, 0x66, 0x20, 0x2a, 0x20, 0x6c, 0x69, 0x67,
+ 0x68, 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x20, 0x20,
+ 0x20, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x61, 0x6d, 0x62, 0x69, 0x65,
+ 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x61,
+ 0x6d, 0x62, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x6e,
+ 0x67, 0x74, 0x68, 0x20, 0x2a, 0x20, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f,
+ 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20,
+ 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20,
+ 0x28, 0x61, 0x6d, 0x62, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6c,
+ 0x6f, 0x72, 0x20, 0x2b, 0x20, 0x64, 0x69, 0x66, 0x66, 0x75, 0x73, 0x65,
+ 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x29, 0x20, 0x2a, 0x20, 0x62, 0x61,
+ 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x7d, 0x0a
+};
+unsigned int __embed_shaders_basic_lit_frag_glsl_len = 744;
diff --git a/mons_exe/include/input.h b/mons_exe/include/input.h
new file mode 100644
index 0000000..533b7e6
--- /dev/null
+++ b/mons_exe/include/input.h
@@ -0,0 +1,113 @@
+#ifndef MONS_INPUT_H
+#define MONS_INPUT_H
+
+#include <stdbool.h>
+
+typedef enum mons_keycode {
+ MONS_KEY_A = 38,
+ MONS_KEY_B = 56,
+ MONS_KEY_C = 54,
+ MONS_KEY_D = 40,
+ MONS_KEY_E = 26,
+ MONS_KEY_F = 41,
+ MONS_KEY_G = 42,
+ MONS_KEY_H = 43,
+ MONS_KEY_I = 31,
+ MONS_KEY_J = 44,
+ MONS_KEY_K = 45,
+ MONS_KEY_L = 46,
+ MONS_KEY_M = 58,
+ MONS_KEY_N = 57,
+ MONS_KEY_O = 32,
+ MONS_KEY_P = 33,
+ MONS_KEY_Q = 24,
+ MONS_KEY_R = 27,
+ MONS_KEY_S = 39,
+ MONS_KEY_T = 28,
+ MONS_KEY_U = 30,
+ MONS_KEY_V = 55,
+ MONS_KEY_W = 25,
+ MONS_KEY_X = 53,
+ MONS_KEY_Y = 29,
+ MONS_KEY_Z = 52,
+ MONS_KEY_1 = 10,
+ MONS_KEY_2 = 11,
+ MONS_KEY_3 = 12,
+ MONS_KEY_4 = 13,
+ MONS_KEY_5 = 14,
+ MONS_KEY_6 = 15,
+ MONS_KEY_7 = 16,
+ MONS_KEY_8 = 17,
+ MONS_KEY_9 = 18,
+ MONS_KEY_0 = 19,
+ MONS_KEY_F1 = 67,
+ MONS_KEY_F2 = 68,
+ MONS_KEY_F3 = 69,
+ MONS_KEY_F4 = 70,
+ MONS_KEY_F5 = 71,
+ MONS_KEY_F6 = 72,
+ MONS_KEY_F7 = 73,
+ MONS_KEY_F8 = 74,
+ MONS_KEY_F9 = 75,
+ MONS_KEY_F10 = 76,
+ MONS_KEY_F11 = 95,
+ MONS_KEY_F12 = 96,
+ MONS_KEY_ESCAPE = 9,
+ MONS_KEY_UP = 111,
+ MONS_KEY_DOWN = 116,
+ MONS_KEY_LEFT = 113,
+ MONS_KEY_RIGHT = 114,
+ MONS_KEY_GRAVE = 49,
+ MONS_KEY_TAB = 23,
+ MONS_KEY_CAPSLOCK = 66,
+ MONS_KEY_LSHIFT = 50,
+ MONS_KEY_RSHIFT = 62,
+ MONS_KEY_LCTRL = 37,
+ MONS_KEY_RCTRL = 105,
+ MONS_KEY_LSUPER = 133,
+ MONS_KEY_RSUPER = 134,
+ MONS_KEY_LMETA = 64,
+ MONS_KEY_RMETA = 108,
+ MONS_KEY_SPACE = 65,
+ MONS_KEY_MENU = 135,
+ MONS_KEY_ENTER = 36,
+ MONS_KEY_BACKSLASH = 51,
+ MONS_KEY_SLASH = 61,
+ MONS_KEY_COMMA = 59,
+ MONS_KEY_PERIOD = 60,
+ MONS_KEY_SEMICOLON = 47,
+ MONS_KEY_QUOTE = 48,
+ MONS_KEY_LBRACKET = 34,
+ MONS_KEY_RBRACKET = 35,
+ MONS_KEY_MINUS = 20,
+ MONS_KEY_EQUAL = 21,
+ MONS_KEY_BACKSPACE = 22,
+ MONS_KEY_PRINT = 107,
+ MONS_KEY_SCROLLLOCK = 78,
+ MONS_KEY_PAUSE = 127,
+ MONS_KEY_INSERT = 118,
+ MONS_KEY_DELETE = 119,
+ MONS_KEY_HOME = 110,
+ MONS_KEY_END = 115,
+ MONS_KEY_PREV = 112,
+ MONS_KEY_NEXT = 117,
+ MONS_KEY_NUMLOCK = 77,
+ MONS_KEY_NUMPAD_1 = 87,
+ MONS_KEY_NUMPAD_2 = 88,
+ MONS_KEY_NUMPAD_3 = 89,
+ MONS_KEY_NUMPAD_4 = 83,
+ MONS_KEY_NUMPAD_5 = 84,
+ MONS_KEY_NUMPAD_6 = 85,
+ MONS_KEY_NUMPAD_7 = 79,
+ MONS_KEY_NUMPAD_8 = 80,
+ MONS_KEY_NUMPAD_9 = 81,
+ MONS_KEY_NUMPAD_0 = 90,
+ MONS_KEY_NUMPAD_DIV = 106,
+ MONS_KEY_NUMPAD_MUL = 63,
+ MONS_KEY_NUMPAD_MINUS = 82,
+ MONS_KEY_NUMPAD_PLUS = 86,
+ MONS_KEY_NUMPAD_DELETE = 91,
+ MONS_KEY_NUMPAD_ENTER = 104,
+} mons_keycode;
+
+#endif
diff --git a/mons_exe/src/input.c b/mons_exe/src/input.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mons_exe/src/input.c
diff --git a/mons_exe/src/main.c b/mons_exe/src/main.c
new file mode 100644
index 0000000..fab3b8d
--- /dev/null
+++ b/mons_exe/src/main.c
@@ -0,0 +1,247 @@
+#include <stdio.h>
+#include <time.h>
+#include <stdlib.h>
+#include <math.h>
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include "glad/gl.h"
+#include "glad/glx.h"
+#include "vertex.h"
+#include "mons_math/vec4.h"
+#include "mons_math/quat.h"
+#include "embedded/shaders/basic.vert.glsl.h"
+#include "embedded/shaders/basic_lit.frag.glsl.h"
+#include "shader.h"
+#include "mesh.h"
+#include "qoi.h"
+#include "texture.h"
+#include "transform.h"
+#include "model.h"
+#include "projection.h"
+#include "json.h"
+#include "hashmap.h"
+#include "gltf.h"
+#include "input.h"
+#include "camera.h"
+#include <memory.h>
+#include "color.h"
+#include "light.h"
+
+struct timespec current_time;
+double delta_time = 0;
+
+int main(void) {
+ // Make Window
+ Display *display = XOpenDisplay(NULL);
+ if (display == NULL) {
+ printf("Cannot connect to X server\n");
+ return EXIT_FAILURE;
+ }
+
+ int screen = DefaultScreen(display);
+
+ int glx_version = gladLoaderLoadGLX(display, screen);
+ if (!glx_version) {
+ printf("Unable to load GLX\n");
+ return EXIT_FAILURE;
+ }
+ printf("Loaded GLX %d.%d\n", GLAD_VERSION_MAJOR(glx_version),
+ GLAD_VERSION_MINOR(glx_version));
+
+ Window root = RootWindow(display, screen);
+
+ GLint visual_attributes[] = {GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 24,
+ None};
+ XVisualInfo *visual_info =
+ glXChooseVisual(display, screen, visual_attributes);
+
+ Colormap colormap =
+ XCreateColormap(display, root, visual_info->visual, AllocNone);
+
+ XSetWindowAttributes attributes;
+ attributes.event_mask =
+ ExposureMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask;
+ attributes.colormap = colormap;
+
+ Window window = XCreateWindow(
+ display, root, 0, 0, 640, 480, 0, visual_info->depth, InputOutput,
+ visual_info->visual, CWColormap | CWEventMask, &attributes);
+
+ // XSizeHints hints = {
+ // .flags = PMinSize | PMaxSize,
+ // .min_width = 640,
+ // .min_height = 480,
+ // .max_width = 640,
+ // .max_height = 480,
+ // };
+ // XSetWMNormalHints(display, window, &hints);
+ XMapWindow(display, window);
+ XStoreName(display, window, "Hello World!");
+
+ if (!window) {
+ printf("Unable to create window\n");
+ return EXIT_FAILURE;
+ }
+
+ GLXContext context = glXCreateContext(display, visual_info, NULL, GL_TRUE);
+ glXMakeCurrent(display, window, context);
+
+ // Load GL
+ int version = gladLoaderLoadGL();
+ if (!version) {
+ printf("Unable to load GL\n");
+ return EXIT_FAILURE;
+ }
+ printf("Loaded GL %d.%d\n", GLAD_VERSION_MAJOR(version),
+ GLAD_VERSION_MINOR(version));
+
+ XWindowAttributes gwa;
+ XGetWindowAttributes(display, window, &gwa);
+ glViewport(0, 0, gwa.width, gwa.height);
+
+ // Setup Shaders
+ mons_shader vertex_shader = mons_create_shader(
+ MONS_SHADER_TYPE_VERTEX, (char *)__embed_shaders_basic_vert_glsl,
+ __embed_shaders_basic_vert_glsl_len);
+ mons_shader fragment_shader = mons_create_shader(
+ MONS_SHADER_TYPE_FRAGMENT, (char *)__embed_shaders_basic_lit_frag_glsl,
+ __embed_shaders_basic_lit_frag_glsl_len);
+ mons_program shader_program =
+ mons_create_program(vertex_shader, fragment_shader);
+
+ FILE *texture_file = fopen("test.qoi", "rb");
+ mons_texture texture = mons_texture_load(texture_file);
+
+ mons_camera camera = {
+ .projection =
+ {
+ .near = 0.01f,
+ .far = 100.0f,
+ .fov = M_PI / 4.0f,
+ .aspect_ratio = gwa.width / (float)gwa.height,
+ },
+ .transform = {
+ .translation = mons_vec3_mul_i(MONS_VEC3_Z, 3),
+ .rotation = MONS_QUAT_IDENTITY,
+ .scale = MONS_VEC3_ONE, }}; clock_gettime(CLOCK_MONOTONIC_RAW, &current_time);
+ mons_model *models = NULL;
+ int model_count = 0;
+ mons_load_gltf("marble_bust/marble_bust_01_4k.gltf", shader_program,
+ &models, &model_count);
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+
+ mons_directional_light light = {
+ .transform = (mons_transform) {
+ .translation = (mons_vec3) { 0.0f, 0.0f, 3.0f },
+ .rotation = MONS_QUAT_IDENTITY,
+ .scale = MONS_VEC3_ONE,
+ },
+ .color = MONS_COLOR_WHITE,
+ };
+ mons_shader_set_vec4_global("light_color", light.color);
+ mons_shader_set_vec3_global("light_position", light.transform.translation);
+
+ float ambient_light = 0.1f;
+ mons_shader_set_float_global("ambient_strength", ambient_light);
+
+ // Main Loop
+ bool key_pressed[256] = {false};
+ bool key_just_pressed[256] = {false};
+ bool quit = false;
+ while (!quit) {
+ memset(key_just_pressed, false, 256);
+ while (XPending(display)) {
+ XEvent xev;
+ XNextEvent(display, &xev);
+ switch (xev.type) {
+ case KeyPress:
+ key_pressed[xev.xkey.keycode] = true;
+ key_just_pressed[xev.xkey.keycode] = true;
+ break;
+ case KeyRelease:
+ key_pressed[xev.xkey.keycode] = false;
+ break;
+ case ConfigureNotify:
+ if (xev.xconfigure.window == window) {
+ camera.projection.aspect_ratio =
+ xev.xconfigure.width / (float)xev.xconfigure.height;
+ glViewport(0, 0, xev.xconfigure.width,
+ xev.xconfigure.height);
+ }
+ default:
+ break;
+ }
+ }
+
+ glClearColor(0.0, 0.0, 0.0, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ struct timespec new_time;
+ clock_gettime(CLOCK_MONOTONIC_RAW, &new_time);
+ delta_time = (new_time.tv_sec - current_time.tv_sec) +
+ (new_time.tv_nsec - current_time.tv_nsec) / 1.0e9;
+ current_time = new_time;
+
+ mons_shader_set_mat4_global("view", mons_mat4_inverse(mons_transform_matrix(camera.transform)), GL_TRUE);
+ mons_shader_set_mat4_global("projection", mons_projection_matrix(camera.projection), GL_FALSE);
+ for (int i = 0; i < model_count; i++) {
+ mons_model_draw(models[i]);
+ mons_transform_rotate(&models[i].transform, mons_quat_from_axis_angle(MONS_VEC3_Y, (M_PI / 4.0f) * delta_time));
+ }
+
+ glBindVertexArray(0);
+
+
+ if (key_pressed[MONS_KEY_ESCAPE]) {
+ quit = true;
+ }
+
+ int x_axis_input = key_pressed[MONS_KEY_D] - key_pressed[MONS_KEY_A];
+ mons_transform_translate(
+ &camera.transform,
+ mons_vec3_mul_f(mons_transform_right(camera.transform), delta_time * x_axis_input));
+ int y_axis_input =
+ key_pressed[MONS_KEY_SPACE] - key_pressed[MONS_KEY_LSHIFT];
+ mons_transform_translate(
+ &camera.transform,
+ mons_vec3_mul_f(mons_transform_up(camera.transform), delta_time * y_axis_input));
+ int z_axis_input = key_pressed[MONS_KEY_W] - key_pressed[MONS_KEY_S];
+ mons_transform_translate(
+ &camera.transform,
+ mons_vec3_mul_f(mons_transform_forward(camera.transform), delta_time * -z_axis_input));
+ int y_rot_input =
+ key_pressed[MONS_KEY_RIGHT] - key_pressed[MONS_KEY_LEFT];
+ mons_transform_rotate(
+ &camera.transform,
+ mons_quat_from_axis_angle(MONS_VEC3_Y,
+ -M_PI / 2.0f * y_rot_input * delta_time));
+ int x_rot_input = key_pressed[MONS_KEY_UP] - key_pressed[MONS_KEY_DOWN];
+ mons_transform_rotate(
+ &camera.transform,
+ mons_quat_from_axis_angle(MONS_VEC3_X,
+ M_PI / 2.0f * x_rot_input * delta_time));
+
+ int fov_input = key_pressed[MONS_KEY_MINUS] - key_pressed[MONS_KEY_EQUAL];
+ camera.projection.fov += (fov_input * M_PI / 8.0 * delta_time);
+ if(key_just_pressed[MONS_KEY_BACKSPACE]) {
+ mons_transform_look_at(&camera.transform, MONS_VEC3_ZERO, MONS_VEC3_Y);
+ }
+ glXSwapBuffers(display, window);
+ }
+
+ glDeleteShader(vertex_shader);
+ glDeleteShader(fragment_shader);
+
+ glXMakeCurrent(display, 0, 0);
+ glXDestroyContext(display, context);
+
+ XDestroyWindow(display, window);
+ XFreeColormap(display, colormap);
+ XCloseDisplay(display);
+
+ gladLoaderUnloadGLX();
+
+ return EXIT_SUCCESS;
+}