adding gfx and ui stuff

This commit is contained in:
Daniel Ledda
2026-06-04 18:22:30 +02:00
parent d676c50961
commit 4dfac3f82f
48 changed files with 26734 additions and 3 deletions

211
gfx/main.c Normal file
View File

@@ -0,0 +1,211 @@
// Library initialisation
#define RAYMATH_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#define STB_TRUETYPE_IMPLEMENTATION
#define TINYOBJ_LOADER_C_IMPLEMENTATION
// Project
#include "lib/djstdlib/core.c"
#include "gfx/gfx.c"
#include "world/world.c"
#include "ui.c"
#include "render.c"
#include "debug.c"
// Graphics bindings and libs
#include "lib/raymath.h"
#include "lib/glad/glad.c"
#include "GLFW/glfw3.h"
typedef struct Frame Frame;
struct Frame {
uint32 width;
uint32 height;
int32 x;
int32 y;
Camera cam;
};
typedef struct GlobalState GlobalState;
struct GlobalState {
struct {
GLFWwindow *handle;
int32 width;
int32 height;
struct {
GLFWcursor *pointer;
GLFWcursor *arrow;
GLFWcursor *forbidden;
} cursors;
} window;
UI_Context *ui;
};
void framebufferSizeCallback(GLFWwindow *window, int width, int height) {
Soma *soma = (Soma *)glfwGetWindowUserPointer(window);
soma->renderer->width = width;
soma->renderer->height = height;
}
GLFWwindow *initWindowAndGL(uint32 windowWidth, uint32 windowHeight) {
if (!glfwInit()) {
return NULL;
}
#ifdef GLFW_WAYLAND_APP_ID
glfwWindowHintString(GLFW_WAYLAND_APP_ID, "Somaesque");
#endif
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_SAMPLES, 4);
GLFWwindow *window = glfwCreateWindow(
windowWidth,
windowHeight,
#ifdef DJSTDLIB_DEBUG
"Somaesque (djstdlib_debug)",
#else
"Somaesque",
#endif
NULL,
NULL);
if (window == NULL) {
print("Failed to create GLFW window\n");
glfwTerminate();
return NULL;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
print("Failed to initilaize GLAD\n");
return NULL;
}
glViewport(0, 0, windowWidth, windowHeight);
glfwSwapInterval(1);
glfwSetInputMode(window, GLFW_CURSOR | GLFW_RAW_MOUSE_MOTION, GLFW_CURSOR_NORMAL);
glfwSetWindowSize(window, windowWidth, windowHeight);
glEnable(GL_DEPTH_TEST);
glEnable(GL_MULTISAMPLE);
return window;
}
static void onMouseScroll(GLFWwindow *window, real64 deltaX, real64 deltaY) {
Soma *soma = (Soma *)glfwGetWindowUserPointer(window);
soma->ui->input->mouse.scroll.dX += deltaX;
soma->ui->input->mouse.scroll.dY += deltaY;
}
static void updateWindow(Soma *soma) {
glfwGetWindowSize(soma->window.handle, &soma->window.width, &soma->window.height);
soma->renderer->width = soma->window.width;
soma->renderer->height = soma->window.height;
}
const int32 TARGET_FPS = 144;
void APIENTRY glDebugCallback(GLenum source, GLenum type, GLuint id,
GLenum severity, GLsizei length,
const GLchar* message, const void* userParam)
{
fprintf(stderr, "GL: %s\n", message);
}
int mainGfx() {
Arena *arena = arenaAlloc(Megabytes(128));
Arena *solutionsArena = arenaAlloc(Megabytes(128));
int32 winWidth = 800;
int32 winHeight = 600;
GLFWwindow *windowHandle = initWindowAndGL(winWidth, winHeight);
if (!windowHandle) {
return 1;
}
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback(glDebugCallback, NULL);
Scene mainScene = createScene(arena);
Camera cam = createCamera(winWidth, winHeight);
Renderer renderer = createRenderer(arena, &mainScene, &cam, createSceneGraphNode(&mainScene));
renderer.solidShader = &solidColorShader;
renderer.phongShader = &phongShader;
renderer.cubeMesh = &cubeMesh;
Arena *uiArena = arenaAlloc(Megabytes(64));
UI_Context ui = ui_initContext(uiArena, &renderer);
glfwSetWindowUserPointer(windowHandle, &soma);
glfwSetFramebufferSizeCallback(windowHandle, framebufferSizeCallback);
glfwSetScrollCallback(windowHandle, onMouseScroll);
// Render loop
real64 lastFrame = glfwGetTime();
real64 timeDelta = 1.0f / TARGET_FPS;
real64 frameStart = lastFrame;
Input lastInput = {0};
Input currInput = {0};
while (!glfwWindowShouldClose(soma.window.handle)) {
glfwPollEvents();
lastInput = currInput;
currInput = getCurrentInput(soma.window.handle);
ui.prevInput = &lastInput;
ui.input = &currInput;
updateWindow(&soma);
processInput(&soma);
Render(&renderer) {
UI_Pass(&ui) {
ui_Soma(&ui, &soma);
}
switch (ui.cursorType) {
case UI_Cursor_Arrow:
glfwSetCursor(soma.window.handle, soma.window.cursors.arrow);
break;
case UI_Cursor_Pointer:
glfwSetCursor(soma.window.handle, soma.window.cursors.pointer);
break;
case UI_Cursor_Forbidden:
glfwSetCursor(soma.window.handle, soma.window.cursors.forbidden);
break;
default:
glfwSetCursor(soma.window.handle, soma.window.cursors.arrow);
break;
}
}
updatePolycubeDisplay(&soma);
recalcScene(soma.scene);
glfwSwapBuffers(soma.window.handle);
real64 frameEnd = glfwGetTime();
real64 frameTime = frameEnd - frameStart;
lastFrame = frameStart;
//println("FPS: %.7f", 1/(frameTime));
frameStart = glfwGetTime();
soma.prevState = soma.state;
soma.state.isInitialState = false;
}
glfwTerminate();
return 0;
}