mirror of
https://github.com/brl/mutter.git
synced 2024-11-23 16:40:41 -05:00
b0df99fbad
Previously the texture unit settings were stored in growable GArrays and every time a new texture unit was encountered it would expand the arrays. However the array wasn't copied when stored in a CoglGles2WrapperSettings struct so all settings had the same array. This meant that it wouldn't detect that a different program is needed if a texture unit is disabled or enabled. The texture unit settings arrays are all now a fixed size and the enabledness of each unit is stored in a bit mask. Therefore the settings can just be copied around by assignment as before. This puts a limit on the number of texture units accessible by Cogl but I think it is worth it to make the code simpler and more efficient. The material API already poses a limit on the number of texture units it can use.
424 lines
15 KiB
C
424 lines
15 KiB
C
/*
|
|
* Clutter COGL
|
|
*
|
|
* A basic GL/GLES Abstraction/Utility Layer
|
|
*
|
|
* Authored By Matthew Allum <mallum@openedhand.com>
|
|
*
|
|
* Copyright (C) 2008 OpenedHand
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
* Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#ifndef __COGL_GLES2_WRAPPER_H__
|
|
#define __COGL_GLES2_WRAPPER_H__
|
|
|
|
#include "cogl-internal.h"
|
|
|
|
G_BEGIN_DECLS
|
|
|
|
#ifdef HAVE_COGL_GLES2
|
|
|
|
typedef struct _CoglGles2Wrapper CoglGles2Wrapper;
|
|
typedef struct _CoglGles2WrapperTextureUnit
|
|
CoglGles2WrapperTextureUnit;
|
|
|
|
typedef struct _CoglGles2WrapperAttributes CoglGles2WrapperAttributes;
|
|
typedef struct _CoglGles2WrapperUniforms CoglGles2WrapperUniforms;
|
|
typedef struct _CoglGles2WrapperTextureUnitSettings
|
|
CoglGles2WrapperTextureUnitSettings;
|
|
typedef struct _CoglGles2WrapperSettings CoglGles2WrapperSettings;
|
|
typedef struct _CoglGles2WrapperProgram CoglGles2WrapperProgram;
|
|
typedef struct _CoglGles2WrapperShader CoglGles2WrapperShader;
|
|
|
|
#define COGL_GLES2_NUM_CUSTOM_UNIFORMS 16
|
|
#define COGL_GLES2_UNBOUND_CUSTOM_UNIFORM -2
|
|
|
|
/* Must be a power of two */
|
|
#define COGL_GLES2_MODELVIEW_STACK_SIZE 32
|
|
#define COGL_GLES2_PROJECTION_STACK_SIZE 2
|
|
#define COGL_GLES2_TEXTURE_STACK_SIZE 2
|
|
|
|
/* Accessors for the texture unit bit mask */
|
|
#define COGL_GLES2_TEXTURE_UNIT_IS_ENABLED(mask, unit) \
|
|
(((mask) & (1 << ((unit) * 2))) ? TRUE : FALSE)
|
|
#define COGL_GLES2_TEXTURE_UNIT_IS_ALPHA_ONLY(mask, unit) \
|
|
(((mask) & (1 << ((unit) * 2 + 1))) ? TRUE : FALSE)
|
|
#define COGL_GLES2_SET_BIT(mask, bit, val) \
|
|
((val) ? ((mask) |= (1 << (bit))) : ((mask) &= ~(1 << (bit))))
|
|
#define COGL_GLES2_TEXTURE_UNIT_SET_ENABLED(mask, unit, val) \
|
|
COGL_GLES2_SET_BIT ((mask), (unit) * 2, (val))
|
|
#define COGL_GLES2_TEXTURE_UNIT_SET_ALPHA_ONLY(mask, unit, val) \
|
|
COGL_GLES2_SET_BIT ((mask), (unit) * 2 + 1, (val))
|
|
|
|
#define COGL_GLES2_MAX_TEXTURE_UNITS (sizeof (guint32) * 8 / 2)
|
|
|
|
/* Dirty flags for shader uniforms */
|
|
enum
|
|
{
|
|
COGL_GLES2_DIRTY_MVP_MATRIX = 1 << 0,
|
|
COGL_GLES2_DIRTY_MODELVIEW_MATRIX = 1 << 1,
|
|
COGL_GLES2_DIRTY_TEXTURE_MATRICES = 1 << 2,
|
|
COGL_GLES2_DIRTY_FOG_DENSITY = 1 << 3,
|
|
COGL_GLES2_DIRTY_FOG_START = 1 << 4,
|
|
COGL_GLES2_DIRTY_FOG_END = 1 << 5,
|
|
COGL_GLES2_DIRTY_FOG_COLOR = 1 << 6,
|
|
COGL_GLES2_DIRTY_ALPHA_TEST_REF = 1 << 7,
|
|
COGL_GLES2_DIRTY_TEXTURE_UNITS = 1 << 8,
|
|
|
|
COGL_GLES2_DIRTY_ALL = (1 << 9) - 1
|
|
};
|
|
|
|
/* Dirty flags for shader vertex attribute pointers */
|
|
enum
|
|
{
|
|
COGL_GLES2_DIRTY_TEX_COORD_VERTEX_ATTRIB = 1 << 0
|
|
};
|
|
|
|
/* Dirty flags for shader vertex attributes enabled status */
|
|
enum
|
|
{
|
|
COGL_GLES2_DIRTY_TEX_COORD_ATTRIB_ENABLES = 1 << 0
|
|
};
|
|
|
|
struct _CoglGles2WrapperAttributes
|
|
{
|
|
GLint multi_texture_coords[COGL_GLES2_MAX_TEXTURE_UNITS];
|
|
};
|
|
|
|
struct _CoglGles2WrapperUniforms
|
|
{
|
|
GLint mvp_matrix_uniform;
|
|
GLint modelview_matrix_uniform;
|
|
GLint texture_matrix_uniforms[COGL_GLES2_MAX_TEXTURE_UNITS];
|
|
GLint texture_sampler_uniforms[COGL_GLES2_MAX_TEXTURE_UNITS];
|
|
|
|
GLint fog_density_uniform;
|
|
GLint fog_start_uniform;
|
|
GLint fog_end_uniform;
|
|
GLint fog_color_uniform;
|
|
|
|
GLint alpha_test_ref_uniform;
|
|
|
|
GLint texture_unit_uniform;
|
|
};
|
|
|
|
/* NB: We get a copy of this for each fragment/vertex
|
|
* program varient we generate so we try to keep it
|
|
* fairly lean */
|
|
struct _CoglGles2WrapperSettings
|
|
{
|
|
guint32 texture_units;
|
|
|
|
GLint alpha_test_func;
|
|
GLint fog_mode;
|
|
|
|
/* The current in-use user program */
|
|
CoglHandle user_program;
|
|
|
|
guint alpha_test_enabled:1;
|
|
guint fog_enabled:1;
|
|
};
|
|
|
|
struct _CoglGles2WrapperTextureUnit
|
|
{
|
|
GLfloat texture_stack[COGL_GLES2_TEXTURE_STACK_SIZE * 16];
|
|
GLuint texture_stack_pos;
|
|
|
|
GLenum texture_coords_type;
|
|
GLint texture_coords_size;
|
|
GLsizei texture_coords_stride;
|
|
const void *texture_coords_pointer;
|
|
|
|
guint texture_coords_enabled:1;
|
|
guint dirty_matrix:1; /*!< shader uniform needs updating */
|
|
};
|
|
|
|
struct _CoglGles2Wrapper
|
|
{
|
|
GLuint matrix_mode;
|
|
GLfloat modelview_stack[COGL_GLES2_MODELVIEW_STACK_SIZE * 16];
|
|
GLuint modelview_stack_pos;
|
|
GLfloat projection_stack[COGL_GLES2_PROJECTION_STACK_SIZE * 16];
|
|
GLuint projection_stack_pos;
|
|
guint active_texture_unit;
|
|
guint active_client_texture_unit;
|
|
|
|
CoglGles2WrapperTextureUnit texture_units[COGL_GLES2_MAX_TEXTURE_UNITS];
|
|
|
|
/* The combined modelview and projection matrix is only updated at
|
|
the last minute in glDrawArrays to avoid recalculating it for
|
|
every change to the modelview matrix */
|
|
GLboolean mvp_uptodate;
|
|
|
|
/* The currently bound program */
|
|
CoglGles2WrapperProgram *current_program;
|
|
|
|
/* The current settings. Effectively these represent anything that
|
|
* will require a modified fixed function shader */
|
|
CoglGles2WrapperSettings settings;
|
|
/* Whether the settings have changed since the last draw */
|
|
gboolean settings_dirty;
|
|
/* Uniforms that have changed since the last draw */
|
|
int dirty_uniforms, dirty_custom_uniforms;
|
|
|
|
/* Attribute pointers that have changed since the last draw */
|
|
int dirty_attribute_pointers;
|
|
|
|
/* Vertex attribute pointer enables that have changed since the last draw */
|
|
int dirty_vertex_attrib_enables;
|
|
|
|
/* List of all compiled program combinations */
|
|
GSList *compiled_programs;
|
|
|
|
/* List of all compiled vertex shaders */
|
|
GSList *compiled_vertex_shaders;
|
|
|
|
/* List of all compiled fragment shaders */
|
|
GSList *compiled_fragment_shaders;
|
|
|
|
/* Values for the uniforms */
|
|
GLfloat alpha_test_ref;
|
|
GLfloat fog_density;
|
|
GLfloat fog_start;
|
|
GLfloat fog_end;
|
|
GLfloat fog_color[4];
|
|
CoglBoxedValue custom_uniforms[COGL_GLES2_NUM_CUSTOM_UNIFORMS];
|
|
};
|
|
|
|
struct _CoglGles2WrapperProgram
|
|
{
|
|
GLuint program;
|
|
|
|
/* The settings that were used to generate this combination */
|
|
CoglGles2WrapperSettings settings;
|
|
|
|
/* The attributes for this program that are not bound up-front
|
|
* with constant indices */
|
|
CoglGles2WrapperAttributes attributes;
|
|
|
|
/* The uniforms for this program */
|
|
CoglGles2WrapperUniforms uniforms;
|
|
GLint custom_uniforms[COGL_GLES2_NUM_CUSTOM_UNIFORMS];
|
|
};
|
|
|
|
struct _CoglGles2WrapperShader
|
|
{
|
|
GLuint shader;
|
|
|
|
/* The settings that were used to generate this shader */
|
|
CoglGles2WrapperSettings settings;
|
|
};
|
|
|
|
/* These defines are missing from GL ES 2 but we can still use them
|
|
with the wrapper functions */
|
|
|
|
#ifndef GL_MODELVIEW
|
|
|
|
#define GL_MODELVIEW 0x1700
|
|
#define GL_PROJECTION 0x1701
|
|
|
|
#define GL_VERTEX_ARRAY 0x8074
|
|
#define GL_TEXTURE_COORD_ARRAY 0x8078
|
|
#define GL_COLOR_ARRAY 0x8076
|
|
#define GL_NORMAL_ARRAY 0x8075
|
|
|
|
#define GL_LIGHTING 0x0B50
|
|
#define GL_ALPHA_TEST 0x0BC0
|
|
|
|
#define GL_FOG 0x0B60
|
|
#define GL_FOG_COLOR 0x0B66
|
|
#define GL_FOG_MODE 0x0B65
|
|
#define GL_FOG_HINT 0x0C54
|
|
#define GL_FOG_DENSITY 0x0B62
|
|
#define GL_FOG_START 0x0B63
|
|
#define GL_FOG_END 0x0B64
|
|
|
|
#define GL_CLIP_PLANE0 0x3000
|
|
#define GL_CLIP_PLANE1 0x3001
|
|
#define GL_CLIP_PLANE2 0x3002
|
|
#define GL_CLIP_PLANE3 0x3003
|
|
#define GL_MAX_CLIP_PLANES 0x0D32
|
|
|
|
#define GL_MODELVIEW_MATRIX 0x0BA6
|
|
#define GL_PROJECTION_MATRIX 0x0BA7
|
|
|
|
#define GL_GENERATE_MIPMAP 0x8191
|
|
|
|
#define GL_TEXTURE_ENV 0x2300
|
|
#define GL_TEXTURE_ENV_MODE 0x2200
|
|
#define GL_MODULATE 0x2100
|
|
|
|
#define GL_EXP 0x8000
|
|
#define GL_EXP2 0x8001
|
|
|
|
#define GL_ADD CGL_ADD
|
|
#define GL_ADD_SIGNED CGL_ADD_SIGNED
|
|
#define GL_INTERPOLATE CGL_INTERPOLATE
|
|
#define GL_SUBTRACT CGL_SUBTRACT
|
|
#define GL_DOT3_RGB CGL_DOT3_RGB
|
|
#define GL_DOT3_RGBA CGL_DOT3_RGBA
|
|
#define GL_CONSTANT CGL_CONSTANT
|
|
#define GL_PRIMARY_COLOR CGL_PRIMARY_COLOR
|
|
#define GL_PREVIOUS CGL_PREVIOUS
|
|
#define GL_COMBINE CGL_COMBINE
|
|
#define GL_COMBINE_RGB CGL_COMBINE_RGB
|
|
#define GL_COMBINE_ALPHA CGL_COMBINE_ALPHA
|
|
#define GL_SRC0_RGB CGL_SRC0_RGB
|
|
#define GL_OPERAND0_RGB CGL_OPERAND0_RGB
|
|
#define GL_SRC1_RGB CGL_SRC1_RGB
|
|
#define GL_OPERAND1_RGB CGL_OPERAND1_RGB
|
|
#define GL_SRC2_RGB CGL_SRC2_RGB
|
|
#define GL_OPERAND2_RGB CGL_OPERAND2_RGB
|
|
#define GL_SRC0_ALPHA CGL_SRC0_ALPHA
|
|
#define GL_OPERAND0_ALPHA CGL_OPERAND0_ALPHA
|
|
#define GL_SRC1_ALPHA CGL_SRC1_ALPHA
|
|
#define GL_OPERAND1_ALPHA CGL_OPERAND1_ALPHA
|
|
#define GL_SRC2_ALPHA CGL_SRC2_ALPHA
|
|
#define GL_OPERAND2_ALPHA CGL_OPERAND2_ALPHA
|
|
#define GL_AMBIENT CGL_AMBIENT
|
|
#define GL_DIFFUSE CGL_DIFFUSE
|
|
#define GL_SPECULAR CGL_SPECULAR
|
|
#define GL_EMISSION CGL_EMISSION
|
|
#define GL_SHININESS CGL_SHININESS
|
|
|
|
#endif /* GL_MODELVIEW */
|
|
|
|
void cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper);
|
|
void cogl_gles2_wrapper_deinit (CoglGles2Wrapper *wrapper);
|
|
|
|
void cogl_wrap_glPushMatrix ();
|
|
void cogl_wrap_glPopMatrix ();
|
|
void cogl_wrap_glMatrixMode (GLenum mode);
|
|
void cogl_wrap_glLoadIdentity ();
|
|
void cogl_wrap_glMultMatrixf (const GLfloat *m);
|
|
void cogl_wrap_glLoadMatrixf (const GLfloat *m);
|
|
void cogl_wrap_glFrustumf (GLfloat left, GLfloat right,
|
|
GLfloat bottom, GLfloat top,
|
|
GLfloat z_near, GLfloat z_far);
|
|
void cogl_wrap_glScalef (GLfloat x, GLfloat y, GLfloat z);
|
|
void cogl_wrap_glTranslatef (GLfloat x, GLfloat y, GLfloat z);
|
|
void cogl_wrap_glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
|
|
void cogl_wrap_glOrthof (GLfloat left, GLfloat right,
|
|
GLfloat bottom, GLfloat top,
|
|
GLfloat near, GLfloat far);
|
|
|
|
void cogl_wrap_glEnable (GLenum cap);
|
|
void cogl_wrap_glDisable (GLenum cap);
|
|
|
|
void cogl_wrap_glTexCoordPointer (GLint size, GLenum type, GLsizei stride,
|
|
const GLvoid *pointer);
|
|
void cogl_wrap_glVertexPointer (GLint size, GLenum type, GLsizei stride,
|
|
const GLvoid *pointer);
|
|
void cogl_wrap_glColorPointer (GLint size, GLenum type, GLsizei stride,
|
|
const GLvoid *pointer);
|
|
void cogl_wrap_glNormalPointer (GLenum type, GLsizei stride,
|
|
const GLvoid *pointer);
|
|
|
|
void cogl_wrap_glTexEnvi (GLenum target, GLenum pname, GLfloat param);
|
|
|
|
void cogl_wrap_glClientActiveTexture (GLenum texture);
|
|
void cogl_wrap_glActiveTexture (GLenum texture);
|
|
|
|
void cogl_wrap_glEnableClientState (GLenum array);
|
|
void cogl_wrap_glDisableClientState (GLenum array);
|
|
|
|
void cogl_wrap_glAlphaFunc (GLenum func, GLclampf ref);
|
|
|
|
void cogl_wrap_glColor4f (GLclampf r, GLclampf g, GLclampf b, GLclampf a);
|
|
|
|
void cogl_wrap_glClipPlanef (GLenum plane, GLfloat *equation);
|
|
|
|
void cogl_wrap_glGetIntegerv (GLenum pname, GLint *params);
|
|
void cogl_wrap_glGetFloatv (GLenum pname, GLfloat *params);
|
|
|
|
void cogl_wrap_glFogf (GLenum pname, GLfloat param);
|
|
void cogl_wrap_glFogfv (GLenum pname, const GLfloat *params);
|
|
|
|
void cogl_wrap_glDrawArrays (GLenum mode, GLint first, GLsizei count);
|
|
void cogl_wrap_glDrawElements (GLenum mode, GLsizei count, GLenum type,
|
|
const GLvoid *indices);
|
|
void cogl_wrap_glTexParameteri (GLenum target, GLenum pname, GLfloat param);
|
|
|
|
void cogl_gles2_wrapper_bind_texture (GLenum target, GLuint texture,
|
|
GLenum internal_format);
|
|
|
|
void cogl_wrap_glMaterialfv (GLenum face, GLenum pname, const GLfloat *params);
|
|
|
|
/* This function is only available on GLES 2 */
|
|
#define cogl_wrap_glGenerateMipmap glGenerateMipmap
|
|
|
|
void _cogl_gles2_clear_cache_for_program (CoglHandle program);
|
|
|
|
/* Remap the missing GL functions to use the wrappers */
|
|
#ifndef COGL_GLES2_WRAPPER_NO_REMAP
|
|
#define glDrawArrays cogl_wrap_glDrawArrays
|
|
#define glDrawElements cogl_wrap_glDrawElements
|
|
#define glPushMatrix cogl_wrap_glPushMatrix
|
|
#define glPopMatrix cogl_wrap_glPopMatrix
|
|
#define glMatrixMode cogl_wrap_glMatrixMode
|
|
#define glLoadIdentity cogl_wrap_glLoadIdentity
|
|
#define glMultMatrixf cogl_wrap_glMultMatrixf
|
|
#define glLoadMatrixf cogl_wrap_glLoadMatrixf
|
|
#define glFrustumf cogl_wrap_glFrustumf
|
|
#define glScalef cogl_wrap_glScalef
|
|
#define glTranslatef cogl_wrap_glTranslatef
|
|
#define glRotatef cogl_wrap_glRotatef
|
|
#define glOrthof cogl_wrap_glOrthof
|
|
#define glEnable cogl_wrap_glEnable
|
|
#define glDisable cogl_wrap_glDisable
|
|
#define glTexCoordPointer cogl_wrap_glTexCoordPointer
|
|
#define glVertexPointer cogl_wrap_glVertexPointer
|
|
#define glColorPointer cogl_wrap_glColorPointer
|
|
#define glNormalPointer cogl_wrap_glNormalPointer
|
|
#define glTexEnvi cogl_wrap_glTexEnvi
|
|
#define glActiveTexture cogl_wrap_glActiveTexture
|
|
#define glClientActiveTexture cogl_wrap_glClientActiveTexture
|
|
#define glEnableClientState cogl_wrap_glEnableClientState
|
|
#define glDisableClientState cogl_wrap_glDisableClientState
|
|
#define glAlphaFunc cogl_wrap_glAlphaFunc
|
|
#define glColor4f cogl_wrap_glColor4f
|
|
#define glClipPlanef cogl_wrap_glClipPlanef
|
|
#define glGetIntegerv cogl_wrap_glGetIntegerv
|
|
#define glGetFloatv cogl_wrap_glGetFloatv
|
|
#define glFogf cogl_wrap_glFogf
|
|
#define glFogfv cogl_wrap_glFogfv
|
|
#define glTexParameteri cogl_wrap_glTexParameteri
|
|
#define glMaterialfv cogl_wrap_glMaterialfv
|
|
#endif /* COGL_GLES2_WRAPPER_NO_REMAP */
|
|
|
|
#else /* HAVE_COGL_GLES2 */
|
|
|
|
/* The extra third parameter of the bind texture wrapper isn't needed
|
|
so we can just directly call glBindTexture */
|
|
#define cogl_gles2_wrapper_bind_texture(target, texture, internal_format) \
|
|
glBindTexture ((target), (texture))
|
|
|
|
/* COGL uses the automatic mipmap generation for GLES 1 so
|
|
glGenerateMipmap doesn't need to do anything */
|
|
#define cogl_wrap_glGenerateMipmap(x) ((void) 0)
|
|
|
|
/* GLES doesn't have glDrawRangeElements, so we simply pretend it does
|
|
* but that it makes no use of the start, end constraints: */
|
|
#define glDrawRangeElements(mode, start, end, count, type, indices) \
|
|
glDrawElements (mode, count, type, indices)
|
|
|
|
#endif /* HAVE_COGL_GLES2 */
|
|
|
|
G_END_DECLS
|
|
|
|
#endif /* __COGL_GLES2_WRAPPER_H__ */
|