Compare commits
No commits in common. "eb871068d80f028fb0487886526346783bb35a4b" and "5944fcda92f47bea10b69b9b5a06aa3e9dcb6fa1" have entirely different histories.
eb871068d8
...
5944fcda92
12 changed files with 129 additions and 396 deletions
|
|
@ -88,7 +88,6 @@ 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
14
README.org
|
|
@ -1,14 +0,0 @@
|
||||||
* 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
|
|
||||||
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
#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 = MVP * vec4(aPos.x, aPos.y, aPos.z, 1.0);
|
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,55 +3,30 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define DEFAUL_REGION_SIZE 1048576 /* 8 * 1024 * 1024 = 8MB */
|
#define DEFAULT_ARENA_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) {
|
||||||
Region *region = new_region(capacity);
|
if (capacity == 0) {
|
||||||
Arena arena = {.begin = region, .end = region};
|
capacity = DEFAULT_ARENA_SIZE;
|
||||||
return arena;
|
|
||||||
}
|
}
|
||||||
|
Arena result = {.capacity = capacity, .size = 0, .data = malloc(capacity)};
|
||||||
void arena_deinit(Arena *arena) {
|
assert(result.data != NULL);
|
||||||
assert(arena->begin != NULL && arena->end != 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) {
|
|
||||||
Region *region = arena->end;
|
|
||||||
assert(region != NULL);
|
|
||||||
|
|
||||||
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 = ®ion->data[region->cursor];
|
|
||||||
region->cursor += size;
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
//void *arena_clear(Arena *arena) {
|
void arena_deinit(Arena *arena) {
|
||||||
// arena->size = 0;
|
free(arena->data);
|
||||||
// return arena->data;
|
*arena = (Arena){.capacity = 0, .size = 0, .data = NULL};
|
||||||
//}
|
}
|
||||||
|
|
||||||
|
void *arena_alloc(Arena *arena, size_t size) {
|
||||||
|
assert(arena->size + size <= arena->capacity);
|
||||||
|
void *result = &arena->data[arena->size];
|
||||||
|
arena->size += size;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *arena_clear(Arena *arena) {
|
||||||
|
arena->size = 0;
|
||||||
|
return arena->data;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,15 @@
|
||||||
#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 {
|
||||||
Region *begin;
|
size_t capacity;
|
||||||
Region *end;
|
size_t size;
|
||||||
|
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
85
src/camera.c
|
|
@ -1,85 +0,0 @@
|
||||||
#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
21
src/camera.h
|
|
@ -1,21 +0,0 @@
|
||||||
#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);
|
|
||||||
149
src/main.c
149
src/main.c
|
|
@ -1,29 +1,103 @@
|
||||||
|
#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 "SDL3/SDL_events.h"
|
#include "arena_allocator.h"
|
||||||
#include "SDL3/SDL_keycode.h"
|
|
||||||
#include "camera.h"
|
// settings
|
||||||
#include "shader.h"
|
const unsigned int SCR_WIDTH = 800;
|
||||||
#include "window.h"
|
const unsigned int SCR_HEIGHT = 600;
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
wn_window window = {0};
|
SDL_Window *window;
|
||||||
if (!wn_window_init(&window)) {
|
SDL_Renderer *renderer;
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize wn_window");
|
SDL_GLContext glcontext;
|
||||||
return EXIT_FAILURE;
|
SDL_Event event;
|
||||||
}
|
|
||||||
wn_shader_code_location shader_code_location = {
|
|
||||||
.vertex_shader_source_path = "shaders/vert.glsl",
|
|
||||||
.fragment_shader_source_path = "shaders/frag.glsl"};
|
|
||||||
|
|
||||||
wn_shader shader = wn_shader_init(shader_code_location);
|
const char *vertexShaderSource = SDL_LoadFile("shaders/vert.glsl", NULL);
|
||||||
if (shader.success == false) {
|
const char *fragmentShaderSource = SDL_LoadFile("shaders/frag.glsl", NULL);
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize shader");
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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[] = {
|
||||||
0.5f, 0.5f, 0.0f, // top right
|
0.5f, 0.5f, 0.0f, // top right
|
||||||
|
|
@ -68,41 +142,19 @@ int main(int argc, char *argv[]) {
|
||||||
// VBOs) when it's not directly necessary.
|
// VBOs) when it's not directly necessary.
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
// Initialise camera
|
while (1) {
|
||||||
Camera camera = Camera_default;
|
// handle input
|
||||||
|
SDL_PollEvent(&event);
|
||||||
bool wants_running = true;
|
if (event.type == SDL_EVENT_QUIT) {
|
||||||
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;
|
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(shader.shaderProgram);
|
glUseProgram(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
|
||||||
|
|
@ -110,15 +162,18 @@ 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
|
||||||
|
|
||||||
wn_swapwindow(&window);
|
SDL_GL_SwapWindow(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
glDeleteVertexArrays(1, &VAO);
|
glDeleteVertexArrays(1, &VAO);
|
||||||
glDeleteBuffers(1, &VBO);
|
glDeleteBuffers(1, &VBO);
|
||||||
glDeleteBuffers(1, &EBO);
|
glDeleteBuffers(1, &EBO);
|
||||||
|
glDeleteProgram(shaderProgram);
|
||||||
|
|
||||||
wn_shader_deinit(shader);
|
SDL_GL_DestroyContext(glcontext);
|
||||||
wn_window_deinit(&window);
|
SDL_DestroyWindow(window);
|
||||||
|
|
||||||
|
SDL_Quit();
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
70
src/shader.c
70
src/shader.c
|
|
@ -1,70 +0,0 @@
|
||||||
#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
18
src/shader.h
|
|
@ -1,18 +0,0 @@
|
||||||
#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
59
src/window.c
|
|
@ -1,59 +0,0 @@
|
||||||
#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
19
src/window.h
|
|
@ -1,19 +0,0 @@
|
||||||
#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);
|
|
||||||
Loading…
Reference in a new issue