aboutsummaryrefslogtreecommitdiff
path: root/mons_exe/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'mons_exe/src/main.c')
-rw-r--r--mons_exe/src/main.c247
1 files changed, 247 insertions, 0 deletions
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;
+}