212 lines
5.7 KiB
C
212 lines
5.7 KiB
C
// 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;
|
|
}
|