summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoronelin <oscar@nelin.dk>2025-11-29 22:04:52 +0000
committeronelin <oscar@nelin.dk>2025-12-18 21:14:16 +0000
commit07116cd28845c3e589ab7e99f32d0ab96dd5cf4d (patch)
tree0382594d2d58376daa527aaa131d81d8273834a5 /src
parentc2335eab1db200481c3e81664f27f9244579397c (diff)
TMP Rework rendering
Diffstat (limited to 'src')
-rw-r--r--src/api/daw.h13
-rw-r--r--src/daw.c124
-rw-r--r--src/gl.c1
-rw-r--r--src/include/daw/rendering.h74
-rw-r--r--src/include/daw/window.h3
-rw-r--r--src/platform_glfw.c3
-rw-r--r--src/rendering.c340
-rw-r--r--src/window.c27
8 files changed, 400 insertions, 185 deletions
diff --git a/src/api/daw.h b/src/api/daw.h
index 2676170..259c743 100644
--- a/src/api/daw.h
+++ b/src/api/daw.h
@@ -6,8 +6,9 @@ extern "C" {
#endif
#include <daw/types.h>
-#include <daw/window.h>
+#include <daw/state.h>
+typedef struct Instance Instance;
/* Essential functions */
Instance* engine_init(const char* windowtitle, i32 windowWidth, i32 windowHeight,
@@ -21,16 +22,6 @@ void engine_stop(Instance* p);
/* Utility functions */
void engine_fps_max(Instance* p, u16 cap);
-void render_set_zoom(f32 new_zoom);
-void render_adjust_zoom(f32 diff);
-void render_add_unit(RenderUnit* u);
-
-/* move this */
-void delay(uint64_t ms);
-
-// file operations
-usize f_get_sz(FILE* f);
-
#ifdef __cplusplus
}
diff --git a/src/daw.c b/src/daw.c
index 284bfc7..2d6a764 100644
--- a/src/daw.c
+++ b/src/daw.c
@@ -41,10 +41,8 @@
Instance* GLOBAL_PLATFORM = NULL;
-static Camera default_camera = {
- .pos = {3, 0, 0},
- .dir = {1, 1, 1},
-};
+#define DEFAULT_CAMERA { .pos = {3, 0, 0}, .dir = {1, 1, 1}, }
+static Camera default_camera = DEFAULT_CAMERA;
input_callback_t* callbacks[128];
usize callbacks_len;
@@ -159,8 +157,74 @@ Instance* engine_init(const char* windowtitle, i32 windowWidth, i32 windowHeight
return p;
}
+// TODO: MOVE TO RENDERING
+static f32 default_quad[8] = {
+ -1.0f, -1.0f,
+ 1.0f, -1.0f,
+ 1.0f, 1.0f,
+ -1.0f, 1.0f,
+};
+
+static f32 default_quad_uv[8] = {
+ 0.f, 0.f,
+ 1.f, 0.f,
+ 1.f, 1.f,
+ 0.f, 1.f,
+};
+
+static u8 default_quad_ibo[6] = {
+ 0, 1, 2,
+ 2, 3, 0,
+};
+
+// TODO: CREATE DEFAULT SHADERBUFF
+#define COUNT(a) sizeof(a) / sizeof(a[0])
+static ShaderBuffer shaderbuf[3] = {
+ SHADERBUFFER_NEW(f32, COUNT(default_quad), 2, default_quad, ShaderBuffer_AccessFrequency_static | ShaderBuffer_AccessType_draw | ShaderBuffer_Type_vertexPosition),
+ SHADERBUFFER_NEW(f32, COUNT(default_quad_uv), 2, default_quad_uv, ShaderBuffer_AccessFrequency_static | ShaderBuffer_AccessType_draw),
+ SHADERBUFFER_NEW(u8, COUNT(default_quad_ibo), 3, default_quad_ibo, ShaderBuffer_AccessFrequency_static | ShaderBuffer_AccessType_draw | ShaderBuffer_Type_vertexIndex),
+};
+#undef COUNT
+
+static const char* default_quad_shader_vertex_src =
+"#version 330 core"
+""
+"layout(location = 0) in vec3 vertexPosition_modelspace;"
+"layout(location = 1) in vec2 vertexUV;"
+""
+"out vec2 UV;"
+""
+"void main() {"
+" gl_Position = vec4(vertexPosition_modelspace, 0, 0);"
+""
+" UV = vertexUV;"
+"}";
+
+static const char* default_quad_shader_fragment_src =
+"#version 330 core"
+""
+"// Ouput data"
+"in vec2 UV;"
+"out vec3 color;"
+""
+"uniform sampler2D textureSampler;"
+""
+"void main() {"
+" color = texture(textureSampler, UV).rgb;"
+"}";
+
+
i32 engine_run(Instance* p, StateType initial_state, void* state_arg) {
+ // TODO: MOVE TO INIT
+ Shader default_quad_shaders[] = {
+ compile_shader(default_quad_shader_vertex_src, Shader_Vertex),
+ compile_shader(default_quad_shader_fragment_src, Shader_Fragment),
+ (Shader){0},
+ };
+ default_quad_shaders[2] = compose_shader(default_quad_shaders, 2);
+ RenderObject default_quad_renderobject;
+
if (p == NULL) {
ERROR("Platform is uninitialized.\n");
INFO("initialize with `engine_init`");
@@ -172,6 +236,7 @@ i32 engine_run(Instance* p, StateType initial_state, void* state_arg) {
StateType state = initial_state;
Window* w = p->window;
+ Camera default_renderbuffer_camera = default_camera;
{
u64 state_init_time = get_time();
@@ -187,8 +252,28 @@ i32 engine_run(Instance* p, StateType initial_state, void* state_arg) {
BUFFERPARAMETER_SET_PARAMETER(BUFFERPARAMETER_SET_TYPE(0, BufferType_texture), BUFFERPARAMETER_TEXTURE_2D)
};
window_init_renderstack(w, 1, 1, p, t);
- w->render_targets->cam[0] = default_camera;
+ //w->render_targets->cam[0] = &default_renderbuffer_camera;
}
+
+ u32 first_texture = 0;
+
+ for (usize i = 0; i < w->render_targets->buffer_len; i++) {
+ if (BUFFERPARAMETER_GET_TYPE(w->render_targets->buffer_parameters[i]) == BufferType_texture) {
+ first_texture = w->render_targets->buffer[i];
+ break;
+ }
+ }
+
+ default_quad_renderobject = RenderObject_new(
+ // Shader
+ &default_quad_shaders[2],
+ // Texture
+ first_texture,
+ // Vertices
+ shaderbuf,
+ sizeof(shaderbuf) / sizeof(ShaderBuffer)
+ );
+
INFO("Initializing state \"%s\" took %.1fns", StateTypeStr[state],
(get_time() - state_init_time));
}
@@ -248,15 +333,36 @@ i32 engine_run(Instance* p, StateType initial_state, void* state_arg) {
// Create only 1 additional framebuffer, in addition to the default
// one. This is used to render a texture that is represented as a quad
// on the default framebuffer.
- FramebufferParameters p[] = {
+ FramebufferParameters fb_params[] = {
{.num_attached_buffers = 1, {200,200}},
};
u32 t[] = {
BUFFERPARAMETER_SET_PARAMETER(BUFFERPARAMETER_SET_TYPE(0, BufferType_texture), BUFFERPARAMETER_TEXTURE_2D)
};
- window_init_renderstack(w, 1, 1, p, t);
- w->render_targets->cam[0] = default_camera;
+ window_init_renderstack(w, 1, 1, fb_params, t);
+
+ //w->render_targets->cam[0] = &default_camera;
}
+
+ u32 first_texture = 0;
+
+ for (usize i = 0; i < w->render_targets->buffer_len; i++) {
+ if (BUFFERPARAMETER_GET_TYPE(w->render_targets->buffer_parameters[i]) == BufferType_texture) {
+ first_texture = w->render_targets->buffer[i];
+ break;
+ }
+ }
+
+ default_quad_renderobject = RenderObject_new(
+ // Shader
+ &default_quad_shaders[2],
+ // Texture
+ first_texture, /*TODO*/
+ // Vertices
+ shaderbuf,
+ sizeof(shaderbuf) / sizeof(ShaderBuffer)
+ );
+
INFO("Initializing state \"%s\" took %.1fns", StateTypeStr[state],
(get_time() - state_init_time));
}
@@ -265,7 +371,7 @@ i32 engine_run(Instance* p, StateType initial_state, void* state_arg) {
/* Render */
const u64 rendertime_begin = get_time();
render_begin(p->window);
- render_present(p->window);
+ render_present(p->window, &default_quad_renderobject);
const u64 rendertime_dt = get_time() - rendertime_begin;
/* Regulate FPS */
diff --git a/src/gl.c b/src/gl.c
index e84b33d..a512b46 100644
--- a/src/gl.c
+++ b/src/gl.c
@@ -248,6 +248,7 @@ RenderObject RenderObject_new(
o.shader = *shader;
o.texture = texture;
+ o.texture_len = 1;
o.buffer = buffers;
o.buffer_len = num_buffers;
o.mvp = gl->GetUniformLocation(o.shader.program, "MVP");
diff --git a/src/include/daw/rendering.h b/src/include/daw/rendering.h
index 590bcb6..a26310e 100644
--- a/src/include/daw/rendering.h
+++ b/src/include/daw/rendering.h
@@ -124,6 +124,7 @@ typedef struct {
// The texture ID, glBindTextures(target, &this->texture)
u32 texture;
+ u32 texture_len;
// Number of buffers
usize buffer_len;
@@ -191,30 +192,6 @@ typedef struct {
} 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);
-
-/* Misc */
-void r_perspective(Camera *c, f32 fov, ivec2 windowsize);
-void r_perspective_ortho(Camera *c, f32 sz, ivec2 windowsize);
-
-void r_set_camera(Camera* c);
-void r_reset_camera(Camera* c, ivec2 windowsize);
-
-//void window_size_callback(GLFWwindow* window, i32 width, i32 height);
-
-// 3D positional coordinates and scale in last element of `pos`
-void engine_draw_model(RenderObject* o, vec4 pos);
-
typedef struct {
vec3 pos;
f32 scale;
@@ -231,11 +208,14 @@ typedef enum {
// Buffer parameter: Frame buffer
// Buffer parameter: Texture buffer
+#define BUFFERPARAMETER_TEXTURE_GET_DIMENSION(bufferparam) (BUFFERPARAMETER_GET_PARAMETER(bufferparam) & 7)
#define BUFFERPARAMETER_TEXTURE_1D 1
#define BUFFERPARAMETER_TEXTURE_2D 2
#define BUFFERPARAMETER_TEXTURE_3D 3
#define BUFFERPARAMETER_TEXTURE_4D 4
+// TODO: Change `2` once we add support for more formats
+#define BUFFERPARAMETER_TEXTURE_GET_FORMAT(bufferparam) (BUFFERPARAMETER_GET_PARAMETER(bufferparam) >> 3 & 2)
#define BUFFERPARAMETER_TEXTURE_FMT_RGBA8 (1 << 4)
#define BUFFERPARAMETER_TEXTURE_FMT_SRGB8 (2 << 4)
#define BUFFERPARAMETER_TEXTURE_FMT_SRGBA8 (3 << 4)
@@ -263,7 +243,7 @@ typedef enum {
typedef struct {
i32 num_attached_buffers;
- ivec4 dimensions; // All objects attached to a framebuffer (in OpenGL) must have same size
+ ivec3 dimensions; // All objects attached to a framebuffer (in OpenGL) must have same size
} FramebufferParameters;
// A render target takes a bunch of drawcalls, and renders it to a texture.
@@ -273,22 +253,15 @@ typedef struct {
// glFrameBuffer
usize framebuffer_len;
- // glTexture / glRenderBuffer / glBuffer / glWhatever
- usize buffer_len;
-
u32 *framebuffer;
- u32 *buffer;
// Number of buffers attached to each of the framebuffers. Used to iteratively
// get all buffers by summing the previous sizes to get the first buffer
// associated with the current.
FramebufferParameters *framebuffer_parameters;
- // Stores per-buffer type, and type-specific parameters.
- u32 *buffer_parameters;
-
- // One cam per framebuffer
- Camera *cam;
+ // One cam per framebuffer, is usually a pointer to user-allocated camera
+ Camera **cam;
//// Called when window is resized with new width and height. Set to NULL to
//// skip changing texture_size. Comparable to glViewport.
@@ -301,8 +274,38 @@ typedef struct {
//// called with the new dimensions of the texture.
//// Set to NULL to skip changing the camera size/perspective.
void (**camera_reset_callback)(Camera*,ivec2);
+
+ // glTexture / glRenderBuffer / glBuffer / glWhatever
+ usize buffer_len;
+ u32 *buffer;
+ // Stores per-buffer type, and type-specific parameters.
+ u32 *buffer_parameters;
} RenderTargets;
+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);
+
+/* Misc */
+void r_perspective(Camera *c, f32 fov, ivec2 windowsize);
+void r_perspective_ortho(Camera *c, f32 sz, ivec2 windowsize);
+
+void r_set_camera(RenderTargets *restrict t, i32 framebuffer_idx, Camera *restrict c);
+void r_reset_camera(Camera* c, ivec2 windowsize);
+
+//void window_size_callback(GLFWwindow* window, i32 width, i32 height);
+
+// 3D positional coordinates and scale in last element of `pos`
+void r_draw_model(void *restrict context, RenderTargets *restrict t, u32 framebuffer_idx, RenderObject* o, vec4 pos);
+
void r_camera_reset_default(Camera* c, ivec2 windowsize);
RenderObject RenderObject_new(
@@ -328,8 +331,9 @@ Texture createTextureFromImageData(unsigned char* image_data, i32 width, i32 hei
void r_create_framebuffers(void* restrict ctx, u32* restrict framebuffer_array, usize num_targets);
void r_destroy_framebuffers(void* restrict ctx, u32* restrict framebuffer_array, usize num_targets);
-void r_create_textures(void *restrict ctx, u32* restrict texture_array, u32* restrict texture_types, ivec4* restrict texture_sizes, usize num_targets);
+void r_create_textures(void *restrict ctx, u32* restrict texture_array, u32* restrict texture_types, ivec3* restrict texture_sizes, usize num_targets);
void r_destroy_textures(void *restrict ctx, u32* textures, usize num_textures);
+void r_attach_buffers(void *restrict ctx, u32 fbo, u32* buffers, u32* buffer_parameters, i32 num_buffers);
void r_init_renderstack(
usize num_fbuf, usize num_buf,
diff --git a/src/include/daw/window.h b/src/include/daw/window.h
index 44ea1fa..4e00774 100644
--- a/src/include/daw/window.h
+++ b/src/include/daw/window.h
@@ -99,9 +99,10 @@ Window* Window_new(const struct Platform *p, const char *restrict title, Window_
/* Rendering functions */
void render_begin(Window* w);
-void render_present(Window* w);
+void render_present(Window* w, RenderObject *restrict default_quad);
void window_reset_drawing(void);
void render(Window* w);
+void draw_model(Window *restrict w, u32 framebuffer_idx, RenderObject* o, vec4 pos);
void window_init_renderstack(Window *restrict w,
usize num_fbuf, usize num_buf,
diff --git a/src/platform_glfw.c b/src/platform_glfw.c
index 5453258..92e29a2 100644
--- a/src/platform_glfw.c
+++ b/src/platform_glfw.c
@@ -133,6 +133,7 @@ void window_destroy_glfw(Window *restrict w) {
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);
+ DEBUG("Resizing to <%d,%d>\n", width, height);
}
bool window_should_close_glfw(Window *restrict window) {
@@ -152,6 +153,7 @@ static void window_resize_callback(GLFWwindow* window, int width, int height) {
const GladGLContext* gl = w->context;
gl->Finish();
}
+ DEBUG("WINDOW RESIZE <%d,%d>\n", width, height);
}
static void framebuffer_resize_callback(GLFWwindow* window, int width, int height) {
@@ -167,6 +169,7 @@ static void framebuffer_resize_callback(GLFWwindow* window, int width, int heigh
//r_reset_camera(c);
}
+ DEBUG("FRAMEBUFFER RESIZE <%d,%d>\n", width, height);
}
static void glfw_err_callback(int code, const char* description) {
diff --git a/src/rendering.c b/src/rendering.c
index 76df988..8f7104e 100644
--- a/src/rendering.c
+++ b/src/rendering.c
@@ -1,4 +1,3 @@
-#include <stdio.h>
#include <string.h>
#include <glad/gl.h>
@@ -11,16 +10,12 @@
#include <daw/daw.h>
#include <daw/utils.h>
#include <daw/rendering.h>
+#include <daw/logging.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);
@@ -441,114 +436,62 @@ void render_begin(Window* w) {
((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];
-
- // bind shader program
- // - set uniforms
- // bind vertex array
- // bind index buffer
-
+void render_present(Window* w, RenderObject *restrict default_quad) {
+ const GladGLContext *restrict gl = w->context;
+ gl->UseProgram(default_quad->shader.program);
+ gl->BindTextureUnit(0, default_quad->texture);
+ gl->BindVertexArray(default_quad->vao);
- const RenderObject* const restrict o = dc.model;
- vec3 pos;
- glm_vec3_copy(dc.pos, pos);
-
- gl->UseProgram(o->shader.program);
- // TODO: Use texture atlas
- gl->BindTextureUnit(0, 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]);
- gl->UniformMatrix4fv(o->model_position, 1, GL_FALSE, &model[0][0]);
+ ShaderBuffer* ibo = NULL;
+ for (usize i = 0; i < default_quad->buffer_len; i++) {
+ const u32 b_gl_type = ShaderBuffer_get_gl_type(default_quad->buffer[i].buffertype);
+ if (b_gl_type == GL_ELEMENT_ARRAY_BUFFER) {
+ ibo = &default_quad->buffer[i];
}
- // 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->EnableVertexAttribArray((u32)i);
+ gl->BindBuffer(b_gl_type, default_quad->buffer[i].buffername);
+ gl->VertexAttribPointer(
+ // index of the attribute
+ (u32)i,
+ // number of component
+ (i32)default_quad->buffer[i].components,
+ // type
+ ShaderBuffer_get_gl_datatype(default_quad->buffer[i].buffertype),
+ // normalized?
+ GL_FALSE,
+ // stride
+ 0,
+ // array buffer offset
+ (void*)0
+ );
+ }
- gl->BindVertexArray(0);
+ // Draw the model !
+ const i32 sz = (i32)(default_quad->buffer->count * default_quad->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);
+ }
- //if (i == 8) {
- // printf("\r obj: %.3f", (double)(get_time() - t) * 1000.);
- //}
+ for (u32 i = 0; i < default_quad->buffer_len; i++) {
+ gl->DisableVertexAttribArray(i);
}
- drawcall_len = 0;
+ gl->BindVertexArray(0);
glfwSwapBuffers(w->window);
}
void window_reset_drawing(void) {
- drawcall_len = 0;
- memset(drawcalls, 0, sizeof(RenderDrawCall) * drawcall_limit);
+ // Clear
}
void r_perspective(Camera *c, f32 fov, ivec2 windowsize) {
@@ -569,10 +512,12 @@ void r_perspective_ortho(Camera *c, f32 sz, ivec2 windowsize) {
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_set_camera(RenderTargets *restrict t, i32 framebuffer_idx, Camera *restrict c) {
+ ASSERT(t != NULL);
+ ASSERT(framebuffer_idx == -1 || framebuffer_idx < (i32)t->framebuffer_len);
+ t->cam[framebuffer_idx] = c;
+}
void r_reset_camera(Camera* c, ivec2 windowsize) {
if (c->type == Camera_Perspective) {
@@ -584,19 +529,92 @@ void r_reset_camera(Camera* c, ivec2 windowsize) {
}
-void engine_draw_model(RenderObject* o, vec4 pos) {
- if (drawcall_len + 1 >= drawcall_limit) return;
-#ifdef _DEBUG
- if (o == NULL) __asm__("int3;");
-#endif
- RenderDrawCall dc = {
- .model = o,
- .scale = pos[3],
- };
+void r_draw_model(void *restrict context, RenderTargets *restrict t, u32 framebuffer_idx, RenderObject* o, vec4 pos) {
+ ASSERT(context != NULL);
+ ASSERT(t != NULL);
+ ASSERT(t->framebuffer != NULL);
+ ASSERT(t->cam != NULL);
+ ASSERT(t->cam[framebuffer_idx] != NULL);
+
+ const GladGLContext *restrict gl = context;
+ Camera c = *t->cam[framebuffer_idx];
+ //const f32 s = pos[3];
+
+ 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);
+
+ gl->UseProgram(o->shader.program);
+ // ENUMERATE FRAMEBUFFER TEXTURES
+ gl->BindTextureUnit(0, 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]);
+ gl->UniformMatrix4fv(o->model_position, 1, GL_FALSE, &model[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
+ );
+ }
- glm_vec3_copy(pos, dc.pos);
+ // 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);
+ }
- drawcalls[drawcall_len++] = dc;
+ gl->BindVertexArray(0);
}
@@ -691,22 +709,100 @@ void r_destroy_framebuffers(void* restrict ctx, u32* restrict framebuffer_array,
}
void r_create_textures(void* restrict ctx, u32* restrict texture_array,
- u32* restrict texture_types,
- ivec4* restrict texture_size, usize num_targets) {
+ u32* restrict texture_parameters,
+ ivec3* restrict texture_size, usize num_targets) {
const GladGLContext* gl = (GladGLContext*)ctx;
- gl->CreateTextures(GL_TEXTURE_2D, num_targets, texture_array);
+ u32 texture_dim = BUFFERPARAMETER_TEXTURE_GET_DIMENSION(texture_parameters[0]);
+ u32 texture_format = BUFFERPARAMETER_TEXTURE_GET_DIMENSION(texture_parameters[0]);
+ u32 gl_texture_format;
+ u32 err;
+
+ for (usize i = 1; i < num_targets; i++) {
+ ASSERT(texture_dim == BUFFERPARAMETER_TEXTURE_GET_DIMENSION(texture_parameters[i]));
+ ASSERT(texture_format == BUFFERPARAMETER_TEXTURE_GET_FORMAT(texture_parameters[i]));
+ }
+
+ switch (texture_format) {
+ case BUFFERPARAMETER_TEXTURE_FMT_RGBA8: gl_texture_format = GL_RGBA8; break;
+ case BUFFERPARAMETER_TEXTURE_FMT_SRGB8: gl_texture_format = GL_SRGB; break;
+ case BUFFERPARAMETER_TEXTURE_FMT_SRGBA8: gl_texture_format = GL_SRGB8_ALPHA8; break;
+ default:
+ ERROR("Failed to convert format to GL internal format!");
+ exit(EXIT_FAILURE);
+ }
+
+ // Convert the texturetype to GL texturetype
+ switch (texture_dim) {
+ case BUFFERPARAMETER_TEXTURE_1D:
+ gl->CreateTextures(GL_TEXTURE_1D, num_targets, texture_array);
+ for (usize i = 0; i < num_targets; i++) {
+ gl->TextureStorage1D(texture_array[i], 1, gl_texture_format, *texture_size[0]);
+ }
+ break;
+
+ case BUFFERPARAMETER_TEXTURE_2D:
+ gl->CreateTextures(GL_TEXTURE_2D, num_targets, texture_array);
+ for (usize i = 0; i < num_targets; i++) {
+ gl->TextureStorage2D(texture_array[i], 1, gl_texture_format, *texture_size[0], *texture_size[1]);
+ }
+ break;
+
+ case BUFFERPARAMETER_TEXTURE_3D:
+ gl->CreateTextures(GL_TEXTURE_3D, num_targets, texture_array);
+ for (usize i = 0; i < num_targets; i++) {
+ gl->TextureStorage3D(texture_array[i], 1, gl_texture_format, *texture_size[0], *texture_size[1], *texture_size[2]);
+ }
+ break;
+ case BUFFERPARAMETER_TEXTURE_4D:
+ ERROR("4D textures are unsupported!");
+ exit(EXIT_FAILURE);
+
+ default:
+ ERROR("Failed to convert dimensionality to GL_TEXTURE_XD");
+ exit(EXIT_FAILURE);
+ }
+ err = gl->GetError();
+
+ if (err) {
+ ERROR("Failed to create textures!");
+ }
+
+ // This should probably be changed in the future
for (usize i = 0; i < num_targets; i++) {
- ASSERT("SWITCH CASE ON BUFFER DIMENSIONALITY");
- ASSERT("SWITCH CASE ON TEXTURE DATA TYPE");
- gl->TextureStorage2D(texture_array[i], 1, texture_types[i], *texture_size[0], *texture_size[1]);
gl->TextureParameteri(texture_array[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
gl->TextureParameteri(texture_array[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
+
+ err = gl->GetError();
+
+ if (err) {
+ ERROR("Failed to set texture parameters!");
+ }
}
void r_destroy_textures(void *restrict ctx, u32* textures, usize num_textures) {
const GladGLContext* gl = (GladGLContext*)ctx;
gl->DeleteTextures(num_textures, textures);
}
+
+void r_attach_buffers(void *restrict ctx, u32 fbo, u32* buffers, u32* buffer_parameters, i32 num_buffers) {
+ const GladGLContext *restrict gl = (GladGLContext*)ctx;
+
+ u32 err;
+
+ for (i32 i = 0; i < num_buffers; i++) {
+ BufferType t = BUFFERPARAMETER_GET_TYPE(buffer_parameters[i]);
+
+ if (t != BufferType_texture) UNIMPLEMENTED;
+
+ // TODO: FINISH ME
+ gl->NamedFramebufferTexture(fbo, GL_COLOR_ATTACHMENT0 + i, buffers[i], 0);
+
+ err = gl->GetError();
+ if (err) {
+ ERROR("Failed to attach buffer!");
+ }
+ }
+}
diff --git a/src/window.c b/src/window.c
index 9702a7f..72717ab 100644
--- a/src/window.c
+++ b/src/window.c
@@ -78,7 +78,7 @@ void window_reset_cameras(Window* w, RenderTargets* restrict targets) {
// Destroy & Create framebuffers (and related buffers?)
if (targets->camera_reset_callback[i] == NULL) continue;
- (*targets->camera_reset_callback)(&targets->cam[i], w->windowsize);
+ targets->camera_reset_callback[i](targets->cam[i], w->windowsize);
}
}
@@ -130,10 +130,11 @@ void window_init_renderstack(Window *restrict w,
void* allocation = malloc(
sizeof(RenderTargets) +
sizeof(*t->framebuffer) * num_fbuf +
- sizeof(*t->buffer) * num_buf +
sizeof(*t->framebuffer_parameters) * num_fbuf +
- sizeof(*t->buffer_parameters) * num_buf +
- sizeof(*t->cam) * num_fbuf
+ sizeof(*t->cam) * num_fbuf +
+ sizeof(*t->camera_reset_callback) * num_fbuf +
+ sizeof(*t->buffer) * num_buf +
+ sizeof(*t->buffer_parameters) * num_buf
// TODO: callbacks
);
@@ -148,28 +149,36 @@ void window_init_renderstack(Window *restrict w,
u64 acc = sizeof(RenderTargets);
ADVANCE_PTR(framebuffer, num_fbuf);
- ADVANCE_PTR(buffer, num_buf);
ADVANCE_PTR(framebuffer_parameters, num_fbuf);
- ADVANCE_PTR(buffer_parameters, num_buf);
ADVANCE_PTR(cam, num_fbuf);
+ ADVANCE_PTR(camera_reset_callback, num_fbuf);
+ ADVANCE_PTR(buffer, num_buf);
+ ADVANCE_PTR(buffer_parameters, num_buf);
// TODO: callbacks
#undef ADVANCE_PTR
memcpy(t->framebuffer_parameters, fb_params, sizeof(*t->framebuffer_parameters) * num_fbuf);
memcpy(t->buffer_parameters, buffer_params, sizeof(*t->buffer_parameters) * num_buf);
+ r_create_framebuffers(w->context, &t->framebuffer[0], num_fbuf);
+
// Iteratively set up each framebuffer and framebuffer-attached objects
usize buffer_offset = 0;
for (usize fb_idx = 0; fb_idx < num_fbuf; fb_idx++) {
FramebufferParameters *p = &t->framebuffer_parameters[fb_idx];
// Check everything is a texture, cuz rn. we don't support anything else
for (isize buffer_idx = 0; buffer_idx < p->num_attached_buffers; buffer_idx++) {
- ASSERT(BUFFERPARAMETER_GET_TYPE(t->buffer_parameters[buffer_idx + buffer_offset]) == BufferType_texture);
+ ASSERT(BUFFERPARAMETER_GET_TYPE(t->buffer_parameters[buffer_offset + buffer_idx]) == BufferType_texture);
}
+
+ // Create `num_attached_buffers` identical buffers
r_create_textures(w->context, &t->buffer[buffer_offset],
&t->buffer_parameters[buffer_offset],
&t->framebuffer_parameters[fb_idx].dimensions,
t->framebuffer_parameters[fb_idx].num_attached_buffers);
+
+ r_attach_buffers(w->context, t->framebuffer[fb_idx], &t->buffer[buffer_offset], &t->buffer_parameters[buffer_offset], t->framebuffer_parameters[fb_idx].num_attached_buffers);
+
//if (BUFFERPARAMETER_GET_TYPE(buffer_params[i]) != BufferType_texture) continue;
//u32 texture_type = BUFFERPARAMETER_GET_PARAMETER(buffer_params[i]);
@@ -195,3 +204,7 @@ void window_free_renderstack(RenderTargets *restrict t) {
// Everything is in the same buffer anyways
free(t->framebuffer);
}
+
+void draw_model(Window *restrict w, u32 framebuffer_idx, RenderObject* o, vec4 pos) {
+ r_draw_model(w->context, w->render_targets, framebuffer_idx, o, pos);
+}