4 * An object oriented GL/GLES Abstraction/Utility Layer
6 * Copyright (C) 2008,2009 Intel Corporation.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
31 /* We don't want to get the remaps from the gl* functions to the
32 cogl_wrap_gl* functions in this file because we need to be able to
33 call the base version */
34 #define COGL_GLES2_WRAPPER_NO_REMAP 1
37 #include "cogl-gles2-wrapper.h"
38 #include "cogl-fixed-vertex-shader.h"
39 #include "cogl-fixed-fragment-shader.h"
40 #include "cogl-context.h"
41 #include "cogl-shader-private.h"
42 #include "cogl-program.h"
43 #include "cogl-internal.h"
45 #define _COGL_GET_GLES2_WRAPPER(wvar, retval) \
46 CoglGles2Wrapper *wvar; \
48 CoglContext *__ctxvar = _cogl_context_get_default (); \
49 if (__ctxvar == NULL) return retval; \
50 wvar = &__ctxvar->drv.gles2; \
53 #define _COGL_GLES2_CHANGE_SETTING(w, var, val) \
55 if ((w)->settings.var != (val)) \
57 (w)->settings.var = (val); \
58 (w)->settings_dirty = TRUE; \
62 #define _COGL_GLES2_CHANGE_UNIFORM(w, flag, var, val) \
64 if ((w)->var != (val)) \
67 (w)->dirty_uniforms |= COGL_GLES2_DIRTY_ ## flag; \
71 #define COGL_GLES2_WRAPPER_VERTEX_ATTRIB 0
72 #define COGL_GLES2_WRAPPER_COLOR_ATTRIB 1
73 #define COGL_GLES2_WRAPPER_NORMAL_ATTRIB 2
77 cogl_gles2_wrapper_create_shader (GLenum type, const char *source)
80 GLint source_len = strlen (source);
83 shader = glCreateShader (type);
84 glShaderSource (shader, 1, &source, &source_len);
85 glCompileShader (shader);
87 glGetShaderiv (shader, GL_COMPILE_STATUS, &status);
91 char shader_log[1024];
94 glGetShaderInfoLog (shader, sizeof (shader_log) - 1, &len, shader_log);
95 shader_log[len] = '\0';
97 g_critical ("%s", shader_log);
99 glDeleteShader (shader);
108 initialize_texture_units (CoglGles2Wrapper *w)
110 /* We save the active texture unit since we may need to temporarily
111 * change this to initialise each new texture unit and we want to
112 * restore the active unit afterwards */
113 int initial_active_unit = w->active_texture_unit;
117 /* We will need to set the matrix mode to GL_TEXTURE to
118 * initialise any new texture units, so we save the current
119 * mode for restoring afterwards */
120 GE( _cogl_wrap_glGetIntegerv (GL_MATRIX_MODE, &prev_mode));
122 for (i = 0; i < COGL_GLES2_MAX_TEXTURE_UNITS; i++)
124 CoglGles2WrapperTextureUnit *new_unit;
126 new_unit = w->texture_units + i;
127 memset (new_unit, 0, sizeof (CoglGles2WrapperTextureUnit));
129 w->active_texture_unit = i;
130 GE( _cogl_wrap_glMatrixMode (GL_TEXTURE));
131 GE( _cogl_wrap_glLoadIdentity ());
133 /* The real GL default is GL_MODULATE but the shader only
134 supports GL_COMBINE so let's default to that instead */
135 GE( _cogl_wrap_glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
137 GE( _cogl_wrap_glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB,
139 GE( _cogl_wrap_glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB,
141 GE( _cogl_wrap_glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_RGB,
143 GE( _cogl_wrap_glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB,
145 GE( _cogl_wrap_glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB,
147 GE( _cogl_wrap_glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA,
149 GE( _cogl_wrap_glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_ALPHA,
151 GE( _cogl_wrap_glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_ALPHA,
153 GE( _cogl_wrap_glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA,
155 GE( _cogl_wrap_glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA,
158 GE( _cogl_wrap_glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE,
162 GE( _cogl_wrap_glMatrixMode ((GLenum) prev_mode));
164 w->settings.texture_units = 0;
166 w->active_texture_unit = initial_active_unit;
170 _cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper)
172 GLfloat default_fog_color[4] = { 0, 0, 0, 0 };
174 memset (wrapper, 0, sizeof (CoglGles2Wrapper));
176 /* Initialize the stacks */
177 _cogl_wrap_glMatrixMode (GL_PROJECTION);
178 _cogl_wrap_glLoadIdentity ();
179 _cogl_wrap_glMatrixMode (GL_MODELVIEW);
180 _cogl_wrap_glLoadIdentity ();
182 /* The gl*ActiveTexture wrappers will initialise the texture
183 * stack for the texture unit when it's first activated */
184 _cogl_wrap_glActiveTexture (GL_TEXTURE0);
185 _cogl_wrap_glClientActiveTexture (GL_TEXTURE0);
187 /* Initialize the fogging options */
188 _cogl_wrap_glDisable (GL_FOG);
189 _cogl_wrap_glFogf (GL_FOG_MODE, GL_LINEAR);
190 _cogl_wrap_glFogf (GL_FOG_DENSITY, 1.0);
191 _cogl_wrap_glFogf (GL_FOG_START, 0);
192 _cogl_wrap_glFogf (GL_FOG_END, 1);
193 _cogl_wrap_glFogfv (GL_FOG_COLOR, default_fog_color);
195 /* Initialize alpha testing */
196 _cogl_wrap_glDisable (GL_ALPHA_TEST);
197 _cogl_wrap_glAlphaFunc (GL_ALWAYS, 0.0f);
199 /* Initialize the point size */
200 _cogl_wrap_glPointSize (1.0f);
202 initialize_texture_units (wrapper);
206 cogl_gles2_get_n_args_for_combine_func (GLenum func)
227 cogl_gles2_settings_equal (const CoglGles2WrapperSettings *a,
228 const CoglGles2WrapperSettings *b,
229 gboolean vertex_tests,
230 gboolean fragment_tests)
234 if (a->texture_units != b->texture_units)
239 if (a->alpha_test_enabled != b->alpha_test_enabled)
241 if (a->alpha_test_enabled && a->alpha_test_func != b->alpha_test_func)
245 if (a->fog_enabled != b->fog_enabled)
248 if (vertex_tests && a->fog_enabled && a->fog_mode != b->fog_mode)
251 /* Compare layer combine operation for each active unit */
253 for (i = 0; i < COGL_GLES2_MAX_TEXTURE_UNITS; i++)
255 if (!!COGL_GLES2_TEXTURE_UNIT_IS_ENABLED (a->texture_units, i) !=
256 !!COGL_GLES2_TEXTURE_UNIT_IS_ENABLED (b->texture_units, i))
259 if (COGL_GLES2_TEXTURE_UNIT_IS_ENABLED (a->texture_units, i))
261 const CoglGles2WrapperTexEnv *tex_env_a = a->tex_env + i;
262 const CoglGles2WrapperTexEnv *tex_env_b = b->tex_env + i;
266 if (tex_env_a->texture_target != tex_env_b->texture_target)
269 if (tex_env_a->point_sprite_coords !=
270 tex_env_b->point_sprite_coords)
273 func = tex_env_a->texture_combine_rgb_func;
275 if (func != tex_env_b->texture_combine_rgb_func)
278 n_args = cogl_gles2_get_n_args_for_combine_func (func);
280 for (arg = 0; arg < n_args; arg++)
282 if (tex_env_a->texture_combine_rgb_src[arg] !=
283 tex_env_b->texture_combine_rgb_src[arg])
285 if (tex_env_a->texture_combine_rgb_op[arg] !=
286 tex_env_b->texture_combine_rgb_op[arg])
295 static CoglGles2WrapperShader *
296 cogl_gles2_get_vertex_shader (const CoglGles2WrapperSettings *settings)
298 GString *shader_source;
300 CoglGles2WrapperShader *shader;
303 int n_texture_units = 0;
305 _COGL_GET_GLES2_WRAPPER (w, NULL);
307 /* Check if we already have a vertex shader for these settings */
308 for (node = w->compiled_vertex_shaders; node; node = node->next)
309 if (cogl_gles2_settings_equal (settings,
310 &((CoglGles2WrapperShader *)
311 node->data)->settings,
313 return (CoglGles2WrapperShader *) node->data;
315 /* Otherwise create a new shader */
316 shader_source = g_string_new (_cogl_fixed_vertex_shader_per_vertex_attribs);
318 for (i = 0; i < COGL_GLES2_MAX_TEXTURE_UNITS; i++)
319 if (COGL_GLES2_TEXTURE_UNIT_IS_ENABLED (settings->texture_units, i))
320 g_string_append_printf (shader_source,
321 "attribute vec4 multi_tex_coord_attrib%d;\n",
324 /* Find the biggest enabled texture unit index */
325 for (i = 0; i < COGL_GLES2_MAX_TEXTURE_UNITS; i++)
326 if (COGL_GLES2_TEXTURE_UNIT_IS_ENABLED (settings->texture_units, i))
327 n_texture_units = i + 1;
329 g_string_append (shader_source, _cogl_fixed_vertex_shader_transform_matrices);
330 g_string_append (shader_source, _cogl_fixed_vertex_shader_output_variables);
332 if (n_texture_units > 0)
334 g_string_append_printf (shader_source,
335 "uniform mat4 texture_matrix[%d];\n",
338 g_string_append_printf (shader_source,
339 "varying vec2 tex_coord[%d];",
343 g_string_append (shader_source, _cogl_fixed_vertex_shader_fogging_options);
344 g_string_append (shader_source, _cogl_fixed_vertex_shader_main_start);
346 for (i = 0; i < COGL_GLES2_MAX_TEXTURE_UNITS; i++)
347 if (COGL_GLES2_TEXTURE_UNIT_IS_ENABLED (settings->texture_units, i) &&
348 !settings->tex_env[i].point_sprite_coords)
350 g_string_append_printf (shader_source,
351 "transformed_tex_coord = "
352 "texture_matrix[%d] "
353 " * multi_tex_coord_attrib%d;\n",
355 g_string_append_printf (shader_source,
356 "tex_coord[%d] = transformed_tex_coord.st "
357 " / transformed_tex_coord.q;\n",
361 g_string_append (shader_source, _cogl_fixed_vertex_shader_frag_color_start);
363 if (settings->fog_enabled)
365 g_string_append (shader_source, _cogl_fixed_vertex_shader_fog_start);
367 switch (settings->fog_mode)
370 g_string_append (shader_source, _cogl_fixed_vertex_shader_fog_exp);
374 g_string_append (shader_source, _cogl_fixed_vertex_shader_fog_exp2);
378 g_string_append (shader_source, _cogl_fixed_vertex_shader_fog_linear);
382 g_string_append (shader_source, _cogl_fixed_vertex_shader_fog_end);
385 g_string_append (shader_source, _cogl_fixed_vertex_shader_end);
387 shader_obj = cogl_gles2_wrapper_create_shader (GL_VERTEX_SHADER,
390 g_string_free (shader_source, TRUE);
395 shader = g_slice_new (CoglGles2WrapperShader);
396 shader->shader = shader_obj;
397 shader->settings = *settings;
399 w->compiled_vertex_shaders = g_slist_prepend (w->compiled_vertex_shaders,
406 cogl_gles2_add_texture_lookup (int unit,
408 GString *shader_source)
410 _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
412 if (w->settings.tex_env[unit].texture_target == GL_TEXTURE_3D_OES)
413 g_string_append_printf (shader_source, "texture3D (texture_unit[%d], ",
416 g_string_append_printf (shader_source, "texture2D (texture_unit[%d], ",
419 /* If point sprite coord generation is being used then divert to the
420 built-in varying var for that instead of the texture
422 if (w->settings.tex_env[unit].point_sprite_coords)
423 g_string_append (shader_source, "gl_PointCoord");
425 g_string_append_printf (shader_source, "tex_coord[%d]", unit);
427 g_string_append_printf (shader_source, ").%s", swizzle);
431 cogl_gles2_add_arg (int unit,
435 GString *shader_source)
437 char alpha_swizzle[5] = "aaaa";
439 g_string_append_c (shader_source, '(');
441 if (operand == GL_ONE_MINUS_SRC_COLOR || operand == GL_ONE_MINUS_SRC_ALPHA)
442 g_string_append_printf (shader_source,
443 "vec4(1.0, 1.0, 1.0, 1.0).%s - ",
446 /* If the operand is reading from the alpha then replace the swizzle
447 with the same number of copies of the alpha */
448 if (operand == GL_SRC_ALPHA || operand == GL_ONE_MINUS_SRC_ALPHA)
450 alpha_swizzle[strlen (swizzle)] = '\0';
451 swizzle = alpha_swizzle;
457 cogl_gles2_add_texture_lookup (unit, swizzle, shader_source);
461 g_string_append_printf (shader_source, "combine_constant[%d].%s",
468 g_string_append_printf (shader_source, "gl_FragColor.%s", swizzle);
472 case GL_PRIMARY_COLOR:
473 g_string_append_printf (shader_source, "frag_color.%s", swizzle);
477 if (src >= GL_TEXTURE0 &&
478 src < GL_TEXTURE0 + COGL_GLES2_MAX_TEXTURE_UNITS)
479 cogl_gles2_add_texture_lookup (src - GL_TEXTURE0,
480 swizzle, shader_source);
484 g_string_append_c (shader_source, ')');
488 cogl_gles2_add_operation (int unit,
490 const GLenum *sources,
491 const GLenum *operands,
493 GString *shader_source)
495 switch (combine_func)
498 cogl_gles2_add_arg (unit, sources[0], operands[0],
499 swizzle, shader_source);
503 cogl_gles2_add_arg (unit, sources[0], operands[0],
504 swizzle, shader_source);
505 g_string_append (shader_source, " * ");
506 cogl_gles2_add_arg (unit, sources[1], operands[1],
507 swizzle, shader_source);
511 cogl_gles2_add_arg (unit, sources[0], operands[0],
512 swizzle, shader_source);
513 g_string_append (shader_source, " + ");
514 cogl_gles2_add_arg (unit, sources[1], operands[1],
515 swizzle, shader_source);
519 cogl_gles2_add_arg (unit, sources[0], operands[0],
520 swizzle, shader_source);
521 g_string_append (shader_source, " + ");
522 cogl_gles2_add_arg (unit, sources[1], operands[1],
523 swizzle, shader_source);
524 g_string_append_printf (shader_source,
525 " - vec4(0.5, 0.5, 0.5, 0.5).%s",
530 cogl_gles2_add_arg (unit, sources[0], operands[0],
531 swizzle, shader_source);
532 g_string_append (shader_source, " - ");
533 cogl_gles2_add_arg (unit, sources[1], operands[1],
534 swizzle, shader_source);
538 cogl_gles2_add_arg (unit, sources[0], operands[0],
539 swizzle, shader_source);
540 g_string_append (shader_source, " * ");
541 cogl_gles2_add_arg (unit, sources[2], operands[2],
542 swizzle, shader_source);
543 g_string_append (shader_source, " + ");
544 cogl_gles2_add_arg (unit, sources[1], operands[1],
545 swizzle, shader_source);
546 g_string_append_printf (shader_source,
547 " * (vec4(1.0, 1.0, 1.0, 1.0).%s - ",
549 cogl_gles2_add_arg (unit, sources[2], operands[2],
550 swizzle, shader_source);
551 g_string_append_c (shader_source, ')');
556 g_string_append (shader_source, "vec4(4 * ((");
557 cogl_gles2_add_arg (unit, sources[0], operands[0],
559 g_string_append (shader_source, " - 0.5) * (");
560 cogl_gles2_add_arg (unit, sources[1], operands[1],
562 g_string_append (shader_source, " - 0.5) + (");
563 cogl_gles2_add_arg (unit, sources[0], operands[0],
565 g_string_append (shader_source, " - 0.5) * (");
566 cogl_gles2_add_arg (unit, sources[1], operands[1],
568 g_string_append (shader_source, " - 0.5) + (");
569 cogl_gles2_add_arg (unit, sources[0], operands[0],
571 g_string_append (shader_source, " - 0.5) * (");
572 cogl_gles2_add_arg (unit, sources[1], operands[1],
574 g_string_append_printf (shader_source, " - 0.5))).%s", swizzle);
580 cogl_gles2_rgb_and_alpha_equal (const CoglGles2WrapperTexEnv *tex_env)
584 if (tex_env->texture_combine_rgb_func != tex_env->texture_combine_alpha_func)
588 cogl_gles2_get_n_args_for_combine_func (tex_env->texture_combine_rgb_func);
590 for (arg = 0; arg < n_args; arg++)
592 if (tex_env->texture_combine_rgb_src[arg] !=
593 tex_env->texture_combine_alpha_src[arg])
596 if (tex_env->texture_combine_rgb_op[arg] != GL_SRC_COLOR ||
597 tex_env->texture_combine_alpha_op[arg] != GL_SRC_ALPHA)
605 static CoglGles2WrapperShader *
606 cogl_gles2_get_fragment_shader (const CoglGles2WrapperSettings *settings)
608 GString *shader_source;
610 CoglGles2WrapperShader *shader;
613 int n_texture_units = 0;
615 _COGL_GET_GLES2_WRAPPER (w, NULL);
617 /* Check if we already have a fragment shader for these settings */
618 for (node = w->compiled_fragment_shaders; node; node = node->next)
619 if (cogl_gles2_settings_equal (settings,
620 &((CoglGles2WrapperShader *)
621 node->data)->settings,
623 return (CoglGles2WrapperShader *) node->data;
625 /* Otherwise create a new shader */
626 shader_source = g_string_new (_cogl_fixed_fragment_shader_variables_start);
628 /* Find the biggest enabled texture unit index */
629 for (i = 0; i < COGL_GLES2_MAX_TEXTURE_UNITS; i++)
630 if (COGL_GLES2_TEXTURE_UNIT_IS_ENABLED (settings->texture_units, i))
631 n_texture_units = i + 1;
633 g_string_append (shader_source, _cogl_fixed_fragment_shader_inputs);
635 if (n_texture_units > 0)
637 g_string_append_printf (shader_source,
638 "varying vec2 tex_coord[%d];\n",
641 g_string_append (shader_source,
642 _cogl_fixed_fragment_shader_texturing_options);
643 g_string_append_printf (shader_source,
644 "uniform sampler2D texture_unit[%d];\n",
648 g_string_append (shader_source, _cogl_fixed_fragment_shader_fogging_options);
650 g_string_append (shader_source, _cogl_fixed_fragment_shader_main_declare);
652 g_string_append (shader_source, _cogl_fixed_fragment_shader_main_start);
654 /* This pointless extra variable is needed to work around an
655 apparent bug in the PowerVR drivers. Without it the alpha
656 blending seems to stop working */
657 g_string_append (shader_source,
658 "vec4 frag_color_copy = frag_color;\n");
660 /* If there are no textures units enabled then we can just directly
661 use the color from the vertex shader */
662 if (n_texture_units == 0)
663 g_string_append (shader_source, "gl_FragColor = frag_color;\n");
665 /* Otherwise we need to calculate the value based on the layer
667 for (i = 0; i < n_texture_units; i++)
668 if (COGL_GLES2_TEXTURE_UNIT_IS_ENABLED (settings->texture_units, i))
670 const CoglGles2WrapperTexEnv *tex_env = settings->tex_env + i;
672 /* If the rgb and alpha combine functions are the same then
673 we can do both with a single statement, otherwise we need
674 to do them separately */
675 if (cogl_gles2_rgb_and_alpha_equal (tex_env))
677 g_string_append (shader_source, "gl_FragColor.rgba = ");
678 cogl_gles2_add_operation (i,
679 tex_env->texture_combine_rgb_func,
680 tex_env->texture_combine_rgb_src,
681 tex_env->texture_combine_rgb_op,
684 g_string_append (shader_source, ";\n");
688 g_string_append (shader_source, "gl_FragColor.rgb = ");
689 cogl_gles2_add_operation (i,
690 tex_env->texture_combine_rgb_func,
691 tex_env->texture_combine_rgb_src,
692 tex_env->texture_combine_rgb_op,
695 g_string_append (shader_source,
697 "gl_FragColor.a = ");
698 cogl_gles2_add_operation (i,
699 tex_env->texture_combine_alpha_func,
700 tex_env->texture_combine_alpha_src,
701 tex_env->texture_combine_alpha_op,
704 g_string_append (shader_source, ";\n");
708 if (settings->fog_enabled)
709 g_string_append (shader_source, _cogl_fixed_fragment_shader_fog);
711 if (settings->alpha_test_enabled)
712 switch (settings->alpha_test_func)
715 g_string_append (shader_source,
716 _cogl_fixed_fragment_shader_alpha_never);
719 g_string_append (shader_source,
720 _cogl_fixed_fragment_shader_alpha_less);
723 g_string_append (shader_source,
724 _cogl_fixed_fragment_shader_alpha_equal);
727 g_string_append (shader_source,
728 _cogl_fixed_fragment_shader_alpha_lequal);
731 g_string_append (shader_source,
732 _cogl_fixed_fragment_shader_alpha_greater);
735 g_string_append (shader_source,
736 _cogl_fixed_fragment_shader_alpha_notequal);
739 g_string_append (shader_source,
740 _cogl_fixed_fragment_shader_alpha_gequal);
743 g_string_append (shader_source, _cogl_fixed_fragment_shader_end);
745 shader_obj = cogl_gles2_wrapper_create_shader (GL_FRAGMENT_SHADER,
748 g_string_free (shader_source, TRUE);
753 shader = g_slice_new (CoglGles2WrapperShader);
754 shader->shader = shader_obj;
755 shader->settings = *settings;
757 w->compiled_fragment_shaders = g_slist_prepend (w->compiled_fragment_shaders,
764 cogl_gles2_wrapper_get_locations (GLuint program,
765 CoglGles2WrapperSettings *settings,
766 CoglGles2WrapperUniforms *uniforms,
767 CoglGles2WrapperAttributes *attribs)
771 uniforms->mvp_matrix_uniform
772 = glGetUniformLocation (program, "mvp_matrix");
773 uniforms->modelview_matrix_uniform
774 = glGetUniformLocation (program, "modelview_matrix");
776 for (i = 0; i < COGL_GLES2_MAX_TEXTURE_UNITS; i++)
777 if (COGL_GLES2_TEXTURE_UNIT_IS_ENABLED (settings->texture_units, i))
779 char *matrix_var_name = g_strdup_printf ("texture_matrix[%d]", i);
780 char *sampler_var_name = g_strdup_printf ("texture_unit[%d]", i);
781 char *tex_coord_var_name =
782 g_strdup_printf ("multi_tex_coord_attrib%d", i);
784 uniforms->texture_matrix_uniforms[i]
785 = glGetUniformLocation (program, matrix_var_name);
786 uniforms->texture_sampler_uniforms[i]
787 = glGetUniformLocation (program, sampler_var_name);
788 attribs->multi_texture_coords[i]
789 = glGetAttribLocation (program, tex_coord_var_name);
791 g_free (tex_coord_var_name);
792 g_free (sampler_var_name);
793 g_free (matrix_var_name);
797 uniforms->texture_matrix_uniforms[i] = -1;
798 uniforms->texture_sampler_uniforms[i] = -1;
799 attribs->multi_texture_coords[i] = -1;
802 uniforms->fog_density_uniform
803 = glGetUniformLocation (program, "fog_density");
804 uniforms->fog_start_uniform
805 = glGetUniformLocation (program, "fog_start");
806 uniforms->fog_end_uniform
807 = glGetUniformLocation (program, "fog_end");
808 uniforms->fog_color_uniform
809 = glGetUniformLocation (program, "fog_color");
811 uniforms->alpha_test_ref_uniform
812 = glGetUniformLocation (program, "alpha_test_ref");
814 uniforms->point_size_uniform
815 = glGetUniformLocation (program, "point_size");
819 cogl_gles2_wrapper_bind_attributes (GLuint program)
821 glBindAttribLocation (program, COGL_GLES2_WRAPPER_VERTEX_ATTRIB,
823 glBindAttribLocation (program, COGL_GLES2_WRAPPER_COLOR_ATTRIB,
825 glBindAttribLocation (program, COGL_GLES2_WRAPPER_NORMAL_ATTRIB,
829 static CoglGles2WrapperProgram *
830 cogl_gles2_wrapper_get_program (const CoglGles2WrapperSettings *settings)
833 CoglGles2WrapperProgram *program;
834 CoglGles2WrapperShader *vertex_shader, *fragment_shader;
836 gboolean custom_vertex_shader = FALSE, custom_fragment_shader = FALSE;
837 CoglProgram *user_program = NULL;
840 _COGL_GET_GLES2_WRAPPER (w, NULL);
842 /* Check if we've already got a program for these settings */
843 for (node = w->compiled_programs; node; node = node->next)
845 program = (CoglGles2WrapperProgram *) node->data;
847 if (cogl_gles2_settings_equal (settings, &program->settings, TRUE, TRUE)
848 && program->settings.user_program == settings->user_program)
849 return (CoglGles2WrapperProgram *) node->data;
852 /* Otherwise create a new program */
854 /* Check whether the currently used custom program has vertex and
856 if (w->settings.user_program != COGL_INVALID_HANDLE)
859 = _cogl_program_pointer_from_handle (w->settings.user_program);
861 for (node = user_program->attached_shaders; node; node = node->next)
864 = _cogl_shader_pointer_from_handle ((CoglHandle) node->data);
866 if (shader->type == COGL_SHADER_TYPE_VERTEX)
867 custom_vertex_shader = TRUE;
868 else if (shader->type == COGL_SHADER_TYPE_FRAGMENT)
869 custom_fragment_shader = TRUE;
873 /* Get or create the fixed functionality shaders for these settings
874 if there is no custom replacement */
875 if (!custom_vertex_shader)
877 vertex_shader = cogl_gles2_get_vertex_shader (settings);
878 if (vertex_shader == NULL)
881 if (!custom_fragment_shader)
883 fragment_shader = cogl_gles2_get_fragment_shader (settings);
884 if (fragment_shader == NULL)
888 program = g_slice_new (CoglGles2WrapperProgram);
890 program->program = glCreateProgram ();
891 if (!custom_vertex_shader)
892 glAttachShader (program->program, vertex_shader->shader);
893 if (!custom_fragment_shader)
894 glAttachShader (program->program, fragment_shader->shader);
896 for (node = user_program->attached_shaders; node; node = node->next)
899 = _cogl_shader_pointer_from_handle ((CoglHandle) node->data);
900 glAttachShader (program->program, shader->gl_handle);
902 cogl_gles2_wrapper_bind_attributes (program->program);
903 glLinkProgram (program->program);
905 glGetProgramiv (program->program, GL_LINK_STATUS, &status);
909 char shader_log[1024];
912 glGetProgramInfoLog (program->program, sizeof (shader_log) - 1, &len, shader_log);
913 shader_log[len] = '\0';
915 g_critical ("%s", shader_log);
917 glDeleteProgram (program->program);
918 g_slice_free (CoglGles2WrapperProgram, program);
923 program->settings = *settings;
925 cogl_gles2_wrapper_get_locations (program->program,
928 &program->attributes);
930 /* We haven't tried to get a location for any of the custom uniforms
932 for (i = 0; i < COGL_PROGRAM_NUM_CUSTOM_UNIFORMS; i++)
933 program->custom_gl_uniforms[i] = COGL_PROGRAM_UNBOUND_CUSTOM_UNIFORM;
935 w->compiled_programs = g_slist_append (w->compiled_programs, program);
941 _cogl_gles2_wrapper_deinit (CoglGles2Wrapper *wrapper)
945 for (node = wrapper->compiled_programs; node; node = next)
948 glDeleteProgram (((CoglGles2WrapperProgram *) node->data)->program);
949 g_slist_free1 (node);
951 wrapper->compiled_programs = NULL;
953 for (node = wrapper->compiled_vertex_shaders; node; node = next)
956 glDeleteShader (((CoglGles2WrapperShader *) node->data)->shader);
957 g_slist_free1 (node);
959 wrapper->compiled_vertex_shaders = NULL;
961 for (node = wrapper->compiled_fragment_shaders; node; node = next)
964 glDeleteShader (((CoglGles2WrapperShader *) node->data)->shader);
965 g_slist_free1 (node);
967 wrapper->compiled_fragment_shaders = NULL;
971 cogl_gles2_wrapper_notify_matrix_changed (CoglGles2Wrapper *wrapper,
974 CoglGles2WrapperTextureUnit *texture_unit;
979 wrapper->dirty_uniforms |= COGL_GLES2_DIRTY_MVP_MATRIX
980 | COGL_GLES2_DIRTY_MODELVIEW_MATRIX;
984 wrapper->dirty_uniforms |= COGL_GLES2_DIRTY_MVP_MATRIX;
988 wrapper->dirty_uniforms |= COGL_GLES2_DIRTY_TEXTURE_MATRICES;
989 texture_unit = wrapper->texture_units + wrapper->active_texture_unit;
990 texture_unit->dirty_matrix = 1;
994 g_critical ("%s: Unexpected matrix mode %d\n", G_STRFUNC, mode);
999 _cogl_wrap_glMatrixMode (GLenum mode)
1001 _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
1003 w->matrix_mode = mode;
1007 cogl_gles2_get_current_matrix (CoglGles2Wrapper *wrapper)
1009 CoglGles2WrapperTextureUnit *texture_unit;
1011 switch (wrapper->matrix_mode)
1014 g_critical ("%s: Unexpected matrix mode %d\n",
1015 G_STRFUNC, wrapper->matrix_mode);
1019 return &wrapper->modelview_matrix;
1022 return &wrapper->projection_matrix;
1025 texture_unit = wrapper->texture_units + wrapper->active_texture_unit;
1026 return &texture_unit->texture_matrix;
1031 _cogl_wrap_glLoadIdentity (void)
1035 _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
1037 matrix = cogl_gles2_get_current_matrix (w);
1039 cogl_matrix_init_identity (matrix);
1041 cogl_gles2_wrapper_notify_matrix_changed (w, w->matrix_mode);
1045 _cogl_wrap_glLoadMatrixf (const GLfloat *m)
1049 _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
1051 matrix = cogl_gles2_get_current_matrix (w);
1053 cogl_matrix_init_from_array (matrix, m);
1055 cogl_gles2_wrapper_notify_matrix_changed (w, w->matrix_mode);
1059 _cogl_wrap_glVertexPointer (GLint size, GLenum type, GLsizei stride,
1060 const GLvoid *pointer)
1062 glVertexAttribPointer (COGL_GLES2_WRAPPER_VERTEX_ATTRIB, size, type,
1063 GL_FALSE, stride, pointer);
1067 _cogl_wrap_glTexCoordPointer (GLint size, GLenum type, GLsizei stride,
1068 const GLvoid *pointer)
1071 CoglGles2WrapperTextureUnit *texture_unit;
1072 _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
1074 active_unit = w->active_client_texture_unit;
1076 texture_unit = w->texture_units + active_unit;
1077 texture_unit->texture_coords_size = size;
1078 texture_unit->texture_coords_type = type;
1079 texture_unit->texture_coords_stride = stride;
1080 texture_unit->texture_coords_pointer = pointer;
1082 w->dirty_attribute_pointers
1083 |= COGL_GLES2_DIRTY_TEX_COORD_VERTEX_ATTRIB;
1087 _cogl_wrap_glColorPointer (GLint size, GLenum type, GLsizei stride,
1088 const GLvoid *pointer)
1090 glVertexAttribPointer (COGL_GLES2_WRAPPER_COLOR_ATTRIB, size, type,
1091 GL_TRUE, stride, pointer);
1095 _cogl_wrap_glNormalPointer (GLenum type, GLsizei stride, const GLvoid *pointer)
1097 glVertexAttribPointer (COGL_GLES2_WRAPPER_NORMAL_ATTRIB, 1, type,
1098 GL_FALSE, stride, pointer);
1102 cogl_gles2_do_set_uniform (GLint location, CoglBoxedValue *value)
1104 switch (value->type)
1106 case COGL_BOXED_NONE:
1109 case COGL_BOXED_INT:
1113 if (value->count == 1)
1114 ptr = value->v.int_value;
1116 ptr = value->v.int_array;
1118 switch (value->size)
1120 case 1: glUniform1iv (location, value->count, ptr); break;
1121 case 2: glUniform2iv (location, value->count, ptr); break;
1122 case 3: glUniform3iv (location, value->count, ptr); break;
1123 case 4: glUniform4iv (location, value->count, ptr); break;
1128 case COGL_BOXED_FLOAT:
1132 if (value->count == 1)
1133 ptr = value->v.float_value;
1135 ptr = value->v.float_array;
1137 switch (value->size)
1139 case 1: glUniform1fv (location, value->count, ptr); break;
1140 case 2: glUniform2fv (location, value->count, ptr); break;
1141 case 3: glUniform3fv (location, value->count, ptr); break;
1142 case 4: glUniform4fv (location, value->count, ptr); break;
1147 case COGL_BOXED_MATRIX:
1151 if (value->count == 1)
1152 ptr = value->v.matrix;
1154 ptr = value->v.float_array;
1156 switch (value->size)
1159 glUniformMatrix2fv (location, value->count, value->transpose, ptr);
1162 glUniformMatrix3fv (location, value->count, value->transpose, ptr);
1165 glUniformMatrix4fv (location, value->count, value->transpose, ptr);
1174 _cogl_wrap_prepare_for_draw (void)
1176 CoglGles2WrapperProgram *program;
1177 guint32 dirty_custom_uniforms = 0;
1179 _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
1181 /* Check if we need to switch programs */
1182 if (w->settings_dirty)
1184 /* Find or create a program for the current settings */
1185 program = cogl_gles2_wrapper_get_program (&w->settings);
1187 if (program == NULL)
1188 /* Can't compile a shader so there is nothing we can do */
1191 /* Start using it if we aren't already */
1192 if (w->current_program != program)
1194 glUseProgram (program->program);
1195 w->current_program = program;
1196 /* All of the uniforms are probably now out of date */
1197 w->dirty_uniforms = COGL_GLES2_DIRTY_ALL;
1198 dirty_custom_uniforms = (1 << COGL_PROGRAM_NUM_CUSTOM_UNIFORMS) - 1;
1200 w->settings_dirty = FALSE;
1204 CoglProgram *user_program =
1205 _cogl_program_pointer_from_handle (w->settings.user_program);
1207 dirty_custom_uniforms = user_program->dirty_custom_uniforms;
1208 program = w->current_program;
1211 /* Make sure all of the uniforms are up to date */
1212 if (w->dirty_uniforms)
1214 if ((w->dirty_uniforms & (COGL_GLES2_DIRTY_MVP_MATRIX
1215 | COGL_GLES2_DIRTY_MODELVIEW_MATRIX)))
1217 CoglMatrix mvp_matrix;
1218 CoglMatrix *modelview_matrix = &w->modelview_matrix;
1219 CoglMatrix *projection_matrix = &w->projection_matrix;
1221 /* FIXME: we should have a cogl_matrix_copy () function */
1222 memcpy (&mvp_matrix, projection_matrix, sizeof (CoglMatrix));
1224 cogl_matrix_multiply (&mvp_matrix, &mvp_matrix, modelview_matrix);
1226 if (program->uniforms.mvp_matrix_uniform != -1)
1227 glUniformMatrix4fv (program->uniforms.mvp_matrix_uniform, 1,
1228 GL_FALSE, (float *) &mvp_matrix);
1229 if (program->uniforms.modelview_matrix_uniform != -1)
1230 glUniformMatrix4fv (program->uniforms.modelview_matrix_uniform, 1,
1231 GL_FALSE, (float *) &modelview_matrix);
1233 if ((w->dirty_uniforms & COGL_GLES2_DIRTY_TEXTURE_MATRICES))
1237 /* TODO - we should probably have a per unit dirty flag too */
1239 for (i = 0; i < COGL_GLES2_MAX_TEXTURE_UNITS; i++)
1241 CoglGles2WrapperTextureUnit *texture_unit;
1242 GLint uniform = program->uniforms.texture_matrix_uniforms[i];
1244 texture_unit = w->texture_units + i;
1246 glUniformMatrix4fv (uniform, 1, GL_FALSE,
1247 (float *) &texture_unit->texture_matrix);
1251 if ((w->dirty_uniforms & COGL_GLES2_DIRTY_FOG_DENSITY)
1252 && program->uniforms.fog_density_uniform != -1)
1253 glUniform1f (program->uniforms.fog_density_uniform, w->fog_density);
1254 if ((w->dirty_uniforms & COGL_GLES2_DIRTY_FOG_START)
1255 && program->uniforms.fog_start_uniform != -1)
1256 glUniform1f (program->uniforms.fog_start_uniform, w->fog_start);
1257 if ((w->dirty_uniforms & COGL_GLES2_DIRTY_FOG_END)
1258 && program->uniforms.fog_end_uniform != -1)
1259 glUniform1f (program->uniforms.fog_end_uniform, w->fog_end);
1261 if ((w->dirty_uniforms & COGL_GLES2_DIRTY_ALPHA_TEST_REF)
1262 && program->uniforms.alpha_test_ref_uniform != -1)
1263 glUniform1f (program->uniforms.alpha_test_ref_uniform,
1266 if ((w->dirty_uniforms & COGL_GLES2_DIRTY_TEXTURE_UNITS))
1270 /* TODO - we should probably have a per unit dirty flag too */
1272 for (i = 0; i < COGL_GLES2_MAX_TEXTURE_UNITS; i++)
1274 GLint uniform = program->uniforms.texture_sampler_uniforms[i];
1277 glUniform1i (uniform, i);
1281 if ((w->dirty_uniforms & COGL_GLES2_DIRTY_POINT_SIZE))
1282 glUniform1f (program->uniforms.point_size_uniform,
1285 w->dirty_uniforms = 0;
1288 if (dirty_custom_uniforms)
1292 if (w->settings.user_program != COGL_INVALID_HANDLE)
1294 CoglProgram *user_program
1295 = _cogl_program_pointer_from_handle (w->settings.user_program);
1296 const char *uniform_name;
1298 for (i = 0; i < COGL_PROGRAM_NUM_CUSTOM_UNIFORMS; i++)
1299 if ((dirty_custom_uniforms & (1 << i))
1300 && (uniform_name = user_program->custom_uniform_names[i]))
1302 if (program->custom_gl_uniforms[i]
1303 == COGL_PROGRAM_UNBOUND_CUSTOM_UNIFORM)
1304 program->custom_gl_uniforms[i]
1305 = glGetUniformLocation (program->program, uniform_name);
1306 if (program->custom_gl_uniforms[i] >= 0)
1307 cogl_gles2_do_set_uniform (program->custom_gl_uniforms[i],
1308 &user_program->custom_uniforms[i]);
1310 user_program->dirty_custom_uniforms = 0;
1314 if (w->dirty_attribute_pointers
1315 & COGL_GLES2_DIRTY_TEX_COORD_VERTEX_ATTRIB)
1319 /* TODO - coverage test */
1320 for (i = 0; i < COGL_GLES2_MAX_TEXTURE_UNITS; i++)
1321 if (COGL_GLES2_TEXTURE_UNIT_IS_ENABLED (w->settings.texture_units, i))
1323 GLint tex_coord_var_index;
1324 CoglGles2WrapperTextureUnit *texture_unit;
1326 texture_unit = w->texture_units + i;
1327 if (!texture_unit->texture_coords_enabled)
1330 /* TODO - we should probably have a per unit dirty flag too */
1332 /* TODO - coverage test */
1333 tex_coord_var_index = program->attributes.multi_texture_coords[i];
1334 glVertexAttribPointer (tex_coord_var_index,
1335 texture_unit->texture_coords_size,
1336 texture_unit->texture_coords_type,
1338 texture_unit->texture_coords_stride,
1339 texture_unit->texture_coords_pointer);
1343 if (w->dirty_vertex_attrib_enables)
1347 /* TODO - coverage test */
1349 /* TODO - we should probably have a per unit dirty flag too */
1351 for (i = 0; i < COGL_GLES2_MAX_TEXTURE_UNITS; i++)
1353 CoglGles2WrapperTextureUnit *texture_unit = w->texture_units + i;
1354 GLint attrib = program->attributes.multi_texture_coords[i];
1358 if (texture_unit->texture_coords_enabled)
1359 glEnableVertexAttribArray (attrib);
1361 glDisableVertexAttribArray (attrib);
1365 w->dirty_vertex_attrib_enables = 0;
1370 _cogl_wrap_glDrawArrays (GLenum mode, GLint first, GLsizei count)
1372 _cogl_wrap_prepare_for_draw ();
1374 glDrawArrays (mode, first, count);
1378 _cogl_wrap_glDrawElements (GLenum mode, GLsizei count, GLenum type,
1379 const GLvoid *indices)
1381 _cogl_wrap_prepare_for_draw ();
1383 glDrawElements (mode, count, type, indices);
1387 _cogl_wrap_glTexEnvi (GLenum target, GLenum pname, GLint param)
1389 CoglGles2WrapperTexEnv *tex_env;
1391 _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
1393 tex_env = w->settings.tex_env + w->active_texture_unit;
1395 if (target == GL_TEXTURE_ENV)
1399 case GL_COMBINE_RGB:
1400 tex_env->texture_combine_rgb_func = param;
1402 case GL_COMBINE_ALPHA:
1403 tex_env->texture_combine_alpha_func = param;
1408 tex_env->texture_combine_rgb_src[pname - GL_SRC0_RGB] = param;
1413 tex_env->texture_combine_alpha_src[pname - GL_SRC0_ALPHA] = param;
1415 case GL_OPERAND0_RGB:
1416 case GL_OPERAND1_RGB:
1417 case GL_OPERAND2_RGB:
1418 tex_env->texture_combine_rgb_op[pname - GL_OPERAND0_RGB] = param;
1420 case GL_OPERAND0_ALPHA:
1421 case GL_OPERAND1_ALPHA:
1422 case GL_OPERAND2_ALPHA:
1423 tex_env->texture_combine_alpha_op[pname - GL_OPERAND0_ALPHA] = param;
1427 w->settings_dirty = TRUE;
1429 else if (target == GL_POINT_SPRITE)
1433 case GL_COORD_REPLACE:
1434 tex_env->point_sprite_coords = param;
1438 w->settings_dirty = TRUE;
1443 _cogl_wrap_glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params)
1445 if (target == GL_TEXTURE_ENV && pname == GL_TEXTURE_ENV_COLOR)
1447 CoglGles2WrapperTexEnv *tex_env;
1449 _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
1451 tex_env = w->settings.tex_env + w->active_texture_unit;
1453 memcpy (tex_env->texture_combine_constant, params, sizeof (GLfloat) * 4);
1458 _cogl_wrap_glClientActiveTexture (GLenum texture)
1460 int texture_unit_index = texture - GL_TEXTURE0;
1461 _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
1463 if (texture_unit_index < COGL_GLES2_MAX_TEXTURE_UNITS)
1464 w->active_client_texture_unit = texture_unit_index;
1468 _cogl_wrap_glActiveTexture (GLenum texture)
1470 int texture_unit_index = texture - GL_TEXTURE0;
1471 _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
1473 glActiveTexture (texture);
1475 if (texture_unit_index < COGL_GLES2_MAX_TEXTURE_UNITS)
1476 w->active_texture_unit = texture_unit_index;
1480 _cogl_wrap_glEnable (GLenum cap)
1482 _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
1487 case GL_TEXTURE_3D_OES:
1488 if (!COGL_GLES2_TEXTURE_UNIT_IS_ENABLED (w->settings.texture_units,
1489 w->active_texture_unit))
1491 COGL_GLES2_TEXTURE_UNIT_SET_ENABLED (w->settings.texture_units,
1492 w->active_texture_unit,
1494 w->settings_dirty = TRUE;
1496 /* Keep track of the last enabled texture unit */
1497 if (w->settings.tex_env[w->active_texture_unit].texture_target != cap)
1499 w->settings.tex_env[w->active_texture_unit].texture_target = cap;
1500 w->settings_dirty = TRUE;
1505 _COGL_GLES2_CHANGE_SETTING (w, fog_enabled, TRUE);
1509 _COGL_GLES2_CHANGE_SETTING (w, alpha_test_enabled, TRUE);
1518 _cogl_wrap_glDisable (GLenum cap)
1520 _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
1525 case GL_TEXTURE_3D_OES:
1526 /* If this was the last enabled texture target then we'll
1527 completely disable the unit */
1528 if (COGL_GLES2_TEXTURE_UNIT_IS_ENABLED (w->settings.texture_units,
1529 w->active_texture_unit) &&
1530 w->settings.tex_env[w->active_texture_unit].texture_target == cap)
1532 COGL_GLES2_TEXTURE_UNIT_SET_ENABLED (w->settings.texture_units,
1533 w->active_texture_unit,
1535 w->settings_dirty = TRUE;
1540 _COGL_GLES2_CHANGE_SETTING (w, fog_enabled, FALSE);
1544 _COGL_GLES2_CHANGE_SETTING (w, alpha_test_enabled, FALSE);
1553 _cogl_wrap_glEnableClientState (GLenum array)
1555 CoglGles2WrapperTextureUnit *texture_unit;
1556 _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
1560 case GL_VERTEX_ARRAY:
1561 glEnableVertexAttribArray (COGL_GLES2_WRAPPER_VERTEX_ATTRIB);
1563 case GL_TEXTURE_COORD_ARRAY:
1564 /* TODO - review if this should be in w->settings? */
1566 texture_unit = w->texture_units + w->active_client_texture_unit;
1567 if (texture_unit->texture_coords_enabled != 1)
1569 texture_unit->texture_coords_enabled = 1;
1570 w->dirty_vertex_attrib_enables
1571 |= COGL_GLES2_DIRTY_TEX_COORD_ATTRIB_ENABLES;
1574 case GL_COLOR_ARRAY:
1575 glEnableVertexAttribArray (COGL_GLES2_WRAPPER_COLOR_ATTRIB);
1577 case GL_NORMAL_ARRAY:
1578 glEnableVertexAttribArray (COGL_GLES2_WRAPPER_NORMAL_ATTRIB);
1584 _cogl_wrap_glDisableClientState (GLenum array)
1586 CoglGles2WrapperTextureUnit *texture_unit;
1587 _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
1591 case GL_VERTEX_ARRAY:
1592 glDisableVertexAttribArray (COGL_GLES2_WRAPPER_VERTEX_ATTRIB);
1594 case GL_TEXTURE_COORD_ARRAY:
1596 texture_unit = w->texture_units + w->active_texture_unit;
1597 /* TODO - review if this should be in w->settings? */
1598 if (texture_unit->texture_coords_enabled != 0)
1600 texture_unit->texture_coords_enabled = 0;
1601 w->dirty_vertex_attrib_enables
1602 |= COGL_GLES2_DIRTY_TEX_COORD_ATTRIB_ENABLES;
1605 case GL_COLOR_ARRAY:
1606 glDisableVertexAttribArray (COGL_GLES2_WRAPPER_COLOR_ATTRIB);
1608 case GL_NORMAL_ARRAY:
1609 glDisableVertexAttribArray (COGL_GLES2_WRAPPER_NORMAL_ATTRIB);
1615 _cogl_wrap_glAlphaFunc (GLenum func, GLclampf ref)
1617 _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
1621 else if (ref > 1.0f)
1624 _COGL_GLES2_CHANGE_SETTING (w, alpha_test_func, func);
1625 _COGL_GLES2_CHANGE_UNIFORM (w, ALPHA_TEST_REF, alpha_test_ref, ref);
1629 _cogl_wrap_glColor4f (GLclampf r, GLclampf g, GLclampf b, GLclampf a)
1631 glVertexAttrib4f (COGL_GLES2_WRAPPER_COLOR_ATTRIB, r, g, b, a);
1635 _cogl_wrap_glColor4ub (GLubyte r, GLubyte g, GLubyte b, GLubyte a)
1637 glVertexAttrib4f (COGL_GLES2_WRAPPER_COLOR_ATTRIB,
1638 r/255.0, g/255.0, b/255.0, a/255.0);
1642 _cogl_wrap_glClipPlanef (GLenum plane, GLfloat *equation)
1648 _cogl_wrap_glGetIntegerv (GLenum pname, GLint *params)
1650 _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
1654 case GL_MAX_CLIP_PLANES:
1658 case GL_MATRIX_MODE:
1659 *params = w->matrix_mode;
1662 case GL_MAX_TEXTURE_UNITS:
1663 glGetIntegerv (GL_MAX_TEXTURE_IMAGE_UNITS, params);
1664 if (*params > COGL_GLES2_MAX_TEXTURE_UNITS)
1665 *params = COGL_GLES2_MAX_TEXTURE_UNITS;
1669 glGetIntegerv (pname, params);
1675 _cogl_wrap_glGetFloatv (GLenum pname, GLfloat *params)
1677 CoglGles2WrapperTextureUnit *texture_unit;
1679 _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
1683 case GL_MODELVIEW_MATRIX:
1684 memcpy (params, &w->modelview_matrix, sizeof (GLfloat) * 16);
1687 case GL_PROJECTION_MATRIX:
1688 memcpy (params, &w->projection_matrix, sizeof (GLfloat) * 16);
1691 case GL_TEXTURE_MATRIX:
1692 texture_unit = w->texture_units + w->active_texture_unit;
1693 memcpy (params, &texture_unit->texture_matrix, sizeof (GLfloat) * 16);
1697 glGetFloatv (GL_VIEWPORT, params);
1703 _cogl_wrap_glFogf (GLenum pname, GLfloat param)
1705 _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
1710 _COGL_GLES2_CHANGE_SETTING (w, fog_mode, param);
1713 case GL_FOG_DENSITY:
1714 _COGL_GLES2_CHANGE_UNIFORM (w, FOG_DENSITY, fog_density,
1719 _COGL_GLES2_CHANGE_UNIFORM (w, FOG_START, fog_start,
1724 _COGL_GLES2_CHANGE_UNIFORM (w, FOG_END, fog_end,
1731 _cogl_wrap_glFogfv (GLenum pname, const GLfloat *params)
1734 _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
1736 if (pname == GL_FOG_COLOR)
1738 for (i = 0; i < 4; i++)
1739 w->fog_color[i] = (params[i]);
1741 w->dirty_uniforms |= COGL_GLES2_DIRTY_FOG_COLOR;
1746 _cogl_wrap_glTexParameteri (GLenum target, GLenum pname, GLfloat param)
1748 if (pname != GL_GENERATE_MIPMAP)
1749 glTexParameteri (target, pname, param);
1753 _cogl_wrap_glMaterialfv (GLenum face, GLenum pname, const GLfloat *params)
1755 /* FIXME: the GLES 2 backend doesn't yet support lighting so this
1756 function can't do anything */
1760 _cogl_wrap_glPointSize (GLfloat size)
1762 _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
1764 w->point_size = size;
1765 w->dirty_uniforms |= COGL_GLES2_DIRTY_POINT_SIZE;
1769 _cogl_gles2_clear_cache_for_program (CoglHandle user_program)
1771 GSList *node, *next, *last = NULL;
1772 CoglGles2WrapperProgram *program;
1774 _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
1776 /* Remove any cached programs that link against this custom program */
1777 for (node = w->compiled_programs; node; node = next)
1780 program = (CoglGles2WrapperProgram *) node->data;
1782 if (program->settings.user_program == user_program)
1784 glDeleteProgram (program->program);
1789 w->compiled_programs = next;
1791 g_slist_free1 (node);