summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorrealtradam <[email protected]>2023-06-04 02:35:00 -0400
committerrealtradam <[email protected]>2023-06-04 02:35:00 -0400
commit35558b39040d37c939bd68b56985d6cb5385a451 (patch)
treeb10516557ba530d96799a8c4bed94b7644938811 /src
parent856ce67eb21f64d86ecf6bb3651985f10e6236c3 (diff)
downloadRodeoKit-gfx-rewrite.tar.gz
RodeoKit-gfx-rewrite.zip
refactor to have graphics and windowing seperategfx-rewrite
Diffstat (limited to 'src')
-rw-r--r--src/audio/rodeo_audio.c4
-rw-r--r--src/gfx/irodeo_gfx.h30
-rw-r--r--src/gfx/irodeo_gfx_t.h49
-rw-r--r--src/gfx/rodeo_gfx.c732
-rw-r--r--src/input/rodeo_input.c16
-rw-r--r--src/rodeo.c861
-rw-r--r--src/rodeo_internal.h29
-rw-r--r--src/rodeo_internal_types.h39
-rw-r--r--src/window/irodeo_window.h30
-rw-r--r--src/window/irodeo_window_t.h21
-rw-r--r--src/window/rodeo_window.c166
11 files changed, 1040 insertions, 937 deletions
diff --git a/src/audio/rodeo_audio.c b/src/audio/rodeo_audio.c
index 5f22357..f049fa2 100644
--- a/src/audio/rodeo_audio.c
+++ b/src/audio/rodeo_audio.c
@@ -17,7 +17,7 @@ static uint32_t **irodeo_audio_channelPool;
//void
//rodeo_audio_initialize(uint32_t num_sound_pools, uint32_t size_sound_pools)
void
-rodeo_audio_initialize(uint32_t channels)
+rodeo_audio_init(uint32_t channels)
{
if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0)
{
@@ -90,7 +90,7 @@ rodeo_audio_initialize(uint32_t channels)
}
void
-rodeo_audio_deinitialize(void)
+rodeo_audio_deinit(void)
{
free(irodeo_audio_channelPool);
Mix_Quit();
diff --git a/src/gfx/irodeo_gfx.h b/src/gfx/irodeo_gfx.h
new file mode 100644
index 0000000..3acc49f
--- /dev/null
+++ b/src/gfx/irodeo_gfx.h
@@ -0,0 +1,30 @@
+
+// -- internal --
+// public
+#include "rodeo/common.h"
+// private
+#include "gfx/irodeo_gfx_t.h"
+
+// -- external --
+#include "bgfx/c99/bgfx.h"
+#include "stc/cstr.h"
+
+bgfx_shader_handle_t
+irodeo_gfx_shader_load(const cstr path);
+
+void
+irodeo_gfx_render_buffer_transient_alloc(void);
+
+void
+irodeo_gfx_frame_stall(void);
+
+#define \
+mrodeo_bgfx_vertex_layout_do(vertex_layout) \
+ mrodeo_defer_do( \
+ bgfx_vertex_layout_begin( \
+ vertex_layout, \
+ bgfx_get_renderer_type() \
+ ), \
+ bgfx_vertex_layout_end(vertex_layout) \
+ )
+
diff --git a/src/gfx/irodeo_gfx_t.h b/src/gfx/irodeo_gfx_t.h
new file mode 100644
index 0000000..7d9d1b7
--- /dev/null
+++ b/src/gfx/irodeo_gfx_t.h
@@ -0,0 +1,49 @@
+#pragma once
+
+// -- internal --
+// public
+#include "rodeo/gfx_t.h"
+
+// -- external --
+#include "bgfx/c99/bgfx.h"
+#define CGLM_FORCE_DEPTH_ZERO_TO_ONE
+#include "cglm/mat4.h"
+
+typedef uint16_t irodeo_index_type_t;
+
+typedef
+struct
+{
+ bgfx_vertex_layout_t vertex_layout;
+ //bgfx_dynamic_vertex_buffer_handle_t vertex_buffer_handle;
+ //bgfx_dynamic_index_buffer_handle_t index_buffer_handle;
+ bgfx_transient_vertex_buffer_t vertex_buffer_handle;
+ bgfx_transient_index_buffer_t index_buffer_handle;
+ rodeo_gfx_vertex_t *batched_vertices;
+ irodeo_index_type_t *batched_indices;
+ irodeo_index_type_t vertex_size;
+ irodeo_index_type_t index_count;
+ irodeo_index_type_t index_size;
+ //irodeo_index_type_t batched_indices[(mrodeo_vertex_size_max / 4) * 6];
+ rodeo_gfx_texture_2d_t default_texture;
+ bgfx_texture_handle_t *active_texture_p;
+ bgfx_shader_handle_t vertex_shader;
+ bgfx_shader_handle_t fragment_shader;
+ bgfx_program_handle_t program_shader;
+ bgfx_uniform_handle_t texture_uniforms[2];
+ mat4 view_matrix;
+ mat4 proj_matrix;
+ uint64_t frame_count;
+ uint32_t frame_limit;
+ uint32_t frame_start;
+ uint32_t frame_end;
+ float frame_time;
+}
+irodeo_gfx_state_t;
+
+struct
+irodeo_gfx_texture_internal
+{
+ bgfx_texture_handle_t texture_bgfx;
+};
+
diff --git a/src/gfx/rodeo_gfx.c b/src/gfx/rodeo_gfx.c
new file mode 100644
index 0000000..38dc145
--- /dev/null
+++ b/src/gfx/rodeo_gfx.c
@@ -0,0 +1,732 @@
+
+// -- internal --
+// public
+#include "rodeo.h" // TODO remove this
+#include "rodeo/gfx.h"
+#include "rodeo/window.h"
+#include "rodeo/log.h"
+// private
+#include "gfx/irodeo_gfx.h"
+#include "window/irodeo_window.h"
+#include "rodeo_config.h"
+
+// -- external --
+#include "bgfx/c99/bgfx.h"
+#define CGLM_FORCE_DEPTH_ZERO_TO_ONE
+#include "cglm/cglm.h"
+#include "SDL_image.h"
+#include "SDL.h" // used for timing, need to replace in this file with BGFX at some point
+
+static irodeo_gfx_state_t irodeo_gfx_state = {0};
+
+void
+rodeo_gfx_init(void)
+{
+
+#ifdef __EMSCRIPTEN__
+ bgfx_render_frame(-1);
+#endif
+
+ bgfx_platform_data_t pd = {0};
+ memset(&pd, 0, sizeof(bgfx_platform_data_t));
+
+#if !__EMSCRIPTEN__
+ // x11
+ pd.ndt = irodeo_window_wmi_get().info.x11.display;
+ pd.nwh = (void*)(uintptr_t)irodeo_window_wmi_get().info.x11.window;
+#else
+ // web
+ pd.nwh = (void*)"#canvas";
+#endif
+
+ bgfx_init_t init = {0};
+ bgfx_init_ctor(&init);
+ //init.type = BGFX_RENDERER_TYPE_COUNT; // auto determine renderer
+ init.type = BGFX_RENDERER_TYPE_OPENGL; // force opengl renderer
+ //SDL_GetWindowSize(irodeo_gfx_state.window, &irodeo_gfx_state.screen_width, &irodeo_gfx_state.screen_height);
+ init.resolution.width = rodeo_window_screen_height_get();
+ init.resolution.height = rodeo_window_screen_width_get();
+ init.resolution.reset = BGFX_RESET_VSYNC;
+ init.platformData = pd;
+ bgfx_init(&init);
+
+ bgfx_set_debug(BGFX_DEBUG_TEXT);
+
+ //bgfx_set_state(BGFX_STATE_CULL_CCW, 0);
+
+ //bgfx_dbg_text_clear(0x65, false);
+
+ bgfx_set_view_clear(
+ 0,
+ BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH,
+ 0x443355FF,
+ 1.0f,
+ 0
+ );
+ bgfx_set_view_rect(0, 0, 0, rodeo_window_screen_width_get(), rodeo_window_screen_height_get());
+
+ rodeo_log(rodeo_logLevel_info, "Setting up default render pipeline...");
+ // set up vertex layout
+ mrodeo_bgfx_vertex_layout_do(&irodeo_gfx_state.vertex_layout)
+ {
+ bgfx_vertex_layout_add(&irodeo_gfx_state.vertex_layout, BGFX_ATTRIB_POSITION, 3, BGFX_ATTRIB_TYPE_FLOAT, false, false);
+ bgfx_vertex_layout_add(&irodeo_gfx_state.vertex_layout, BGFX_ATTRIB_COLOR0, 4, BGFX_ATTRIB_TYPE_FLOAT, false, false);
+ bgfx_vertex_layout_add(&irodeo_gfx_state.vertex_layout, BGFX_ATTRIB_TEXCOORD0, 2, BGFX_ATTRIB_TYPE_FLOAT, false, false);
+ bgfx_vertex_layout_add(&irodeo_gfx_state.vertex_layout, BGFX_ATTRIB_TEXCOORD1, 1, BGFX_ATTRIB_TYPE_FLOAT, false, false);
+ }
+
+ // load shaders
+ cstr shader_path = cstr_lit("???");
+ switch(bgfx_get_renderer_type()) {
+ case BGFX_RENDERER_TYPE_NOOP:
+ rodeo_log(
+ rodeo_logLevel_error,
+ "BGFX failed to get determine an appropriate renderer"
+ );
+ exit(EXIT_FAILURE);
+ case BGFX_RENDERER_TYPE_OPENGLES:
+ cstr_assign(
+ &shader_path,
+ "shaders/100_es/"
+ );
+ break;
+ case BGFX_RENDERER_TYPE_VULKAN:
+ cstr_assign(
+ &shader_path,
+ "shaders/spirv/"
+ );
+ break;
+ case BGFX_RENDERER_TYPE_OPENGL:
+ cstr_assign(
+ &shader_path,
+ "shaders/opengl/"
+ );
+ break;
+ default:
+ rodeo_log(
+ rodeo_logLevel_error,
+ "No shaders implemented for BGFX renderer chosen"
+ );
+ exit(EXIT_FAILURE);
+ }
+ cstr vertex_shader_path = cstr_lit("simple.vertex.bin");
+ cstr fragment_shader_path = cstr_lit("simple.fragment.bin");
+
+ cstr_insert_s(
+ &vertex_shader_path,
+ 0,
+ shader_path
+ );
+ cstr_insert_s(
+ &fragment_shader_path,
+ 0,
+ shader_path
+ );
+
+ irodeo_gfx_state.vertex_shader = irodeo_gfx_shader_load(vertex_shader_path);
+ irodeo_gfx_state.fragment_shader = irodeo_gfx_shader_load(fragment_shader_path);
+ irodeo_gfx_state.program_shader = bgfx_create_program(
+ irodeo_gfx_state.vertex_shader,
+ irodeo_gfx_state.fragment_shader,
+ true
+ );
+ rodeo_log(
+ rodeo_logLevel_info,
+ "Default render pipeline finished setup"
+ );
+
+ //bgfx_texture_handle_t default_bgfx_texture = rodeo_texture_2d_create_default();
+
+ irodeo_gfx_state.default_texture.internal_texture = malloc(sizeof(irodeo_gfx_texture_internal_t));
+
+ // used for binding textures to shader uniforms
+ irodeo_gfx_state.texture_uniforms[0] = bgfx_create_uniform("default_texture", BGFX_UNIFORM_TYPE_SAMPLER, 1);
+ irodeo_gfx_state.texture_uniforms[1] = bgfx_create_uniform("texture_0", BGFX_UNIFORM_TYPE_SAMPLER, 1);
+
+ {
+ // represents 1 pixel sized white texture
+ const uint8_t default_texture_data[] = {
+ //red, blue, green, alpha
+ 0xff, 0xff, 0xff, 0xff,
+ };
+
+ irodeo_gfx_state.default_texture.internal_texture->texture_bgfx =
+ bgfx_create_texture_2d(
+ 1,
+ 1,
+ false,
+ 0,
+ BGFX_TEXTURE_FORMAT_RGBA8,
+ BGFX_SAMPLER_UVW_CLAMP | BGFX_SAMPLER_MAG_POINT,
+ bgfx_copy(
+ &default_texture_data,
+ sizeof(default_texture_data)
+ )
+ );
+ irodeo_gfx_state.default_texture.width = 1;
+ irodeo_gfx_state.default_texture.height = 1;
+
+ irodeo_gfx_state.active_texture_p = &irodeo_gfx_state.default_texture.internal_texture->texture_bgfx;
+ }
+
+ SDL_SetWindowResizable(irodeo_window_get(), true);
+
+ bgfx_reset(
+ (uint32_t)rodeo_window_screen_width_get(),
+ (uint32_t)rodeo_window_screen_height_get(),
+ //BGFX_RESET_MSAA_X16 | BGFX_RESET_MAXANISOTROPY,
+ BGFX_RESET_VSYNC,
+ BGFX_TEXTURE_FORMAT_COUNT
+ );
+
+ rodeo_random_seed_set(SDL_GetTicks64());
+
+ irodeo_gfx_state.frame_end = (uint32_t)SDL_GetPerformanceCounter();
+}
+
+void
+rodeo_gfx_deinit(void)
+{
+
+ free(irodeo_gfx_state.default_texture.internal_texture);
+
+ bgfx_destroy_program(irodeo_gfx_state.program_shader);
+ bgfx_shutdown();
+}
+
+void
+rodeo_gfx_frame_begin(void)
+{
+ //vec3 eye = {0.0f, 0.0f, -35.0f};
+ //vec3 center = {0.0f, 0.0f, 0.0f};
+ //vec3 up = {0, 1, 0};
+
+ //glm_lookat(eye, center, up, view);
+
+ glm_mat4_identity(irodeo_gfx_state.view_matrix);
+
+ //glm_perspective(glm_rad(60.f), 640.f / 480.f, 0.1f, 100.0f, proj);
+
+ // TODO: figure out if why 'zo' is correct
+ // but 'no' is incorrect
+ glm_ortho_rh_zo(
+ 0,
+ (float)rodeo_window_screen_width_get(),
+ (float)rodeo_window_screen_height_get(),
+ 0,
+ // near
+ -0.1f,
+ // far
+ 100.0f,
+ irodeo_gfx_state.proj_matrix
+ );
+
+ bgfx_set_view_transform(0, irodeo_gfx_state.view_matrix, irodeo_gfx_state.proj_matrix);
+ bgfx_set_view_rect(0, 0, 0, rodeo_window_screen_width_get(), rodeo_window_screen_height_get());
+ bgfx_touch(0);
+
+ irodeo_gfx_render_buffer_transient_alloc();
+
+ irodeo_gfx_state.frame_start = irodeo_gfx_state.frame_end;
+}
+
+void
+rodeo_gfx_frame_end(void)
+{
+ rodeo_gfx_renderer_flush();
+
+ bgfx_frame(false);
+
+ #ifndef __EMSCRIPTEN__
+ irodeo_gfx_frame_stall();
+ #endif
+ irodeo_gfx_state.frame_count += 1;
+ irodeo_gfx_state.frame_end = (uint32_t)SDL_GetPerformanceCounter();
+ //
+#ifndef __EMSCRIPTEN__
+ //irodeo_gfx_state.frame_time = ((float)(irodeo_gfx_state.frame_end - irodeo_gfx_state.frame_start) * 1000.0f / (float)SDL_GetPerformanceFrequency());
+ irodeo_gfx_state.frame_time = (1.0f/60.f) * 1000; //((float)(state.end_frame - state.start_frame) * 1000.0f / (float)SDL_GetPerformanceFrequency());
+#else
+ irodeo_gfx_state.frame_time = (1.0f/60.f) * 1000; //((float)(state.end_frame - state.start_frame) * 1000.0f / (float)SDL_GetPerformanceFrequency());
+#endif
+}
+
+float
+rodeo_gfx_frame_time_get(void)
+{
+ return irodeo_gfx_state.frame_time; //(float)bgfx_get_stats()->cpuTimeFrame;
+}
+
+float
+rodeo_gfx_frame_perSecond_get(void)
+{
+ return 1.0f / (rodeo_gfx_frame_time_get() / 1000.0f);
+}
+
+// measures how much time there is left in the remaining frame until
+// the frame target time is reached. If we surpassed the target time
+// then this will be negative
+float
+irodeo_gfx_frame_remaining_get(void)
+{
+ #ifdef __EMSCRIPTEN__
+ float target = 60.0f;
+ #else
+ float target = (float)rodeo_gfx_frame_limit_get();
+ #endif
+
+ float result = (1/target * 1000.0f) - ((float)(SDL_GetPerformanceCounter() - irodeo_gfx_state.frame_start) / (float)SDL_GetPerformanceFrequency() * 1000.0f);
+
+ return result;
+}
+
+
+// used internally at the end of every frame to fill for time
+// in order to reach the desired framerate
+void
+irodeo_gfx_frame_stall(void)
+{
+ // if no frame limit then run as fast as possible
+ if(rodeo_gfx_frame_limit_get() == 0)
+ {
+ return;
+ }
+
+ // sleep isnt perfectly accurate so we sleep for a slightly shorter
+ // amount of time
+ float stall_time = irodeo_gfx_frame_remaining_get();
+ if(stall_time > 0.0005)
+ {
+ SDL_Delay((uint32_t)(stall_time * 0.9995));
+ }
+
+ // then we spinlock for the small remaining amount of time
+ stall_time = irodeo_gfx_frame_remaining_get();
+ while(stall_time > 0.0005) {
+ stall_time = irodeo_gfx_frame_remaining_get();
+ }
+}
+
+void
+rodeo_gfx_renderer_flush(void)
+{
+ // set default texture
+ bgfx_set_texture(
+ 0,
+ irodeo_gfx_state.texture_uniforms[0],
+ rodeo_gfx_texture_2d_default_get()->internal_texture->texture_bgfx,
+ UINT32_MAX
+ );
+ if(irodeo_gfx_state.active_texture_p != NULL)
+ {
+ // set dynamic texture
+ bgfx_set_texture(
+ 1,
+ irodeo_gfx_state.texture_uniforms[1],
+ *irodeo_gfx_state.active_texture_p,
+ UINT32_MAX
+ );
+ }
+ else
+ {
+ // set to default if none exists
+ bgfx_set_texture(
+ 1,
+ irodeo_gfx_state.texture_uniforms[1],
+ rodeo_gfx_texture_2d_default_get()->internal_texture->texture_bgfx,
+ UINT32_MAX
+ );
+ }
+
+ if(irodeo_gfx_state.vertex_size > 0)
+ {
+ bgfx_set_state(
+ BGFX_STATE_CULL_CW |
+ BGFX_STATE_WRITE_RGB |
+ BGFX_STATE_WRITE_A |
+ //BGFX_STATE_DEPTH_TEST_LESS |
+ //BGFX_STATE_MSAA |
+ BGFX_STATE_BLEND_ALPHA,
+ 0
+ );
+
+ // upload remaining batched vertices
+ bgfx_set_transient_vertex_buffer(0, &irodeo_gfx_state.vertex_buffer_handle, 0, irodeo_gfx_state.vertex_size);
+ //const bgfx_memory_t* vbm = bgfx_copy(irodeo_gfx_state.batched_vertices, sizeof(rodeo_gfx_vertex_t) * irodeo_gfx_state.vertex_size);
+ //bgfx_update_dynamic_vertex_buffer(irodeo_gfx_state.vertex_buffer_handle, 0, vbm);
+
+ // upload remaining batched indices
+ bgfx_set_transient_index_buffer(&irodeo_gfx_state.index_buffer_handle, 0, irodeo_gfx_state.index_size);
+ //bgfx_set_dynamic_index_buffer(irodeo_gfx_state.index_buffer_handle, 0, irodeo_gfx_state.index_size);
+ //const bgfx_memory_t* ibm = bgfx_copy(irodeo_gfx_state.batched_indices, sizeof(uint16_t) * irodeo_gfx_state.index_size);
+ //bgfx_update_dynamic_index_buffer(irodeo_gfx_state.index_buffer_handle, 0, ibm);
+
+
+ // submit vertices & batches
+ bgfx_submit(0, irodeo_gfx_state.program_shader, 0, BGFX_DISCARD_NONE);
+
+ // reset arrays
+ irodeo_gfx_state.vertex_size = 0;
+ irodeo_gfx_state.index_size = 0;
+ irodeo_gfx_state.index_count = 0;
+
+ // allocate new buffers
+ irodeo_gfx_render_buffer_transient_alloc();
+ }
+ irodeo_gfx_state.active_texture_p = NULL;
+}
+
+const rodeo_gfx_texture_2d_t*
+rodeo_gfx_texture_2d_default_get(void)
+{
+ return &irodeo_gfx_state.default_texture;
+}
+
+rodeo_gfx_texture_2d_t
+rodeo_gfx_texture_2d_create_from_RGBA8(
+ const uint16_t width,
+ const uint16_t height,
+ const uint8_t memory[]
+)
+{
+ rodeo_gfx_texture_2d_t texture;
+ texture.internal_texture = malloc(sizeof(irodeo_gfx_texture_internal_t));
+ bgfx_copy(memory, (uint32_t)width * (uint32_t)height * sizeof(uint8_t) * 4);
+ texture.internal_texture->texture_bgfx =
+ bgfx_create_texture_2d(
+ width,
+ height,
+ false,
+ 0,
+ BGFX_TEXTURE_FORMAT_RGBA8,
+ BGFX_SAMPLER_UVW_CLAMP | BGFX_SAMPLER_MAG_POINT,
+ bgfx_copy(memory, (uint32_t)width * (uint32_t)height * sizeof(uint8_t) * 4)
+ );
+
+ texture.width = width;
+ texture.height = height;
+
+ return texture;
+}
+
+void
+rodeo_gfx_texture_2d_destroy(rodeo_gfx_texture_2d_t *texture)
+{
+ bgfx_destroy_texture(texture->internal_texture->texture_bgfx);
+ free(texture->internal_texture);
+}
+
+void
+rodeo_gfx_rectangle_draw(
+ const rodeo_rectangle_t *rectangle,
+ const rodeo_color_RGBAFloat_t *color
+)
+{
+ rodeo_gfx_texture_2d_draw(
+ rectangle,
+ NULL,
+ color,
+ NULL
+ );
+}
+
+void
+rodeo_gfx_texture_2d_draw(
+ // cant be NULL
+ const rodeo_rectangle_t *destination,
+ // default: entire texture
+ const rodeo_rectangle_t *source,
+ // default: white
+ const rodeo_color_RGBAFloat_t *color,
+ // default: default texture
+ const rodeo_gfx_texture_2d_t *texture
+)
+{
+ // whether to use default or custom texture
+ float texture_uniform_slot = 0.0;
+
+ rodeo_rectangle_t source_applied;
+ if(source != NULL && texture != NULL)
+ {
+ source_applied = (rodeo_rectangle_t){
+ .x = source->x / (float)texture->width,
+ .y = source->y / (float)texture->height,
+ .width = source->width / (float)texture->width,
+ .height = source->height / (float)texture->height,
+ };
+ }
+ else
+ {
+ source_applied = (rodeo_rectangle_t){
+ .x = 0.0f,
+ .y = 0.0f,
+ .width = 1.0f,
+ .height = 1.0f,
+ };
+ }
+
+ rodeo_color_RGBAFloat_t color_applied;
+ if(color != NULL)
+ {
+ color_applied = *color;
+ }
+ else
+ {
+ color_applied = (rodeo_color_RGBAFloat_t){
+ { 1.0f, 1.0f, 1.0f, 1.0f }
+ };
+ }
+
+ // if not using texture: use default instead
+ // otherwise check what current texture is active
+ // if none or the same: set it
+ // if different: flush and then set it
+ if(texture != NULL)
+ {
+ if(irodeo_gfx_state.active_texture_p != NULL)
+ {
+ if(&texture->internal_texture->texture_bgfx != irodeo_gfx_state.active_texture_p)
+ {
+ rodeo_gfx_renderer_flush();
+ }
+ }
+ texture_uniform_slot = 1.0;
+ irodeo_gfx_state.active_texture_p = &texture->internal_texture->texture_bgfx;
+ }
+
+
+ if(irodeo_gfx_state.vertex_size < mrodeo_vertex_size_max)
+ {
+ irodeo_gfx_state.batched_vertices[irodeo_gfx_state.vertex_size] =
+ (rodeo_gfx_vertex_t)
+ {
+ .x = destination->width + destination->x,
+ .y = destination->height + destination->y,
+ //.z = 0.0f,
+ .color = color_applied,
+ .texture_id = texture_uniform_slot,
+ .texture_x = source_applied.width + source_applied.x,
+ .texture_y = source_applied.height + source_applied.y,
+ };
+ irodeo_gfx_state.vertex_size += 1;
+ irodeo_gfx_state.batched_vertices[irodeo_gfx_state.vertex_size] =
+ (rodeo_gfx_vertex_t)
+ {
+ .x = destination->width + destination->x,
+ .y = destination->y,
+ //.z = 0.0f,
+ .color = color_applied,
+ .texture_id = texture_uniform_slot,
+ .texture_x = source_applied.width + source_applied.x,
+ .texture_y = source_applied.y,
+ };
+ irodeo_gfx_state.vertex_size += 1;
+ irodeo_gfx_state.batched_vertices[irodeo_gfx_state.vertex_size] =
+ (rodeo_gfx_vertex_t)
+ {
+ .x = destination->x,
+ .y = destination->y,
+ //.z = 0.0f,
+ .color = color_applied,
+ .texture_id = texture_uniform_slot,
+ .texture_x = source_applied.x,
+ .texture_y = source_applied.y,
+ };
+ irodeo_gfx_state.vertex_size += 1;
+ irodeo_gfx_state.batched_vertices[irodeo_gfx_state.vertex_size] =
+ (rodeo_gfx_vertex_t)
+ {
+ .x = destination->x,
+ .y = destination->height + destination->y,
+ //.z = 0.0f,
+ .color = color_applied,
+ .texture_id = texture_uniform_slot,
+ .texture_x = source_applied.x,
+ .texture_y = source_applied.height + source_applied.y,
+ };
+ irodeo_gfx_state.vertex_size += 1;
+
+ irodeo_index_type_t indices[] =
+ {
+ 0, 1, 3,
+ 1, 2, 3
+ //2, 1, 0,
+ //2, 3, 1
+ };
+ irodeo_gfx_state.batched_indices[irodeo_gfx_state.index_size] = irodeo_gfx_state.index_count + indices[0];
+ irodeo_gfx_state.index_size += 1;
+ irodeo_gfx_state.batched_indices[irodeo_gfx_state.index_size] = irodeo_gfx_state.index_count + indices[1];
+ irodeo_gfx_state.index_size += 1;
+ irodeo_gfx_state.batched_indices[irodeo_gfx_state.index_size] = irodeo_gfx_state.index_count + indices[2];
+ irodeo_gfx_state.index_size += 1;
+ irodeo_gfx_state.batched_indices[irodeo_gfx_state.index_size] = irodeo_gfx_state.index_count + indices[3];
+ irodeo_gfx_state.index_size += 1;
+ irodeo_gfx_state.batched_indices[irodeo_gfx_state.index_size] = irodeo_gfx_state.index_count + indices[4];
+ irodeo_gfx_state.index_size += 1;
+ irodeo_gfx_state.batched_indices[irodeo_gfx_state.index_size] = irodeo_gfx_state.index_count + indices[5];
+ irodeo_gfx_state.index_size += 1;
+ irodeo_gfx_state.index_count += 4;
+ }
+
+ if(irodeo_gfx_state.vertex_size >= mrodeo_vertex_size_max)
+ {
+ rodeo_gfx_renderer_flush();
+ }
+}
+
+rodeo_gfx_texture_2d_t
+rodeo_gfx_texture_2d_create_from_path(cstr path)
+{
+ // load image to surface
+ SDL_Surface *surface = IMG_Load(cstr_str(&path));
+ if(surface == NULL)
+ {
+ rodeo_log(
+ rodeo_logLevel_error,
+ "Loading texture from image failed: %s",
+ IMG_GetError()
+ );
+ return (rodeo_gfx_texture_2d_t){0};
+ }
+
+ // check and handle a color key for transparency
+ // not sure if I actually need this...
+ //uint32_t color_key;
+ //if(SDL_GetColorKey(surface, &color_key) == 0)
+ //{
+ // SDL_SetColorKey(surface, SDL_TRUE, color_key);
+ //}
+
+ // convert pixel format of surface into RGBA8
+ SDL_Surface *converted_surface =
+ SDL_ConvertSurfaceFormat(
+ surface,
+ // pixel format needs to be backwards
+ // of what bgfx uses for some reason
+ SDL_PIXELFORMAT_ABGR8888,
+ 0
+ );
+ if(converted_surface == NULL)
+ {
+ rodeo_log(
+ rodeo_logLevel_error,
+ "Converting image to RGBA8 while loading texture failed: %s",
+ SDL_GetError()
+ );
+ SDL_FreeSurface(surface);
+ return (rodeo_gfx_texture_2d_t){0};
+ }
+
+ // load the pixel data into our own texture
+ rodeo_gfx_texture_2d_t texture = rodeo_gfx_texture_2d_create_from_RGBA8(
+ (uint16_t)converted_surface->w,
+ (uint16_t)converted_surface->h,
+ converted_surface->pixels
+ );
+
+ SDL_FreeSurface(surface);
+ SDL_FreeSurface(converted_surface);
+
+ return texture;
+}
+
+uint64_t
+rodeo_gfx_frame_count_get(void)
+{
+ return irodeo_gfx_state.frame_count;
+}
+
+void
+rodeo_gfx_frame_limit_set(uint32_t limit)
+{
+ #ifdef __EMSCRIPTEN__
+ rodeo_log(
+ rodeo_logLevel_warning,
+ "Framerate limit cannot be set on web platform. Limit is enforced by platform to 60fps"
+ );
+ #else
+ irodeo_gfx_state.frame_limit = limit;
+ #endif
+}
+
+uint32_t
+rodeo_gfx_frame_limit_get(void)
+{
+ #ifdef __EMSCRIPTEN__
+ return 60;
+ #else
+ return irodeo_gfx_state.frame_limit;
+ #endif
+}
+
+cstr
+rodeo_gfx_renderer_name_get(void)
+{
+ return cstr_from(
+ bgfx_get_renderer_name(bgfx_get_renderer_type())
+ );
+}
+
+bgfx_shader_handle_t
+irodeo_gfx_shader_load(const cstr path)
+{
+ const char* path_cstr = cstr_str(&path);
+
+ FILE *file = fopen(path_cstr, "rb");
+
+ if(!file)
+ {
+ rodeo_log(
+ rodeo_logLevel_error,
+ "Shader file \"%s\" not found",
+ path_cstr
+ );
+ return (bgfx_shader_handle_t)BGFX_INVALID_HANDLE;
+ }
+
+ fseek(file, 0, SEEK_END);
+ int64_t file_size_temp = ftell(file);
+ if(file_size_temp < 0)
+ {
+ rodeo_log(
+ rodeo_logLevel_error,
+ "Failed to get current file position of given stream(ftell() error)"
+ );
+ exit(EXIT_FAILURE);
+ }
+ if((file_size_temp + 1) > UINT32_MAX)
+ {
+ rodeo_log(
+ rodeo_logLevel_error,
+ "File size larger then what bgfx can allocate"
+ );
+ exit(EXIT_FAILURE);
+ }
+ uint32_t file_size = (uint32_t)file_size_temp;
+ fseek(file, 0, SEEK_SET);
+
+
+ const bgfx_memory_t *mem = bgfx_alloc(file_size + 1);
+ fread(mem->data, 1, file_size, file);
+ mem->data[mem->size - 1] = '\0';
+ fclose(file);
+
+ bgfx_shader_handle_t shader = bgfx_create_shader(mem);
+ rodeo_log(
+ rodeo_logLevel_info,
+ "Shader loaded with idx: %"PRIu8"",
+ shader.idx
+ );
+
+ return shader;
+}
+
+void
+irodeo_gfx_render_buffer_transient_alloc(void)
+{
+ bgfx_alloc_transient_vertex_buffer(&irodeo_gfx_state.vertex_buffer_handle, mrodeo_vertex_size_max, &irodeo_gfx_state.vertex_layout);
+ bgfx_alloc_transient_index_buffer(&irodeo_gfx_state.index_buffer_handle, mrodeo_index_size_max, false);
+ irodeo_gfx_state.batched_vertices = (rodeo_gfx_vertex_t*)irodeo_gfx_state.vertex_buffer_handle.data;
+ irodeo_gfx_state.batched_indices = (irodeo_index_type_t*)irodeo_gfx_state.index_buffer_handle.data;
+}
+
diff --git a/src/input/rodeo_input.c b/src/input/rodeo_input.c
index f6f0d9f..ee2d180 100644
--- a/src/input/rodeo_input.c
+++ b/src/input/rodeo_input.c
@@ -4,8 +4,10 @@
#include "rodeo/input.h"
#include "irodeo_input_t.h"
#include "rodeo/log.h"
-// pirvate
+#include "rodeo/window.h"
+// private
#include "rodeo_internal.h"
+#include "window/irodeo_window.h"
// -- external --
#include "SDL.h"
@@ -17,7 +19,7 @@
static irodeo_input_state_t istate = {0};
bool
-rodeo_input_events_poll(void)
+rodeo_input_poll(void)
{
SDL_Event event = {0};
while(SDL_PollEvent(&event))
@@ -26,7 +28,7 @@ rodeo_input_events_poll(void)
{
case SDL_QUIT:
{
- return true;
+ rodeo_window_quit();
}
//break;
case SDL_WINDOWEVENT:
@@ -41,17 +43,17 @@ rodeo_input_events_poll(void)
BGFX_RESET_VSYNC,
BGFX_TEXTURE_FORMAT_COUNT
);
- irodeo_screen_width_set((uint16_t)width);
- irodeo_screen_height_set((uint16_t)height);
+ irodeo_window_screen_width_setVar((uint16_t)width);
+ irodeo_window_screen_height_setVar((uint16_t)height);
rodeo_log(
rodeo_logLevel_warning,
"%"PRIu16"x",
- rodeo_screen_width_get()
+ rodeo_window_screen_width_get()
);
rodeo_log(
rodeo_logLevel_warning,
"%"PRIu16"\n",
- rodeo_screen_height_get()
+ rodeo_window_screen_height_get()
);
}
}
diff --git a/src/rodeo.c b/src/rodeo.c
index 6978a52..4699f86 100644
--- a/src/rodeo.c
+++ b/src/rodeo.c
@@ -3,7 +3,6 @@
// public
#include "rodeo.h"
#include "rodeo_types.h"
-#include "rodeo/input.h"
// private
#include "rodeo_internal.h"
#include "rodeo_internal_types.h"
@@ -31,383 +30,6 @@
static irodeo_state_t state = {0};
void
-rodeo_window_init(
- uint16_t screen_height,
- uint16_t screen_width,
- cstr title
-)
-{
- state.window = NULL;
- state.screen_surface = NULL;
- state.screen_height = screen_height;
- state.screen_width = screen_width;
- state.frame_count = 0;
-
- rodeo_log(
- rodeo_logLevel_info,
- "Initializing SDL..."
- );
-
- {
- uint32_t init_flags_sdl = 0;
- init_flags_sdl = init_flags_sdl | SDL_INIT_VIDEO;
- init_flags_sdl = init_flags_sdl | SDL_INIT_AUDIO;
- init_flags_sdl = init_flags_sdl | SDL_INIT_GAMECONTROLLER;
-
- if(SDL_Init(init_flags_sdl) < 0)
- {
- rodeo_log(
- rodeo_logLevel_error,
- "Failed to initialize SDL. SDL_Error: %s",
- SDL_GetError()
- );
- exit(EXIT_FAILURE);
- }
- rodeo_log(
- rodeo_logLevel_info,
- "Success initializing SDL"
- );
- }
-
- rodeo_log(
- rodeo_logLevel_info,
- "Initializing SDL window..."
- );
- state.window = SDL_CreateWindow(
- cstr_str(&title),
- SDL_WINDOWPOS_UNDEFINED,
- SDL_WINDOWPOS_UNDEFINED,
- screen_width,
- screen_height,
- SDL_WINDOW_SHOWN //| SDL_WINDOW_RESIZABLE
- );
- if(state.window == NULL)
- {
- rodeo_log(
- rodeo_logLevel_error,
- "Failed creating SDL window. SDL_Error: %s",
- SDL_GetError()
- );
- exit(EXIT_FAILURE);
- }
- rodeo_log(
- rodeo_logLevel_info,
- "Success initializing SDL window"
- );
-
-#if !__EMSCRIPTEN__
- rodeo_log(
- rodeo_logLevel_info,
- "SDL setting up driver specific information..."
- );
- SDL_VERSION(&state.wmi.version);
- if(
- !SDL_GetWindowWMInfo(
- state.window,
- &state.wmi
- )
- )
- {
- rodeo_log(
- rodeo_logLevel_error,
- "SDL failed to get driver specific information. SDL Error: %s", SDL_GetError()
- );
- exit(EXIT_FAILURE);
- }
- rodeo_log(
- rodeo_logLevel_info,
- "Success getting driver specific information"
- );
- bgfx_render_frame(-1);
-#endif
-
-
- bgfx_platform_data_t pd;
- memset(&pd, 0, sizeof(bgfx_platform_data_t));
-
-#if !__EMSCRIPTEN__
- // x11
- pd.ndt = state.wmi.info.x11.display;
- pd.nwh = (void*)(uintptr_t)state.wmi.info.x11.window;
-#else
- // web
- pd.nwh = (void*)"#canvas";
-#endif
-
- bgfx_init_t init = {0};
- bgfx_init_ctor(&init);
- //init.type = BGFX_RENDERER_TYPE_COUNT; // auto determine renderer
- init.type = BGFX_RENDERER_TYPE_OPENGL; // force opengl renderer
- //SDL_GetWindowSize(state.window, &state.screen_width, &state.screen_height);
- init.resolution.width = state.screen_width;
- init.resolution.height = state.screen_height;
- init.resolution.reset = BGFX_RESET_VSYNC;
- init.platformData = pd;
- bgfx_init(&init);
-
- bgfx_set_debug(BGFX_DEBUG_TEXT);
-
- //bgfx_set_state(BGFX_STATE_CULL_CCW, 0);
-
- //bgfx_dbg_text_clear(0x65, false);
-
- bgfx_set_view_clear(
- 0,
- BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH,
- 0x443355FF,
- 1.0f,
- 0
- );
- bgfx_set_view_rect(0, 0, 0, state.screen_width, state.screen_height);
-
- rodeo_log(rodeo_logLevel_info, "Setting up default render pipeline...");
- // set up vertex layout
- mrodeo_bgfx_vertex_layout_do(&state.vertex_layout)
- {
- bgfx_vertex_layout_add(&state.vertex_layout, BGFX_ATTRIB_POSITION, 3, BGFX_ATTRIB_TYPE_FLOAT, false, false);
- bgfx_vertex_layout_add(&state.vertex_layout, BGFX_ATTRIB_COLOR0, 4, BGFX_ATTRIB_TYPE_FLOAT, false, false);
- bgfx_vertex_layout_add(&state.vertex_layout, BGFX_ATTRIB_TEXCOORD0, 2, BGFX_ATTRIB_TYPE_FLOAT, false, false);
- bgfx_vertex_layout_add(&state.vertex_layout, BGFX_ATTRIB_TEXCOORD1, 1, BGFX_ATTRIB_TYPE_FLOAT, false, false);
- }
-
- // load shaders
- cstr shader_path = cstr_lit("???");
- switch(bgfx_get_renderer_type()) {
- case BGFX_RENDERER_TYPE_NOOP:
- rodeo_log(
- rodeo_logLevel_error,
- "BGFX failed to get determine an appropriate renderer"
- );
- exit(EXIT_FAILURE);
- case BGFX_RENDERER_TYPE_OPENGLES:
- cstr_assign(
- &shader_path,
- "shaders/100_es/"
- );
- break;
- case BGFX_RENDERER_TYPE_VULKAN:
- cstr_assign(
- &shader_path,
- "shaders/spirv/"
- );
- break;
- case BGFX_RENDERER_TYPE_OPENGL:
- cstr_assign(
- &shader_path,
- "shaders/opengl/"
- );
- break;
- default:
- rodeo_log(
- rodeo_logLevel_error,
- "No shaders implemented for BGFX renderer chosen"
- );
- exit(EXIT_FAILURE);
- }
- cstr vertex_shader_path = cstr_lit("simple.vertex.bin");
- cstr fragment_shader_path = cstr_lit("simple.fragment.bin");
-
- cstr_insert_s(
- &vertex_shader_path,
- 0,
- shader_path
- );
- cstr_insert_s(
- &fragment_shader_path,
- 0,
- shader_path
- );
-
- state.vertex_shader = irodeo_shader_load(vertex_shader_path);
- state.fragment_shader = irodeo_shader_load(fragment_shader_path);
- state.program_shader = bgfx_create_program(
- state.vertex_shader,
- state.fragment_shader,
- true
- );
- rodeo_log(
- rodeo_logLevel_info,
- "Default render pipeline finished setup"
- );
-
- //bgfx_texture_handle_t default_bgfx_texture = rodeo_texture_2d_create_default();
-
- state.default_texture.internal_texture = malloc(sizeof(irodeo_texture_internal_t));
-
- // used for binding textures to shader uniforms
- state.texture_uniforms[0] = bgfx_create_uniform("default_texture", BGFX_UNIFORM_TYPE_SAMPLER, 1);
- state.texture_uniforms[1] = bgfx_create_uniform("texture_0", BGFX_UNIFORM_TYPE_SAMPLER, 1);
-
- {
- // represents 1 pixel sized white texture
- const uint8_t default_texture_data[] = {
- //red, blue, green, alpha
- 0xff, 0xff, 0xff, 0xff,
- };
-
- state.default_texture.internal_texture->texture_bgfx =
- bgfx_create_texture_2d(
- 1,
- 1,
- false,
- 0,
- BGFX_TEXTURE_FORMAT_RGBA8,
- BGFX_SAMPLER_UVW_CLAMP | BGFX_SAMPLER_MAG_POINT,
- bgfx_copy(
- &default_texture_data,
- sizeof(default_texture_data)
- )
- );
- state.default_texture.width = 1;
- state.default_texture.height = 1;
-
- rodeo_audio_initialize(4 * 4);
-
- state.active_texture_p = &state.default_texture.internal_texture->texture_bgfx;
- }
-
- SDL_SetWindowResizable(state.window, true);
-
- /*
- rodeo_log(
- rodeo_logLevel_info,
- "%"PRIu32", %b\n",
- bgfx_get_caps()->limits.transientVbSize,
- bgfx_get_caps()->homogeneousDepth
- );*/
-
- //vec3 eye = {0.0f, 0.0f, -35.0f};
- //vec3 center = {0.0f, 0.0f, 0.0f};
- //vec3 up = {0, 1, 0};
-
- //glm_lookat(eye, center, up, view);
-
- glm_mat4_identity(state.view_matrix);
-
- //glm_perspective(glm_rad(60.f), 640.f / 480.f, 0.1f, 100.0f, proj);
-
- // TODO: figure out if why 'zo' is correct
- // but 'no' is incorrect
- glm_ortho_rh_zo(
- 0,
- (float)state.screen_width,
- (float)state.screen_height,
- 0,
- // near
- -0.1f,
- // far
- 100.0f,
- state.proj_matrix
- );
-
- rodeo_random_seed_set(SDL_GetTicks64());
-
- state.end_frame = SDL_GetPerformanceCounter();
-}
-
-void
-rodeo_window_deinit(void)
-{
- free(state.default_texture.internal_texture);
-
- //bgfx_destroy_dynamic_index_buffer(state.index_buffer_handle);
- //bgfx_destroy_dynamic_vertex_buffer(state.vertex_buffer_handle);
- bgfx_destroy_program(state.program_shader);
- bgfx_shutdown();
-
- SDL_DestroyWindow(state.window);
- Mix_Quit();
- SDL_Quit();
-}
-
-SDL_Window *
-irodeo_window_get(void)
-{
- return state.window;
-}
-
-uint16_t
-rodeo_screen_width_get(void)
-{
- return state.screen_width;
-}
-
-uint16_t
-rodeo_screen_height_get(void)
-{
- return state.screen_height;
-}
-
-void
-irodeo_screen_width_set(uint16_t width)
-{
- state.screen_width = width;
-}
-
-void
-irodeo_screen_height_set(uint16_t height)
-{
- state.screen_height = height;
-}
-
-void
-rodeo_frame_begin(void)
-{
- state.quit = rodeo_input_events_poll();
-
- bgfx_set_view_transform(0, state.view_matrix, state.proj_matrix);
- bgfx_set_view_rect(0, 0, 0, state.screen_width, state.screen_height);
- bgfx_touch(0);
-
- irodeo_render_buffer_transient_alloc();
-
- state.start_frame = state.end_frame;
-}
-
-void
-rodeo_frame_end(void)
-{
- rodeo_renderer_flush();
-
- bgfx_frame(false);
-
- #ifndef __EMSCRIPTEN__
- irodeo_frame_stall();
- #endif
- state.frame_count += 1;
- state.end_frame = SDL_GetPerformanceCounter();
-
-#ifndef __EMSCRIPTEN__
- state.frame_time = ((float)(state.end_frame - state.start_frame) * 1000.0f / (float)SDL_GetPerformanceFrequency());
-#else
- state.frame_time = (1.0f/60.f) * 1000; //((float)(state.end_frame - state.start_frame) * 1000.0f / (float)SDL_GetPerformanceFrequency());
-#endif
-
-
- /*
- float minimum_fps = 20.0f;
- float temp_frame_time = ((float)(state.end_frame - state.start_frame) * 1000.0f / (float)SDL_GetPerformanceFrequency());
- state.frame_time = (temp_frame_time < ((1.0f/minimum_fps) * 1000)) ? temp_frame_time : ((1.0f / minimum_fps) * 1000);
- */
- /*
- rodeo_log(
- rodeo_logLevel_info,
- "Vertex Buffer Used: %f",
- (float)bgfx_get_stats()->transientVbUsed / (float)bgfx_get_caps()->limits.transientVbSize
- );
- */
-}
-
-void
-irodeo_render_buffer_transient_alloc(void)
-{
- bgfx_alloc_transient_vertex_buffer(&state.vertex_buffer_handle, mrodeo_vertex_size_max, &state.vertex_layout);
- bgfx_alloc_transient_index_buffer(&state.index_buffer_handle, mrodeo_index_size_max, false);
- state.batched_vertices = (rodeo_vertex_t*)state.vertex_buffer_handle.data;
- state.batched_indices = (irodeo_index_type_t*)state.index_buffer_handle.data;
-}
-
-void
rodeo_mainLoop_run(
rodeo_mainLoop_function main_loop_func
)
@@ -415,25 +37,13 @@ rodeo_mainLoop_run(
#if __EMSCRIPTEN__
emscripten_set_main_loop(main_loop_func, 0, 1);
#else
- while(!rodeo_window_quit_get())
+ while(!rodeo_window_shouldQuit())
{
main_loop_func();
}
#endif
}
-bool
-rodeo_window_quit_get(void)
-{
- return state.quit;
-}
-
-void
-rodeo_window_quit_set(bool quit)
-{
- state.quit = quit;
-}
-
void
rodeo_debug_text_draw(u_int16_t x, u_int16_t y, const char *format, ...)
{
@@ -443,432 +53,6 @@ rodeo_debug_text_draw(u_int16_t x, u_int16_t y, const char *format, ...)
}
}
-cstr
-rodeo_renderer_name_get(void)
-{
- return cstr_from(
- bgfx_get_renderer_name(bgfx_get_renderer_type())
- );
-}
-
-void
-rodeo_renderer_flush(void)
-{
- // set default texture
- bgfx_set_texture(
- 0,
- state.texture_uniforms[0],
- rodeo_texture_2d_default_get()->internal_texture->texture_bgfx,
- UINT32_MAX
- );
- if(state.active_texture_p != NULL)
- {
- // set dynamic texture
- bgfx_set_texture(
- 1,
- state.texture_uniforms[1],
- *state.active_texture_p,
- UINT32_MAX
- );
- }
- else
- {
- // set to default if none exists
- bgfx_set_texture(
- 1,
- state.texture_uniforms[1],
- rodeo_texture_2d_default_get()->internal_texture->texture_bgfx,
- UINT32_MAX
- );
- }
-
- if(state.vertex_size > 0)
- {
- bgfx_set_state(
- BGFX_STATE_CULL_CW |
- BGFX_STATE_WRITE_RGB |
- BGFX_STATE_WRITE_A |
- //BGFX_STATE_DEPTH_TEST_LESS |
- //BGFX_STATE_MSAA |
- BGFX_STATE_BLEND_ALPHA,
- 0
- );
-
- // upload remaining batched vertices
- bgfx_set_transient_vertex_buffer(0, &state.vertex_buffer_handle, 0, state.vertex_size);
- //const bgfx_memory_t* vbm = bgfx_copy(state.batched_vertices, sizeof(rodeo_vertex_t) * state.vertex_size);
- //bgfx_update_dynamic_vertex_buffer(state.vertex_buffer_handle, 0, vbm);
-
- // upload remaining batched indices
- bgfx_set_transient_index_buffer(&state.index_buffer_handle, 0, state.index_size);
- //bgfx_set_dynamic_index_buffer(state.index_buffer_handle, 0, state.index_size);
- //const bgfx_memory_t* ibm = bgfx_copy(state.batched_indices, sizeof(uint16_t) * state.index_size);
- //bgfx_update_dynamic_index_buffer(state.index_buffer_handle, 0, ibm);
-
-
- // submit vertices & batches
- bgfx_submit(0, state.program_shader, 0, BGFX_DISCARD_NONE);
-
- // reset arrays
- state.vertex_size = 0;
- state.index_size = 0;
- state.index_count = 0;
-
- // allocate new buffers
- irodeo_render_buffer_transient_alloc();
- }
- state.active_texture_p = NULL;
-}
-
-const rodeo_texture_2d_t*
-rodeo_texture_2d_default_get(void)
-{
- return &state.default_texture;
-}
-
-rodeo_texture_2d_t
-rodeo_texture_2d_create_from_RGBA8(
- const uint16_t width,
- const uint16_t height,
- const uint8_t memory[]
-)
-{
- rodeo_texture_2d_t texture;
- texture.internal_texture = malloc(sizeof(irodeo_texture_internal_t));
- texture.internal_texture->texture_bgfx =
- bgfx_create_texture_2d(
- width,
- height,
- false,
- 0,
- BGFX_TEXTURE_FORMAT_RGBA8,
- BGFX_SAMPLER_UVW_CLAMP | BGFX_SAMPLER_MAG_POINT,
- bgfx_copy(memory, (uint32_t)width * (uint32_t)height * sizeof(uint8_t) * 4)
- );
-
- texture.width = width;
- texture.height = height;
-
- return texture;
-}
-
-void
-rodeo_texture_2d_destroy(rodeo_texture_2d_t *texture)
-{
- bgfx_destroy_texture(texture->internal_texture->texture_bgfx);
- free(texture->internal_texture);
-}
-
-void
-rodeo_rectangle_draw(
- const rodeo_rectangle_t *rectangle,
- const rodeo_color_RGBAFloat_t *color
-)
-{
- rodeo_texture_2d_draw(
- rectangle,
- NULL,
- color,
- NULL
- );
-}
-
-void
-rodeo_texture_2d_draw(
- // cant be NULL
- const rodeo_rectangle_t *destination,
- // default: entire texture
- const rodeo_rectangle_t *source,
- // default: white
- const rodeo_color_RGBAFloat_t *color,
- // default: default texture
- const rodeo_texture_2d_t *texture
-)
-{
- // whether to use default or custom texture
- float texture_uniform_slot = 0.0;
-
- rodeo_rectangle_t source_applied;
- if(source != NULL && texture != NULL)
- {
- source_applied = (rodeo_rectangle_t){
- .x = source->x / (float)texture->width,
- .y = source->y / (float)texture->height,
- .width = source->width / (float)texture->width,
- .height = source->height / (float)texture->height,
- };
- }
- else
- {
- source_applied = (rodeo_rectangle_t){
- .x = 0.0f,
- .y = 0.0f,
- .width = 1.0f,
- .height = 1.0f,
- };
- }
-
- rodeo_color_RGBAFloat_t color_applied;
- if(color != NULL)
- {
- color_applied = *color;
- }
- else
- {
- color_applied = (rodeo_color_RGBAFloat_t){
- { 1.0f, 1.0f, 1.0f, 1.0f }
- };
- }
-
- // if not using texture: use default instead
- // otherwise check what current texture is active
- // if none or the same: set it
- // if different: flush and then set it
- if(texture != NULL)
- {
- if(state.active_texture_p != NULL)
- {
- if(&texture->internal_texture->texture_bgfx != state.active_texture_p)
- {
- rodeo_renderer_flush();
- }
- }
- texture_uniform_slot = 1.0;
- state.active_texture_p = &texture->internal_texture->texture_bgfx;
- }
-
-
- if(state.vertex_size < mrodeo_vertex_size_max)
- {
- state.batched_vertices[state.vertex_size] =
- (rodeo_vertex_t)
- {
- .x = destination->width + destination->x,
- .y = destination->height + destination->y,
- //.z = 0.0f,
- .color = color_applied,
- .texture_id = texture_uniform_slot,
- .texture_x = source_applied.width + source_applied.x,
- .texture_y = source_applied.height + source_applied.y,
- };
- state.vertex_size += 1;
- state.batched_vertices[state.vertex_size] =
- (rodeo_vertex_t)
- {
- .x = destination->width + destination->x,
- .y = destination->y,
- //.z = 0.0f,
- .color = color_applied,
- .texture_id = texture_uniform_slot,
- .texture_x = source_applied.width + source_applied.x,
- .texture_y = source_applied.y,
- };
- state.vertex_size += 1;
- state.batched_vertices[state.vertex_size] =
- (rodeo_vertex_t)
- {
- .x = destination->x,
- .y = destination->y,
- //.z = 0.0f,
- .color = color_applied,
- .texture_id = texture_uniform_slot,
- .texture_x = source_applied.x,
- .texture_y = source_applied.y,
- };
- state.vertex_size += 1;
- state.batched_vertices[state.vertex_size] =
- (rodeo_vertex_t)
- {
- .x = destination->x,
- .y = destination->height + destination->y,
- //.z = 0.0f,
- .color = color_applied,
- .texture_id = texture_uniform_slot,
- .texture_x = source_applied.x,
- .texture_y = source_applied.height + source_applied.y,
- };
- state.vertex_size += 1;
-
- irodeo_index_type_t indices[] =
- {
- 0, 1, 3,
- 1, 2, 3
- //2, 1, 0,
- //2, 3, 1
- };
- state.batched_indices[state.index_size] = state.index_count + indices[0];
- state.index_size += 1;
- state.batched_indices[state.index_size] = state.index_count + indices[1];
- state.index_size += 1;
- state.batched_indices[state.index_size] = state.index_count + indices[2];
- state.index_size += 1;
- state.batched_indices[state.index_size] = state.index_count + indices[3];
- state.index_size += 1;
- state.batched_indices[state.index_size] = state.index_count + indices[4];
- state.index_size += 1;
- state.batched_indices[state.index_size] = state.index_count + indices[5];
- state.index_size += 1;
- state.index_count += 4;
- }
-
- if(state.vertex_size >= mrodeo_vertex_size_max)
- {
- rodeo_renderer_flush();
- }
-}
-
-rodeo_texture_2d_t
-rodeo_texture_2d_create_from_path(cstr path)
-{
- // load image to surface
- SDL_Surface *surface = IMG_Load(cstr_str(&path));
- if(surface == NULL)
- {
- rodeo_log(
- rodeo_logLevel_error,
- "Loading texture from image failed: %s",
- IMG_GetError()
- );
- return (rodeo_texture_2d_t){0};
- }
-
- // check and handle a color key for transparency
- // not sure if I actually need this...
- //uint32_t color_key;
- //if(SDL_GetColorKey(surface, &color_key) == 0)
- //{
- // SDL_SetColorKey(surface, SDL_TRUE, color_key);
- //}
-
- // convert pixel format of surface into RGBA8
- SDL_Surface *converted_surface =
- SDL_ConvertSurfaceFormat(
- surface,
- // pixel format needs to be backwards
- // of what bgfx uses for some reason
- SDL_PIXELFORMAT_ABGR8888,
- 0
- );
- if(converted_surface == NULL)
- {
- rodeo_log(
- rodeo_logLevel_error,
- "Converting image to RGBA8 while loading texture failed: %s",
- SDL_GetError()
- );
- SDL_FreeSurface(surface);
- return (rodeo_texture_2d_t){0};
- }
-
- // load the pixel data into our own texture
- rodeo_texture_2d_t texture = rodeo_texture_2d_create_from_RGBA8(
- (uint16_t)converted_surface->w,
- (uint16_t)converted_surface->h,
- converted_surface->pixels
- );
-
- SDL_FreeSurface(surface);
- SDL_FreeSurface(converted_surface);
-
- return texture;
-}
-
-bgfx_shader_handle_t
-irodeo_shader_load(const cstr path)
-{
- const char* path_cstr = cstr_str(&path);
- bgfx_shader_handle_t invalid = BGFX_INVALID_HANDLE;
-
- FILE *file = fopen(path_cstr, "rb");
-
- if(!file)
- {
- rodeo_log(
- rodeo_logLevel_error,
- "Shader file \"%s\" not found",
- path_cstr
- );
- return invalid;
- }
-
- fseek(file, 0, SEEK_END);
- int64_t file_size_temp = ftell(file);
- if(file_size_temp < 0)
- {
- rodeo_log(
- rodeo_logLevel_error,
- "Failed to get current file position of given stream(ftell() error)"
- );
- exit(EXIT_FAILURE);
- }
- if((file_size_temp + 1) > UINT32_MAX)
- {
- rodeo_log(
- rodeo_logLevel_error,
- "File size larger then what bgfx can allocate"
- );
- exit(EXIT_FAILURE);
- }
- uint32_t file_size = (uint32_t)file_size_temp;
- fseek(file, 0, SEEK_SET);
-
-
- const bgfx_memory_t *mem = bgfx_alloc(file_size + 1);
- fread(mem->data, 1, file_size, file);
- mem->data[mem->size - 1] = '\0';
- fclose(file);
-
- bgfx_shader_handle_t shader = bgfx_create_shader(mem);
- rodeo_log(
- rodeo_logLevel_info,
- "Shader loaded with idx: %"PRIu8"",
- shader.idx
- );
-
- return shader;
-}
-
-uint64_t
-rodeo_frame_count_get(void)
-{
- return state.frame_count;
-}
-
-float
-rodeo_frame_time_get(void)
-{
- return state.frame_time;
-}
-
-float
-rodeo_frame_perSecond_get(void)
-{
- return 1.0f / (rodeo_frame_time_get() / 1000.0f);
-}
-
-void
-rodeo_frame_limit_set(uint32_t limit)
-{
- #ifdef __EMSCRIPTEN__
- rodeo_log(
- rodeo_logLevel_warning,
- "Framerate limit cannot be set on web platform. Limit is enforced by platform to 60fps"
- );
- #else
- state.frame_limit = limit;
- #endif
-}
-
-uint32_t
-rodeo_frame_limit_get(void)
-{
- #ifdef __EMSCRIPTEN__
- return 60;
- #else
- return state.frame_limit;
- #endif
-}
-
void
irodeo_random_seed_set(stc64_t seed)
{
@@ -881,46 +65,3 @@ irodeo_random_seed_get(void)
return &state.random_seed;
}
-// measures how much time there is left in the remaining frame until
-// the frame target time is reached. If we surpassed the target time
-// then this will be negative
-float
-irodeo_frame_remaining_get(void)
-{
- #ifdef __EMSCRIPTEN__
- float target = 60.0f;
- #else
- float target = (float)rodeo_frame_limit_get();
- #endif
-
- float result = (1/target * 1000.0f) - ((float)(SDL_GetPerformanceCounter() - state.start_frame) / (float)SDL_GetPerformanceFrequency() * 1000.0f);
-
- return result;
-}
-
-// used internally at the end of every frame to fill for time
-// in order to reach the desired framerate
-void
-irodeo_frame_stall(void)
-{
- // if no frame limit then run as fast as possible
- if(rodeo_frame_limit_get() == 0)
- {
- return;
- }
-
- // sleep isnt perfectly accurate so we sleep for a slightly shorter
- // amount of time
- float stall_time = irodeo_frame_remaining_get();
- if(stall_time > 0.0005)
- {
- SDL_Delay((uint32_t)(stall_time * 0.9995));
- }
-
- // then we spinlock for the small remaining amount of time
- stall_time = irodeo_frame_remaining_get();
- while(stall_time > 0.0005) {
- stall_time = irodeo_frame_remaining_get();
- }
-}
-
diff --git a/src/rodeo_internal.h b/src/rodeo_internal.h
index 167215b..cc76df7 100644
--- a/src/rodeo_internal.h
+++ b/src/rodeo_internal.h
@@ -8,30 +8,6 @@
// -- external --
#include "SDL.h"
-#define \
-mrodeo_bgfx_vertex_layout_do(vertex_layout) \
- mrodeo_defer_do( \
- bgfx_vertex_layout_begin( \
- vertex_layout, \
- bgfx_get_renderer_type() \
- ), \
- bgfx_vertex_layout_end(vertex_layout) \
- )
-
-SDL_Window *
-irodeo_window_get(void);
-
-void
-irodeo_screen_width_set(uint16_t width);
-
-void
-irodeo_screen_height_set(uint16_t height);
-
-void
-irodeo_render_buffer_transient_alloc(void);
-
-bgfx_shader_handle_t
-irodeo_shader_load(const cstr path);
void
irodeo_random_seed_set(stc64_t seed);
@@ -39,8 +15,3 @@ irodeo_random_seed_set(stc64_t seed);
stc64_t*
irodeo_random_seed_get(void);
-float
-irodeo_frame_remaining_get(void);
-
-void
-irodeo_frame_stall(void);
diff --git a/src/rodeo_internal_types.h b/src/rodeo_internal_types.h
index 4b3a6ff..263b9c0 100644
--- a/src/rodeo_internal_types.h
+++ b/src/rodeo_internal_types.h
@@ -18,50 +18,11 @@
/*#define CGLM_CLIPSPACE_INCLUDE_ALL*/
#include "cglm/cglm.h"
-typedef uint16_t irodeo_index_type_t;
-
typedef struct
{
- SDL_Window* window;
- SDL_Surface* screen_surface;
- SDL_SysWMinfo wmi;
- uint16_t screen_width;
- uint16_t screen_height;
- SDL_Event sdl_event;
- bool quit;
-
- bgfx_vertex_layout_t vertex_layout;
- //bgfx_dynamic_vertex_buffer_handle_t vertex_buffer_handle;
- //bgfx_dynamic_index_buffer_handle_t index_buffer_handle;
- bgfx_transient_vertex_buffer_t vertex_buffer_handle;
- bgfx_transient_index_buffer_t index_buffer_handle;
- rodeo_vertex_t *batched_vertices;
- irodeo_index_type_t *batched_indices;
- irodeo_index_type_t vertex_size;
- irodeo_index_type_t index_count;
- irodeo_index_type_t index_size;
- //irodeo_index_type_t batched_indices[(mrodeo_vertex_size_max / 4) * 6];
- rodeo_texture_2d_t default_texture;
- bgfx_texture_handle_t *active_texture_p;
- bgfx_shader_handle_t vertex_shader;
- bgfx_shader_handle_t fragment_shader;
- bgfx_program_handle_t program_shader;
- bgfx_uniform_handle_t texture_uniforms[2];
- mat4 view_matrix;
- mat4 proj_matrix;
-
stc64_t random_seed;
uint64_t frame_count;
- uint64_t start_frame;
- uint64_t end_frame;
- float frame_time;
uint32_t frame_limit;
}
irodeo_state_t;
-
-struct
-irodeo_texture_internal_t
-{
- bgfx_texture_handle_t texture_bgfx;
-};
diff --git a/src/window/irodeo_window.h b/src/window/irodeo_window.h
new file mode 100644
index 0000000..f0c02e2
--- /dev/null
+++ b/src/window/irodeo_window.h
@@ -0,0 +1,30 @@
+#pragma once
+
+// -- internal --
+// private
+#include "irodeo_window_t.h"
+
+// -- external --
+#include "SDL.h"
+#include "SDL_syswm.h"
+
+SDL_Window *
+irodeo_window_get(void);
+
+SDL_Surface *
+irodeo_window_surface_get(void);
+
+void
+irodeo_window_screen_width_setVar(uint16_t width);
+
+void
+irodeo_window_screen_height_setVar(uint16_t height);
+
+SDL_Window *
+irodeo_window_get(void);
+
+SDL_Surface *
+irodeo_window_surface_get(void);
+
+SDL_SysWMinfo
+irodeo_window_wmi_get(void);
diff --git a/src/window/irodeo_window_t.h b/src/window/irodeo_window_t.h
new file mode 100644
index 0000000..e2dd0a4
--- /dev/null
+++ b/src/window/irodeo_window_t.h
@@ -0,0 +1,21 @@
+#pragma once
+
+// -- external --
+#include "SDL.h"
+#include "SDL_syswm.h"
+
+// -- system --
+#include "inttypes.h"
+#include "stdbool.h"
+
+typedef
+struct
+{
+ SDL_Window* window;
+ SDL_Surface* screen_surface;
+ SDL_SysWMinfo wmi;
+ uint16_t screen_width;
+ uint16_t screen_height;
+ bool quit;
+}
+irodeo_window_state_t;
diff --git a/src/window/rodeo_window.c b/src/window/rodeo_window.c
new file mode 100644
index 0000000..5267bfa
--- /dev/null
+++ b/src/window/rodeo_window.c
@@ -0,0 +1,166 @@
+
+// -- internal --
+// public
+#include "rodeo/window.h"
+#include "rodeo/log.h"
+// private
+#include "window/irodeo_window.h"
+
+// -- external --
+#include "SDL.h"
+#include "stc/cstr.h"
+
+static irodeo_window_state_t irodeo_window_state = {0};
+
+void
+rodeo_window_init(
+ uint16_t screen_height,
+ uint16_t screen_width,
+ cstr title
+)
+{
+ irodeo_window_state.window = NULL;
+ irodeo_window_state.screen_surface = NULL;
+ irodeo_window_state.screen_height = screen_height;
+ irodeo_window_state.screen_width = screen_width;
+
+ rodeo_log(
+ rodeo_logLevel_info,
+ "Initializing SDL..."
+ );
+
+ {
+ uint32_t init_flags_sdl = 0;
+ init_flags_sdl = init_flags_sdl | SDL_INIT_VIDEO;
+ init_flags_sdl = init_flags_sdl | SDL_INIT_AUDIO;
+ init_flags_sdl = init_flags_sdl | SDL_INIT_GAMECONTROLLER;
+
+ if(SDL_Init(init_flags_sdl) < 0)
+ {
+ rodeo_log(
+ rodeo_logLevel_error,
+ "Failed to initialize SDL. SDL_Error: %s",
+ SDL_GetError()
+ );
+ exit(EXIT_FAILURE);
+ }
+ rodeo_log(
+ rodeo_logLevel_info,
+ "Success initializing SDL"
+ );
+ }
+
+ rodeo_log(
+ rodeo_logLevel_info,
+ "Initializing SDL window..."
+ );
+ irodeo_window_state.window = SDL_CreateWindow(
+ cstr_str(&title),
+ SDL_WINDOWPOS_UNDEFINED,
+ SDL_WINDOWPOS_UNDEFINED,
+ screen_width,
+ screen_height,
+ SDL_WINDOW_SHOWN //| SDL_WINDOW_RESIZABLE
+ );
+ if(irodeo_window_state.window == NULL)
+ {
+ rodeo_log(
+ rodeo_logLevel_error,
+ "Failed creating SDL window. SDL_Error: %s",
+ SDL_GetError()
+ );
+ exit(EXIT_FAILURE);
+ }
+ rodeo_log(
+ rodeo_logLevel_info,
+ "Success initializing SDL window"
+ );
+
+#if !__EMSCRIPTEN__
+ rodeo_log(
+ rodeo_logLevel_info,
+ "SDL setting up driver specific information..."
+ );
+ SDL_VERSION(&irodeo_window_state.wmi.version);
+ if(
+ !SDL_GetWindowWMInfo(
+ irodeo_window_state.window,
+ &irodeo_window_state.wmi
+ )
+ )
+ {
+ rodeo_log(
+ rodeo_logLevel_error,
+ "SDL failed to get driver specific information. SDL Error: %s", SDL_GetError()
+ );
+ exit(EXIT_FAILURE);
+ }
+ rodeo_log(
+ rodeo_logLevel_info,
+ "Success getting driver specific information"
+ );
+#endif
+
+}
+
+void
+rodeo_window_deinit(void)
+{
+ SDL_DestroyWindow(irodeo_window_state.window);
+ //Mix_Quit();
+ SDL_Quit();
+}
+
+uint16_t
+rodeo_window_screen_width_get(void)
+{
+ return irodeo_window_state.screen_width;
+}
+
+uint16_t
+rodeo_window_screen_height_get(void)
+{
+ return irodeo_window_state.screen_height;
+}
+
+void
+irodeo_window_screen_width_setVar(uint16_t width)
+{
+ irodeo_window_state.screen_width = width;
+}
+
+void
+irodeo_window_screen_height_setVar(uint16_t height)
+{
+ irodeo_window_state.screen_height = height;
+}
+
+bool
+rodeo_window_shouldQuit(void)
+{
+ return irodeo_window_state.quit;
+}
+
+void
+rodeo_window_quit(void)
+{
+ irodeo_window_state.quit = true;
+}
+
+SDL_Window *
+irodeo_window_get(void)
+{
+ return irodeo_window_state.window;
+}
+
+SDL_Surface *
+irodeo_window_surface_get(void)
+{
+ return irodeo_window_state.screen_surface;
+}
+
+SDL_SysWMinfo
+irodeo_window_wmi_get(void)
+{
+ return irodeo_window_state.wmi;
+}