diff options
| -rw-r--r-- | gfx/include/gfx/renderer.h | 16 | ||||
| -rw-r--r-- | gfx/src/renderer/renderer.c | 64 | ||||
| -rw-r--r-- | gfx/src/renderer/renderer_impl.h | 11 | ||||
| -rw-r--r-- | gltfview/src/game.c | 32 | 
4 files changed, 86 insertions, 37 deletions
| diff --git a/gfx/include/gfx/renderer.h b/gfx/include/gfx/renderer.h index 1517af6..13e6c2c 100644 --- a/gfx/include/gfx/renderer.h +++ b/gfx/include/gfx/renderer.h | |||
| @@ -17,8 +17,22 @@ typedef struct Renderer Renderer; | |||
| 17 | // Main Renderer. | 17 | // Main Renderer. | 
| 18 | // ----------------------------------------------------------------------------- | 18 | // ----------------------------------------------------------------------------- | 
| 19 | 19 | ||
| 20 | typedef enum RenderSceneMode { | ||
| 21 | RenderDefault, | ||
| 22 | RenderDebug, | ||
| 23 | RenderNormals, | ||
| 24 | RenderNormalMappedNormals, | ||
| 25 | RenderTangents | ||
| 26 | } RenderSceneMode; | ||
| 27 | |||
| 28 | typedef struct RenderSceneParams { | ||
| 29 | RenderSceneMode mode; | ||
| 30 | const Scene* scene; | ||
| 31 | const SceneCamera* camera; | ||
| 32 | } RenderSceneParams; | ||
| 33 | |||
| 20 | /// Render the scene. | 34 | /// Render the scene. | 
| 21 | void gfx_render_scene(Renderer*, const Scene*, const SceneCamera*); | 35 | void gfx_render_scene(Renderer*, const RenderSceneParams*); | 
| 22 | 36 | ||
| 23 | // ----------------------------------------------------------------------------- | 37 | // ----------------------------------------------------------------------------- | 
| 24 | // Immediate Mode Renderer. | 38 | // Immediate Mode Renderer. | 
| diff --git a/gfx/src/renderer/renderer.c b/gfx/src/renderer/renderer.c index 1e96873..bddde90 100644 --- a/gfx/src/renderer/renderer.c +++ b/gfx/src/renderer/renderer.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | #include <gfx/render_backend.h> | 12 | #include <gfx/render_backend.h> | 
| 13 | #include <gfx/util/ibl.h> | 13 | #include <gfx/util/ibl.h> | 
| 14 | #include <gfx/util/shader.h> | ||
| 14 | 15 | ||
| 15 | #include <log/log.h> | 16 | #include <log/log.h> | 
| 16 | #include <math/mat4.h> | 17 | #include <math/mat4.h> | 
| @@ -40,8 +41,22 @@ void renderer_destroy(Renderer* renderer) { | |||
| 40 | return; | 41 | return; | 
| 41 | } | 42 | } | 
| 42 | assert(renderer->render_backend); | 43 | assert(renderer->render_backend); | 
| 44 | RenderBackend* render_backend = renderer->render_backend; | ||
| 43 | if (renderer->ibl) { | 45 | if (renderer->ibl) { | 
| 44 | gfx_destroy_ibl(renderer->render_backend, &renderer->ibl); | 46 | gfx_destroy_ibl(render_backend, &renderer->ibl); | 
| 47 | } | ||
| 48 | if (renderer->shaders.debug) { | ||
| 49 | gfx_destroy_shader_program(render_backend, &renderer->shaders.debug); | ||
| 50 | } | ||
| 51 | if (renderer->shaders.normals) { | ||
| 52 | gfx_destroy_shader_program(render_backend, &renderer->shaders.normals); | ||
| 53 | } | ||
| 54 | if (renderer->shaders.normal_mapped_normals) { | ||
| 55 | gfx_destroy_shader_program( | ||
| 56 | render_backend, &renderer->shaders.normal_mapped_normals); | ||
| 57 | } | ||
| 58 | if (renderer->shaders.tangents) { | ||
| 59 | gfx_destroy_shader_program(render_backend, &renderer->shaders.tangents); | ||
| 45 | } | 60 | } | 
| 46 | } | 61 | } | 
| 47 | 62 | ||
| @@ -64,6 +79,36 @@ static bool init_ibl(Renderer* renderer) { | |||
| 64 | return true; | 79 | return true; | 
| 65 | } | 80 | } | 
| 66 | 81 | ||
| 82 | static ShaderProgram* load_shader(Renderer* renderer, RenderSceneMode mode) { | ||
| 83 | assert(renderer); | ||
| 84 | |||
| 85 | #define LOAD_AND_RETURN(pShader, constructor) \ | ||
| 86 | { \ | ||
| 87 | if (!pShader) { \ | ||
| 88 | pShader = constructor(renderer->render_backend); \ | ||
| 89 | } \ | ||
| 90 | assert(pShader); \ | ||
| 91 | return pShader; \ | ||
| 92 | } | ||
| 93 | |||
| 94 | switch (mode) { | ||
| 95 | case RenderDefault: | ||
| 96 | return 0; | ||
| 97 | case RenderDebug: | ||
| 98 | LOAD_AND_RETURN(renderer->shaders.debug, gfx_make_debug3d_shader); | ||
| 99 | case RenderNormals: | ||
| 100 | LOAD_AND_RETURN(renderer->shaders.normals, gfx_make_view_normals_shader); | ||
| 101 | case RenderNormalMappedNormals: | ||
| 102 | LOAD_AND_RETURN( | ||
| 103 | renderer->shaders.normal_mapped_normals, | ||
| 104 | gfx_make_view_normal_mapped_normals_shader); | ||
| 105 | case RenderTangents: | ||
| 106 | LOAD_AND_RETURN(renderer->shaders.tangents, gfx_make_view_tangents_shader); | ||
| 107 | } | ||
| 108 | assert(false); | ||
| 109 | return 0; | ||
| 110 | } | ||
| 111 | |||
| 67 | // static void log_matrix(const mat4* m) { | 112 | // static void log_matrix(const mat4* m) { | 
| 68 | // for (int row = 0; row < 4; ++row) { | 113 | // for (int row = 0; row < 4; ++row) { | 
| 69 | // LOGI("[ %5.2f, %5.2f, %5.2f, %5.2f ]", m->val[0][row], m->val[1][row], | 114 | // LOGI("[ %5.2f, %5.2f, %5.2f, %5.2f ]", m->val[0][row], m->val[1][row], | 
| @@ -124,6 +169,7 @@ cleanup: | |||
| 124 | typedef struct RenderState { | 169 | typedef struct RenderState { | 
| 125 | RenderBackend* render_backend; | 170 | RenderBackend* render_backend; | 
| 126 | Renderer* renderer; | 171 | Renderer* renderer; | 
| 172 | ShaderProgram* shader; // Null to use scene shaders. | ||
| 127 | const Scene* scene; | 173 | const Scene* scene; | 
| 128 | const Camera* camera; | 174 | const Camera* camera; | 
| 129 | const mat4* camera_rotation; // From camera to world space, rotation only. | 175 | const mat4* camera_rotation; // From camera to world space, rotation only. | 
| @@ -209,7 +255,7 @@ static void draw_recursively( | |||
| 209 | // relatively large, but still, the culling would be conservative. | 255 | // relatively large, but still, the culling would be conservative. | 
| 210 | 256 | ||
| 211 | // Apply common shader uniforms not captured by materials. | 257 | // Apply common shader uniforms not captured by materials. | 
| 212 | ShaderProgram* shader = mesh->shader; | 258 | ShaderProgram* shader = state->shader ? state->shader : mesh->shader; | 
| 213 | gfx_set_mat4_uniform(shader, "ModelMatrix", &model_matrix); | 259 | gfx_set_mat4_uniform(shader, "ModelMatrix", &model_matrix); | 
| 214 | gfx_set_mat4_uniform(shader, "Modelview", &modelview); | 260 | gfx_set_mat4_uniform(shader, "Modelview", &modelview); | 
| 215 | gfx_set_mat4_uniform(shader, "View", state->view_matrix); | 261 | gfx_set_mat4_uniform(shader, "View", state->view_matrix); | 
| @@ -259,11 +305,16 @@ static void draw_recursively( | |||
| 259 | } | 305 | } | 
| 260 | } | 306 | } | 
| 261 | 307 | ||
| 262 | void gfx_render_scene( | 308 | void gfx_render_scene(Renderer* renderer, const RenderSceneParams* params) { | 
| 263 | Renderer* renderer, const Scene* scene, const SceneCamera* camera) { | ||
| 264 | assert(renderer); | 309 | assert(renderer); | 
| 265 | assert(scene); | 310 | assert(params); | 
| 266 | assert(camera); | 311 | assert(params->scene); | 
| 312 | assert(params->camera); | ||
| 313 | |||
| 314 | ShaderProgram* const shader = load_shader(renderer, params->mode); | ||
| 315 | |||
| 316 | const Scene* scene = params->scene; | ||
| 317 | const SceneCamera* camera = params->camera; | ||
| 267 | 318 | ||
| 268 | RenderBackend* render_backend = renderer->render_backend; | 319 | RenderBackend* render_backend = renderer->render_backend; | 
| 269 | 320 | ||
| @@ -280,6 +331,7 @@ void gfx_render_scene( | |||
| 280 | RenderState state = { | 331 | RenderState state = { | 
| 281 | .render_backend = render_backend, | 332 | .render_backend = render_backend, | 
| 282 | .renderer = renderer, | 333 | .renderer = renderer, | 
| 334 | .shader = shader, | ||
| 283 | .scene = scene, | 335 | .scene = scene, | 
| 284 | .camera = &camera->camera, | 336 | .camera = &camera->camera, | 
| 285 | .camera_rotation = &camera_rotation, | 337 | .camera_rotation = &camera_rotation, | 
| diff --git a/gfx/src/renderer/renderer_impl.h b/gfx/src/renderer/renderer_impl.h index b25d14c..1e28eb5 100644 --- a/gfx/src/renderer/renderer_impl.h +++ b/gfx/src/renderer/renderer_impl.h | |||
| @@ -4,13 +4,20 @@ | |||
| 4 | 4 | ||
| 5 | #include <stdbool.h> | 5 | #include <stdbool.h> | 
| 6 | 6 | ||
| 7 | typedef struct IBL IBL; | 7 | typedef struct IBL IBL; | 
| 8 | typedef struct Texture Texture; | 8 | typedef struct ShaderProgram ShaderProgram; | 
| 9 | typedef struct Texture Texture; | ||
| 9 | 10 | ||
| 10 | typedef struct Renderer { | 11 | typedef struct Renderer { | 
| 11 | RenderBackend* render_backend; | 12 | RenderBackend* render_backend; | 
| 12 | IBL* ibl; | 13 | IBL* ibl; | 
| 13 | Texture* brdf_integration_map; | 14 | Texture* brdf_integration_map; | 
| 15 | struct { | ||
| 16 | ShaderProgram* debug; | ||
| 17 | ShaderProgram* normals; | ||
| 18 | ShaderProgram* normal_mapped_normals; | ||
| 19 | ShaderProgram* tangents; | ||
| 20 | } shaders; | ||
| 14 | } Renderer; | 21 | } Renderer; | 
| 15 | 22 | ||
| 16 | /// Create a new renderer. | 23 | /// Create a new renderer. | 
| diff --git a/gltfview/src/game.c b/gltfview/src/game.c index 698267e..c711ce1 100644 --- a/gltfview/src/game.c +++ b/gltfview/src/game.c | |||
| @@ -40,24 +40,6 @@ static const char* GIRL = | |||
| 40 | 40 | ||
| 41 | static const char* CLOUDS1_TEXTURE = "/assets/skybox/clouds1/clouds1_west.bmp"; | 41 | static const char* CLOUDS1_TEXTURE = "/assets/skybox/clouds1/clouds1_west.bmp"; | 
| 42 | 42 | ||
| 43 | // TODO: Move this debug rendering to the renderer. | ||
| 44 | static ShaderProgram* load_shader( | ||
| 45 | RenderBackend* render_backend, const char* view_mode) { | ||
| 46 | ShaderProgram* shader = 0; | ||
| 47 | if (strcmp(view_mode, "debug") == 0) { | ||
| 48 | shader = gfx_make_debug3d_shader(render_backend); | ||
| 49 | } else if (strcmp(view_mode, "normals") == 0) { | ||
| 50 | shader = gfx_make_view_normals_shader(render_backend); | ||
| 51 | } else if (strcmp(view_mode, "normal_mapped_normals") == 0) { | ||
| 52 | shader = gfx_make_view_normal_mapped_normals_shader(render_backend); | ||
| 53 | } else if (strcmp(view_mode, "tangents") == 0) { | ||
| 54 | shader = gfx_make_view_tangents_shader(render_backend); | ||
| 55 | } else { | ||
| 56 | shader = gfx_make_cook_torrance_shader(render_backend); | ||
| 57 | } | ||
| 58 | return shader; | ||
| 59 | } | ||
| 60 | |||
| 61 | /// Load the skyquad texture. | 43 | /// Load the skyquad texture. | 
| 62 | static Texture* load_environment_map(RenderBackend* render_backend) { | 44 | static Texture* load_environment_map(RenderBackend* render_backend) { | 
| 63 | return gfx_load_texture( | 45 | return gfx_load_texture( | 
| @@ -111,12 +93,6 @@ static SceneNode* load_scene( | |||
| 111 | return 0; | 93 | return 0; | 
| 112 | } | 94 | } | 
| 113 | 95 | ||
| 114 | // TODO: Move the debug rendering to the renderer. | ||
| 115 | // ShaderProgram* shader = load_shader(game->render_backend, view_mode); | ||
| 116 | // if (!shader) { | ||
| 117 | // return false; | ||
| 118 | // } | ||
| 119 | |||
| 120 | SceneNode* scene_node = gfx_load_scene( | 96 | SceneNode* scene_node = gfx_load_scene( | 
| 121 | game->gfx, sky_light_node, | 97 | game->gfx, sky_light_node, | 
| 122 | &(LoadSceneCmd){.origin = SceneFromFile, .filepath = scene_filepath}); | 98 | &(LoadSceneCmd){.origin = SceneFromFile, .filepath = scene_filepath}); | 
| @@ -285,16 +261,16 @@ void game_update(Game* game, double t, double dt) { | |||
| 285 | } | 261 | } | 
| 286 | 262 | ||
| 287 | void game_render(const Game* game) { | 263 | void game_render(const Game* game) { | 
| 288 | gfx_render_scene(game->renderer, game->scene, game->camera); | 264 | gfx_render_scene( | 
| 265 | game->renderer, | ||
| 266 | &(RenderSceneParams){ | ||
| 267 | .mode = RenderDefault, .scene = game->scene, .camera = game->camera}); | ||
| 289 | 268 | ||
| 290 | ImmRenderer* imm = gfx_get_imm_renderer(game->gfx); | 269 | ImmRenderer* imm = gfx_get_imm_renderer(game->gfx); | 
| 291 | assert(imm); | 270 | assert(imm); | 
| 292 | gfx_imm_start(imm); | 271 | gfx_imm_start(imm); | 
| 293 | gfx_imm_set_camera(imm, gfx_get_camera_camera(game->camera)); | 272 | gfx_imm_set_camera(imm, gfx_get_camera_camera(game->camera)); | 
| 294 | gfx_imm_set_colour(imm, vec4_make(0.2, 0.2, 1.0, 0.3)); | 273 | gfx_imm_set_colour(imm, vec4_make(0.2, 0.2, 1.0, 0.3)); | 
| 295 | // DEBUG | ||
| 296 | // const aabb3 box = aabb3_make(vec3_make(0, 0, 0), vec3_make(1, 1, 1)); | ||
| 297 | // gfx_imm_draw_aabb(imm, box); | ||
| 298 | render_bounding_boxes(imm, gfx_get_scene_root(game->scene)); | 274 | render_bounding_boxes(imm, gfx_get_scene_root(game->scene)); | 
| 299 | gfx_imm_end(imm); | 275 | gfx_imm_end(imm); | 
| 300 | } | 276 | } | 
