summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gfx/include/gfx/util/scene.h4
-rw-r--r--gfx/include/gfx/util/shader.h12
-rw-r--r--gfx/shaders/cook_torrance.frag41
-rw-r--r--gfx/shaders/cook_torrance.vert17
-rw-r--r--gfx/src/util/scene.c59
-rw-r--r--gfx/src/util/shader.c86
-rw-r--r--gltfview/src/game.c12
7 files changed, 173 insertions, 58 deletions
diff --git a/gfx/include/gfx/util/scene.h b/gfx/include/gfx/util/scene.h
index 7340d1d..0aad3d3 100644
--- a/gfx/include/gfx/util/scene.h
+++ b/gfx/include/gfx/util/scene.h
@@ -19,6 +19,7 @@ typedef struct LoadSceneCmd {
19 size_t size_bytes; 19 size_t size_bytes;
20 }; 20 };
21 }; 21 };
22 ShaderProgram* shader;
22} LoadSceneCmd; 23} LoadSceneCmd;
23 24
24/// Load a scene. 25/// Load a scene.
@@ -30,5 +31,4 @@ typedef struct LoadSceneCmd {
30/// characteristics (presence of normals, tangents, etc) is assigned. 31/// characteristics (presence of normals, tangents, etc) is assigned.
31/// 32///
32/// Currently only supports the GLTF format. 33/// Currently only supports the GLTF format.
33bool gfx_load_scene( 34bool gfx_load_scene(Gfx*, SceneNode* root_node, const LoadSceneCmd*);
34 Gfx*, SceneNode* root_node, ShaderProgram* shader, const LoadSceneCmd*);
diff --git a/gfx/include/gfx/util/shader.h b/gfx/include/gfx/util/shader.h
index d801153..cadca55 100644
--- a/gfx/include/gfx/util/shader.h
+++ b/gfx/include/gfx/util/shader.h
@@ -1,8 +1,11 @@
1/// A variety of shaders included for convenience. 1/// A variety of shaders included for convenience.
2#pragma once 2#pragma once
3 3
4typedef struct RenderBackend RenderBackend; 4#include <stddef.h>
5typedef struct ShaderProgram ShaderProgram; 5
6typedef struct RenderBackend RenderBackend;
7typedef struct ShaderCompilerDefine ShaderCompilerDefine;
8typedef struct ShaderProgram ShaderProgram;
6 9
7/// Create a BRDF integration map shader. 10/// Create a BRDF integration map shader.
8ShaderProgram* gfx_make_brdf_integration_map_shader(RenderBackend*); 11ShaderProgram* gfx_make_brdf_integration_map_shader(RenderBackend*);
@@ -10,6 +13,11 @@ ShaderProgram* gfx_make_brdf_integration_map_shader(RenderBackend*);
10/// Create a Cook-Torrance shader. 13/// Create a Cook-Torrance shader.
11ShaderProgram* gfx_make_cook_torrance_shader(RenderBackend*); 14ShaderProgram* gfx_make_cook_torrance_shader(RenderBackend*);
12 15
16/// Create a Cook-Torrance shader with additional shader compiler defines.
17/// This function can be used to create shader permutations.
18ShaderProgram* gfx_make_cook_torrance_shader_perm(
19 RenderBackend*, const ShaderCompilerDefine*, size_t num_defines);
20
13/// Create a 3D debugging shader. 21/// Create a 3D debugging shader.
14ShaderProgram* gfx_make_debug3d_shader(RenderBackend*); 22ShaderProgram* gfx_make_debug3d_shader(RenderBackend*);
15 23
diff --git a/gfx/shaders/cook_torrance.frag b/gfx/shaders/cook_torrance.frag
index b2bfd7d..18d9d18 100644
--- a/gfx/shaders/cook_torrance.frag
+++ b/gfx/shaders/cook_torrance.frag
@@ -7,9 +7,15 @@ uniform vec3 EmissiveFactor;
7 7
8uniform sampler2D BaseColorTexture; 8uniform sampler2D BaseColorTexture;
9uniform sampler2D MetallicRoughnessTexture; 9uniform sampler2D MetallicRoughnessTexture;
10#ifdef HAS_EMISSIVE_MAP
10uniform sampler2D EmissiveTexture; 11uniform sampler2D EmissiveTexture;
12#endif
13#ifdef HAS_OCCLUSION_MAP
11uniform sampler2D AmbientOcclusionTexture; 14uniform sampler2D AmbientOcclusionTexture;
15#endif
16#ifdef HAS_NORMAL_MAP
12uniform sampler2D NormalMap; 17uniform sampler2D NormalMap;
18#endif
13 19
14// TODO: Handle case in which there is no sky. Pass a boolean. 20// TODO: Handle case in which there is no sky. Pass a boolean.
15uniform samplerCube Sky; 21uniform samplerCube Sky;
@@ -22,19 +28,28 @@ uniform vec3 CameraPosition; // World space.
22 28
23// World-space position and normal. 29// World-space position and normal.
24in vec3 Position; 30in vec3 Position;
31#ifdef HAS_NORMALS
25in vec3 Normal; 32in vec3 Normal;
33#endif
26#ifdef HAS_TANGENTS 34#ifdef HAS_TANGENTS
27in vec4 Tangent; 35in vec4 Tangent;
28#endif // HAS_TANGENTS 36#endif
37#ifdef HAS_TEXCOORDS
29in vec2 Texcoord; 38in vec2 Texcoord;
39#endif
30 40
31layout (location = 0) out vec4 Colour; 41layout (location = 0) out vec4 Colour;
32 42
33#define PI 3.1415926535897932384626433832795 43#define PI 3.1415926535897932384626433832795
34#define INV_PI 0.3183098861837907 44#define INV_PI 0.3183098861837907
35 45
36// TODO: Move to "normal.h" 46/// Transform a normal map sample into world space.
37vec3 get_vs_normal(vec3 normalWs, vec3 normalMapSample) { 47///
48/// |normalWs| is the surface normal in world space.
49/// |normalMapSample| is the normal map sample, not necessarily normalized.
50///
51/// TODO: Move to "normal.h"
52vec3 get_ws_normal(vec3 normalWs, vec3 normalMapSample) {
38 vec3 N = normalize(Normal); 53 vec3 N = normalize(Normal);
39#ifdef HAS_TANGENTS 54#ifdef HAS_TANGENTS
40 //vec3 T = normalize(tangent.xyz - dot(tangent.xyz, N) * N); 55 //vec3 T = normalize(tangent.xyz - dot(tangent.xyz, N) * N);
@@ -127,12 +142,12 @@ void main()
127 // TODO: Also use the specular F0 map from the model, and emissive. Make sure 142 // TODO: Also use the specular F0 map from the model, and emissive. Make sure
128 // to use all maps. 143 // to use all maps.
129 // https://sketchfab.com/models/b81008d513954189a063ff901f7abfe4 144 // https://sketchfab.com/models/b81008d513954189a063ff901f7abfe4
130 // TODO: Normal map samples should not be gamma-corrected when loaded, they 145#ifdef HAS_NORMAL_MAP
131 // are already authored as linear. 146 vec3 normalMapSample = texture(NormalMap, Texcoord).xyz * 2.0 - 1.0;
132 vec3 normalMapSample = normalize(texture(NormalMap, Texcoord).xyz * 2.0 - 1.0); 147 vec3 N = get_ws_normal(Normal, normalMapSample);
133 //vec3 normalMapSample = texture(NormalMap, Texcoord).xyz; 148#elif HAS_NORMALS
134 //normalMapSample = normalize(pow(normalMapSample, vec3(1.0 / 2.2)) * 2.0 - 1.0); 149 vec3 N = normalize(Normal);
135 vec3 N = get_vs_normal(Normal, normalMapSample); 150#endif
136 vec3 V = normalize(CameraPosition - Position); 151 vec3 V = normalize(CameraPosition - Position);
137 vec3 R = reflect(-V, N); 152 vec3 R = reflect(-V, N);
138 // Not needed for IBL. 153 // Not needed for IBL.
@@ -150,8 +165,16 @@ void main()
150 // TODO: Other factors. 165 // TODO: Other factors.
151 vec3 albedo = vec3(BaseColorFactor) * texture(BaseColorTexture, Texcoord).rgb; 166 vec3 albedo = vec3(BaseColorFactor) * texture(BaseColorTexture, Texcoord).rgb;
152 vec3 metal_roughness = texture(MetallicRoughnessTexture, Texcoord).rgb; 167 vec3 metal_roughness = texture(MetallicRoughnessTexture, Texcoord).rgb;
168#ifdef HAS_EMISSIVE_MAP
153 vec3 emissive = texture(EmissiveTexture, Texcoord).rgb; 169 vec3 emissive = texture(EmissiveTexture, Texcoord).rgb;
170#else
171 vec3 emissive = vec3(0.0);
172#endif
173#ifdef HAS_OCCLUSION_MAP
154 float occlusion = texture(AmbientOcclusionTexture, Texcoord).r; 174 float occlusion = texture(AmbientOcclusionTexture, Texcoord).r;
175#else
176 float occlusion = 0.0;
177#endif
155 float metallic = MetallicFactor * metal_roughness.b; 178 float metallic = MetallicFactor * metal_roughness.b;
156 float roughness = metal_roughness.g; 179 float roughness = metal_roughness.g;
157 180
diff --git a/gfx/shaders/cook_torrance.vert b/gfx/shaders/cook_torrance.vert
index 56dfeda..6425565 100644
--- a/gfx/shaders/cook_torrance.vert
+++ b/gfx/shaders/cook_torrance.vert
@@ -4,29 +4,40 @@ uniform mat4 ModelMatrix;
4uniform mat4 MVP; 4uniform mat4 MVP;
5 5
6layout (location = 0) in vec3 vPosition; 6layout (location = 0) in vec3 vPosition;
7// TODO: Add HAS_NORMALS 7#ifdef HAS_NORMALS
8layout (location = 1) in vec3 vNormal; 8layout (location = 1) in vec3 vNormal;
9#endif
9#ifdef HAS_TANGENTS 10#ifdef HAS_TANGENTS
10layout (location = 2) in vec4 vTangent; 11layout (location = 2) in vec4 vTangent;
11#endif // HAS_TANGENTS 12#endif // HAS_TANGENTS
13#ifdef HAS_TEXCOORDS
12layout (location = 3) in vec2 vTexcoord; 14layout (location = 3) in vec2 vTexcoord;
15#endif
13 16
14// World-space position and normal. 17// World-space position and normal.
15out vec3 Position; 18out vec3 Position;
19#ifdef HAS_NORMALS
16out vec3 Normal; 20out vec3 Normal;
21#endif
17#ifdef HAS_TANGENTS 22#ifdef HAS_TANGENTS
18out vec4 Tangent; 23out vec4 Tangent;
19#endif // HAS_TANGENTS 24#endif
25#ifdef HAS_TEXCOORDS
20out vec2 Texcoord; 26out vec2 Texcoord;
27#endif
21 28
22void main() 29void main()
23{ 30{
24 Position = vec3(ModelMatrix * vec4(vPosition, 1.0)); 31 Position = vec3(ModelMatrix * vec4(vPosition, 1.0));
32#ifdef HAS_NORMALS
25 Normal = mat3(ModelMatrix) * vNormal; 33 Normal = mat3(ModelMatrix) * vNormal;
26 //Normal = normalize(ModelMatrix * vec4(vNormal, 0.0)).xyz; 34 //Normal = normalize(ModelMatrix * vec4(vNormal, 0.0)).xyz;
35#endif
27#ifdef HAS_TANGENTS 36#ifdef HAS_TANGENTS
28 Tangent = vec4(mat3(ModelMatrix) * vTangent.xyz, vTangent.w); 37 Tangent = vec4(mat3(ModelMatrix) * vTangent.xyz, vTangent.w);
29#endif // HAS_TANGENTS 38#endif
39#ifdef HAS_TEXCOORDS
30 Texcoord = vTexcoord; 40 Texcoord = vTexcoord;
41#endif
31 gl_Position = MVP * vec4(vPosition, 1.0); 42 gl_Position = MVP * vec4(vPosition, 1.0);
32} 43}
diff --git a/gfx/src/util/scene.c b/gfx/src/util/scene.c
index 706e518..52812e9 100644
--- a/gfx/src/util/scene.c
+++ b/gfx/src/util/scene.c
@@ -90,6 +90,8 @@
90#include <gfx/scene/node.h> 90#include <gfx/scene/node.h>
91#include <gfx/scene/object.h> 91#include <gfx/scene/object.h>
92#include <gfx/scene/scene.h> 92#include <gfx/scene/scene.h>
93#include <gfx/sizes.h>
94#include <gfx/util/shader.h>
93#include <gfx/util/texture.h> 95#include <gfx/util/texture.h>
94 96
95#include <cstring.h> 97#include <cstring.h>
@@ -127,6 +129,14 @@
127#define UNIFORM_AMBIENT_OCCLUSION_TEXTURE "AmbientOcclusionTexture" 129#define UNIFORM_AMBIENT_OCCLUSION_TEXTURE "AmbientOcclusionTexture"
128#define UNIFORM_NORMAL_MAP "NormalMap" 130#define UNIFORM_NORMAL_MAP "NormalMap"
129 131
132// Shader compiler defines. Must match the names in shaders.
133#define DEFINE_HAS_TEXCOORDS "HAS_TEXCOORDS"
134#define DEFINE_HAS_NORMALS "HAS_NORMALS"
135#define DEFINE_HAS_TANGENTS "HAS_TANGENTS"
136#define DEFINE_HAS_NORMAL_MAP "HAS_NORMAL_MAP"
137#define DEFINE_HAS_OCCLUSION_MAP "HAS_OCCLUSION_MAP"
138#define DEFINE_HAS_EMISSIVE_MAP "HAS_EMISSIVE_MAP"
139
130typedef enum TextureType { 140typedef enum TextureType {
131 BaseColorTexture, 141 BaseColorTexture,
132 MetallicRoughnessTexture, 142 MetallicRoughnessTexture,
@@ -153,6 +163,45 @@ typedef struct MeshPermutation {
153 }; 163 };
154} MeshPermutation; 164} MeshPermutation;
155 165
166/// Build shader compiler defines from a mesh permutation.
167static size_t make_defines(
168 MeshPermutation perm, ShaderCompilerDefine* defines) {
169 static const char* str_true = "1";
170 size_t next = 0;
171
172#define check(field, define) \
173 if (perm.field) { \
174 defines[next].name = sstring_make(define); \
175 defines[next].value = sstring_make(str_true); \
176 next++; \
177 }
178
179 check(has_texcoords, DEFINE_HAS_TEXCOORDS);
180 check(has_normals, DEFINE_HAS_NORMALS);
181 check(has_tangents, DEFINE_HAS_TANGENTS);
182 check(has_normal_map, DEFINE_HAS_NORMAL_MAP);
183 check(has_occlusion_texture, DEFINE_HAS_OCCLUSION_MAP);
184 check(has_emissive_texture, DEFINE_HAS_EMISSIVE_MAP);
185
186 return next;
187}
188
189/// Compile a shader permutation.
190static ShaderProgram* make_shader_permutation(
191 RenderBackend* render_backend, MeshPermutation perm) {
192 LOGD(
193 "Compiling Cook-Torrance shader permutation: texcoords: %d, normals: "
194 "%d, tangents: %d, normal map: %d, AO map: %d, emissive map: %d",
195 perm.has_texcoords, perm.has_normals, perm.has_tangents,
196 perm.has_normal_map, perm.has_occlusion_texture,
197 perm.has_emissive_texture);
198
199 ShaderCompilerDefine defines[GFX_MAX_SHADER_COMPILER_DEFINES];
200 const size_t num_defines = make_defines(perm, defines);
201 return gfx_make_cook_torrance_shader_perm(
202 render_backend, defines, num_defines);
203}
204
156/// Map a texture type to the name of the shader uniform used to access the 205/// Map a texture type to the name of the shader uniform used to access the
157/// texture. 206/// texture.
158static const char* TextureUniformName(TextureType type) { 207static const char* TextureUniformName(TextureType type) {
@@ -502,7 +551,6 @@ static bool load_meshes(
502 assert(gfx); 551 assert(gfx);
503 assert(buffers); 552 assert(buffers);
504 assert(materials); 553 assert(materials);
505 assert(shader);
506 assert(geometries); 554 assert(geometries);
507 assert(meshes); 555 assert(meshes);
508 assert(scene_objects); 556 assert(scene_objects);
@@ -687,6 +735,9 @@ static bool load_meshes(
687 // they can share shaders, the renderer can check later whether uniforms 735 // they can share shaders, the renderer can check later whether uniforms
688 // have the same values. Also, changing uniforms is much faster than 736 // have the same values. Also, changing uniforms is much faster than
689 // swapping shaders, so shader caching is the most important thing here. 737 // swapping shaders, so shader caching is the most important thing here.
738 if (!shader) {
739 shader = make_shader_permutation(render_backend, perm);
740 }
690 assert(shader); 741 assert(shader);
691 742
692 meshes[next_mesh] = gfx_make_mesh(&(MeshDesc){ 743 meshes[next_mesh] = gfx_make_mesh(&(MeshDesc){
@@ -996,9 +1047,7 @@ cleanup:
996 return false; 1047 return false;
997} 1048}
998 1049
999bool gfx_load_scene( 1050bool gfx_load_scene(Gfx* gfx, SceneNode* root_node, const LoadSceneCmd* cmd) {
1000 Gfx* gfx, SceneNode* root_node, ShaderProgram* shader,
1001 const LoadSceneCmd* cmd) {
1002 assert(gfx); 1051 assert(gfx);
1003 assert(root_node); 1052 assert(root_node);
1004 assert(cmd); 1053 assert(cmd);
@@ -1036,7 +1085,7 @@ bool gfx_load_scene(
1036 &options, data, &tangent_buffers, &num_tangent_buffers); 1085 &options, data, &tangent_buffers, &num_tangent_buffers);
1037 1086
1038 success = load_scene( 1087 success = load_scene(
1039 data, gfx, root_node, cmd->filepath, shader, tangent_buffers, 1088 data, gfx, root_node, cmd->filepath, cmd->shader, tangent_buffers,
1040 num_tangent_buffers); 1089 num_tangent_buffers);
1041 1090
1042cleanup: 1091cleanup:
diff --git a/gfx/src/util/shader.c b/gfx/src/util/shader.c
index a07c66e..fdfb1d3 100644
--- a/gfx/src/util/shader.c
+++ b/gfx/src/util/shader.c
@@ -22,10 +22,12 @@
22#include <shaders/view_texture.vert.h> 22#include <shaders/view_texture.vert.h>
23 23
24#include <assert.h> 24#include <assert.h>
25#include <string.h>
25 26
26static ShaderProgram* make_shader_program(RenderBackend* render_backend, 27static ShaderProgram* make_shader_program(
27 const char* vert_source, 28 RenderBackend* render_backend, const char* vert_source,
28 const char* frag_source) { 29 const char* frag_source, const ShaderCompilerDefine* defines,
30 size_t num_defines) {
29 assert(render_backend); 31 assert(render_backend);
30 assert(vert_source); 32 assert(vert_source);
31 assert(frag_source); 33 assert(frag_source);
@@ -33,9 +35,18 @@ static ShaderProgram* make_shader_program(RenderBackend* render_backend,
33 Shader* vert = 0; 35 Shader* vert = 0;
34 Shader* frag = 0; 36 Shader* frag = 0;
35 37
36 ShaderDesc vertex_shader_desc = {.code = vert_source, .type = VertexShader}; 38 ShaderDesc vertex_shader_desc = {
37 ShaderDesc fragment_shader_desc = {.code = frag_source, 39 .code = vert_source, .type = VertexShader, .num_defines = num_defines};
38 .type = FragmentShader}; 40 ShaderDesc fragment_shader_desc = {
41 .code = frag_source, .type = FragmentShader, .num_defines = num_defines};
42 if (num_defines > 0) {
43 memcpy(
44 vertex_shader_desc.defines, defines,
45 num_defines * sizeof(ShaderCompilerDefine));
46 memcpy(
47 fragment_shader_desc.defines, defines,
48 num_defines * sizeof(ShaderCompilerDefine));
49 }
39 vert = gfx_make_shader(render_backend, &vertex_shader_desc); 50 vert = gfx_make_shader(render_backend, &vertex_shader_desc);
40 if (!vert) { 51 if (!vert) {
41 goto cleanup; 52 goto cleanup;
@@ -44,8 +55,9 @@ static ShaderProgram* make_shader_program(RenderBackend* render_backend,
44 if (!frag) { 55 if (!frag) {
45 goto cleanup; 56 goto cleanup;
46 } 57 }
47 ShaderProgramDesc shader_program_desc = {.vertex_shader = vert, 58
48 .fragment_shader = frag}; 59 ShaderProgramDesc shader_program_desc = {
60 .vertex_shader = vert, .fragment_shader = frag};
49 ShaderProgram* prog = 61 ShaderProgram* prog =
50 gfx_make_shader_program(render_backend, &shader_program_desc); 62 gfx_make_shader_program(render_backend, &shader_program_desc);
51 if (!prog) { 63 if (!prog) {
@@ -63,53 +75,63 @@ cleanup:
63 return 0; 75 return 0;
64} 76}
65 77
66ShaderProgram* 78ShaderProgram* gfx_make_brdf_integration_map_shader(
67gfx_make_brdf_integration_map_shader(RenderBackend* render_backend) { 79 RenderBackend* render_backend) {
68 return make_shader_program(render_backend, quad_vert, 80 return make_shader_program(
69 brdf_integration_map_frag); 81 render_backend, quad_vert, brdf_integration_map_frag, 0, 0);
70} 82}
71 83
72ShaderProgram* gfx_make_cook_torrance_shader(RenderBackend* render_backend) { 84ShaderProgram* gfx_make_cook_torrance_shader(RenderBackend* render_backend) {
73 return make_shader_program(render_backend, cook_torrance_vert, 85 return make_shader_program(
74 cook_torrance_frag); 86 render_backend, cook_torrance_vert, cook_torrance_frag, 0, 0);
87}
88
89ShaderProgram* gfx_make_cook_torrance_shader_perm(
90 RenderBackend* render_backend, const ShaderCompilerDefine* defines,
91 size_t num_defines) {
92 return make_shader_program(
93 render_backend, cook_torrance_vert, cook_torrance_frag, defines,
94 num_defines);
75} 95}
76 96
77ShaderProgram* gfx_make_irradiance_map_shader(RenderBackend* render_backend) { 97ShaderProgram* gfx_make_irradiance_map_shader(RenderBackend* render_backend) {
78 return make_shader_program(render_backend, cubemap_filtering_vert, 98 return make_shader_program(
79 irradiance_map_frag); 99 render_backend, cubemap_filtering_vert, irradiance_map_frag, 0, 0);
80} 100}
81 101
82ShaderProgram* 102ShaderProgram* gfx_make_prefiltered_environment_map_shader(
83gfx_make_prefiltered_environment_map_shader(RenderBackend* render_backend) { 103 RenderBackend* render_backend) {
84 return make_shader_program(render_backend, cubemap_filtering_vert, 104 return make_shader_program(
85 prefiltered_environment_map_frag); 105 render_backend, cubemap_filtering_vert, prefiltered_environment_map_frag,
106 0, 0);
86} 107}
87 108
88ShaderProgram* gfx_make_debug3d_shader(RenderBackend* render_backend) { 109ShaderProgram* gfx_make_debug3d_shader(RenderBackend* render_backend) {
89 return make_shader_program(render_backend, debug3d_vert, debug3d_frag); 110 return make_shader_program(render_backend, debug3d_vert, debug3d_frag, 0, 0);
90} 111}
91 112
92ShaderProgram* gfx_make_skyquad_shader(RenderBackend* render_backend) { 113ShaderProgram* gfx_make_skyquad_shader(RenderBackend* render_backend) {
93 return make_shader_program(render_backend, skyquad_vert, skyquad_frag); 114 return make_shader_program(render_backend, skyquad_vert, skyquad_frag, 0, 0);
94} 115}
95 116
96ShaderProgram* 117ShaderProgram* gfx_make_view_normal_mapped_normals_shader(
97gfx_make_view_normal_mapped_normals_shader(RenderBackend* render_backend) { 118 RenderBackend* render_backend) {
98 return make_shader_program(render_backend, view_normal_mapped_normals_vert, 119 return make_shader_program(
99 view_normal_mapped_normals_frag); 120 render_backend, view_normal_mapped_normals_vert,
121 view_normal_mapped_normals_frag, 0, 0);
100} 122}
101 123
102ShaderProgram* gfx_make_view_normals_shader(RenderBackend* render_backend) { 124ShaderProgram* gfx_make_view_normals_shader(RenderBackend* render_backend) {
103 return make_shader_program(render_backend, view_normals_vert, 125 return make_shader_program(
104 view_normals_frag); 126 render_backend, view_normals_vert, view_normals_frag, 0, 0);
105} 127}
106 128
107ShaderProgram* gfx_make_view_tangents_shader(RenderBackend* render_backend) { 129ShaderProgram* gfx_make_view_tangents_shader(RenderBackend* render_backend) {
108 return make_shader_program(render_backend, view_tangents_vert, 130 return make_shader_program(
109 view_tangents_frag); 131 render_backend, view_tangents_vert, view_tangents_frag, 0, 0);
110} 132}
111 133
112ShaderProgram* gfx_make_view_texture_shader(RenderBackend* render_backend) { 134ShaderProgram* gfx_make_view_texture_shader(RenderBackend* render_backend) {
113 return make_shader_program(render_backend, view_texture_vert, 135 return make_shader_program(
114 view_texture_frag); 136 render_backend, view_texture_vert, view_texture_frag, 0, 0);
115} 137}
diff --git a/gltfview/src/game.c b/gltfview/src/game.c
index f2e5a88..bd474d6 100644
--- a/gltfview/src/game.c
+++ b/gltfview/src/game.c
@@ -37,6 +37,7 @@ static const char* DAMAGED_HELMET =
37 37
38static const char* CLOUDS1_TEXTURE = "/assets/skybox/clouds1/clouds1_west.bmp"; 38static const char* CLOUDS1_TEXTURE = "/assets/skybox/clouds1/clouds1_west.bmp";
39 39
40// TODO: Move this debug rendering to the renderer.
40static ShaderProgram* load_shader( 41static ShaderProgram* load_shader(
41 RenderBackend* render_backend, const char* view_mode) { 42 RenderBackend* render_backend, const char* view_mode) {
42 ShaderProgram* shader = 0; 43 ShaderProgram* shader = 0;
@@ -147,13 +148,14 @@ static bool load_scene(
147 return false; 148 return false;
148 } 149 }
149 150
150 ShaderProgram* shader = load_shader(game->render_backend, view_mode); 151 // TODO: Move the debug rendering to the renderer.
151 if (!shader) { 152 // ShaderProgram* shader = load_shader(game->render_backend, view_mode);
152 return false; 153 // if (!shader) {
153 } 154 // return false;
155 // }
154 156
155 if (!gfx_load_scene( 157 if (!gfx_load_scene(
156 game->gfx, sky_node, shader, 158 game->gfx, sky_node,
157 &(LoadSceneCmd){ 159 &(LoadSceneCmd){
158 .origin = SceneFromFile, .filepath = scene_filepath})) { 160 .origin = SceneFromFile, .filepath = scene_filepath})) {
159 return false; 161 return false;