Compare commits

...

10 commits

12 changed files with 389 additions and 122 deletions

View file

@ -88,6 +88,7 @@ target_include_directories(${PROJECT_NAME} PRIVATE
) )
target_link_libraries(${PROJECT_NAME} PRIVATE target_link_libraries(${PROJECT_NAME} PRIVATE
m
${SDL3_LIBRARIES} ${SDL3_LIBRARIES}
${SDL3_image_LIBRARIES} ${SDL3_image_LIBRARIES}
${CGLM_LIBRARIES} ${CGLM_LIBRARIES}

14
README.org Normal file
View file

@ -0,0 +1,14 @@
* Todo list
- [ ] Create arena allocator
- [ ] Create dynamic arrays using arena allocator
- [ ] Create stack function caller for calling library deallocators
- [ ] Create method of storing models and model data
- [ ] implement textures and simple lighting
- [ ] Figure out a simple game to make with this engine
* TODO Arena Allocator Requirements
- [ ] Sub arenas
- [ ] contiguos memory spaces for dynamic arrays that grow larger than the arena size
** Optional
- [ ] free lists to reuse abandoned chunks of memory arenas

View file

@ -1,8 +1,10 @@
#version 330 core #version 330 core
layout (location = 0) in vec3 aPos; layout (location = 0) in vec3 aPos;
uniform mat4 MVP;
void main() void main()
{ {
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); gl_Position = MVP * vec4(aPos.x, aPos.y, aPos.z, 1.0);
} }

View file

@ -3,30 +3,55 @@
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> #include <stdlib.h>
#define DEFAULT_ARENA_SIZE 1048576 /* 8 * 1024 * 1024 : 8MB*/ #define DEFAUL_REGION_SIZE 1048576 /* 8 * 1024 * 1024 = 8MB */
Region *new_region(size_t capacity) {
if (capacity == 0) {
capacity = DEFAUL_REGION_SIZE;
}
Region *region = malloc(capacity);
assert(region != NULL);
*region = (Region){.next = NULL,
.capacity = capacity + sizeof(Region),
.cursor = sizeof(Region) - 1};
return region;
}
Arena arena_init(size_t capacity) { Arena arena_init(size_t capacity) {
if (capacity == 0) { Region *region = new_region(capacity);
capacity = DEFAULT_ARENA_SIZE; Arena arena = {.begin = region, .end = region};
} return arena;
Arena result = {.capacity = capacity, .size = 0, .data = malloc(capacity)};
assert(result.data != NULL);
return result;
} }
void arena_deinit(Arena *arena) { void arena_deinit(Arena *arena) {
free(arena->data); assert(arena->begin != NULL && arena->end != NULL);
*arena = (Arena){.capacity = 0, .size = 0, .data = NULL}; Region *region = arena->begin;
while (region != NULL) {
Region *next_region = region->next;
free(region);
region = next_region;
}
*arena = (Arena){.begin = NULL, .end = NULL};
} }
void *arena_alloc(Arena *arena, size_t size) { void *arena_alloc(Arena *arena, size_t size) {
assert(arena->size + size <= arena->capacity); Region *region = arena->end;
void *result = &arena->data[arena->size]; assert(region != NULL);
arena->size += size;
if (region->cursor + size > region->capacity) {
if (size < DEFAUL_REGION_SIZE)
size = DEFAUL_REGION_SIZE;
region->next = new_region(size);
arena->end = region->next;
region = region->next;
}
void *result = &region->data[region->cursor];
region->cursor += size;
return result; return result;
} }
void *arena_clear(Arena *arena) { //void *arena_clear(Arena *arena) {
arena->size = 0; // arena->size = 0;
return arena->data; // return arena->data;
} //}

View file

@ -1,15 +1,23 @@
#pragma once #pragma once
#include <stddef.h> #include <stddef.h>
#include <stdint.h>
typedef struct Region_s Region;
struct Region_s {
Region *next;
size_t capacity;
size_t cursor;
uintptr_t data[];
};
typedef struct { typedef struct {
size_t capacity; Region *begin;
size_t size; Region *end;
unsigned char *data;
} Arena; } Arena;
Arena arena_init(size_t capacity); Arena arena_init(size_t capacity);
void arena_deinit(Arena *arena); void arena_deinit(Arena *arena);
void *arena_alloc(Arena *arena, size_t size); void *arena_alloc(Arena *arena, size_t size);
void *arena_clear(Arena *arena); //void *arena_clear(Arena *arena);

85
src/camera.c Normal file
View file

@ -0,0 +1,85 @@
#include "camera.h"
#include "SDL3/SDL_keyboard.h"
#include "cglm/mat4.h"
#include "cglm/cam.h"
#include "cglm/vec3.h"
#include <SDL3/SDL_mouse.h>
#include <cglm/util.h>
#include <math.h>
static float mouse_x, mouse_y;
Camera Camera_default = {
.position = {0.0f, 0.0f, 3.0f},
.forward = {0.0f, 0.0f, -1.0f},
.yaw = -1.5707963268f, // -90 deg in radians
.pitch = 0
};
void camera_tick(Camera *camera) {
// Mouse input
SDL_GetRelativeMouseState(&mouse_x, &mouse_y);
camera->yaw += mouse_x * glm_rad(MOUSE_SENSITIVITY);
camera->pitch -= mouse_y * glm_rad(MOUSE_SENSITIVITY);
// Restrict pitch
if (camera->pitch > glm_rad(89.0f))
camera->pitch = glm_rad(89.0f);
if (camera->pitch < glm_rad(-89.0f))
camera->pitch = glm_rad(-89.0f);
// Camera Direction
camera->forward[0] = cosf(camera->yaw) * cosf(camera->pitch);
camera->forward[1] = sinf(camera->pitch);
camera->forward[2] = sinf(camera->yaw) * cosf(camera->pitch);
glm_normalize(camera->forward);
vec3 camera_right;
vec3 up = {0.0f, 1.0f ,0.0f};
glm_cross(up, camera->forward, camera_right);
glm_normalize(camera_right);
// Move camera based on wasd;
const bool *keyboardState = SDL_GetKeyboardState(NULL);
if (keyboardState[SDL_SCANCODE_W]) {
vec3 calc_buff;
glm_vec3_scale(camera->forward, MOVEMENT_SPEED, calc_buff);
glm_vec3_add(camera->position, calc_buff, camera->position);
}
if (keyboardState[SDL_SCANCODE_S]) {
vec3 calc_buff;
glm_vec3_scale(camera->forward, MOVEMENT_SPEED, calc_buff);
glm_vec3_sub(camera->position, calc_buff, camera->position);
}
if (keyboardState[SDL_SCANCODE_A]) {
vec3 calc_buff;
glm_vec3_scale(camera_right, MOVEMENT_SPEED, calc_buff);
glm_vec3_add(camera->position, calc_buff, camera->position);
}
if (keyboardState[SDL_SCANCODE_D]) {
vec3 calc_buff;
glm_vec3_scale(camera_right, MOVEMENT_SPEED, calc_buff);
glm_vec3_sub(camera->position, calc_buff, camera->position);
}
}
void camera_calc_mvp(mat4 *mvp_result, Camera *camera) {
// Get position to look and up vector
vec3 camera_target;
glm_vec3_add(camera->position , camera->forward, camera_target);
vec3 up = {0.0f, 1.0f ,0.0f};
mat4 model;
glm_mat4_identity(model);
mat4 view;
glm_lookat(camera->position, camera_target, up, view);
mat4 projection;
float fov = glm_rad(45.0f); // fov y
float aspect = 800.0f / 600.0f;
float near = 0.1f;
float far = 100.0f;
glm_perspective(fov, aspect, near, far, projection);
glm_mat4_mulN((mat4*[]){&projection, &view, &model}, 3, *mvp_result);
}

21
src/camera.h Normal file
View file

@ -0,0 +1,21 @@
#pragma once
#include <cglm/types.h>
#define MOVEMENT_SPEED 0.02f
#define MOUSE_SENSITIVITY 0.05f
struct Camera_s {
vec3 position;
vec3 forward;
float yaw;
float pitch;
};
typedef struct Camera_s Camera;
extern Camera Camera_default;
void camera_calc_mvp (mat4 *mvp_result, Camera *camera);
void get_camera_position (vec3 *position_result, Camera *camera);
void camera_tick(Camera *camera);

View file

@ -1,102 +1,28 @@
#include <SDL3/SDL_init.h>
#include <SDL3/SDL_log.h>
#include <SDL3/SDL_render.h>
#include <SDL3/SDL_video.h>
#include <GL/glew.h> #include <GL/glew.h>
#include <SDL3/SDL.h>
#include <stdlib.h> #include <stdlib.h>
#include "arena_allocator.h" #include "SDL3/SDL_events.h"
#include "SDL3/SDL_keycode.h"
// settings #include "camera.h"
const unsigned int SCR_WIDTH = 800; #include "shader.h"
const unsigned int SCR_HEIGHT = 600; #include "window.h"
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
SDL_Window *window; wn_window window = {0};
SDL_Renderer *renderer; if (!wn_window_init(&window)) {
SDL_GLContext glcontext; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize wn_window");
SDL_Event event;
const char *vertexShaderSource = SDL_LoadFile("shaders/vert.glsl", NULL);
const char *fragmentShaderSource = SDL_LoadFile("shaders/frag.glsl", NULL);
if (!SDL_Init(SDL_INIT_VIDEO)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s",
SDL_GetError());
return EXIT_FAILURE; return EXIT_FAILURE;
} }
wn_shader_code_location shader_code_location = {
.vertex_shader_source_path = "shaders/vert.glsl",
.fragment_shader_source_path = "shaders/frag.glsl"};
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); wn_shader shader = wn_shader_init(shader_code_location);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6); if (shader.success == false) {
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize shader");
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
window = SDL_CreateWindow("Hello SDL3", 320, 240,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
if (!window) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s",
SDL_GetError());
return EXIT_FAILURE; return EXIT_FAILURE;
} }
glcontext = SDL_GL_CreateContext(window);
if (!glcontext) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Couldn't create OpenGL Context: %s", SDL_GetError());
return EXIT_FAILURE;
}
GLenum glewError = glewInit();
if (glewError != GLEW_OK) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error initializing GLEW! %s",
glewGetErrorString(glewError));
}
if (!SDL_GL_MakeCurrent(window, glcontext)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Couldn't make glcontext current: %s", SDL_GetError());
}
// vertex shader
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
// check for shader compile errors
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Failed to compile vertex shader: %s", infoLog);
}
// fragment shader
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
// check for shader compile errors
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Failed to compile fragment shader: %s", infoLog);
}
// Free source code memory
SDL_free((void *)vertexShaderSource);
SDL_free((void *)fragmentShaderSource);
// link shaders
unsigned int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
// check for linking errors
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Failed to link shader program: %s", infoLog);
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
// set up vertex data (and buffer(s)) and configure vertex attributes // set up vertex data (and buffer(s)) and configure vertex attributes
float vertices[] = { float vertices[] = {
@ -142,19 +68,41 @@ int main(int argc, char *argv[]) {
// VBOs) when it's not directly necessary. // VBOs) when it's not directly necessary.
glBindVertexArray(0); glBindVertexArray(0);
while (1) { // Initialise camera
// handle input Camera camera = Camera_default;
SDL_PollEvent(&event);
if (event.type == SDL_EVENT_QUIT) { bool wants_running = true;
break; while (wants_running) {
// TODO: Create event handler files
while (SDL_PollEvent(&window.event)) {
switch (window.event.type) {
case SDL_EVENT_QUIT:
wants_running = false;
break;
case SDL_EVENT_KEY_DOWN:
if (window.event.key.key == SDLK_ESCAPE) {
wants_running = false;
}
break;
}
} }
// Handle camera
camera_tick(&camera);
// TODO: make shader handler
mat4 mvp;
camera_calc_mvp(&mvp, &camera);
int mvp_uniform_location =
glGetUniformLocation(shader.shaderProgram, "MVP");
glUniformMatrix4fv(mvp_uniform_location, 1, GL_FALSE, &mvp[0][0]);
// render // render
glClearColor(0.1f, 0.3f, 0.4f, 1.f); glClearColor(0.1f, 0.3f, 0.4f, 1.f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
// draw our first triangle // draw our first triangle
glUseProgram(shaderProgram); glUseProgram(shader.shaderProgram);
glBindVertexArray( glBindVertexArray(
VAO); // seeing as we only have a single VAO there's no need to bind it VAO); // seeing as we only have a single VAO there's no need to bind it
// every time, but we'll do so to keep things a bit more organized // every time, but we'll do so to keep things a bit more organized
@ -162,18 +110,15 @@ int main(int argc, char *argv[]) {
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
// glBindVertexArray(0); // no need to unbind it every time // glBindVertexArray(0); // no need to unbind it every time
SDL_GL_SwapWindow(window); wn_swapwindow(&window);
} }
glDeleteVertexArrays(1, &VAO); glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO); glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO); glDeleteBuffers(1, &EBO);
glDeleteProgram(shaderProgram);
SDL_GL_DestroyContext(glcontext); wn_shader_deinit(shader);
SDL_DestroyWindow(window); wn_window_deinit(&window);
SDL_Quit();
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

70
src/shader.c Normal file
View file

@ -0,0 +1,70 @@
#include "shader.h"
#include "SDL3/SDL_iostream.h"
#include "SDL3/SDL_log.h"
#include <GLES2/gl2.h>
wn_shader wn_shader_init(wn_shader_code_location shader_code_location) {
wn_shader shader = {.shaderProgram = 0, .success = false};
const char *vertexShaderSource =
SDL_LoadFile(shader_code_location.vertex_shader_source_path, NULL);
const char *fragmentShaderSource =
SDL_LoadFile(shader_code_location.fragment_shader_source_path, NULL);
// vertex shader
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
// check for shader compile errors
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Failed to compile vertex shader: %s", infoLog);
return shader;
}
// fragment shader
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
// check for shader compile errors
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Failed to compile fragment shader: %s", infoLog);
return shader;
}
// Free source code memory
SDL_free((void *)vertexShaderSource);
SDL_free((void *)fragmentShaderSource);
// link shaders
unsigned int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
// check for linking errors
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Failed to link shader program: %s", infoLog);
return shader;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
shader.shaderProgram = shaderProgram;
shader.success = true;
return shader;
}
void wn_shader_deinit(wn_shader shader) {
glDeleteProgram(shader.shaderProgram);
}

18
src/shader.h Normal file
View file

@ -0,0 +1,18 @@
#pragma once
#include <stdbool.h>
typedef struct {
const char *vertex_shader_source_path;
const char *fragment_shader_source_path;
} wn_shader_code_location;
struct wn_shader_s {
unsigned int shaderProgram;
bool success;
};
typedef struct wn_shader_s wn_shader;
wn_shader wn_shader_init(wn_shader_code_location shader_code_location);
void wn_shader_deinit(wn_shader shader);

59
src/window.c Normal file
View file

@ -0,0 +1,59 @@
#include "window.h"
#include "SDL3/SDL_init.h"
#include <GL/glew.h>
#include <SDL3/SDL_log.h>
#include <SDL3/SDL_opengl.h>
bool wn_window_init(wn_window *window) {
window->window = SDL_CreateWindow("Hello SDL3", 320, 240,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
if (!SDL_Init(SDL_INIT_VIDEO)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s",
SDL_GetError());
return false;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
if (!window->window) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s",
SDL_GetError());
return false;
}
window->glcontext = SDL_GL_CreateContext(window->window);
if (!window->glcontext) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Couldn't create OpenGL Context: %s", SDL_GetError());
return false;
}
GLenum glewError = glewInit();
if (glewError != GLEW_OK) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error initializing GLEW! %s",
glewGetErrorString(glewError));
}
if (!SDL_GL_MakeCurrent(window->window, window->glcontext)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Couldn't make glcontext current: %s", SDL_GetError());
}
// hide and lock mouse
SDL_SetWindowRelativeMouseMode(window->window, true);
SDL_GetRelativeMouseState(NULL, NULL);
return true;
}
void wn_window_deinit(wn_window *window) {
SDL_GL_DestroyContext(window->glcontext);
SDL_DestroyWindow(window->window);
SDL_Quit();
}
void wn_swapwindow(wn_window *window) { SDL_GL_SwapWindow(window->window); }

19
src/window.h Normal file
View file

@ -0,0 +1,19 @@
#pragma once
#include "SDL3/SDL_events.h"
#include "SDL3/SDL_render.h"
#include "SDL3/SDL_video.h"
#include <stdbool.h>
struct wn_window_s {
SDL_Window *window;
SDL_Renderer *renderer;
SDL_GLContext glcontext;
SDL_Event event;
};
typedef struct wn_window_s wn_window;
bool wn_window_init(wn_window *window);
void wn_window_deinit(wn_window *window);
void wn_swapwindow(wn_window *window);