aboutsummaryrefslogtreecommitdiff
path: root/src/core/shader_program.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/shader_program.c')
-rw-r--r--src/core/shader_program.c119
1 files changed, 77 insertions, 42 deletions
diff --git a/src/core/shader_program.c b/src/core/shader_program.c
index 3cbe48d..eeb46f8 100644
--- a/src/core/shader_program.c
+++ b/src/core/shader_program.c
@@ -72,17 +72,23 @@ void gfx_deactivate_shader_program(const ShaderProgram* prog) {
72 ASSERT_GL; 72 ASSERT_GL;
73} 73}
74 74
75static void set_texture_uniform( 75static void set_int_uniform(GLuint prog, const char* name, int value) {
76 GLuint prog, const char* name, int texture_unit, const Texture* texture) {
77 assert(prog != 0); 76 assert(prog != 0);
78 assert(name); 77 assert(name);
79 assert(texture);
80 78
81 const GLint location = glGetUniformLocation(prog, name); 79 const GLint location = glGetUniformLocation(prog, name);
82 if (location >= 0) { 80 if (location >= 0) {
83 glActiveTexture(GL_TEXTURE0 + texture_unit); 81 glUniform1i(location, value);
84 glBindTexture(texture->target, texture->id); 82 }
85 glUniform1i(location, texture_unit); 83}
84
85static void set_float_uniform(GLuint prog, const char* name, float value) {
86 assert(prog != 0);
87 assert(name);
88
89 const GLint location = glGetUniformLocation(prog, name);
90 if (location >= 0) {
91 glUniform1f(location, value);
86 } 92 }
87} 93}
88 94
@@ -118,13 +124,17 @@ static void set_vec4_uniform(GLuint prog, const char* name, vec4 value) {
118 } 124 }
119} 125}
120 126
121static void set_float_uniform(GLuint prog, const char* name, float value) { 127static void set_texture_uniform(
128 GLuint prog, const char* name, int texture_unit, const Texture* texture) {
122 assert(prog != 0); 129 assert(prog != 0);
123 assert(name); 130 assert(name);
131 assert(texture);
124 132
125 const GLint location = glGetUniformLocation(prog, name); 133 const GLint location = glGetUniformLocation(prog, name);
126 if (location >= 0) { 134 if (location >= 0) {
127 glUniform1f(location, value); 135 glActiveTexture(GL_TEXTURE0 + texture_unit);
136 glBindTexture(texture->target, texture->id);
137 glUniform1i(location, texture_unit);
128 } 138 }
129} 139}
130 140
@@ -135,23 +145,30 @@ void gfx_apply_uniforms(const ShaderProgram* prog) {
135 for (int i = 0; i < prog->num_uniforms; ++i) { 145 for (int i = 0; i < prog->num_uniforms; ++i) {
136 const ShaderUniform* uniform = &prog->uniforms[i]; 146 const ShaderUniform* uniform = &prog->uniforms[i];
137 switch (uniform->type) { 147 switch (uniform->type) {
138 case UniformTexture: 148 case UniformInt:
139 set_texture_uniform( 149 set_int_uniform(prog->id, uniform->name.str, uniform->value.uniform_int);
140 prog->id, uniform->name.str, next_texture_unit, 150 break;
141 uniform->value.texture); 151 case UniformFloat:
142 next_texture_unit++; 152 set_float_uniform(
153 prog->id, uniform->name.str, uniform->value.uniform_float);
143 break; 154 break;
144 case UniformMat4: 155 case UniformMat4:
145 set_mat4_uniform(prog->id, uniform->name.str, &uniform->value.mat4, 1); 156 set_mat4_uniform(
157 prog->id, uniform->name.str, &uniform->value.uniform_mat4, 1);
146 break; 158 break;
147 case UniformVec3: 159 case UniformVec3:
148 set_vec3_uniform(prog->id, uniform->name.str, uniform->value.vec3); 160 set_vec3_uniform(
161 prog->id, uniform->name.str, uniform->value.uniform_vec3);
149 break; 162 break;
150 case UniformVec4: 163 case UniformVec4:
151 set_vec4_uniform(prog->id, uniform->name.str, uniform->value.vec4); 164 set_vec4_uniform(
165 prog->id, uniform->name.str, uniform->value.uniform_vec4);
152 break; 166 break;
153 case UniformFloat: 167 case UniformTexture:
154 set_float_uniform(prog->id, uniform->name.str, uniform->value.scalar); 168 set_texture_uniform(
169 prog->id, uniform->name.str, next_texture_unit,
170 uniform->value.texture);
171 next_texture_unit++;
155 break; 172 break;
156 case UniformMat4Array: 173 case UniformMat4Array:
157 set_mat4_uniform( 174 set_mat4_uniform(
@@ -179,8 +196,9 @@ static ShaderUniform* get_or_allocate_uniform(
179 196
180 // Create the uniform if it does not exist. 197 // Create the uniform if it does not exist.
181 if (prog->num_uniforms == GFX_MAX_UNIFORMS_PER_SHADER) { 198 if (prog->num_uniforms == GFX_MAX_UNIFORMS_PER_SHADER) {
182 FAIL("Exceeded the maximum number of uniforms per shader. Please increase " 199 FAIL(
183 "this value."); 200 "Exceeded the maximum number of uniforms per shader. Please increase "
201 "this value.");
184 return 0; 202 return 0;
185 } 203 }
186 ShaderUniform* uniform = &prog->uniforms[prog->num_uniforms]; 204 ShaderUniform* uniform = &prog->uniforms[prog->num_uniforms];
@@ -191,21 +209,38 @@ static ShaderUniform* get_or_allocate_uniform(
191// The functions below save the value of a uniform in the shader program. If the 209// The functions below save the value of a uniform in the shader program. If the
192// uniform does not even exist, then there is no need to store the value. 210// uniform does not even exist, then there is no need to store the value.
193 211
194void gfx_set_texture_uniform( 212void gfx_set_int_uniform(ShaderProgram* prog, const char* name, int value) {
195 ShaderProgram* prog, const char* name, const Texture* texture) {
196 assert(prog); 213 assert(prog);
197 assert(name); 214 assert(name);
198 assert(texture);
199 215
216 // No need to store the uniform on our side if it does not exist in the
217 // program.
200 const GLint location = glGetUniformLocation(prog->id, name); 218 const GLint location = glGetUniformLocation(prog->id, name);
201 if (location < 0) { 219 if (location < 0) {
202 return; 220 return;
203 } 221 }
204 ShaderUniform* uniform = get_or_allocate_uniform(prog, name); 222 ShaderUniform* uniform = get_or_allocate_uniform(prog, name);
205 assert(uniform); 223 assert(uniform);
206 uniform->name = sstring_make(name); 224 uniform->name = sstring_make(name);
207 uniform->type = UniformTexture; 225 uniform->type = UniformInt;
208 uniform->value.texture = texture; 226 uniform->value.uniform_int = value;
227}
228
229void gfx_set_float_uniform(ShaderProgram* prog, const char* name, float value) {
230 assert(prog);
231 assert(name);
232
233 // No need to store the uniform on our side if it does not exist in the
234 // program.
235 const GLint location = glGetUniformLocation(prog->id, name);
236 if (location < 0) {
237 return;
238 }
239 ShaderUniform* uniform = get_or_allocate_uniform(prog, name);
240 assert(uniform);
241 uniform->name = sstring_make(name);
242 uniform->type = UniformFloat;
243 uniform->value.uniform_float = value;
209} 244}
210 245
211void gfx_set_mat4_uniform( 246void gfx_set_mat4_uniform(
@@ -220,9 +255,9 @@ void gfx_set_mat4_uniform(
220 } 255 }
221 ShaderUniform* uniform = get_or_allocate_uniform(prog, name); 256 ShaderUniform* uniform = get_or_allocate_uniform(prog, name);
222 assert(uniform); 257 assert(uniform);
223 uniform->name = sstring_make(name); 258 uniform->name = sstring_make(name);
224 uniform->type = UniformMat4; 259 uniform->type = UniformMat4;
225 uniform->value.mat4 = *mat; 260 uniform->value.uniform_mat4 = *mat;
226} 261}
227 262
228void gfx_set_vec3_uniform(ShaderProgram* prog, const char* name, vec3 value) { 263void gfx_set_vec3_uniform(ShaderProgram* prog, const char* name, vec3 value) {
@@ -235,9 +270,9 @@ void gfx_set_vec3_uniform(ShaderProgram* prog, const char* name, vec3 value) {
235 } 270 }
236 ShaderUniform* uniform = get_or_allocate_uniform(prog, name); 271 ShaderUniform* uniform = get_or_allocate_uniform(prog, name);
237 assert(uniform); 272 assert(uniform);
238 uniform->name = sstring_make(name); 273 uniform->name = sstring_make(name);
239 uniform->type = UniformVec3; 274 uniform->type = UniformVec3;
240 uniform->value.vec3 = value; 275 uniform->value.uniform_vec3 = value;
241} 276}
242 277
243void gfx_set_vec4_uniform(ShaderProgram* prog, const char* name, vec4 value) { 278void gfx_set_vec4_uniform(ShaderProgram* prog, const char* name, vec4 value) {
@@ -250,26 +285,26 @@ void gfx_set_vec4_uniform(ShaderProgram* prog, const char* name, vec4 value) {
250 } 285 }
251 ShaderUniform* uniform = get_or_allocate_uniform(prog, name); 286 ShaderUniform* uniform = get_or_allocate_uniform(prog, name);
252 assert(uniform); 287 assert(uniform);
253 uniform->name = sstring_make(name); 288 uniform->name = sstring_make(name);
254 uniform->type = UniformVec4; 289 uniform->type = UniformVec4;
255 uniform->value.vec4 = value; 290 uniform->value.uniform_vec4 = value;
256} 291}
257 292
258void gfx_set_float_uniform(ShaderProgram* prog, const char* name, float value) { 293void gfx_set_texture_uniform(
294 ShaderProgram* prog, const char* name, const Texture* texture) {
259 assert(prog); 295 assert(prog);
260 assert(name); 296 assert(name);
297 assert(texture);
261 298
262 // No need to store the uniform on our side if it does not exist in the
263 // program.
264 const GLint location = glGetUniformLocation(prog->id, name); 299 const GLint location = glGetUniformLocation(prog->id, name);
265 if (location < 0) { 300 if (location < 0) {
266 return; 301 return;
267 } 302 }
268 ShaderUniform* uniform = get_or_allocate_uniform(prog, name); 303 ShaderUniform* uniform = get_or_allocate_uniform(prog, name);
269 assert(uniform); 304 assert(uniform);
270 uniform->name = sstring_make(name); 305 uniform->name = sstring_make(name);
271 uniform->type = UniformFloat; 306 uniform->type = UniformTexture;
272 uniform->value.scalar = value; 307 uniform->value.texture = texture;
273} 308}
274 309
275void gfx_set_mat4_array_uniform( 310void gfx_set_mat4_array_uniform(
@@ -277,7 +312,7 @@ void gfx_set_mat4_array_uniform(
277 assert(prog); 312 assert(prog);
278 assert(name); 313 assert(name);
279 assert(mats); 314 assert(mats);
280 315
281 const GLint location = glGetUniformLocation(prog->id, name); 316 const GLint location = glGetUniformLocation(prog->id, name);
282 if (location < 0) { 317 if (location < 0) {
283 return; 318 return;