summaryrefslogtreecommitdiff
path: root/src/rendering
diff options
context:
space:
mode:
Diffstat (limited to 'src/rendering')
-rw-r--r--src/rendering/CMakeLists.txt33
-rw-r--r--src/rendering/include/engine/rendering/platform.h57
-rw-r--r--src/rendering/include/engine/rendering/platform_glfw.h32
-rw-r--r--src/rendering/include/engine/rendering/rendering.h288
-rw-r--r--src/rendering/include/engine/rendering/window.h53
-rw-r--r--src/rendering/src/gl.c281
-rw-r--r--src/rendering/src/platform_glfw.c232
-rw-r--r--src/rendering/src/rendering.c696
-rw-r--r--src/rendering/src/window.c83
9 files changed, 0 insertions, 1755 deletions
diff --git a/src/rendering/CMakeLists.txt b/src/rendering/CMakeLists.txt
deleted file mode 100644
index f3f4710..0000000
--- a/src/rendering/CMakeLists.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-add_library(daw_rendering
- src/gl.c
- src/rendering.c
- src/window.c
- src/platform_glfw.c
- ${GLAD_HEADER}
- )
-
-add_custom_command(
- OUTPUT ${GLAD_HEADER}
- COMMAND
- glad
- --api gl:core=4.6
- --out-path ${CMAKE_BINARY_DIR}
- --reproducible
- c
- --header-only
- --mx
- )
-
-set_property(SOURCE src/window.c APPEND PROPERTY OBJECT_DEPENDS ${GLAD_HEADER})
-set_property(SOURCE src/rendering.c APPEND PROPERTY OBJECT_DEPENDS ${GLAD_HEADER})
-
-target_compile_options(daw_rendering PUBLIC ${BUILD_OPTS})
-target_include_directories(daw_rendering PRIVATE
- ${DAW_INCLUDE_DIRS}
- ${GLFW_INCLUDE_DIR}
-)
-target_link_libraries(daw_rendering PRIVATE
- OpenGL::GL
- cglm
- glfw
-)
diff --git a/src/rendering/include/engine/rendering/platform.h b/src/rendering/include/engine/rendering/platform.h
deleted file mode 100644
index ea51c47..0000000
--- a/src/rendering/include/engine/rendering/platform.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef PLATFORM_H
-#define PLATFORM_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <cglm/ivec2.h>
-
-#include <engine/core/types.h>
-// TODO: We only need the window once all the garbage in Instance is cleaned up.
-#include <engine/core/platform.h>
-#include <engine/rendering/window.h>
-
-#define DAW_WINDOW_VSYNC (1 << 0)
-#define DAW_WINDOW_FULLSCREEN (1 << 1)
-#define DAW_WINDOW_RESIZEABLE (1 << 2)
-
-// Whether or not it is clever to force API consistency using a struct like this
-// can be debated, at the time of writing it seemed like a smart idea.
-
-// Platform libraries must implement a struct Platform:
-struct Platform {
- /* Initialize a window for the given platform. The rendering backend should
- * also be initialized here.
- * Parameters:
- * const char* title: window title.
- * ivec2 windowsize: the size in pixels for the new window.
- * const u32 flags: window flags, such as static size and fullscreen.
- * The flags are platform agnostic and needs to be
- * converted to the specific library
- * Returns:
- * A pointer to a struct Window, NULL on error.
- */
- Window* (*window_init)(const char *restrict title, ivec2 windowsize, const u32 flags);
-
- /* Destroy, close, and free up resources related to the window and the
- * platform library specific resources.
- */
- void (*window_destroy)(Window *restrict w);
-
- /* Resize the given window. Resize callbacks are handled by the wrapper
- * implementation.
- */
- void (*window_resize)(Window *restrict window, int width, int height);
-
- /* Return true if the platform has ordered the window to exit. */
- bool (*window_should_close)(Window *restrict w);
-
- /* Poll events on the window from the operating system. */
- void (*window_poll)(void);
-};
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/src/rendering/include/engine/rendering/platform_glfw.h b/src/rendering/include/engine/rendering/platform_glfw.h
deleted file mode 100644
index 949968d..0000000
--- a/src/rendering/include/engine/rendering/platform_glfw.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef ENGINE_RENDERING_PLATFORM_GLFW_H
-#define ENGINE_RENDERING_PLATFORM_GLFW_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <cglm/ivec2.h>
-
-#include <engine/core/types.h>
-#include <engine/rendering/platform.h>
-#include <engine/rendering/window.h>
-
-Window* window_init_glfw(const char *restrict windowtitle, ivec2 windowsize, const u32 flags);
-void window_destroy_glfw(Window *restrict w);
-void window_resize_glfw(Window *restrict window, int width, int height);
-bool window_should_close_glfw(Window *restrict window);
-void window_poll_glfw(void);
-
-const struct Platform Platform_GLFW = {
- .window_init = window_init_glfw,
- .window_destroy = window_destroy_glfw,
- .window_resize = window_resize_glfw,
- .window_should_close = window_should_close_glfw,
- .window_poll = window_poll_glfw,
-};
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
diff --git a/src/rendering/include/engine/rendering/rendering.h b/src/rendering/include/engine/rendering/rendering.h
deleted file mode 100644
index a996257..0000000
--- a/src/rendering/include/engine/rendering/rendering.h
+++ /dev/null
@@ -1,288 +0,0 @@
-#ifndef ENGINE_RENDERING_RENDERING_H
-#define ENGINE_RENDERING_RENDERING_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <engine/core/types.h>
-#include <engine/rendering/window.h>
-
-#include <cglm/ivec2.h>
-
-/* Definitions */
-#define RGBA(_r, _g, _b, _a) ((Engine_color){.r = _r, .g = _g, .b = _b, .a = _a})
-#define RGB(_r, _g, _b) RGBA(_r, _g, _b, 0xFF)
-
-/* Types */
-/* TODO: Cleanup these types. */
-typedef struct {
- u8 r;
- u8 g;
- u8 b;
- u8 a;
-} Engine_color;
-
-typedef struct {
- /* Maybe implement types, such as `atlas` (default), `standalone`, or
- * something idk. */
- u32 id;
- i32 width;
- i32 height;
-} Texture;
-
-typedef struct {
- u32 texture_id;
- ivec2 coord;
-} Sprite;
-
-typedef enum {
- Shader_Error,
-
- Shader_Program,
- Shader_Vertex,
- Shader_Tessellation,
- Shader_Geometry,
- Shader_Fragment,
- Shader_Compute,
-} ShaderType;
-
-typedef struct {
- /* Shader proram */
- ShaderType type;
- u32 program;
-} Shader;
-
-typedef struct {
- vec3 position;
- vec3 size;
- mat4 rotation;
-} Transform;
-
-typedef enum {
- ShaderBufferFlag_none = 0x00,
-
- // First 3 bytes describe the access frequency.
- ShaderBuffer_AccessFrequency_stream = 0b0000000000001, // 1
- ShaderBuffer_AccessFrequency_static = 0b0000000000010, // 2
- ShaderBuffer_AccessFrequency_dynamic = 0b0000000000011, // 3
-
- // Next 3 bytes describe the access type.
- ShaderBuffer_AccessType_draw = 0b0000000001000, // 8
- ShaderBuffer_AccessType_read = 0b0000000010000, // 16
- ShaderBuffer_AccessType_copy = 0b0000000011000, // 24
-
- // Next 3 bytes describe the buffer type
- ShaderBuffer_Type_vertexData = 0b0000001000000, // 64
- ShaderBuffer_Type_vertexPosition = 0b0000010000000, // 128
- ShaderBuffer_Type_vertexIndex = 0b0000011000000, // 192
-
- // Next 4 bytes are designated for the data type
- ShaderBuffer_DataType_nil = 0b0001000000000, // 512
-
- ShaderBuffer_DataType_f32 = 0b0010000000000, // 1024
- ShaderBuffer_DataType_f64 = 0b0011000000000, // 1536
-
- ShaderBuffer_DataType_i8 = 0b0100000000000, // 2048
- ShaderBuffer_DataType_i16 = 0b0101000000000, // 2560
- ShaderBuffer_DataType_i32 = 0b0110000000000, // 3072
- ShaderBuffer_DataType_i64 = 0b0111000000000, // 3584
-
- ShaderBuffer_DataType_u8 = 0b1000000000000, // 4096
- ShaderBuffer_DataType_u16 = 0b1001000000000, // 4608
- ShaderBuffer_DataType_u32 = 0b1010000000000, // 5120
- ShaderBuffer_DataType_u64 = 0b1011000000000, // 5632
-} ShaderBufferFlag;
-
-typedef struct {
- // The backend ID, ie. glGenBuffer(numBufferObjects, &this->buffername)
- u32 buffername;
- // Array, access, and data, type.
- u32 buffertype;
- // Buffer size of `data`. To get the size of the actual data, size_elem * count
- usize size;
- // Number of elements
- usize count;
- // components per generic vertex attribute (ie, 3 for RGB, 2 for UV)
- usize components;
- // size of each element
- usize size_elem;
- // Pointer to the data
- void* data;
-} ShaderBuffer;
-
-// SHADERBUFFER_NEW is a constructor that takes the
-// * type T, as one of f32, f64, i8, i16, i32, i64, u8, u16, u32, or u64.
-// * COUNT, number of elements in the buffer
-// * COMPONENTS, number of elements to be grouped together, ie. 3 for a vec3.
-// * DATA, the buffer (it is pointed to automatically)
-// * FLAGS, are low-level GL flags that hints the access frequency, the access
-// type, and what buffer type it is, such as "data" or an index buffer.
-#define SHADERBUFFER_NEW(T, COUNT, COMPONENTS, DATA, FLAGS) \
- (ShaderBuffer){ \
- .buffername = 0, \
- .buffertype = ShaderBuffer_DataType_##T | FLAGS, \
- .size = COUNT * sizeof(T), \
- .count = COUNT, \
- .components = COMPONENTS, \
- .size_elem = sizeof(T), \
- .data = DATA, \
- }
-
-typedef struct {
- /* Shader proram */
- Shader shader;
- /* Vertex Array Object */
- u32 vao;
-
- /* MVP (a uniform from the shader).
- * This could also probably be generalized */
- i32 mvp;
-
- // The texture ID, glBindTextures(target, &this->texture)
- u32 texture;
-
- // Number of buffers
- usize buffer_len;
-
- // The vertex buffer is also just a buffer
- ShaderBuffer* buffer;
-} RenderObject;
-
-typedef struct {
- // Index of the model in the RenderBatch models buffer
- usize model_idx;
- // The transformation of the model
- Transform transform;
-} BatchModelInstance;
-
-typedef struct {
- // Size of models buffer
- usize msize;
- // number of models in the `models` buffer
- usize mcount;
- // Pointers to original models in this batch
- RenderObject **models;
-
- // Size of instance buffer
- usize inst_size;
- // number of instances in the `instances` buffer
- usize inst_count;
- // Pointers to original models in this batch
- BatchModelInstance *instances;
-
- // The rendered destination object
- RenderObject renderobj;
-} RenderBatch;
-
-typedef enum {
- Camera_Perspective,
- Camera_Orthogonal,
-} CameraType;
-
-typedef struct {
- /* Position of the camera in world-space. */
- vec3 pos;
-
- /* The viewing direction of the camera, relative to the camera. */
- vec3 dir;
-
- /* Perspective matrix. Initialize with r_perspective_ortho or r_perspective. */
- /* Alternatively, use `glm_perspective` or `glm_ortho`. */
- mat4 per;
-
- /* Used to re-calculate the perspective matrix when resizing the window */
- CameraType type;
- /* Yes, could use a singular "f32 arg", but this is more extendable in the
- * future. */
- union {
- struct {f32 fov;} perspective;
- struct {f32 sz;} orthogonal;
- } parameters;
-
-} Camera;
-
-usize ShaderBufferDataType_size(u16 flags);
-
-ShaderBufferFlag ShaderBuffer_get_access_frequency(u64 flags);
-ShaderBufferFlag ShaderBuffer_get_access_type(u64 flags);
-ShaderBufferFlag ShaderBuffer_get_type(u64 flags);
-ShaderBufferFlag ShaderBuffer_get_data_type(u64 flags);
-
-/* Conversion to GL types */
-u32 ShaderBuffer_get_gl_type(u64 flags);
-u32 ShaderBuffer_get_gl_accesstype(u64 flags);
-u32 ShaderBuffer_get_gl_datatype(u64 flags);
-
-/* Rendering functions */
-void render_begin(Window* w);
-void render_present(Window* w);
-void drawcall_reset(void);
-void render(Window* w);
-
-/* Misc */
-void r_perspective(f32 fov, Camera *c);
-void r_perspective_ortho(f32 sz, Camera *c);
-
-void r_set_camera(Camera* c);
-void r_reset_camera(Camera* c);
-
-//void window_size_callback(GLFWwindow* window, i32 width, i32 height);
-
-void engine_draw_sprite(Sprite* s, ivec2* pos, f32 scale);
-void engine_draw_sprite_ex(Sprite* s, ivec2* pos, f32 scale,
- Engine_color colormod);
-void engine_draw_model(RenderObject* o, vec3 pos);
-
-Sprite sprite_new(u64 tid, u8 coord);
-
-typedef enum {
- RenderDrawCallType_Text,
- RenderDrawCallType_Sprite,
- RenderDrawCallType_Model,
-} RenderDrawCallType;
-
-typedef struct {
- RenderDrawCallType type;
- union {
- void* data;
- struct {
- Sprite* sprite;
- i32 x;
- i32 y;
- f32 scale;
- } sprite;
- struct {
- RenderObject* model;
- vec3 pos;
- f32 scale;
- } model;
- } data;
-} RenderDrawCall;
-
-// TODO make all the shader buffers a list
-
-RenderObject RenderObject_new(
- Shader* shader,
- u32 texture,
- ShaderBuffer *restrict buffers, usize num_buffers);
-
-int renderbatch_new(RenderBatch* renderbatch, usize count);
-i32 renderbatch_add(RenderBatch* renderbatch, RenderObject* obj, Transform* t);
-void renderbatch_transform(RenderBatch* renderbatch, usize obj_idx, Transform* t);
-int renderbatch_refresh(RenderBatch* renderbatch);
-
-Shader compile_shader(const char* file_path, const ShaderType shader_type);
-Shader compose_shader(Shader *shaders, usize shaders_len);
-void shaders_delete(Shader* shader, usize shader_len);
-
-u32 ComposeShader(u32 *shaders, usize shaders_len);
-
-ShaderType guess_shadertype_from_filename(const char *restrict fname);
-
-Texture createTextureFromImageData(unsigned char* image_data, i32 width, i32 height, u8 components);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/src/rendering/include/engine/rendering/window.h b/src/rendering/include/engine/rendering/window.h
deleted file mode 100644
index a964b38..0000000
--- a/src/rendering/include/engine/rendering/window.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef WINDOW_H
-#define WINDOW_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <cglm/ivec2.h>
-
-#include <engine/core/types.h>
-#include <engine/ctrl/input.h>
-
-#ifndef ENGINE_RENDERING_WINDOW_H_EXCLUDE_EXTERNS
-extern u64 (*get_time)(void);
-#endif
-
-typedef enum {
- WINDOW_FRAMEWORK_NONE = 0,
- WINDOW_FRAMEWORK_GLFW,
-} Window_framework;
-
-typedef enum {
- WINDOW_RENDERER_NONE = 0,
- WINDOW_RENDERER_OPENGL,
-} Window_renderer;
-
-typedef struct {
- // Specifies the framwork & renderer combo used.
- Window_framework framework;
- Window_renderer renderer;
-
- // Window *buffer* size, in pixels.
- ivec2 windowsize;
-
- // These are used differently depending on the framework / renderer combo.
- // Subject to change to a union of backend-dependent structs
- void* window;
- void* context;
-
- /* The ctrl is probably the only sensible thing in this struct. */
- usize bindings_sz;
- usize bindings_len;
- i_ctx** bindings;
-} Window;
-
-Window* Window_new(const char *restrict title, Window_framework framework, Window_renderer renderer, ivec2 size, u32 flags);
-
-void get_mousepos(double *x, double *y);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/src/rendering/src/gl.c b/src/rendering/src/gl.c
deleted file mode 100644
index 920518f..0000000
--- a/src/rendering/src/gl.c
+++ /dev/null
@@ -1,281 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <glad/gl.h>
-
-#include <engine/core/types.h>
-#include <engine/core/logging.h>
-
-#include <engine/rendering/rendering.h>
-#include <engine/core/platform.h>
-#include <engine/engine.h>
-
-extern Instance* GLOBAL_PLATFORM;
-
-const char* ShaderType_str[] = {
- [Shader_Error] = "Shader_Error",
- [Shader_Program] = "Shader_Program",
- [Shader_Vertex] = "Shader_Vertex",
- [Shader_Tessellation] = "Shader_Tessellation",
- [Shader_Geometry] = "Shader_Geometry",
- [Shader_Fragment] = "Shader_Fragment",
- [Shader_Compute] = "Shader_Compute",
-};
-
-Shader compile_shader(const char* file_path, const ShaderType shader_type) {
- u32 shaderID = 0;
- GLenum shadertype = GL_INVALID_ENUM;
-
- i32 Result = GL_FALSE;
- i32 infolog_len;
-
- char* source = NULL;
- FILE* file = NULL;
-
- const GladGLContext* gl = GLOBAL_PLATFORM->window->context;
-
- if (file_path == NULL) {
- WARN("Empty path to shader");
- return (Shader){.program = 0, .type = Shader_Error};
- }
-
- switch (shader_type) {
- case Shader_Vertex:
- shadertype = GL_VERTEX_SHADER;
- break;
- case Shader_Fragment:
- shadertype = GL_FRAGMENT_SHADER;
- break;
- default: break;
- }
-
- file = fopen(file_path, "r");
-
- shaderID = gl->CreateShader(shadertype);
- LOG("CREATED SHADER ID %d", shaderID);
-
- if(file != NULL) {
- const usize size = f_get_sz(file);
-
- source = calloc((usize)size + 1, sizeof(char));
-
- // Assume the whole file is successfully read
- fread(source, sizeof(char), (usize)size, file);
-
- fclose(file);
- } else {
- ERROR("Cannot open \"" TERM_COLOR_YELLOW "%s" TERM_COLOR_RESET"\".", file_path);
- return (Shader){.program = 0, .type = Shader_Error};
- }
-
- // Compile shader
- INFO("Compiling shader \"" TERM_COLOR_YELLOW "%s" TERM_COLOR_RESET"\".", file_path);
- char const* src_ptr = source;
- gl->ShaderSource(shaderID, 1, &src_ptr , NULL);
- gl->CompileShader(shaderID);
-
- // Check shader
- gl->GetShaderiv(shaderID, GL_COMPILE_STATUS, &Result);
- gl->GetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &infolog_len);
- if ( infolog_len > 0 ) {
- char* msg = calloc((usize)infolog_len + 1, sizeof(char));
- gl->GetShaderInfoLog(shaderID, infolog_len, NULL, msg);
- ERROR("Failed to compile shader: " TERM_COLOR_YELLOW "%s" TERM_COLOR_RESET, msg);
- free(msg);
- }
-
- free(source);
-
- return (Shader){.program = shaderID, .type = shader_type};
-}
-
-
-// http://www.opengl-tutorial.org/beginners-tutorials/tutorial-2-the-first-triangle/
-u32 load_shaders(
- const GladGLContext* gl,
- const char* vertex_file_path,
- const char* fragment_file_path) {
-
- i32 Result = GL_FALSE;
- i32 infolog_len;
-
- // Create the shaders
- const Shader vertexShader = compile_shader(vertex_file_path, Shader_Vertex);
- const Shader fragmentShader = compile_shader(fragment_file_path, Shader_Fragment);
-
- // Link the program
- INFO("Linking program");
- u32 ProgramID = gl->CreateProgram();
-
- if (vertex_file_path != NULL) gl->AttachShader(ProgramID, vertexShader.program);
- if (fragment_file_path != NULL) gl->AttachShader(ProgramID, fragmentShader.program);
-
- gl->LinkProgram(ProgramID);
-
- // Check the program
- gl->GetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
- gl->GetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &infolog_len);
- if ( infolog_len > 0 ){
- char* msg = calloc((usize)infolog_len + 1, sizeof(char));
- gl->GetShaderInfoLog(ProgramID, infolog_len, NULL, msg);
- ERROR("Compiling shader: " TERM_COLOR_YELLOW "%s" TERM_COLOR_RESET, msg);
- free(msg);
- }
-
- gl->DetachShader(ProgramID, vertexShader.program);
- gl->DetachShader(ProgramID, fragmentShader.program);
-
- //gl->DeleteShader(vertexShader.program);
- //gl->DeleteShader(fragmentShader.program);
-
- return ProgramID;
-}
-
-/* Returns a shader program */
-Shader compose_shader(Shader *shaders, usize shaders_len) {
- const GladGLContext* gl = GLOBAL_PLATFORM->window->context;
- i32 Result = GL_FALSE;
-
- if (shaders_len == 0) {
- ERROR("No shaders provided!");
- return (Shader){.program = 0, .type = Shader_Error};
- }
-
- u32 prog = gl->CreateProgram();
-
- if (prog == 0) {
- ERROR("Failed to create program!");
- return (Shader){.program = 0, .type = Shader_Error};
- }
-
- for (usize i = 0; i < shaders_len; i++) {
- gl->AttachShader(prog, shaders[i].program);
- INFO("Attaching shader %d to %d", shaders[i].program, prog);
- }
-
- gl->LinkProgram(prog);
-
- // Check the program
- gl->GetProgramiv(prog, GL_LINK_STATUS, &Result);
- if (Result != GL_TRUE) {
- // Get the size of the log
- i32 log_len = 0;
- i32 msg_len = 0;
- gl->GetProgramiv(prog, GL_INFO_LOG_LENGTH, &log_len);
- char* msg = calloc((usize)log_len + 1, sizeof(char));
-
- // Copy the log message(s)
- gl->GetProgramInfoLog(prog, log_len, &msg_len, msg);
-
- ERROR("(Compose) Compiling shader:\n" TERM_COLOR_YELLOW "%s" TERM_COLOR_RESET "\n", msg);
- free(msg);
- }
-
- for (usize i = 0; i < shaders_len; i++) {
- gl->DetachShader(prog, shaders[i].program);
- }
-
- return (Shader){.program = prog, .type = Shader_Program};
-}
-
-/* Free up resources associated with `shader` */
-void shaders_delete(Shader* shader, usize shader_len) {
- const GladGLContext* gl = GLOBAL_PLATFORM->window->context;
-
- for (usize i = 0; i < shader_len; i++) {
- gl->DeleteShader(shader[i].program);
- }
-}
-
-GLenum ShaderBuffer_get_gl_access(u64 flags) {
- const ShaderBufferFlag access = ShaderBuffer_get_access_type(flags);
-
- switch(flags & 0b111) {
- case ShaderBuffer_AccessFrequency_stream:
- switch(access) {
- case ShaderBuffer_AccessType_draw: return GL_STREAM_DRAW;
- case ShaderBuffer_AccessType_read: return GL_STREAM_READ;
- case ShaderBuffer_AccessType_copy: return GL_STREAM_COPY;
- default: return GL_STREAM_DRAW;
- }
- case ShaderBuffer_AccessFrequency_static:
- switch(access) {
- case ShaderBuffer_AccessType_draw: return GL_STATIC_DRAW;
- case ShaderBuffer_AccessType_read: return GL_STATIC_READ;
- case ShaderBuffer_AccessType_copy: return GL_STATIC_COPY;
- default: return GL_STATIC_DRAW;
- }
- case ShaderBuffer_AccessFrequency_dynamic:
- switch(access) {
- case ShaderBuffer_AccessType_draw: return GL_DYNAMIC_DRAW;
- case ShaderBuffer_AccessType_read: return GL_DYNAMIC_READ;
- case ShaderBuffer_AccessType_copy: return GL_DYNAMIC_COPY;
- default: return GL_DYNAMIC_DRAW;
- }
- default: return GL_STATIC_DRAW;
- }
-}
-
-RenderObject RenderObject_new(
- Shader* shader,
- u32 texture,
- ShaderBuffer *restrict buffers, usize num_buffers) {
-
- GladGLContext *gl = GLOBAL_PLATFORM->window->context;
- RenderObject o;
-
- gl->GenVertexArrays(1, &(o.vao));
- gl->BindVertexArray(o.vao);
-
- /* For each buffer in the shader, */
- /* The shader should be generalied, */
- for (usize i = 0; i < num_buffers; i++) {
- const usize sz = buffers[i].size_elem * buffers[i].count;
- const u32 b_gl_type = ShaderBuffer_get_gl_type(buffers[i].buffertype);
-
- gl->GenBuffers(1, &(buffers[i].buffername));
- gl->BindBuffer(b_gl_type, buffers[i].buffername);
- gl->BufferData(b_gl_type, (isize)sz, buffers[i].data, ShaderBuffer_get_gl_accesstype(buffers[i].buffertype));
- }
-
- o.shader = *shader;
- o.texture = texture;
- o.buffer = buffers;
- o.buffer_len = num_buffers;
- o.mvp = gl->GetUniformLocation(o.shader.program, "MVP");
-
- // It is very much a non-issue if we don't find the model view projection in
- // the shader. In fact, it is removed from a shader program if it is not used.
- // TODO: Add common uniforms, should be a list of strings (uniform name) &
- // their locations (i32), such as
- // * mouse coords,
- // * time,
- // * delta time,
- // * modelviewprojection,
- // * window size.
- // These should be added to the RenderObject, if found.
-
- // if (o.mvp == -1) {
- // WARN("Unable to find \"MVP\" input in shader program");
- //}
-
- gl->BindVertexArray(0);
-
-
- return o;
-}
-
-ShaderType guess_shadertype_from_filename(const char *restrict fname) {
- const usize path_len = strlen(fname);
-
- if (path_len <= 4) {
- ERROR("Unable to determine shader type from suffix! (%s)", fname);
- return Shader_Error;
- }
-
- if (!strncmp(".vert", &fname[path_len - 5], 5)) { return Shader_Vertex; }
- if (!strncmp(".frag", &fname[path_len - 5], 5)) { return Shader_Fragment; }
-
- return Shader_Error;
-}
diff --git a/src/rendering/src/platform_glfw.c b/src/rendering/src/platform_glfw.c
deleted file mode 100644
index 47638e2..0000000
--- a/src/rendering/src/platform_glfw.c
+++ /dev/null
@@ -1,232 +0,0 @@
-// Required for OpenGL rendering backend
-#define GLAD_GL_IMPLEMENTATION
-#include <glad/gl.h>
-#undef GLAD_GL_IMPLEMENTATION
-
-// TODO: import vulkan thingymajig once I get around to it.
-// TODO: move OpenGL initialization code at some point
-
-#undef GLFW_INCLUDE_NONE
-#include <GLFW/glfw3.h>
-
-#include <engine/core/logging.h>
-
-#include <engine/rendering/platform.h>
-
-static void window_resize_callback(GLFWwindow *restrict window, int width, int height);
-static void framebuffer_resize_callback(GLFWwindow *restrict window, int width, int height);
-static void glfw_err_callback(int code, const char* description);
-static void render_init_opengl(Window *restrict w, const u32 flags);
-static void window_size(GLFWwindow *restrict w, ivec2 *restrict dst);
-
-
-Window* window_init_glfw(const char *restrict windowtitle, ivec2 windowsize, const u32 flags) {
- Window* ret = NULL;
- GLFWwindow* window = NULL;
-
- glfwSetErrorCallback(&glfw_err_callback);
-
- INFO_("initializing glfw...");
- if (glfwInit() == GLFW_FALSE) {
- const char *desc;
- int code = glfwGetError(&desc);
- ERROR("failed to initialize glfw [%d]: %s\n", code, *desc);
- exit(EXIT_FAILURE);
- } else
- printf("ok\n");
-
-
- INFO_("initializing window...");
- //glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
- if (!(flags & DAW_WINDOW_RESIZEABLE)) {
- glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
- }
-
- glfwWindowHint(GLFW_DECORATED, GLFW_FALSE);
- glfwWindowHint(GLFW_FLOATING, GLFW_TRUE);
-
- glfwWindowHint(GLFW_SAMPLES, 0); // Disable anti aliasing
-
- // Use a modern opengl version
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
-
- // Lean and mean
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
-
-#ifdef __APPLE__
- // To make MacOS happy; should not be needed
- glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
-#endif
-
- /* "On Wayland specifically, you need to swap the buffers
- * once of a window for it to become visible." */
- {
- GLFWmonitor* mon = NULL;
- if (flags & DAW_WINDOW_FULLSCREEN) mon = glfwGetPrimaryMonitor();
-
- window = glfwCreateWindow(windowsize[0], windowsize[1], windowtitle, mon, NULL);
- }
-
- if (window == NULL) {
- ERROR("Failed to create GLFW window!\n");
- const char *desc;
- int code = glfwGetError(&desc);
- ERROR("failed to initialize glfw window [%d]: %s\n", code, desc);
- exit(EXIT_FAILURE);
- } else
- printf("ok\n");
-
- // Setup callbacks
- glfwSetFramebufferSizeCallback(window, framebuffer_resize_callback);
- glfwSetWindowSizeCallback(window, window_resize_callback);
- glfwSetKeyCallback(window, (GLFWkeyfun)key_callback);
-
- // Create the window datastructure
- ret = (Window*)calloc(1, sizeof(Window));
- ret->framework = WINDOW_FRAMEWORK_GLFW;
- ret->renderer = WINDOW_RENDERER_NONE;
- ret->window = window;
- /* Last parameter is used for the renderer */
- ret->context = NULL;
-
- {
- ivec2 wsize;
- vec2 wscaling;
- glfwGetWindowContentScale(window, &wscaling[0], &wscaling[1]);
- glfwGetWindowSize(window, &wsize[0], &wsize[1]);
-
- ret->windowsize[0] = (i32)((f32)wsize[0] * wscaling[0]);
- ret->windowsize[1] = (i32)((f32)wsize[1] * wscaling[1]);
-
- INFO("WINDOW CONTENT SCALING: %.2f x %.2f", wscaling[0], wscaling[1]);
- INFO("WINDOW SIZE: %d x %d -> %d x %d", wsize[0], wsize[1], ret->windowsize[0], ret->windowsize[1]);
- }
-
- // TODO: set this to `ret` once all the garbage is moved to `struct Window`
- glfwSetWindowUserPointer(window, (void*)ret);
-
- render_init_opengl(ret, flags);
-
- return ret;
-}
-
-void window_destroy_glfw(Window *restrict w) {
- glfwDestroyWindow(w->window);
- w->window = NULL;
-
- // If we ever do multi-window support, we need to make sure this is the last
- // window before terminating
- glfwTerminate();
-
- switch(w->renderer) {
- case WINDOW_RENDERER_OPENGL:
- // Missing unloader function in glad MX library
- free(w->context);
- w->context = NULL;
- break;
- default:
- ERROR("Destroying unknown renderer type.");
- }
-}
-
-void window_resize_glfw(Window *restrict window, int width, int height) {
- window_resize_callback(window->window, width, height);
- framebuffer_resize_callback(window->window, width, height);
-}
-
-bool window_should_close_glfw(Window *restrict window) {
- return glfwWindowShouldClose(window->window);
-}
-
-void window_poll_glfw(void) {
- glfwPollEvents();
-}
-
-// Helper function implementations
-static void window_resize_callback(GLFWwindow* window, int width, int height) {
- (void)width; (void)height;
- Window* w = glfwGetWindowUserPointer(window);
- glfwSwapBuffers(window);
- if (w != NULL) {
- const GladGLContext* gl = w->context;
- gl->Finish();
- }
-}
-
-static void framebuffer_resize_callback(GLFWwindow* window, int width, int height) {
- (void)width; (void)height;
- Window* w = glfwGetWindowUserPointer(window);
- if (w != NULL) {
- const GladGLContext* gl = w->context;
- //TODO: Move the camera to window->renderer
- //Camera* c = w->cam;
- gl->Viewport(0,0, width, height);
- w->windowsize[0] = width;
- w->windowsize[1] = height;
-
- //r_reset_camera(c);
- }
-}
-
-static void glfw_err_callback(int code, const char* description) {
- ERROR("glfw [%d]: %s\n", code, description);
- // Terminate?
- exit(EXIT_FAILURE);
-}
-
-static void render_init_opengl(Window *restrict w, const u32 flags) {
- if (w->renderer != WINDOW_RENDERER_NONE || w->context != NULL) {
- ERROR("Window already initialized with a renderer!");
- return;
- }
-
- // This is GLFW specific
- glfwMakeContextCurrent(w->window);
-
- GladGLContext* ctx = (GladGLContext*)malloc(sizeof(GladGLContext));
- if (!ctx) {
- ERROR("Failed to allocate memory for context");
- }
-
- int version = gladLoadGLContext(ctx, glfwGetProcAddress);
- INFO("Loaded OpenGL %d.%d", GLAD_VERSION_MAJOR(version), GLAD_VERSION_MINOR(version));
-
- if (ctx == NULL) {
- ERROR("Failed to create glad context");
- exit(EXIT_FAILURE);
- }
-
- if (flags & DAW_WINDOW_VSYNC) {
- glfwSwapInterval(1);
- } else {
- glfwSwapInterval(0);
- }
-
-
- ctx->Viewport(0, 0, w->windowsize[0], w->windowsize[1]);
-
-#ifdef _DEBUG
- ctx->ClearColor((float)0x10 / 255.f, (float)0x0a / 255.f, (float)0x33 / 255.f, 0.f);
-#else
- ctx->ClearColor(0x0, 0x0, 0x0, 0.f);
-#endif
-
- // Make sure faces closest to the camera are drawn on-top of faces that are
- // further away
- ctx->Enable(GL_DEPTH_TEST);
- ctx->DepthFunc(GL_LESS);
-
- w->context = ctx;
- w->renderer = WINDOW_RENDERER_OPENGL;
-}
-
-static void window_size(GLFWwindow *restrict w, ivec2 *restrict dst) {
- ivec2 wsize;
- vec2 wscaling;
- glfwGetWindowContentScale(w, &wscaling[0], &wscaling[1]);
- glfwGetWindowSize(w, &wsize[0], &wsize[1]);
-
- *dst[0] = (i32)((f32)wsize[0] * wscaling[0]);
- *dst[1] = (i32)((f32)wsize[1] * wscaling[1]);
-}
diff --git a/src/rendering/src/rendering.c b/src/rendering/src/rendering.c
deleted file mode 100644
index 8932cfc..0000000
--- a/src/rendering/src/rendering.c
+++ /dev/null
@@ -1,696 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-
-#include <glad/gl.h>
-#include <GLFW/glfw3.h>
-#include <cglm/cam.h>
-#include <cglm/vec2.h>
-#include <cglm/mat4.h>
-
-
-#include <engine/engine.h>
-#include <engine/utils.h>
-#include <engine/rendering/rendering.h>
-
-
-/* Extern globals */
-extern Instance* GLOBAL_PLATFORM;
-
-/* Globals */
-#define drawcall_limit (64 * 1024)
-RenderDrawCall drawcalls[drawcall_limit];
-i32 drawcall_len = 0;
-
-usize
-ShaderBufferDataType_size(u16 flags) {
- const ShaderBufferFlag t = ShaderBuffer_get_data_type(flags);
- switch (t) {
- case ShaderBuffer_DataType_nil: return 0;
- case ShaderBuffer_DataType_f32: return sizeof(f32);
- case ShaderBuffer_DataType_f64: return sizeof(f64);
- case ShaderBuffer_DataType_i8: return sizeof(i8);
- case ShaderBuffer_DataType_i16: return sizeof(i16);
- case ShaderBuffer_DataType_i32: return sizeof(i32);
- case ShaderBuffer_DataType_i64: return sizeof(i64);
- case ShaderBuffer_DataType_u8: return sizeof(u8);
- case ShaderBuffer_DataType_u16: return sizeof(u16);
- case ShaderBuffer_DataType_u32: return sizeof(u32);
- case ShaderBuffer_DataType_u64: return sizeof(u64);
- default: return 0;
- }
-}
-
-ShaderBufferFlag ShaderBuffer_get_access_frequency(u64 flags) { return flags & (0b111 << 0); }
-ShaderBufferFlag ShaderBuffer_get_access_type(u64 flags) { return flags & (0b111 << 3); }
-ShaderBufferFlag ShaderBuffer_get_type(u64 flags) { return flags & (0b111 << 6); }
-ShaderBufferFlag ShaderBuffer_get_data_type(u64 flags) { return flags & (0b1111 << 9); }
-
-u32 ShaderBuffer_get_gl_type(u64 flags) {
- switch(ShaderBuffer_get_type(flags)) {
- case ShaderBuffer_Type_vertexData:
- return GL_ARRAY_BUFFER;
- case ShaderBuffer_Type_vertexPosition:
- return GL_ARRAY_BUFFER;
- case ShaderBuffer_Type_vertexIndex:
- return GL_ELEMENT_ARRAY_BUFFER;
- default:
- return GL_ARRAY_BUFFER;
- }
-}
-
-
-u32 ShaderBuffer_get_gl_accesstype(u64 flags) {
- switch (ShaderBuffer_get_access_frequency(flags)) {
- case ShaderBuffer_AccessFrequency_stream:
- switch (ShaderBuffer_get_access_type(flags)) {
- case ShaderBuffer_AccessType_draw: return GL_STREAM_DRAW;
- case ShaderBuffer_AccessType_read: return GL_STREAM_READ;
- case ShaderBuffer_AccessType_copy: return GL_STREAM_COPY;
- default: return 0;
- }
-
- case ShaderBuffer_AccessFrequency_static:
- switch (ShaderBuffer_get_access_type(flags)) {
- case ShaderBuffer_AccessType_draw: return GL_STATIC_DRAW;
- case ShaderBuffer_AccessType_read: return GL_STATIC_READ;
- case ShaderBuffer_AccessType_copy: return GL_STATIC_COPY;
- default: return 0;
- }
- case ShaderBuffer_AccessFrequency_dynamic:
- switch (ShaderBuffer_get_access_type(flags)) {
- case ShaderBuffer_AccessType_draw: return GL_DYNAMIC_DRAW;
- case ShaderBuffer_AccessType_read: return GL_DYNAMIC_READ;
- case ShaderBuffer_AccessType_copy: return GL_DYNAMIC_COPY;
- default: return 0;
- }
- default: return 0;
- }
-}
-
-ShaderBufferFlag ShaderBuffer_get_gl_datatype(u64 flags) {
- switch (ShaderBuffer_get_data_type(flags)) {
- case ShaderBuffer_DataType_nil: return GL_NONE;
-
- case ShaderBuffer_DataType_f32: return GL_FLOAT;
- case ShaderBuffer_DataType_f64: return GL_DOUBLE;
-
- case ShaderBuffer_DataType_i8: return GL_BYTE;
- case ShaderBuffer_DataType_i16: return GL_SHORT;
- case ShaderBuffer_DataType_i32: return GL_INT;
- case ShaderBuffer_DataType_i64: return GL_INT64_ARB;
-
- case ShaderBuffer_DataType_u8: return GL_UNSIGNED_BYTE;
- case ShaderBuffer_DataType_u16: return GL_UNSIGNED_SHORT;
- case ShaderBuffer_DataType_u32: return GL_UNSIGNED_INT;
- case ShaderBuffer_DataType_u64: return GL_UNSIGNED_INT64_ARB;
-
- default: return GL_NONE;
- }
-}
-
-// `RenderBatch` is used for batch rendering. The struct is used as a
-// "management" parent structure to keep track of multiple `RenderObject`s that
-// are put into a final `RenderObject` to render.
-// `RenderObject`s are copied to the internal `models` array, to which the
-// pointer to the copied RenderObject is returned, or NULL if an error occurred.
-// If changes are made to a render object the batch should be refreshed.
-// Renderbatches assumes that all buffer layouts are the same.
-
-// renderbatch_new: Create a new render batch with space for `count` models.
-int renderbatch_new(RenderBatch* renderbatch, usize count) {
- /* TODO: Make it such that you can add identical models with different
- * transforms, so you instead of relying on renderobject[n] to copy to the
- * renderobject we have something like
- *
- * model {
- * renderobj_idx // index in renderobj[n] that this model represents
- * transform {
- * size;
- * pos;
- * rotation;
- * };
- * };
- *
- * For this to work we will likely need to extend the shaderbuffer struct to
- * also hold what type of data the buffer contains, s.t. we can apply the
- * transformation to only geometry data.
- *
- * We'll therefore have both data type and buffer type stored somehow,
- * maybe like we did the ShaderBufferDataType.
- * TODO: Also use shaderbuffertype.
- * */
- if (renderbatch == NULL) {
- ERROR("renderbatch was null!");
- return -1;
- }
-
- usize numisnstances = count;
-
- if (count == 0) {
- // Just allocate enough for a couple hundred
- count = 256;
- numisnstances = count * 4;
- }
-
-
- renderbatch->msize = sizeof(RenderObject) * count;
- renderbatch->mcount = 0;
- renderbatch->inst_size = sizeof(BatchModelInstance) * numisnstances;
- renderbatch->inst_count = 0;
- renderbatch->models = (RenderObject**)calloc(count, sizeof(RenderObject*));
-
- if (renderbatch->models == NULL) {
- ERROR("Failed to allocate %lu size of bytes for models array!", sizeof(RenderObject*) * count);
- return -1;
- }
-
- renderbatch->instances = (BatchModelInstance*)calloc(numisnstances, sizeof(BatchModelInstance));
-
- if (renderbatch->instances == NULL) {
- ERROR("Failed to allocate %lu size of bytes for batch instances array!", sizeof(BatchModelInstance) * numisnstances);
- return -1;
- }
-
- memset(&(renderbatch->renderobj), 0, sizeof(RenderObject));
-
- return 0;
-}
-
-// Appends the data in src onto dst. More space for `data` is allocated if
-// necessary, in which case a pointer to the new ShaderBuffer is returned.
-ShaderBuffer* shaderbuffer_cat(ShaderBuffer* dst, ShaderBuffer *restrict src) {
- if (dst == NULL) {
- ERROR("dst is null");
- }
- else if (src == NULL) {
- ERROR("src is null");
- }
-
- if (ShaderBuffer_get_data_type(dst->buffertype) != ShaderBuffer_get_data_type(src->buffertype)) {
- ERROR("Failed to concatenate shader buffers, incompatible datatypes: %d != %d", dst->buffertype, src->buffertype);
- }
- if (dst->components != src->components) {
- ERROR("Failed to concatenate shader buffers, incompatible number of components: %d != %d", dst->components, src->components);
- }
-
- // Assume that we single-handedly control the pointer to the data, copy and
- // free the stuff.
-
- // Verify the size
- const usize sz_src = src->size_elem * src->count;
- const usize sz_dst = dst->size_elem * dst->count;
- if (dst->data == NULL || sz_dst + sz_src >= dst->size) {
- const usize sz_new = (1 + ((sz_src + sz_dst) / 4096)) * 4096;
- // Resize dst size
- dst->data = realloc(dst->data, sz_new);
- dst->size = sz_new;
- }
-
- memcpy(dst->data + sz_dst, src->data, sz_src);
-
- dst->count += src->count;
-
- return dst;
-}
-
-// Add a render object to the render batch.
-i32 renderbatch_add(RenderBatch* renderbatch, RenderObject* obj, Transform* t) {
- // Check if its a valid renderbatch
- if (renderbatch == NULL) {
- ERROR("renderbatch was null!");
- return -1;
- }
-
- // Check whether we have initialized models & instance memory
- if (renderbatch->models == NULL) {
- const usize sz = 8 * sizeof(RenderObject*);
- renderbatch->models = calloc(8, sizeof(RenderObject*));
- renderbatch->msize = sz;
- renderbatch->mcount = 0;
- }
-
- if (renderbatch->instances == NULL) {
- // Allocate enough for 4 times the models
- const usize modelbufsz = renderbatch->msize / sizeof(RenderObject*);
- const usize sz = 4 * modelbufsz * sizeof(BatchModelInstance);
- renderbatch->instances = calloc(4 * modelbufsz, sizeof(BatchModelInstance));
- renderbatch->inst_size = sz;
- renderbatch->inst_count = 0;
- }
-
- // The index of the model
- isize model_idx = -1;
-
- // Find the model, to check if it already exists
- for (usize i = 0; i < renderbatch->mcount; i++) {
- // Compare the model pointers
- if (obj == renderbatch->models[i]) {
- model_idx = (isize)i;
- break;
- }
- }
-
- // Model doesn't exist, add it
- if (-1 == model_idx) {
- // Check if there's room enough
- if ((1 + renderbatch->mcount) * sizeof(RenderObject*) > renderbatch->msize) {
- // Realloc if necessary
- const usize sz = renderbatch->msize * 2;
- renderbatch->models = realloc(renderbatch->models, sz);
- renderbatch->msize = sz;
- }
-
- // If this is the first model, we want to copy the renderobj, and
- // shaderbuffer parameters.
- if (renderbatch->mcount == 0) {
- // Shader, VAO, modelviewprojection, and texture, are set when the shaderobj
- // is actually created with RenderObject_new later.
- // The number of buffers should be the same.
- //renderbatch->renderobj.shader = obj->shader;
- //renderbatch->renderobj.texture = obj->texture;
-
- renderbatch->renderobj.buffer_len = obj->buffer_len;
- if (renderbatch->renderobj.buffer == NULL) {
- renderbatch->renderobj.buffer = calloc(obj->buffer_len, sizeof(ShaderBuffer));
- } else {
- ERROR("RenderObj buffer is already initialized!");
- return -1;
- }
-
- // Copy each buffers parameters
- for (usize i = 0; i < renderbatch->renderobj.buffer_len; i++) {
- renderbatch->renderobj.buffer[i].buffername = 0;
- renderbatch->renderobj.buffer[i].buffertype = obj->buffer[i].buffertype;
- // Size and count should be zero
-
- renderbatch->renderobj.buffer[i].components = obj->buffer[i].components;
- renderbatch->renderobj.buffer[i].size_elem = obj->buffer[i].size_elem;
- // Data should also be null
- }
- }
-
- //// Only concatenate the buffers once we refresh
- //for (usize i = 0; i < renderbatch->renderobj.buffer_len; i++) {
- // shaderbuffer_cat(&renderbatch->renderobj.buffer[i], &obj->buffer[i]);
- //}
-
- model_idx = (isize)renderbatch->mcount;
- renderbatch->models[renderbatch->mcount++] = obj;
- }
-
- // Create batch instance
- // Check if there's room enough
- if ((1 + renderbatch->inst_count) * sizeof(BatchModelInstance) > renderbatch->inst_size) {
- // Realloc if necessary
- const usize sz = renderbatch->inst_size * 2;
- renderbatch->instances = realloc(renderbatch->instances, sz);
- renderbatch->inst_size = sz;
- }
-
- BatchModelInstance inst = {
- .model_idx = (usize)model_idx,
- .transform = *t,
- };
-
- // Add it to the batch
- renderbatch->instances[renderbatch->inst_count++] = inst;
-
- // Return instance index
- return (i32)renderbatch->inst_count - 1;
-}
-
-void renderbatch_transform(RenderBatch* renderbatch, usize obj_idx, Transform* t) {
- // TODO: Combine transformation, ie. pos' += pos, etc.
- const usize m = renderbatch->instances[obj_idx].model_idx;
- const RenderObject* model = renderbatch->models[m];
- renderbatch->instances[obj_idx].transform = *t;
-
- if(renderbatch->inst_count < obj_idx) {
- ERROR("renderbatch_transform: object index is outside range!");
- return;
- }
- /* TODO: Update the model data, we might need to
- * 0. Iteratively go through each renderobj buffer, to find a vertexPosition
- * buffer,
- * 1. Calculate the models start index in the renderobj,
- * 2. Apply transformation to the model in the renderobj buffer.
- * */
- usize b;
- for (b = 0; b < renderbatch->renderobj.buffer_len; b++) {
- if (ShaderBuffer_Type_vertexPosition != ShaderBuffer_get_type(renderbatch->renderobj.buffer[b].buffertype)
- || ShaderBuffer_DataType_f32 != ShaderBuffer_get_data_type(renderbatch->renderobj.buffer[b].buffertype)) {
- continue;
- }
- }
-
- usize offset = 0;
- for (usize i = 0; i < obj_idx; i++) {
- const usize idx = renderbatch->instances[i].model_idx;
- offset += renderbatch->models[idx]->buffer->size_elem
- * renderbatch->models[idx]->buffer->count;
- }
-
- float *data = renderbatch->renderobj.buffer[b].data;
- data = &data[offset];
- const usize len = model->buffer[b].count;
-
- Transform tt = renderbatch->instances[obj_idx].transform;
- if (model->buffer[b].components == 2) {
- for (usize v = 0; v < len; v += 2) {
- // scale
- // rotate
- // offset
- glm_vec2_add(&data[v], tt.position, &data[v]);
- }
- }
- else if (model->buffer[b].components == 3) {
- for (usize v = 0; v < len; v += 3) {
- // scale
- // rotate
- // offset
- glm_vec3_add(&data[v], tt.position, &data[v]);
- }
- }
-}
-
-// renderbatch_refresh: Copy all instances/models in the renderbatch to the
-// batchs' model.
-int renderbatch_refresh(RenderBatch* renderbatch) {
- const usize bufs = renderbatch->renderobj.buffer_len;
- usize *offsets = calloc(bufs, sizeof(usize));
-
- // Reset renderobj buffers
- for (usize b = 0; b < renderbatch->renderobj.buffer_len; b++) {
- // Zero the old data
- renderbatch->renderobj.buffer[b].count = 0;
- memset(renderbatch->renderobj.buffer[b].data, 0, renderbatch->renderobj.buffer[b].size);
- }
-
- // Copy the instances models buffers, and vertex position buffers with translations applied
- for (usize i = 0; i < renderbatch->inst_count; i++) {
- const usize m = renderbatch->instances[i].model_idx;
- const RenderObject* model = renderbatch->models[m];
- Transform t = renderbatch->instances[i].transform;
-
- for (usize b = 0; b < renderbatch->renderobj.buffer_len; b++) {
- shaderbuffer_cat(&renderbatch->renderobj.buffer[b], &model->buffer[b]);
-
- if (ShaderBuffer_Type_vertexPosition == ShaderBuffer_get_type(renderbatch->renderobj.buffer[b].buffertype)) {
- if (ShaderBuffer_DataType_f32 != ShaderBuffer_get_data_type(renderbatch->renderobj.buffer[b].buffertype)) {
- WARN("Buffer data type is not f32, skipping transformation...");
- continue;
- }
- // Apply transformation in renderbatch buffer-memory
-
- float *data = renderbatch->renderobj.buffer[b].data;
- const usize len = model->buffer[b].count;
- // Data points to the start of the model in renderobj
- data = &data[renderbatch->renderobj.buffer[b].count - len];
-
- if (model->buffer[b].components == 2) {
- for (usize v = 0; v < len; v += 2) {
- // scale
- // rotate
- // offset
- glm_vec2_add(&data[v], t.position, &data[v]);
- }
- }
- else if (model->buffer[b].components == 3) {
- for (usize v = 0; v < len; v += 3) {
- // scale
- // rotate
- // offset
- glm_vec3_add(&data[v], t.position, &data[v]);
- }
- }
- }
- }
- }
-
- free(offsets);
- return 0;
-}
-
-
-/* Implementations */
-
-/* Clear the screen,
- * To be used inbetween draw calls */
-void render_begin(Window* w) {
- glfwMakeContextCurrent(w->window);
- ((GladGLContext*)(w->context))->Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-}
-
-void render_present(Window* w) {
- /* This is GL specific, TODO: move the GL-specific code elsewhere. Maybe make
- * this whole present GL specific? assign it as a fn ptr in the Window struct? */
- GladGLContext *restrict gl = w->context;
- Camera c = *GLOBAL_PLATFORM->cam;
-
- mat4 view; // view
- vec3 angle; // viewing angle / direction of the camera
- mat4 camera_matrix;
-
- glm_vec3_sub(c.pos, c.dir, angle);
- glm_lookat(c.pos, angle, GLM_YUP, view);
- glm_mat4_mul(c.per, view, camera_matrix);
-
- for (i32 drawcall_idx = 0; drawcall_idx < drawcall_len; drawcall_idx++) {
- RenderDrawCall dc = drawcalls[drawcall_idx];
- switch (dc.type) {
- case RenderDrawCallType_Sprite: {
- // TODO render a quad
- } break;
-
- case RenderDrawCallType_Model: {
-
- // bind shader program
- // - set uniforms
- // bind vertex array
- // bind index buffer
-
-
- RenderObject* o = dc.data.model.model;
- vec3 pos;
- glm_vec3_copy(dc.data.model.pos, pos);
-
- gl->UseProgram(o->shader.program);
- // TODO: Use texture atlas
- gl->ActiveTexture(GL_TEXTURE0);
- gl->BindTexture(GL_TEXTURE_2D, o->texture);
-
- {
- mat4 model = GLM_MAT4_IDENTITY_INIT;
- mat4 modelviewprojection;
-
- model[3][0] = pos[0];
- model[3][1] = pos[1];
- model[3][2] = pos[2];
-
- // modelviewprojection = p * view * model
- glm_mat4_mul(model, camera_matrix, modelviewprojection);
-
- // TODO: Do this only once during initialization
- gl->UniformMatrix4fv(o->mvp, 1, GL_FALSE, &modelviewprojection[0][0]);
- }
-
- // TODO the buffers need to be abstracted a bit more
- gl->BindVertexArray(o->vao);
-
- ShaderBuffer* ibo = NULL;
- for (usize i = 0; i < o->buffer_len; i++) {
- const u32 b_gl_type = ShaderBuffer_get_gl_type(o->buffer[i].buffertype);
- if (b_gl_type == GL_ELEMENT_ARRAY_BUFFER) {
- ibo = &o->buffer[i];
- }
-
- gl->EnableVertexAttribArray((u32)i);
- gl->BindBuffer(b_gl_type, o->buffer[i].buffername);
- gl->VertexAttribPointer(
- // index of the attribute
- (u32)i,
- // number of component
- (i32)o->buffer[i].components,
- // type
- ShaderBuffer_get_gl_datatype(o->buffer[i].buffertype),
- // normalized?
- GL_FALSE,
- // stride
- 0,
- // array buffer offset
- (void*)0
- );
- }
-
- // Draw the model !
- const i32 sz = (i32)(o->buffer->count * o->buffer->size_elem);
- if (ibo) {
- gl->DrawElements(
- GL_TRIANGLES,
- (i32)ibo->count,
- ShaderBuffer_get_gl_datatype(ibo->buffertype),
- (void*)0
- );
- } else {
- // Starting from vertex 0; 3 vertices total -> 1 triangle
- gl->DrawArrays(GL_TRIANGLES, 0, sz);
- }
-
- for (u32 i = 0; i < o->buffer_len; i++) {
- gl->DisableVertexAttribArray(i);
- }
-
- gl->BindVertexArray(0);
-
- //if (i == 8) {
- // printf("\r obj: %.3f", (double)(get_time() - t) * 1000.);
- //}
- } break;
- default:
- break;
- }
- }
-
- drawcall_len = 0;
-
- glfwSwapBuffers(w->window);
-}
-
-void drawcall_reset(void) {
- drawcall_len = 0;
- memset(drawcalls, 0, sizeof(RenderDrawCall) * drawcall_limit);
-}
-
-void r_perspective(f32 fov, Camera *c) {
- const f32 ratio = (f32)GLOBAL_PLATFORM->window->windowsize[0]
- / (f32)GLOBAL_PLATFORM->window->windowsize[1];
-
- c->type = Camera_Perspective;
- c->parameters.perspective.fov = fov;
-
- glm_perspective(glm_rad(fov), ratio, 0.1f, 100.0f, c->per);
-}
-
-void r_perspective_ortho(f32 sz, Camera *c) {
- const f32 ratio = (f32)GLOBAL_PLATFORM->window->windowsize[0]
- / (f32)GLOBAL_PLATFORM->window->windowsize[1];
-
- c->type = Camera_Orthogonal;
- c->parameters.orthogonal.sz = sz;
-
- glm_ortho(-sz * ratio, sz * ratio, -sz, sz, -sz * 10.f, sz * 10.f, c->per);
-}
-
-void r_set_camera(Camera* c) {
- GLOBAL_PLATFORM->cam = c;
-}
-
-
-void r_reset_camera(Camera* c) {
- if (c->type == Camera_Perspective) {
- r_perspective(c->parameters.perspective.fov, c);
- }
- else if (c->type == Camera_Orthogonal) {
- r_perspective_ortho(c->parameters.orthogonal.sz, c);
- }
-}
-
-void engine_draw_sprite(Sprite* s, ivec2* pos, f32 scale) {
- if (drawcall_len + 1 >= drawcall_limit) return;
-#ifdef _DEBUG
- if (s == NULL) __asm__("int3;");
-#endif
- drawcalls[drawcall_len++] =
- (RenderDrawCall){.type = RenderDrawCallType_Sprite,
- .data.sprite = {
- .sprite = s,
- .x = *pos[0],
- .y = *pos[1],
- .scale = scale,
- //.mod = {0xFF, 0xFF, 0xFF, 0xFF},
- }};
-}
-
-void engine_draw_sprite_ex(Sprite* s, ivec2* pos, f32 scale,
- Engine_color colormod) {
- if (drawcall_len + 1 >= drawcall_limit) return;
-#ifdef _DEBUG
- if (s == NULL) __asm__("int3;");
-#endif
- drawcalls[drawcall_len++] = (RenderDrawCall){
- .type = RenderDrawCallType_Sprite,
- .data.sprite = {
- .sprite = s,
- .x = *pos[0],
- .y = *pos[1],
- .scale = scale,
- //.mod = {colormod.r, colormod.g, colormod.b, colormod.a},
- }};
-}
-
-void engine_draw_model(RenderObject* o, vec3 pos) {
- if (drawcall_len + 1 >= drawcall_limit) return;
-#ifdef _DEBUG
- if (o == NULL) __asm__("int3;");
-#endif
- RenderDrawCall dc = {
- .type = RenderDrawCallType_Model,
- .data.model = {
- .model = o,
- .scale = 1.f,
- }};
-
-
- glm_vec3_copy(pos, dc.data.model.pos);
-
- drawcalls[drawcall_len++] = dc;
-}
-
-Sprite sprite_new(u64 tid, u8 coord) {
- const i32 ts = 16;
- // FIXME; used to be
- //((struct Resources*)GLOBAL_PLATFORM->data)->textures[tid]->tilesize;
- return (Sprite){
- .texture_id = (u32)tid,
- {
- ts * (coord & 0x0F),
- ts * ((coord & 0xF0) >> 4),
- }};
-}
-
-Texture createTextureFromImageData(unsigned char* image_data, i32 width, i32 height, u8 components) {
- Window* restrict w = GLOBAL_PLATFORM->window;
- Texture t;
- t.width = width;
- t.height = height;
-
- if (w->renderer != WINDOW_RENDERER_OPENGL) {
- ERROR("createTextureFromImageData not implemented for chosen renderer!");
- return (Texture){.id = 0, .width = 0, .height = 0};
- }
-
- const GladGLContext* gl = w->context;
-
- gl->GenTextures(1, &t.id);
- gl->BindTexture(GL_TEXTURE_2D, t.id);
- u32 err = gl->GetError();
- if (err) {
- ERROR("Failed to bind texture from image data!");
- }
-
- /* TODO: Support more formats than rgb and rgba, such as gray, gray/alpha, etc.*/
- u32 format = GL_RGB;
- if (components == 4) format = GL_RGBA;
-
- /* TODO: Don't force internal format to RGB */
-
- gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, format,
- GL_UNSIGNED_BYTE, image_data);
-
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
- gl->BindTexture(GL_TEXTURE_2D, 0);
-
- return t;
-}
diff --git a/src/rendering/src/window.c b/src/rendering/src/window.c
deleted file mode 100644
index d761543..0000000
--- a/src/rendering/src/window.c
+++ /dev/null
@@ -1,83 +0,0 @@
-#include <time.h>
-
-/* TODO: REMOVE THIS INCLUSION */
-#include <engine/engine.h>
-
-#include <engine/core/types.h>
-#include <engine/core/logging.h>
-
-#define ENGINE_RENDERING_WINDOW_H_EXCLUDE_EXTERNS
-#include <engine/rendering/window.h>
-#undef ENGINE_RENDERING_WINDOW_H_EXCLUDE_EXTERNS
-
-#include <engine/rendering/platform_glfw.h>
-
-#include <glad/gl.h>
-
-#undef GLFW_INCLUDE_NONE
-#include <GLFW/glfw3.h>
-
-#include <cglm/ivec2.h>
-
-extern Instance* GLOBAL_PLATFORM;
-
-static inline u64 platform_get_time_usec(void) {
- struct timespec t;
- int res = clock_gettime(CLOCK_MONOTONIC, &t);
- if (res != 0) {
- // TODO: Check errno
- WARN("Failed to get system time");
- }
- return (u64)(t.tv_sec * 1000000 + t.tv_nsec / 1000);
-}
-
-/* wrapper to get time in ms */
-u64 (*get_time)(void) = platform_get_time_usec;
-
-
-#define DAW_WINDOW_VSYNC (1 << 0)
-#define DAW_WINDOW_FULLSCREEN (1 << 1)
-#define DAW_WINDOW_RESIZEABLE (1 << 2)
-
-// Wrapper to get a specific window and set up related structures.
-Window* Window_new(const char *restrict title, Window_framework framework, Window_renderer renderer, ivec2 size, u32 flags) {
- Window* w = NULL;
-
- switch (framework) {
- case WINDOW_FRAMEWORK_GLFW:
- switch (renderer) {
- case WINDOW_RENDERER_OPENGL:
- /* For now, pass instance as NULL, fix it once all the necessary bs is
- * out of struct Instance */
- w = Platform_GLFW.window_init(title, size, flags);
-
- w->bindings = NULL;
- w->bindings_sz = 0;
- w->bindings_len = 0;
-
- /// TODO
- //w->cam = &default_camera;
- return w;
- break;
- default:
- ERROR("Unsupported renderer.");
- }
- break;
- default:
- ERROR("Unsupported framework.");
- }
- return NULL;
-}
-
-void get_mousepos(double *x, double *y) {
- Window* w = GLOBAL_PLATFORM->window;
-
- switch(w->framework) {
- case WINDOW_FRAMEWORK_GLFW:
- glfwGetCursorPos(GLOBAL_PLATFORM->window->window, x, y);
- break;
- default:
- ERROR("get_mouse_pos not implemented for chosen framework.");
- }
-
-}