aboutsummaryrefslogtreecommitdiff
path: root/src/render
diff options
context:
space:
mode:
Diffstat (limited to 'src/render')
-rw-r--r--src/render/imm.c14
-rw-r--r--src/render/llr.c121
-rw-r--r--src/render/llr_impl.h31
-rw-r--r--src/render/renderer.c51
4 files changed, 71 insertions, 146 deletions
diff --git a/src/render/imm.c b/src/render/imm.c
index 8a93488..7ab8d62 100644
--- a/src/render/imm.c
+++ b/src/render/imm.c
@@ -21,12 +21,14 @@ bool gfx_imm_make(Imm* renderer, GfxCore* gfxcore, LLR* llr) {
21 renderer->llr = llr; 21 renderer->llr = llr;
22 22
23 renderer->triangles = gfx_make_geometry( 23 renderer->triangles = gfx_make_geometry(
24 gfxcore, 24 gfxcore, &(GeometryDesc){
25 &(GeometryDesc){.type = Triangles, 25 .type = Triangles,
26 .buffer_usage = BufferDynamic, 26 .buffer_usage = BufferDynamic,
27 .num_verts = num_triangle_verts, 27 .num_verts = num_triangle_verts,
28 .positions3d = (BufferView3d){ 28 .positions3d = (BufferView3d){
29 .size_bytes = num_triangle_verts * sizeof(vec3)}}); 29 .size_bytes = num_triangle_verts * sizeof(vec3),
30 .count = num_triangle_verts}
31 });
30 if (!renderer->triangles) { 32 if (!renderer->triangles) {
31 goto cleanup; 33 goto cleanup;
32 } 34 }
diff --git a/src/render/llr.c b/src/render/llr.c
index 76935f9..752b65b 100644
--- a/src/render/llr.c
+++ b/src/render/llr.c
@@ -1,14 +1,15 @@
1#include "llr_impl.h" 1#include "llr_impl.h"
2 2
3#include "animation_impl.h" 3#include "animation_impl.h"
4#include "memory.h" 4#include "scene/light_impl.h"
5#include "scene/material_impl.h"
6#include "scene/mesh_impl.h"
5#include "scene/node_impl.h" 7#include "scene/node_impl.h"
6 8
7#include <gfx/core.h> 9#include <gfx/core.h>
8#include <gfx/util/ibl.h> 10#include <gfx/util/ibl.h>
9 11
10#include <cassert.h> 12#include <cassert.h>
11#include <error.h>
12 13
13static const int IRRADIANCE_MAP_WIDTH = 1024; 14static const int IRRADIANCE_MAP_WIDTH = 1024;
14static const int IRRADIANCE_MAP_HEIGHT = 1024; 15static const int IRRADIANCE_MAP_HEIGHT = 1024;
@@ -17,114 +18,30 @@ static const int PREFILTERED_ENVIRONMENT_MAP_HEIGHT = 128;
17static const int BRDF_INTEGRATION_MAP_WIDTH = 512; 18static const int BRDF_INTEGRATION_MAP_WIDTH = 512;
18static const int BRDF_INTEGRATION_MAP_HEIGHT = 512; 19static const int BRDF_INTEGRATION_MAP_HEIGHT = 512;
19 20
20static void make_environment_light(
21 Light* light, const EnvironmentLightDesc* desc) {
22 assert(light);
23 assert(desc);
24 light->type = EnvironmentLightType;
25 light->environment.environment_map = desc->environment_map;
26}
27
28Light* gfx_make_light(const LightDesc* desc) {
29 assert(desc);
30
31 Light* light = mem_alloc_light();
32
33 switch (desc->type) {
34 case EnvironmentLightType:
35 make_environment_light(light, &desc->light.environment);
36 break;
37 default:
38 log_error("Unhandled light type");
39 gfx_destroy_light(&light);
40 return 0;
41 }
42
43 return light;
44}
45
46void gfx_destroy_light(Light** light) {
47 assert(light);
48 if (*light) {
49 mem_free_light(light);
50 }
51}
52
53static void material_make(Material* material, const MaterialDesc* desc) {
54 assert(material);
55 assert(desc);
56 assert(desc->num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL);
57 material->num_uniforms = desc->num_uniforms;
58 for (int i = 0; i < desc->num_uniforms; ++i) {
59 material->uniforms[i] = desc->uniforms[i];
60 }
61}
62
63Material* gfx_make_material(const MaterialDesc* desc) {
64 assert(desc);
65 Material* material = mem_alloc_material();
66 material_make(material, desc);
67 return material;
68}
69
70void gfx_destroy_material(Material** material) { mem_free_material(material); }
71
72static void set_uniform(ShaderProgram* prog, const ShaderUniform* uniform) {
73 switch (uniform->type) {
74 case UniformTexture:
75 gfx_set_texture_uniform(prog, uniform->name.str, uniform->value.texture);
76 break;
77 case UniformMat4:
78 gfx_set_mat4_uniform(prog, uniform->name.str, &uniform->value.mat4);
79 break;
80 case UniformVec3:
81 gfx_set_vec3_uniform(prog, uniform->name.str, uniform->value.vec3);
82 break;
83 case UniformVec4:
84 gfx_set_vec4_uniform(prog, uniform->name.str, uniform->value.vec4);
85 break;
86 case UniformFloat:
87 gfx_set_float_uniform(prog, uniform->name.str, uniform->value.scalar);
88 break;
89 case UniformMat4Array:
90 gfx_set_mat4_array_uniform(
91 prog, uniform->name.str, uniform->value.array.values,
92 uniform->value.array.count);
93 break;
94 }
95}
96
97/// Activate the material. 21/// Activate the material.
98/// 22///
99/// This configures the shader uniforms that are specific to the material. 23/// This configures the shader uniforms that are specific to the material.
100static void gfx_material_activate( 24static void material_activate(ShaderProgram* shader, const Material* material) {
101 ShaderProgram* shader, const Material* material) {
102 assert(material); 25 assert(material);
103 for (int i = 0; i < material->num_uniforms; ++i) { 26 for (int i = 0; i < material->num_uniforms; ++i) {
104 const ShaderUniform* uniform = &material->uniforms[i]; 27 const ShaderUniform* uniform = &material->uniforms[i];
105 set_uniform(shader, uniform); 28 gfx_set_uniform(shader, uniform);
29 }
30 if (material->alpha_mode != Opaque) {
31 gfx_set_uniform(
32 shader, &(ShaderUniform){.name = sstring_make("AlphaMode"),
33 .type = UniformInt,
34 .value.uniform_int = material->alpha_mode});
35 }
36 if (material->alpha_mode == Mask) {
37 gfx_set_uniform(
38 shader,
39 &(ShaderUniform){.name = sstring_make("AlphaCutoff"),
40 .type = UniformFloat,
41 .value.uniform_float = material->alpha_cutoff});
106 } 42 }
107} 43}
108 44
109static void mesh_make(Mesh* mesh, const MeshDesc* desc) {
110 assert(mesh);
111 assert(desc);
112 assert(desc->geometry);
113 assert(desc->material);
114 assert(desc->shader);
115 mesh->geometry = desc->geometry;
116 mesh->material = desc->material;
117 mesh->shader = desc->shader;
118}
119
120Mesh* gfx_make_mesh(const MeshDesc* desc) {
121 Mesh* mesh = mem_alloc_mesh();
122 mesh_make(mesh, desc);
123 return mesh;
124}
125
126void gfx_destroy_mesh(Mesh** mesh) { mem_free_mesh(mesh); }
127
128/// Initialize renderer state for IBL. 45/// Initialize renderer state for IBL.
129static bool init_ibl(LLR* renderer) { 46static bool init_ibl(LLR* renderer) {
130 assert(renderer); 47 assert(renderer);
@@ -314,7 +231,7 @@ static void configure_state(LLR* renderer) {
314 231
315 // Geometry may be rendered without a material. 232 // Geometry may be rendered without a material.
316 if (renderer->material) { 233 if (renderer->material) {
317 gfx_material_activate(renderer->shader, renderer->material); 234 material_activate(renderer->shader, renderer->material);
318 } 235 }
319 } 236 }
320 237
diff --git a/src/render/llr_impl.h b/src/render/llr_impl.h
index c85ad15..9d70843 100644
--- a/src/render/llr_impl.h
+++ b/src/render/llr_impl.h
@@ -3,8 +3,6 @@
3#include <gfx/render/llr.h> 3#include <gfx/render/llr.h>
4#include <gfx/sizes.h> 4#include <gfx/sizes.h>
5 5
6#include "../types.h"
7
8#include <math/mat4.h> 6#include <math/mat4.h>
9#include <math/vec3.h> 7#include <math/vec3.h>
10 8
@@ -12,41 +10,12 @@
12#include <stddef.h> 10#include <stddef.h>
13#include <stdint.h> 11#include <stdint.h>
14 12
15typedef struct Geometry Geometry;
16typedef struct GfxCore GfxCore; 13typedef struct GfxCore GfxCore;
17typedef struct IBL IBL; 14typedef struct IBL IBL;
18typedef struct Material Material; 15typedef struct Material Material;
19typedef struct ShaderProgram ShaderProgram; 16typedef struct ShaderProgram ShaderProgram;
20typedef struct Texture Texture; 17typedef struct Texture Texture;
21 18
22/// An environment light.
23typedef struct EnvironmentLight {
24 const Texture* environment_map;
25 const Texture* irradiance_map; // Renderer implementation.
26 const Texture* prefiltered_environment_map; // Renderer implementation.
27 int max_reflection_lod; // Mandatory when prefiltered_environment_map is
28 // given.
29} EnvironmentLight;
30
31/// A scene light.
32typedef struct Light {
33 LightType type;
34 union {
35 EnvironmentLight environment;
36 };
37} Light;
38
39typedef struct Material {
40 ShaderUniform uniforms[GFX_MAX_UNIFORMS_PER_MATERIAL];
41 int num_uniforms;
42} Material;
43
44typedef struct Mesh {
45 const Geometry* geometry;
46 const Material* material;
47 ShaderProgram* shader; // TODO: Move this back to Material?
48} Mesh;
49
50/// Immediate mode renderer. 19/// Immediate mode renderer.
51/// 20///
52/// The renderer caches state changes in memory and only programs the underlying 21/// The renderer caches state changes in memory and only programs the underlying
diff --git a/src/render/renderer.c b/src/render/renderer.c
index b513ed4..a9d9bef 100644
--- a/src/render/renderer.c
+++ b/src/render/renderer.c
@@ -3,10 +3,11 @@
3#include "animation_impl.h" 3#include "animation_impl.h"
4#include "llr_impl.h" 4#include "llr_impl.h"
5#include "memory.h" 5#include "memory.h"
6#include "scene/material_impl.h"
7#include "scene/mesh_impl.h"
6#include "scene/model_impl.h" 8#include "scene/model_impl.h"
7#include "scene/node_impl.h" 9#include "scene/node_impl.h"
8#include "scene/object_impl.h" 10#include "scene/object_impl.h"
9#include "scene/scene_impl.h"
10 11
11#include <gfx/core.h> 12#include <gfx/core.h>
12#include <gfx/render/llr.h> 13#include <gfx/render/llr.h>
@@ -86,12 +87,13 @@ static ShaderProgram* load_shader(Renderer* renderer, RenderSceneMode mode) {
86// } 87// }
87 88
88typedef struct RenderState { 89typedef struct RenderState {
89 GfxCore* gfxcore; 90 GfxCore* gfxcore;
90 LLR* llr; 91 LLR* llr;
91 Renderer* renderer; 92 Renderer* renderer;
92 ShaderProgram* shader; // Null to use scene shaders. 93 ShaderProgram* shader; // Null to use scene shaders.
93 const Scene* scene; 94 const Scene* scene;
94 const Anima* anima; 95 const Anima* anima;
96 RenderSceneFilter filter;
95} RenderState; 97} RenderState;
96 98
97static void draw_children( 99static void draw_children(
@@ -153,6 +155,24 @@ static void draw_recursively(
153 continue; 155 continue;
154 } 156 }
155 157
158 // Filter out by material.
159 const Material* material = mesh->material;
160 if (material) {
161 const AlphaMode mode = material->alpha_mode;
162 switch (state->filter) {
163 case RenderOpaqueAndAlphaMasked:
164 if (mode == Blend) {
165 continue;
166 }
167 break;
168 case RenderTransparent:
169 if (mode != Blend) {
170 continue;
171 }
172 break;
173 }
174 }
175
156 // TODO: Here we would frustum-cull the mesh. The AABB would have to be 176 // TODO: Here we would frustum-cull the mesh. The AABB would have to be
157 // transformed by the model matrix. Rotation would make the AABB 177 // transformed by the model matrix. Rotation would make the AABB
158 // relatively large, but still, the culling would be conservative. 178 // relatively large, but still, the culling would be conservative.
@@ -208,6 +228,22 @@ void gfx_render_scene(Renderer* renderer, const RenderSceneParams* params) {
208 228
209 gfx_llr_set_camera(renderer->llr, camera); 229 gfx_llr_set_camera(renderer->llr, camera);
210 gfx_llr_set_aspect(renderer->llr, aspect); 230 gfx_llr_set_aspect(renderer->llr, aspect);
231 // TODO: Render Opaque and Mask alpha-mode materials first, then Blend ones.
232 // TODO: I'm not sure if this belongs to the scene renderer per se, or if it
233 // is something that should be driven from the outside. Specifically, the
234 // caller could pass in a filter that determines what objects to render. The
235 // filter could include alpha mode.
236 // This caller would be some component that understands render passes and
237 // potentially renders the scene multiple times as needed. For example, a
238 // depth-prepass, followed by G-buffer, followed by some post-processing,
239 // etc. Rename this renderer to scene_renderer?
240 // TODO: When rendering transparent geometry, we need to turn off depth
241 // writes.
242 // Opaque.
243 state.filter = RenderOpaqueAndAlphaMasked;
244 draw_recursively(&state, mat4_id(), gfx_get_scene_root(scene));
245 // Transparent.
246 state.filter = RenderTransparent;
211 draw_recursively(&state, mat4_id(), gfx_get_scene_root(scene)); 247 draw_recursively(&state, mat4_id(), gfx_get_scene_root(scene));
212} 248}
213 249
@@ -236,6 +272,7 @@ static void update_rec(SceneNode* node, const Camera* camera, R t) {
236 } 272 }
237} 273}
238 274
275// TODO: Move this outside the renderer.
239void gfx_update(Scene* scene, const Camera* camera, R t) { 276void gfx_update(Scene* scene, const Camera* camera, R t) {
240 assert(scene); 277 assert(scene);
241 assert(camera); 278 assert(camera);