2008-04-25 13:37:36 +00:00
|
|
|
/*
|
2009-04-27 14:48:12 +00:00
|
|
|
* Cogl
|
2008-04-25 13:37:36 +00:00
|
|
|
*
|
2009-04-27 14:48:12 +00:00
|
|
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
2008-04-25 13:37:36 +00:00
|
|
|
*
|
2009-04-27 14:48:12 +00:00
|
|
|
* Copyright (C) 2007,2008,2009 Intel Corporation.
|
2008-04-25 13:37:36 +00:00
|
|
|
*
|
|
|
|
* 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_TEXTURE_H
|
|
|
|
#define __COGL_TEXTURE_H
|
|
|
|
|
2009-04-30 17:00:22 +00:00
|
|
|
#include "cogl-bitmap-private.h"
|
2009-04-01 16:16:44 +00:00
|
|
|
#include "cogl-handle.h"
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 17:46:42 +00:00
|
|
|
#include "cogl-material-private.h"
|
2008-04-25 13:37:36 +00:00
|
|
|
|
Fully integrates CoglMaterial throughout the rest of Cogl
This glues CoglMaterial in as the fundamental way that Cogl describes how to
fill in geometry.
It adds cogl_set_source (), which is used to set the material which will be
used by all subsequent drawing functions
It adds cogl_set_source_texture as a convenience for setting up a default
material with a single texture layer, and cogl_set_source_color is now also
a convenience for setting up a material with a solid fill.
"drawing functions" include, cogl_rectangle, cogl_texture_rectangle,
cogl_texture_multiple_rectangles, cogl_texture_polygon (though the
cogl_texture_* funcs have been renamed; see below for details),
cogl_path_fill/stroke and cogl_vertex_buffer_draw*.
cogl_texture_rectangle, cogl_texture_multiple_rectangles and
cogl_texture_polygon no longer take a texture handle; instead the current
source material is referenced. The functions have also been renamed to:
cogl_rectangle_with_texture_coords, cogl_rectangles_with_texture_coords
and cogl_polygon respectivly.
Most code that previously did:
cogl_texture_rectangle (tex_handle, x, y,...);
needs to be changed to now do:
cogl_set_source_texture (tex_handle);
cogl_rectangle_with_texture_coords (x, y,....);
In the less likely case where you were blending your source texture with a color
like:
cogl_set_source_color4ub (r,g,b,a); /* where r,g,b,a isn't just white */
cogl_texture_rectangle (tex_handle, x, y,...);
you will need your own material to do that:
mat = cogl_material_new ();
cogl_material_set_color4ub (r,g,b,a);
cogl_material_set_layer (mat, 0, tex_handle));
cogl_set_source_material (mat);
Code that uses the texture coordinates, 0, 0, 1, 1 don't need to use
cog_rectangle_with_texure_coords since these are the coordinates that
cogl_rectangle will use.
For cogl_texture_polygon; as well as dropping the texture handle, the
n_vertices and vertices arguments were transposed for consistency. So
code previously written as:
cogl_texture_polygon (tex_handle, 3, verts, TRUE);
need to be written as:
cogl_set_source_texture (tex_handle);
cogl_polygon (verts, 3, TRUE);
All of the unit tests have been updated to now use the material API and
test-cogl-material has been renamed to test-cogl-multitexture since any
textured quad is now technically a test of CoglMaterial but this test
specifically creates a material with multiple texture layers.
Note: The GLES backend has not been updated yet; that will be done in a
following commit.
2009-01-23 16:15:40 +00:00
|
|
|
typedef struct _CoglTexture CoglTexture;
|
|
|
|
typedef struct _CoglTexSliceSpan CoglTexSliceSpan;
|
|
|
|
typedef struct _CoglSpanIter CoglSpanIter;
|
2009-06-04 15:04:57 +00:00
|
|
|
typedef struct _CoglTexturePixel CoglTexturePixel;
|
2008-04-25 13:37:36 +00:00
|
|
|
|
|
|
|
struct _CoglTexSliceSpan
|
|
|
|
{
|
|
|
|
gint start;
|
|
|
|
gint size;
|
|
|
|
gint waste;
|
|
|
|
};
|
|
|
|
|
2009-03-23 12:29:15 +00:00
|
|
|
struct _CoglSpanIter
|
|
|
|
{
|
|
|
|
gint index;
|
|
|
|
GArray *array;
|
|
|
|
CoglTexSliceSpan *span;
|
|
|
|
float pos;
|
|
|
|
float next_pos;
|
|
|
|
float origin;
|
|
|
|
float cover_start;
|
|
|
|
float cover_end;
|
|
|
|
float intersect_start;
|
|
|
|
float intersect_end;
|
|
|
|
float intersect_start_local;
|
|
|
|
float intersect_end_local;
|
|
|
|
gboolean intersects;
|
|
|
|
};
|
|
|
|
|
2009-06-04 15:04:57 +00:00
|
|
|
/* This is used to store the first pixel of each slice. This is only
|
|
|
|
used when glGenerateMipmap is not available */
|
|
|
|
struct _CoglTexturePixel
|
|
|
|
{
|
|
|
|
/* We need to store the format of the pixel because we store the
|
|
|
|
data in the source format which might end up being different for
|
|
|
|
each slice if a subregion is updated with a different format */
|
|
|
|
GLenum gl_format;
|
|
|
|
GLenum gl_type;
|
|
|
|
guint8 data[4];
|
|
|
|
};
|
|
|
|
|
2008-04-25 13:37:36 +00:00
|
|
|
struct _CoglTexture
|
|
|
|
{
|
2009-04-01 16:16:44 +00:00
|
|
|
CoglHandleObject _parent;
|
2008-04-25 13:37:36 +00:00
|
|
|
CoglBitmap bitmap;
|
|
|
|
gboolean bitmap_owner;
|
|
|
|
GLenum gl_target;
|
|
|
|
GLenum gl_intformat;
|
|
|
|
GLenum gl_format;
|
|
|
|
GLenum gl_type;
|
|
|
|
GArray *slice_x_spans;
|
|
|
|
GArray *slice_y_spans;
|
|
|
|
GArray *slice_gl_handles;
|
|
|
|
gint max_waste;
|
2009-06-04 15:04:57 +00:00
|
|
|
GLenum min_filter;
|
|
|
|
GLenum mag_filter;
|
2008-04-25 13:37:36 +00:00
|
|
|
gboolean is_foreign;
|
|
|
|
GLint wrap_mode;
|
2008-05-07 16:12:54 +00:00
|
|
|
gboolean auto_mipmap;
|
2009-06-04 15:04:57 +00:00
|
|
|
gboolean mipmaps_dirty;
|
|
|
|
|
|
|
|
/* This holds a copy of the first pixel in each slice. It is only
|
|
|
|
used to force an automatic update of the mipmaps when
|
|
|
|
glGenerateMipmap is not available. */
|
|
|
|
CoglTexturePixel *first_pixels;
|
2008-04-25 13:37:36 +00:00
|
|
|
};
|
|
|
|
|
Fully integrates CoglMaterial throughout the rest of Cogl
This glues CoglMaterial in as the fundamental way that Cogl describes how to
fill in geometry.
It adds cogl_set_source (), which is used to set the material which will be
used by all subsequent drawing functions
It adds cogl_set_source_texture as a convenience for setting up a default
material with a single texture layer, and cogl_set_source_color is now also
a convenience for setting up a material with a solid fill.
"drawing functions" include, cogl_rectangle, cogl_texture_rectangle,
cogl_texture_multiple_rectangles, cogl_texture_polygon (though the
cogl_texture_* funcs have been renamed; see below for details),
cogl_path_fill/stroke and cogl_vertex_buffer_draw*.
cogl_texture_rectangle, cogl_texture_multiple_rectangles and
cogl_texture_polygon no longer take a texture handle; instead the current
source material is referenced. The functions have also been renamed to:
cogl_rectangle_with_texture_coords, cogl_rectangles_with_texture_coords
and cogl_polygon respectivly.
Most code that previously did:
cogl_texture_rectangle (tex_handle, x, y,...);
needs to be changed to now do:
cogl_set_source_texture (tex_handle);
cogl_rectangle_with_texture_coords (x, y,....);
In the less likely case where you were blending your source texture with a color
like:
cogl_set_source_color4ub (r,g,b,a); /* where r,g,b,a isn't just white */
cogl_texture_rectangle (tex_handle, x, y,...);
you will need your own material to do that:
mat = cogl_material_new ();
cogl_material_set_color4ub (r,g,b,a);
cogl_material_set_layer (mat, 0, tex_handle));
cogl_set_source_material (mat);
Code that uses the texture coordinates, 0, 0, 1, 1 don't need to use
cog_rectangle_with_texure_coords since these are the coordinates that
cogl_rectangle will use.
For cogl_texture_polygon; as well as dropping the texture handle, the
n_vertices and vertices arguments were transposed for consistency. So
code previously written as:
cogl_texture_polygon (tex_handle, 3, verts, TRUE);
need to be written as:
cogl_set_source_texture (tex_handle);
cogl_polygon (verts, 3, TRUE);
All of the unit tests have been updated to now use the material API and
test-cogl-material has been renamed to test-cogl-multitexture since any
textured quad is now technically a test of CoglMaterial but this test
specifically creates a material with multiple texture layers.
Note: The GLES backend has not been updated yet; that will be done in a
following commit.
2009-01-23 16:15:40 +00:00
|
|
|
/* To improve batching of geometry when submitting vertices to OpenGL we
|
|
|
|
* log the texture rectangles we want to draw to a journal, so when we
|
|
|
|
* later flush the journal we aim to batch data, and gl draw calls. */
|
|
|
|
typedef struct _CoglJournalEntry
|
2008-12-11 15:33:38 +00:00
|
|
|
{
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 17:46:42 +00:00
|
|
|
CoglHandle material;
|
|
|
|
int n_layers;
|
|
|
|
CoglMaterialFlushOptions flush_options;
|
|
|
|
CoglMatrix model_view;
|
|
|
|
/* XXX: These entries are pretty big now considering the padding in
|
|
|
|
* CoglMaterialFlushOptions and CoglMatrix, so we might need to optimize this
|
|
|
|
* later. */
|
Fully integrates CoglMaterial throughout the rest of Cogl
This glues CoglMaterial in as the fundamental way that Cogl describes how to
fill in geometry.
It adds cogl_set_source (), which is used to set the material which will be
used by all subsequent drawing functions
It adds cogl_set_source_texture as a convenience for setting up a default
material with a single texture layer, and cogl_set_source_color is now also
a convenience for setting up a material with a solid fill.
"drawing functions" include, cogl_rectangle, cogl_texture_rectangle,
cogl_texture_multiple_rectangles, cogl_texture_polygon (though the
cogl_texture_* funcs have been renamed; see below for details),
cogl_path_fill/stroke and cogl_vertex_buffer_draw*.
cogl_texture_rectangle, cogl_texture_multiple_rectangles and
cogl_texture_polygon no longer take a texture handle; instead the current
source material is referenced. The functions have also been renamed to:
cogl_rectangle_with_texture_coords, cogl_rectangles_with_texture_coords
and cogl_polygon respectivly.
Most code that previously did:
cogl_texture_rectangle (tex_handle, x, y,...);
needs to be changed to now do:
cogl_set_source_texture (tex_handle);
cogl_rectangle_with_texture_coords (x, y,....);
In the less likely case where you were blending your source texture with a color
like:
cogl_set_source_color4ub (r,g,b,a); /* where r,g,b,a isn't just white */
cogl_texture_rectangle (tex_handle, x, y,...);
you will need your own material to do that:
mat = cogl_material_new ();
cogl_material_set_color4ub (r,g,b,a);
cogl_material_set_layer (mat, 0, tex_handle));
cogl_set_source_material (mat);
Code that uses the texture coordinates, 0, 0, 1, 1 don't need to use
cog_rectangle_with_texure_coords since these are the coordinates that
cogl_rectangle will use.
For cogl_texture_polygon; as well as dropping the texture handle, the
n_vertices and vertices arguments were transposed for consistency. So
code previously written as:
cogl_texture_polygon (tex_handle, 3, verts, TRUE);
need to be written as:
cogl_set_source_texture (tex_handle);
cogl_polygon (verts, 3, TRUE);
All of the unit tests have been updated to now use the material API and
test-cogl-material has been renamed to test-cogl-multitexture since any
textured quad is now technically a test of CoglMaterial but this test
specifically creates a material with multiple texture layers.
Note: The GLES backend has not been updated yet; that will be done in a
following commit.
2009-01-23 16:15:40 +00:00
|
|
|
} CoglJournalEntry;
|
2008-12-11 15:33:38 +00:00
|
|
|
|
2008-04-25 13:37:36 +00:00
|
|
|
CoglTexture*
|
|
|
|
_cogl_texture_pointer_from_handle (CoglHandle handle);
|
|
|
|
|
2009-03-23 12:29:15 +00:00
|
|
|
void
|
|
|
|
_cogl_texture_set_wrap_mode_parameter (CoglTexture *tex,
|
|
|
|
GLenum wrap_mode);
|
|
|
|
|
2009-06-04 15:04:57 +00:00
|
|
|
void
|
|
|
|
_cogl_texture_set_filters (CoglHandle handle,
|
|
|
|
GLenum min_filter,
|
|
|
|
GLenum mag_filter);
|
|
|
|
|
|
|
|
void
|
|
|
|
_cogl_texture_ensure_mipmaps (CoglHandle handle);
|
|
|
|
|
Fully integrates CoglMaterial throughout the rest of Cogl
This glues CoglMaterial in as the fundamental way that Cogl describes how to
fill in geometry.
It adds cogl_set_source (), which is used to set the material which will be
used by all subsequent drawing functions
It adds cogl_set_source_texture as a convenience for setting up a default
material with a single texture layer, and cogl_set_source_color is now also
a convenience for setting up a material with a solid fill.
"drawing functions" include, cogl_rectangle, cogl_texture_rectangle,
cogl_texture_multiple_rectangles, cogl_texture_polygon (though the
cogl_texture_* funcs have been renamed; see below for details),
cogl_path_fill/stroke and cogl_vertex_buffer_draw*.
cogl_texture_rectangle, cogl_texture_multiple_rectangles and
cogl_texture_polygon no longer take a texture handle; instead the current
source material is referenced. The functions have also been renamed to:
cogl_rectangle_with_texture_coords, cogl_rectangles_with_texture_coords
and cogl_polygon respectivly.
Most code that previously did:
cogl_texture_rectangle (tex_handle, x, y,...);
needs to be changed to now do:
cogl_set_source_texture (tex_handle);
cogl_rectangle_with_texture_coords (x, y,....);
In the less likely case where you were blending your source texture with a color
like:
cogl_set_source_color4ub (r,g,b,a); /* where r,g,b,a isn't just white */
cogl_texture_rectangle (tex_handle, x, y,...);
you will need your own material to do that:
mat = cogl_material_new ();
cogl_material_set_color4ub (r,g,b,a);
cogl_material_set_layer (mat, 0, tex_handle));
cogl_set_source_material (mat);
Code that uses the texture coordinates, 0, 0, 1, 1 don't need to use
cog_rectangle_with_texure_coords since these are the coordinates that
cogl_rectangle will use.
For cogl_texture_polygon; as well as dropping the texture handle, the
n_vertices and vertices arguments were transposed for consistency. So
code previously written as:
cogl_texture_polygon (tex_handle, 3, verts, TRUE);
need to be written as:
cogl_set_source_texture (tex_handle);
cogl_polygon (verts, 3, TRUE);
All of the unit tests have been updated to now use the material API and
test-cogl-material has been renamed to test-cogl-multitexture since any
textured quad is now technically a test of CoglMaterial but this test
specifically creates a material with multiple texture layers.
Note: The GLES backend has not been updated yet; that will be done in a
following commit.
2009-01-23 16:15:40 +00:00
|
|
|
gboolean
|
|
|
|
_cogl_texture_span_has_waste (CoglTexture *tex,
|
|
|
|
gint x_span_index,
|
|
|
|
gint y_span_index);
|
|
|
|
|
2009-03-23 12:29:15 +00:00
|
|
|
void
|
|
|
|
_cogl_span_iter_begin (CoglSpanIter *iter,
|
|
|
|
GArray *array,
|
|
|
|
float origin,
|
|
|
|
float cover_start,
|
|
|
|
float cover_end);
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
_cogl_span_iter_end (CoglSpanIter *iter);
|
|
|
|
|
|
|
|
void
|
|
|
|
_cogl_span_iter_next (CoglSpanIter *iter);
|
|
|
|
|
2008-04-25 13:37:36 +00:00
|
|
|
#endif /* __COGL_TEXTURE_H */
|