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.c148
1 files changed, 106 insertions, 42 deletions
diff --git a/src/core/shader_program.c b/src/core/shader_program.c
index 3cbe48d..3840019 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,67 @@ 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_uniform(ShaderProgram* prog, const ShaderUniform* uniform) {
195 ShaderProgram* prog, const char* name, const Texture* texture) { 213 switch (uniform->type) {
214 case UniformInt:
215 gfx_set_int_uniform(prog, uniform->name.str, uniform->value.uniform_int);
216 break;
217 case UniformFloat:
218 gfx_set_float_uniform(
219 prog, uniform->name.str, uniform->value.uniform_float);
220 break;
221 case UniformMat4:
222 gfx_set_mat4_uniform(prog, uniform->name.str, &uniform->value.uniform_mat4);
223 break;
224 case UniformVec3:
225 gfx_set_vec3_uniform(prog, uniform->name.str, uniform->value.uniform_vec3);
226 break;
227 case UniformVec4:
228 gfx_set_vec4_uniform(prog, uniform->name.str, uniform->value.uniform_vec4);
229 break;
230 case UniformTexture:
231 gfx_set_texture_uniform(prog, uniform->name.str, uniform->value.texture);
232 break;
233 case UniformMat4Array:
234 gfx_set_mat4_array_uniform(
235 prog, uniform->name.str, uniform->value.array.values,
236 uniform->value.array.count);
237 break;
238 }
239}
240
241void gfx_set_int_uniform(ShaderProgram* prog, const char* name, int value) {
196 assert(prog); 242 assert(prog);
197 assert(name); 243 assert(name);
198 assert(texture);
199 244
245 // No need to store the uniform on our side if it does not exist in the
246 // program.
200 const GLint location = glGetUniformLocation(prog->id, name); 247 const GLint location = glGetUniformLocation(prog->id, name);
201 if (location < 0) { 248 if (location < 0) {
202 return; 249 return;
203 } 250 }
204 ShaderUniform* uniform = get_or_allocate_uniform(prog, name); 251 ShaderUniform* uniform = get_or_allocate_uniform(prog, name);
205 assert(uniform); 252 assert(uniform);
206 uniform->name = sstring_make(name); 253 uniform->name = sstring_make(name);
207 uniform->type = UniformTexture; 254 uniform->type = UniformInt;
208 uniform->value.texture = texture; 255 uniform->value.uniform_int = value;
256}
257
258void gfx_set_float_uniform(ShaderProgram* prog, const char* name, float value) {
259 assert(prog);
260 assert(name);
261
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);
265 if (location < 0) {
266 return;
267 }
268 ShaderUniform* uniform = get_or_allocate_uniform(prog, name);
269 assert(uniform);
270 uniform->name = sstring_make(name);
271 uniform->type = UniformFloat;
272 uniform->value.uniform_float = value;
209} 273}
210 274
211void gfx_set_mat4_uniform( 275void gfx_set_mat4_uniform(
@@ -220,9 +284,9 @@ void gfx_set_mat4_uniform(
220 } 284 }
221 ShaderUniform* uniform = get_or_allocate_uniform(prog, name); 285 ShaderUniform* uniform = get_or_allocate_uniform(prog, name);
222 assert(uniform); 286 assert(uniform);
223 uniform->name = sstring_make(name); 287 uniform->name = sstring_make(name);
224 uniform->type = UniformMat4; 288 uniform->type = UniformMat4;
225 uniform->value.mat4 = *mat; 289 uniform->value.uniform_mat4 = *mat;
226} 290}
227 291
228void gfx_set_vec3_uniform(ShaderProgram* prog, const char* name, vec3 value) { 292void gfx_set_vec3_uniform(ShaderProgram* prog, const char* name, vec3 value) {
@@ -235,9 +299,9 @@ void gfx_set_vec3_uniform(ShaderProgram* prog, const char* name, vec3 value) {
235 } 299 }
236 ShaderUniform* uniform = get_or_allocate_uniform(prog, name); 300 ShaderUniform* uniform = get_or_allocate_uniform(prog, name);
237 assert(uniform); 301 assert(uniform);
238 uniform->name = sstring_make(name); 302 uniform->name = sstring_make(name);
239 uniform->type = UniformVec3; 303 uniform->type = UniformVec3;
240 uniform->value.vec3 = value; 304 uniform->value.uniform_vec3 = value;
241} 305}
242 306
243void gfx_set_vec4_uniform(ShaderProgram* prog, const char* name, vec4 value) { 307void gfx_set_vec4_uniform(ShaderProgram* prog, const char* name, vec4 value) {
@@ -250,26 +314,26 @@ void gfx_set_vec4_uniform(ShaderProgram* prog, const char* name, vec4 value) {
250 } 314 }
251 ShaderUniform* uniform = get_or_allocate_uniform(prog, name); 315 ShaderUniform* uniform = get_or_allocate_uniform(prog, name);
252 assert(uniform); 316 assert(uniform);
253 uniform->name = sstring_make(name); 317 uniform->name = sstring_make(name);
254 uniform->type = UniformVec4; 318 uniform->type = UniformVec4;
255 uniform->value.vec4 = value; 319 uniform->value.uniform_vec4 = value;
256} 320}
257 321
258void gfx_set_float_uniform(ShaderProgram* prog, const char* name, float value) { 322void gfx_set_texture_uniform(
323 ShaderProgram* prog, const char* name, const Texture* texture) {
259 assert(prog); 324 assert(prog);
260 assert(name); 325 assert(name);
326 assert(texture);
261 327
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); 328 const GLint location = glGetUniformLocation(prog->id, name);
265 if (location < 0) { 329 if (location < 0) {
266 return; 330 return;
267 } 331 }
268 ShaderUniform* uniform = get_or_allocate_uniform(prog, name); 332 ShaderUniform* uniform = get_or_allocate_uniform(prog, name);
269 assert(uniform); 333 assert(uniform);
270 uniform->name = sstring_make(name); 334 uniform->name = sstring_make(name);
271 uniform->type = UniformFloat; 335 uniform->type = UniformTexture;
272 uniform->value.scalar = value; 336 uniform->value.texture = texture;
273} 337}
274 338
275void gfx_set_mat4_array_uniform( 339void gfx_set_mat4_array_uniform(
@@ -277,7 +341,7 @@ void gfx_set_mat4_array_uniform(
277 assert(prog); 341 assert(prog);
278 assert(name); 342 assert(name);
279 assert(mats); 343 assert(mats);
280 344
281 const GLint location = glGetUniformLocation(prog->id, name); 345 const GLint location = glGetUniformLocation(prog->id, name);
282 if (location < 0) { 346 if (location < 0) {
283 return; 347 return;