diff options
| author | realtradam <[email protected]> | 2023-01-06 15:53:53 -0500 |
|---|---|---|
| committer | realtradam <[email protected]> | 2023-01-06 15:53:53 -0500 |
| commit | 729a6b3b9cb0315106c87079a0eba9b294f02159 (patch) | |
| tree | 4d7062c70b13349685bd7dc39295af6b1dc64a25 | |
| parent | b1f855a82b40f1caeaf4d672638f2cfc933c8040 (diff) | |
| download | RodeoKit-729a6b3b9cb0315106c87079a0eba9b294f02159.tar.gz RodeoKit-729a6b3b9cb0315106c87079a0eba9b294f02159.zip | |
render batching for coloured rectangles
| -rw-r--r-- | .gitmodules | 3 | ||||
| -rw-r--r-- | CMakeLists.txt | 13 | ||||
| -rwxr-xr-x | build_shaders | 3 | ||||
| m--------- | external/cglm | 0 | ||||
| -rw-r--r-- | include/rodeo.h | 61 | ||||
| -rw-r--r-- | include/rodeo_math.h | 7 | ||||
| -rw-r--r-- | include/rodeo_types.h | 57 | ||||
| -rw-r--r-- | src/compile_flags.txt | 1 | ||||
| -rw-r--r-- | src/rodeo.c | 188 | ||||
| -rw-r--r-- | src/rodeo_math.c | 14 | ||||
| -rw-r--r-- | src/shaders/simple.fragment.sc | 8 | ||||
| -rw-r--r-- | src/shaders/simple.vertex.sc | 10 | ||||
| -rw-r--r-- | src/shaders/varying.def.sc | 6 |
13 files changed, 324 insertions, 47 deletions
diff --git a/.gitmodules b/.gitmodules index d15c2d1..78c2c7e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "external/bgfx"] path = external/bgfx url = https://github.com/bkaradzic/bgfx.git +[submodule "external/cglm"] + path = external/cglm + url = https://github.com/recp/cglm diff --git a/CMakeLists.txt b/CMakeLists.txt index f0f046d..ec7310d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,7 @@ project(RodeoEngine) file(GLOB SOURCES "src/rodeo.c" + "src/rodeo_math.c" ) #add_library(lib src/lib.c) @@ -27,6 +28,9 @@ if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") endif() add_subdirectory(external/SDL) +add_subdirectory(external/cglm EXCLUDE_FROM_ALL) + +#option(CGLM_FORCE_LEFT_HANDED "" ON) ExternalProject_Add(project_bgfx #BUILD_IN_SOURCE true # this just doesn't work @@ -45,6 +49,7 @@ target_include_directories(${PROJECT_NAME} PUBLIC external/SDL/include PUBLIC external/bgfx/include PUBLIC external/bx/include + PUBLIC external/cglm/include PUBLIC include ) @@ -53,11 +58,11 @@ target_link_directories(${PROJECT_NAME} PRIVATE external/bgfx ) + ExternalProject_Get_Property(project_bgfx BINARY_DIR) #message("++" ${BINARY_DIR}) -target_link_libraries(${PROJECT_NAME} +target_link_libraries(${PROJECT_NAME} PRIVATE SDL2::SDL2 # dynamic lib - #SDL3::SDL3 # dynamic lib - #SDL3::SDL3-static # static lib - ${BINARY_DIR}/.build/linux64_gcc/bin/libbgfx-shared-libRelease.so + cglm + ${BINARY_DIR}/.build/linux64_gcc/bin/libbgfx-shared-libDebug.so ) diff --git a/build_shaders b/build_shaders new file mode 100755 index 0000000..6399436 --- /dev/null +++ b/build_shaders @@ -0,0 +1,3 @@ +#! /bin/sh +./external/bgfx/.build/linux64_gcc/bin/shadercRelease -f ./src/shaders/simple.vertex.sc -o ./build_dir/simple.vertex.bin --platform linux --type vertex --verbose -i ./external/bgfx/src/ -p spirv +./external/bgfx/.build/linux64_gcc/bin/shadercRelease -f ./src/shaders/simple.fragment.sc -o ./build_dir/simple.fragment.bin --platform linux --type fragment --verbose -i ./external/bgfx/src/ -p spirv diff --git a/external/cglm b/external/cglm new file mode 160000 +Subproject 38771599c704d29888e2f360b12b02535bcaec3 diff --git a/include/rodeo.h b/include/rodeo.h index 86505f1..4686cb5 100644 --- a/include/rodeo.h +++ b/include/rodeo.h @@ -1,40 +1,23 @@ #include <stdbool.h> +#include <stdio.h> +#include <string.h> +#include <limits.h> + #include "SDL2/SDL.h" #include "SDL2/SDL_syswm.h" +#include "bgfx/c99/bgfx.h" -typedef -struct -Rodeo__\ -data_t -{ - SDL_Window* window; - SDL_Surface* screen_surface; - SDL_SysWMinfo wmi; - int screen_width; - int screen_height; - SDL_Event sdl_event; - bool quit; -} Rodeo__data_t; +#include "rodeo_types.h" -typedef -struct -Rodeo__\ -color_t -{ - float red; - float green; - float blue; - float alpha; -} Rodeo__color_t; void Rodeo__\ init_window( - Rodeo__data_t* state, - int screen_height, - int screen_width, - char* title - ); + Rodeo__data_t* state, + int screen_height, + int screen_width, + char* title +); void Rodeo__\ @@ -56,3 +39,25 @@ void Rodeo__\ draw_debug_text(u_int16_t x, u_int16_t y, const char *format, ...); +const char * +Rodeo__\ +get_renderer_name_as_string(); + +void +Rodeo__\ +flush_batch(Rodeo__data_t *state); + +void +Rodeo__\ +draw_rectangle( + Rodeo__data_t *state, + u_int16_t x, + u_int16_t y, + u_int16_t width, + u_int16_t height, + struct Rodeo__color_rgba_t color +); + +bgfx_shader_handle_t +Rodeo__\ +load_shader(const char* path); diff --git a/include/rodeo_math.h b/include/rodeo_math.h new file mode 100644 index 0000000..13db9b3 --- /dev/null +++ b/include/rodeo_math.h @@ -0,0 +1,7 @@ +#include "stdint.h" +#include "rodeo_types.h" + +uint32_t +Rodeo__\ +Math__\ +color_rgba_to_uint32(const struct Rodeo__color_rgba_t color); diff --git a/include/rodeo_types.h b/include/rodeo_types.h new file mode 100644 index 0000000..08748e5 --- /dev/null +++ b/include/rodeo_types.h @@ -0,0 +1,57 @@ +#pragma once +#include <stdbool.h> +#include <stdint.h> + +#include "SDL2/SDL.h" +#include "SDL2/SDL_syswm.h" +#include "bgfx/c99/bgfx.h" + +#define RODEO__MAX_VERTEX_SIZE 8192 + +typedef +struct +Rodeo__\ +color_rgba_t +{ + float red; + float green; + float blue; + float alpha; +} Rodeo__color_t; + +typedef +struct +Rodeo__\ +position_color_vertex_t +{ + float x; + float y; + float z; + uint32_t abgr; +} Rodeo__position_color_vertex_t; + +typedef +struct +Rodeo__\ +data_t +{ + SDL_Window* window; + SDL_Surface* screen_surface; + SDL_SysWMinfo wmi; + int screen_width; + int 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; + uint16_t vertex_size; + Rodeo__position_color_vertex_t batched_vertices[RODEO__MAX_VERTEX_SIZE]; + uint16_t index_count; + uint16_t index_size; + uint16_t batched_indices[(RODEO__MAX_VERTEX_SIZE / 4) * 6]; + bgfx_shader_handle_t vertex_shader; + bgfx_shader_handle_t fragment_shader; + bgfx_program_handle_t program_shader; +} Rodeo__data_t; diff --git a/src/compile_flags.txt b/src/compile_flags.txt index 834f763..0d92969 100644 --- a/src/compile_flags.txt +++ b/src/compile_flags.txt @@ -3,3 +3,4 @@ -I../external/SDL/include -I../external/bgfx/include -I../external/bx/include +-I../external/cglm/include diff --git a/src/rodeo.c b/src/rodeo.c index 3885ceb..18c1666 100644 --- a/src/rodeo.c +++ b/src/rodeo.c @@ -1,10 +1,10 @@ #include "SDL2/SDL.h" #include "SDL2/SDL_syswm.h" #include "bgfx/c99/bgfx.h" +#include "cglm/cglm.h" #include "rodeo.h" - -//static Rodeo__data_t Rodeo__State = { 0 }; +#include "rodeo_math.h" void Rodeo__\ @@ -27,13 +27,13 @@ init_window( } state->window = SDL_CreateWindow( - title, - SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, - screen_width, - screen_height, - SDL_WINDOW_SHOWN - ); + title, + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + screen_width, + screen_height, + SDL_WINDOW_SHOWN + ); if(state->window == NULL) { @@ -64,14 +64,13 @@ init_window( 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 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_reset(state->screen_width, state->screen_height, BGFX_RESET_VSYNC, init.resolution.format); - bgfx_set_debug(BGFX_DEBUG_TEXT); bgfx_set_view_clear( @@ -83,15 +82,32 @@ init_window( ); bgfx_set_view_rect(0, 0, 0, state->screen_width, state->screen_height); - bgfx_touch(0); + bgfx_vertex_layout_begin(&state->vertex_layout, bgfx_get_renderer_type()); + 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_UINT8, true, false); + bgfx_vertex_layout_end(&state->vertex_layout); - bgfx_frame(false); + state->vertex_buffer_handle = bgfx_create_dynamic_vertex_buffer(RODEO__MAX_VERTEX_SIZE, &state->vertex_layout, BGFX_BUFFER_NONE); + + state->index_buffer_handle = bgfx_create_dynamic_index_buffer((RODEO__MAX_VERTEX_SIZE / 4) * 6, BGFX_BUFFER_NONE); + + // load shaders + state->vertex_shader = Rodeo__load_shader("./external/RodeoEngine/build_dir/simple.vertex.bin"); + state->fragment_shader = Rodeo__load_shader("./external/RodeoEngine/build_dir/simple.fragment.bin"); + state->program_shader = bgfx_create_program( + state->vertex_shader, + state->fragment_shader, + true + ); } void Rodeo__\ deinit_window(Rodeo__data_t* state) { + 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); } @@ -107,12 +123,37 @@ void Rodeo__\ begin(Rodeo__data_t* state) { + //vec3 eye = {0.0f, 0.0f, -35.0f}; + //vec3 center = {0.0f, 0.0f, 0.0f}; + //vec3 up = {0, 1, 0}; + mat4 view; + //glm_lookat(eye, center, up, view); + glm_mat4_identity(view); + + mat4 proj; + //glm_perspective(glm_rad(60.f), 640.f / 480.f, 0.1f, 100.0f, proj); + glm_ortho( + 0, + state->screen_width, + state->screen_height, + 0, + 100.0f, // backwards because winding is wrong + -0.1f, // TODO: fix cglm winding order + proj + ); + bgfx_set_view_transform(0, view, proj); + bgfx_set_view_rect(0, 0, 0, state->screen_width, state->screen_height); + bgfx_touch(0); } void Rodeo__\ end(Rodeo__data_t* state) { + Rodeo__flush_batch(state); + + bgfx_frame(false); + while(SDL_PollEvent(&state->sdl_event)) { if(state->sdl_event.type == SDL_QUIT) @@ -120,8 +161,6 @@ end(Rodeo__data_t* state) state->quit = true; } } - bgfx_touch(0); - bgfx_frame(false); } void @@ -133,3 +172,122 @@ draw_debug_text(u_int16_t x, u_int16_t y, const char *format, ...) bgfx_dbg_text_vprintf(x, y, 0x65, format, argList); va_end(argList); } + +const char * +Rodeo__\ +get_renderer_name_as_string() +{ + return bgfx_get_renderer_name(bgfx_get_renderer_type()); +} + +void +Rodeo__\ +flush_batch(Rodeo__data_t *state) +{ + if(state->vertex_size > 0) + { + // upload remaining batched vertices + bgfx_set_dynamic_vertex_buffer(0, state->vertex_buffer_handle, 0, state->vertex_size); + const bgfx_memory_t* vbm = bgfx_copy(state->batched_vertices, sizeof(Rodeo__position_color_vertex_t) * state->vertex_size); + bgfx_update_dynamic_vertex_buffer(state->vertex_buffer_handle, 0, vbm); + + // upload remaining batched indices + 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_ALL); + + // reset arrays + state->vertex_size = 0; + state->index_size = 0; + state->index_count = 0; + } +} + +void +Rodeo__\ +draw_rectangle( + Rodeo__data_t *state, + u_int16_t x, + u_int16_t y, + u_int16_t width, + u_int16_t height, + struct Rodeo__color_rgba_t color +) +{ + const uint32_t abgr = Rodeo__Math__color_rgba_to_uint32(color); + if(state->vertex_size < RODEO__MAX_VERTEX_SIZE) + { + state->batched_vertices[state->vertex_size] = + (Rodeo__position_color_vertex_t) + { + (float)width + (float)x, (float)height + (float)y, 0.0f, abgr + }; + state->vertex_size += 1; + state->batched_vertices[state->vertex_size] = + (Rodeo__position_color_vertex_t) + { + (float)width + (float)x, (float)y, 0.0f, abgr + }; + state->vertex_size += 1; + state->batched_vertices[state->vertex_size] = + (Rodeo__position_color_vertex_t) + { + (float)x, (float)y, 0.0f, abgr + }; + state->vertex_size += 1; + state->batched_vertices[state->vertex_size] = + (Rodeo__position_color_vertex_t) + { + (float)x, (float)height + (float)y, 0.0f, abgr + }; + state->vertex_size += 1; + + state->batched_indices[state->index_size] = state->index_count; + state->index_size += 1; + state->batched_indices[state->index_size] = state->index_count + 1; + state->index_size += 1; + state->batched_indices[state->index_size] = state->index_count + 3; + state->index_size += 1; + state->batched_indices[state->index_size] = state->index_count + 1; + state->index_size += 1; + state->batched_indices[state->index_size] = state->index_count + 2; + state->index_size += 1; + state->batched_indices[state->index_size] = state->index_count + 3; + state->index_size += 1; + state->index_count += 4; + } + + if(state->vertex_size >= RODEO__MAX_VERTEX_SIZE) + { + Rodeo__flush_batch(state); + } +} + +bgfx_shader_handle_t +Rodeo__\ +load_shader(const char* path) +{ + bgfx_shader_handle_t invalid = BGFX_INVALID_HANDLE; + + FILE *file = fopen(path, "rb"); + + if(!file) + { + printf("Error: shader file \"%s\" not found", path); + return invalid; + } + + fseek(file, 0, SEEK_END); + long file_size = ftell(file); + 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); + + return bgfx_create_shader(mem); +} diff --git a/src/rodeo_math.c b/src/rodeo_math.c new file mode 100644 index 0000000..99f61af --- /dev/null +++ b/src/rodeo_math.c @@ -0,0 +1,14 @@ +#include "rodeo.h" +#include "rodeo_math.h" + +uint32_t +Rodeo__\ +Math__\ +color_rgba_to_uint32(const struct Rodeo__color_rgba_t color) +{ + return + ((uint32_t)(uint8_t)(color.red * 255)) + | ((uint32_t)(uint8_t)(color.green * 255)) << (8 * 1) + | ((uint32_t)(uint8_t)(color.blue * 255)) << (8 * 2) + | ((uint32_t)(uint8_t)(color.alpha * 255)) << (8 * 3); +} diff --git a/src/shaders/simple.fragment.sc b/src/shaders/simple.fragment.sc new file mode 100644 index 0000000..3a58d8d --- /dev/null +++ b/src/shaders/simple.fragment.sc @@ -0,0 +1,8 @@ +$input v_color0 + +#include <bgfx_shader.sh> + +void main() +{ + gl_FragColor = v_color0; +} diff --git a/src/shaders/simple.vertex.sc b/src/shaders/simple.vertex.sc new file mode 100644 index 0000000..56b8736 --- /dev/null +++ b/src/shaders/simple.vertex.sc @@ -0,0 +1,10 @@ +$input a_position, a_color0 +$output v_color0 + +#include <bgfx_shader.sh> + +void main() +{ + gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0)); + v_color0 = a_color0; +} diff --git a/src/shaders/varying.def.sc b/src/shaders/varying.def.sc new file mode 100644 index 0000000..2ae9226 --- /dev/null +++ b/src/shaders/varying.def.sc @@ -0,0 +1,6 @@ +// outputs; +vec4 v_color0 : COLOR0; + +// inputs; +vec3 a_position : POSITION; +vec4 a_color0 : COLOR0; |
