We now prepend a set of defines to any given GLSL shader so that we can
define builtin uniforms/attributes within the "cogl" namespace that we
can use to provide compatibility across a range of the earlier versions
of GLSL.
This updates test-cogl-shader-glsl.c and test-shader.c so they no longer
needs to special case GLES vs GL when splicing together its shaders as
well as the blur, colorize and desaturate effects.
To get a feel for the new, portable uniform/attribute names here are the
defines for OpenGL vertex shaders:
#define cogl_position_in gl_Vertex
#define cogl_color_in gl_Color
#define cogl_tex_coord_in gl_MultiTexCoord0
#define cogl_tex_coord0_in gl_MultiTexCoord0
#define cogl_tex_coord1_in gl_MultiTexCoord1
#define cogl_tex_coord2_in gl_MultiTexCoord2
#define cogl_tex_coord3_in gl_MultiTexCoord3
#define cogl_tex_coord4_in gl_MultiTexCoord4
#define cogl_tex_coord5_in gl_MultiTexCoord5
#define cogl_tex_coord6_in gl_MultiTexCoord6
#define cogl_tex_coord7_in gl_MultiTexCoord7
#define cogl_normal_in gl_Normal
#define cogl_position_out gl_Position
#define cogl_point_size_out gl_PointSize
#define cogl_color_out gl_FrontColor
#define cogl_tex_coord_out gl_TexCoord
#define cogl_modelview_matrix gl_ModelViewMatrix
#define cogl_modelview_projection_matrix gl_ModelViewProjectionMatrix
#define cogl_projection_matrix gl_ProjectionMatrix
#define cogl_texture_matrix gl_TextureMatrix
And for fragment shaders we have:
#define cogl_color_in gl_Color
#define cogl_tex_coord_in gl_TexCoord
#define cogl_color_out gl_FragColor
#define cogl_depth_out gl_FragDepth
#define cogl_front_facing gl_FrontFacing
The GLES2 wrapper was referring to COGL_MATERIAL_PROGRAM_TYPE_GLSL but
this has since been renamed to COGL_PIPELINE_PROGRAM_TYPE_GLSL so the
GLES2 backend wouldn't compile.
The gles2 wrapper functions don't understand about the CoglBuffer API so
they don't support attributes stored in a CoglVertexArray. Instead of
teaching the backend about buffers we are going to wait until we have
overhauled the GLES 2 backend. We are currently making progress
consolidating the GLES 2 backend with a new GLSL backend for
CoglMaterial. This will hugely simplify the GLES 2 support and share
code with the OpenGL backend. In the end it's hoped that this problem
will simply go away so it doesn't make much sense to solve it with the
current design.
This applies an API naming change that's been deliberated over for a
while now which is to rename CoglMaterial to CoglPipeline.
For now the new pipeline API is marked as experimental and public
headers continue to talk about materials not pipelines. The CoglMaterial
API is now maintained in terms of the cogl_pipeline API internally.
Currently this API is targeting Cogl 2.0 so we will have time to
integrate it properly with other upcoming Cogl 2.0 work.
The basic reasons for the rename are:
- That the term "material" implies to many people that they are
constrained to fragment processing; perhaps as some kind of high-level
texture abstraction.
- In Clutter they get exposed by ClutterTexture actors which may be
re-inforcing this misconception.
- When comparing how other frameworks use the term material, a material
sometimes describes a multi-pass fragment processing technique which
isn't the case in Cogl.
- In code, "CoglPipeline" will hopefully be a much more self documenting
summary of what these objects represent; a full GPU pipeline
configuration including, for example, vertex processing, fragment
processing and blending.
- When considering the API documentation story, at some point we need a
document introducing developers to how the "GPU pipeline" works so it
should become intuitive that CoglPipeline maps back to that
description of the GPU pipeline.
- This is consistent in terminology and concept to OpenGL 4's new
pipeline object which is a container for program objects.
Note: The cogl-material.[ch] files have been renamed to
cogl-material-compat.[ch] because otherwise git doesn't seem to treat
the change as a moving the old cogl-material.c->cogl-pipeline.c and so
we loose all our git-blame history.
This merges the two implementations of CoglProgram for the GLES2 and
GL backends into one. The implementation is more like the GLES2
version which would track the uniform values and delay sending them to
GL. CoglProgram is now effectively just a GList of CoglShaders along
with an array of stored uniform values. CoglProgram never actually
creates a GL program, instead this is left up to the GLSL material
backend. This is necessary on GLES2 where we may need to relink the
user's program with different generated shaders depending on the other
emulated fixed function state. It will also be necessary in the future
GLSL backends for regular OpenGL. The GLSL and ARBfp material backends
are now the ones that create and link the GL program from the list of
shaders. The linked program is attached to the private material state
so that it can be reused if the CoglProgram is used again with the
same material. This does mean the program will get relinked if the
shader is used with multiple materials. This will be particularly bad
if the legacy cogl_program_use function is used because that
effectively always makes one-shot materials. This problem will
hopefully be alleviated if we make a hash table with a cache of
generated programs. The cogl program would then need to become part of
the hash lookup.
Each CoglProgram now has an age counter which is incremented every
time a shader is added. This is used by the material backends to
detect when we need to create a new GL program for the user program.
The internal _cogl_use_program function now takes a GL program handle
rather than a CoglProgram. It no longer needs any special differences
for GLES2. The GLES2 wrapper function now also uses this function to
bind its generated shaders.
The ARBfp shaders no longer store a copy of the program source but
instead just directly create a program object when cogl_shader_source
is called. This avoids having to reupload the source if the same
shader is used in multiple materials.
There are currently a few gross hacks to get the GLES2 backend to work
with this. The problem is that the GLSL material backend is now
generating a complete GL program but the GLES2 wrapper still needs to
add its fixed function emulation shaders if the program doesn't
provide either a vertex or fragment shader. There is a new function in
the GLES2 wrapper called _cogl_gles2_use_program which replaces the
previous cogl_program_use implementation. It extracts the GL shaders
from the GL program object and creates a new GL program containing all
of the shaders plus its fixed function emulation. This new program is
returned to the GLSL material backend so that it can still flush the
custom uniforms using it. The user_program is attached to the GLES2
settings struct as before but its stored using a GL program handle
rather than a CoglProgram pointer. This hack will go away once the
GLSL material backend replaces the GLES2 wrapper by generating the
code itself.
Under Mesa this currently generates some GL errors when glClear is
called in test-cogl-shader-glsl. I think this is due to a bug in Mesa
however. When the user program on the material is changed the GLSL
backend gets notified and deletes the GL program that it linked from
the user shaders. The program will still be bound in GL
however. Leaving a deleted shader bound exposes a bug in Mesa's
glClear implementation. More details are here:
https://bugs.freedesktop.org/show_bug.cgi?id=31194
*** WARNING: THIS COMMIT CHANGES THE BUILD ***
Do not recurse into the backend directories to build private, internal
libraries.
We only recurse from clutter/ into the cogl sub-directory; from there,
we don't recurse any further. All the backend-specific code in Cogl and
Clutter is compiled conditionally depending on the macros defined by the
configure script.
We still recurse from the top-level directory into doc, clutter and
tests, because gtk-doc and tests do not deal nicely with non-recursive
layouts.
This change makes Clutter compile slightly faster, and cleans up the
build system, especially when dealing with introspection data.
Ideally, we also want to make Cogl part of the top-level build, so that
we can finally drop the sed trick to change the shared library from the
GIR before compiling it.
Currently disabled:
‣ OSX backend
‣ Fruity backend
Currently enabled but untested:
‣ EGL backend
‣ Windows backend
Instead of exposing an API that provides an OpenGL state machine style
where you first have to bind the program to the context using
cogl_program_use() followed by updating uniforms using
cogl_program_uniform_xyz we now have uniform setter methods that take an
explicit CoglHandle for the program.
This deprecates cogl_program_use and all the cogl_program_uniform
variants and provides the following replacements:
cogl_program_set_uniform_1i
cogl_program_set_uniform_1f
cogl_program_set_uniform_int
cogl_program_set_uniform_float
cogl_program_set_uniform_matrix
This makes CoglProgram/Shader automatically detect when the user has
given an ARBfp program by checking for "!!ARBfp1.0" at the beginning of
the user's source.
ARBfp local parameters can be set with cogl_program_uniform_float
assuming you pass a @size of 4 (all ARBfp program.local parameters
are vectors of 4 floats).
This doesn't expose ARBfp environment parameters or double precision
local parameters.
This makes the gles2 cogl_program_use consistent with the GL version by
not binding the program immediately and instead leaving it to
cogl-material.c to bind the program when actually drawing something.
Previously custom uniforms were tracked in _CoglGles2Wrapper but as part
of a process to consolidate the gl/gles2 shader code it seems to make
sense for this state to be tracked in the CoglProgram object instead.
http://bugzilla.o-hand.com/show_bug.cgi?id=2179
Instead of having to query GL and translate the GL enum into a
CoglShaderType each time cogl_shader_get_type is called we now keep
track of the type in CoglShader.
Nothing was storing the shader type when a shader was created so it
would get confused about whether it was a custom vertex or fragment
shader.
Also the 'type' member of CoglShader was a GLenum but the only place
that read it was treating it as if it was CoglShaderType. This changes
it be CoglShaderType.
This function creates a CoglBitmap which internally references a
CoglBuffer. The map and unmap functions will divert to mapping the
buffer. There are also now bind and unbind functions which should be
used instead of map and unmap whenever the data doesn't need to be
read from the CPU but will instead be passed to GL for packing or
unpacking. For bitmaps created from buffers this just binds the
bitmap.
cogl_texture_new_from_buffer now just uses this function to wrap the
buffer in a bitmap rather than trying to bind the buffer
immediately. This means that the buffer will be bound only at the
point right before the texture data is uploaded.
This approach means that using a pixel array will take the fastest
upload route if possible, but can still fallback to copying the data
by mapping the buffer if some conversion is needed. Previously it
would just crash in this case because the texture functions were all
passed a NULL pointer.
http://bugzilla.clutter-project.org/show_bug.cgi?id=2112
The CoglBitmap struct is now only defined within cogl-bitmap.c so that
all of its members can now only be accessed with accessor
functions. To get to the data pointer for the bitmap image you must
first call _cogl_bitmap_map and later call _cogl_bitmap_unmap. The map
function takes the same arguments as cogl_pixel_array_map so that
eventually we can make a bitmap optionally internally divert to a
pixel array.
There is a _cogl_bitmap_new_from_data function which constructs a new
bitmap object and takes ownership of the data pointer. The function
gets passed a destroy callback which gets called when the bitmap is
freed. This is similar to how gdk_pixbuf_new_from_data
works. Alternatively NULL can be passed for the destroy function which
means that the caller will manage the life of the pointer (but must
guarantee that it stays alive at least until the bitmap is
freed). This mechanism is used instead of the old approach of creating
a CoglBitmap struct on the stack and manually filling in the
members. It could also later be used to create a CoglBitmap that owns
a GdkPixbuf ref so that we don't necessarily have to copy the
GdkPixbuf data when converting to a bitmap.
There is also _cogl_bitmap_new_shared. This creates a bitmap using a
reference to another CoglBitmap for the data. This is a bit of a hack
but it is needed by the atlas texture backend which wants to divert
the set_region virtual to another texture but it needs to override the
format of the bitmap to ignore the premult flag.
In ddb9016be4 the GL texture driver backend was changed to include
cogl-material-opengl-private.h instead of cogl-material-private.h.
However the gles texture backend was missed from this so it was giving
a compiler warning about using an undeclared function.
glTexSubImage3D was being called directly in cogl-texture-3d.c but the
function is only available since GL version 1.2 so on Windows it won't
be possible to directly link to it. Also under GLES it is only
available conditionally in an extension.
This moves the code supporting _cogl_material_flush_gl_state into
cogl-material-opengl.c as part of an effort to reduce the size of
cogl-material.c to keep it manageable.
In general cogl-material.c has become far to large to manage in one
source file. As one of the ways to try and break it down this patch
starts to move some of lower level texture unit state management out
into cogl-material-opengl.c. The naming is such because the plan is to
follow up and migrate the very GL specific state flushing code into the
same file.
This adds a publicly exposed experimental API for a 3D texture
backend. There is a feature flag which can be checked for whether 3D
textures are supported. Although we require OpenGL 1.2 which has 3D
textures in core, GLES only provides them through an extension so the
feature can be used to detect that.
The textures can be created with one of two new API functions :-
cogl_texture_3d_new_with_size
and
cogl_texture_3d_new_from_data
There is also internally a new_from_bitmap function. new_from_data is
implemented in terms of this function.
The two constructors are effectively the only way to upload data to a
3D texture. It does not work to call glTexImage2D with the
GL_TEXTURE_3D target so the virtual for cogl_texture_set_region does
nothing. It would be possible to make cogl_texture_get_data do
something sensible like returning all of the images as a single long
image but this is not currently implemented and instead the virtual
just always fails. We may want to add API specific to the 3D texture
backend to get and set a sub region of the texture.
All of those three functions can throw a GError. This will happen if
the GPU does not support 3D textures or it does not support NPOTs and
an NPOT size is requested. It will also fail if the FBO extension is
not supported and the COGL_TEXTURE_NO_AUTO_MIPMAP flag is not
given. This could be avoided by copying the code for the
GL_GENERATE_MIPMAP TexParameter fallback, but in the interests of
keeping the code simple this is not yet done.
This adds a couple of functions to cogl-texture-driver for uploading
3D data and querying the 3D proxy
texture. prep_gl_for_pixels_upload_full now also takes sets the
GL_UNPACK_IMAGE_HEIGHT parameter so that 3D textures can have padding
between the images. Whenever 3D texture is uploading, both the height
of the images and the height of all of the data is specified (either
explicitly or implicilty from the CoglBitmap) so that the image height
can be deduced by dividing by the depth.
Previously when comparing whether the settings for a layer are equal
it would only check if one of them was enabled. If so then it would
assume the other one was enabled and continue to compare the texture
environment. Now it also checks whether the enabledness differs.
Previously COGL_OBJECT_DEFINE would always define deprecated
cogl_$type_{ref,unref} functions even if the type is new or if the
type is entirely internal. An application would still find it
difficult to use these because they wouldn't be in the headers, but it
still looks bad that they are exported from the shared library. This
patch changes it so that the deprecated ref counting functions are
defined using a separate macro and only the types that have these
functions in the headers call this macro.
Under big GL, _cogl_texture_driver_size_supported uses the proxy
texture to check whether the given texture size is supported. Proxy
textures aren't available under GLES so previously this would just
return TRUE to assume all texture sizes are supported. This patch
makes it use glGetIntegerv with GL_MAX_TEXTURE_SIZE to give a second
best guess.
This fixes the sliced texture backend so that it will use slices when
the texture is too big.
This adds a new API call to enable point sprite coordinate generation
for a material layer:
void
cogl_material_set_layer_point_sprite_coords_enabled (CoglHandle material,
int layer_index,
gboolean enable);
There is also a corresponding get function.
Enabling point sprite coords simply sets the GL_COORD_REPLACE of the
GL_POINT_SPRITE glTexEnv when flusing the material. There is no
separate application control for glEnable(GL_POINT_SPRITE). Instead it
is left permanently enabled under the assumption that it has no affect
unless GL_COORD_REPLACE is enabled for a texture unit.
http://bugzilla.openedhand.com/show_bug.cgi?id=2047
This adds three new feature flags COGL_FEATURE_TEXTURE_NPOT_BASIC,
COGL_FEATURE_TEXTURE_NPOT_MIPMAP and COGL_FEATURE_TEXTURE_NPOT_REPEAT
that can tell you if your hardware supports non power of two textures,
npot textures + mipmaps and npot textures + wrap modes other than
CLAMP_TO_EDGE.
The pre-existing COGL_FEATURE_TEXTURE_NPOT feature implies all of the
above.
By default GLES 2 core supports npot textures but mipmaps and repeat
modes can only be used with power of two textures. This patch also makes
GLES check for the GL_OES_texture_npot extension to determine if mipmaps
and repeating are supported with npot textures.
Commit 7fae8ac051 changed cogl-defines.h.in so there is only a
single copy in clutter/cogl/ instead of one for each driver. However
the old files were still mentioned in the EXTRA_DIST of the
Makefile.am so make distcheck was failing.
This will be defined in cogl-defines.h whenever Cogl is built using a
winsys that supports X11. This implies CoglTexturePixmapX11 will be
available.
To make this work the two separate cogl-defines.h.in files have been
merged into one. The configure script now makes a @COGL_DEFINES@
substitution variable which contains the #define lines to put in
rather than directly having them in the seperate files.
This adds the framework needed to check for winsys specific extensions
(such as GLX extensions) using a similar mechanism to the
cogl-feature-functions header. There is a separate
cogl-winsys-feature-functions header which will contain macros to list
the extensions and functions. cogl_create_context_winsys now calls
_cogl_feature_check for each of these functions. _cogl_feature_check
has had to be changed to accept the driver prefix as the first
parameter so that it can prepend "GLX" rather than "GL" in this case.
This adds an internal rectangle texture backend which is mostly based
on the CoglTexture2D backend. It will throw assert failures if any
operations are attempted that rectangle textures don't support, such
as mipmapping or hardware repeating.
The include path for the winsys and driver folder was given relative
to $(srcdir) so it would end up relative to the driver folder which is
wrong. It is now specified as $(srcdir)/../../winsys to get the right
location. The driver folder is removed because it is actually just
$(srcdir) and that is already included.
Some internal symbols used for the GLES 2 wrapper were accidentally
being exported. This prepends an underscore to them so they won't
appear in the shared library.
OpenGL 3.0 deprecated querying of the GL_{RED,GREEN,BLUE}_BITS
constants, and the FBO extension provides a mechanism to query for the
color buffer sizes which *should* work even with the default
framebuffer. Unfortunately, this doesn't seem to hold for Mesa - so we
just use this for the offscreen CoglFramebuffer type, and we fall back
to glGetIntegerv() for the onscreen one.
http://bugzilla.openedhand.com/show_bug.cgi?id=2094
This adds a _cogl_bind_gl_texture_transient function that should be used
instead of glBindTexture so we can have a consistent cache of the
textures bound to each texture unit so we can avoid some redundant
binding.
As part of an effort to improve the architecture of CoglMaterial
internally this overhauls how we flush layer state to OpenGL by adding a
formal backend abstraction for fragment processing and further
formalizing the CoglTextureUnit abstraction.
There are three backends: "glsl", "arbfp" and "fixed". The fixed backend
uses the OpenGL fixed function APIs to setup the fragment processing,
the arbfp backend uses code generation to handle fragment processing
using an ARBfp program, and the GLSL backend is currently only there as
a formality to handle user programs associated with a material. (i.e.
the glsl backend doesn't yet support code generation)
The GLSL backend has highest precedence, then arbfp and finally the
fixed. If a backend can't support some particular CoglMaterial feature
then it will fallback to the next backend.
This adds three new COGL_DEBUG options:
* "disable-texturing" as expected should disable all texturing
* "disable-arbfp" always make the arbfp backend fallback
* "disable-glsl" always make the glsl backend fallback
* "show-source" show code generated by the arbfp/glsl backends
The Cogl context has now a feature_flags_private enum that will allow us
to query and use OpenGL features without exposing them in the public
API.
The ARB_fragment_program extension is the first user of those flags.
Looking for this extension only happens in the gl driver as the gles
drivers will not expose them.
One can use _cogl_features_available_private() to check for the
availability of such private features.
While at it, reindent cogl-internal.h as described in CODING_STYLE.
At two places in cogl_wrap_prepare_for_draw it was trying to loop over
the texture units to flush some state. However it was retrieving the
texture unit pointer using w->active_texture_unit instead of the loop
index so it would end up with the wrong state.
Also in glEnableClientState it was using the active unit instead of
the client active unit.
While this is totally fine (0 in the pointer context will be converted
in the right internal NULL representation, which could be a value with
some bits to 1), I believe it's clearer to use NULL in the pointer
context.
It seems that, in most case, it's more an overlook than a deliberate
choice to use FALSE/0 as NULL, eg. copying a _COGL_GET_CONTEXT (ctx, 0)
or a g_return_val_if_fail (cond, 0) from a function returning a
gboolean.
In 91cde78a7 I accidentally changed the function names that get looked
up for the framebuffer extension under GLES so that they didn't have
any suffix. The spec for extension specifies that they should have the
OES suffix.
Since using addresses that might change is something that finally
the FSF acknowledge as a plausible scenario (after changing address
twice), the license blurb in the source files should use the URI
for getting the license in case the library did not come with it.
Not that URIs cannot possibly change, but at least it's easier to
set up a redirection at the same place.
As a side note: this commit closes the oldes bug in Clutter's bug
report tool.
http://bugzilla.openedhand.com/show_bug.cgi?id=521
This adds a COGL_INDICES_TYPE_UNSIGNED_INT enum value so that unsigned
ints can be used with cogl_vertex_buffer_indices_new. Unsigned ints
are not supported in core on GLES so a feature flag has also been
added to advertise this. GLES only sets the feature if the
GL_OES_element_index_uint extension is available. It is an error to
call indices_new() with unsigned ints unless the feature is
advertised.
http://bugzilla.openedhand.com/show_bug.cgi?id=1998
Previously the GLES2 backend needed a special wrapper for
glBindTexture because it needed to know the internal GL format of the
texture in order to correctly implement the GL_MODULATE texture env
mode. When GL_MODULATE is used then the RGB values are taken from the
previous texture layer rather than being fetched from the
texture. However since the material API was added Cogl no longer uses
the GL_MODULATE texture env mode but instead always uses GL_COMBINE.
Compiling the GLES2 backend broke since the more-texture-backends
branch merge because the cogl_get_internal_gl_format function was
removed and there was one place in GLES2 specific code that was using
this to bind the texture.
The texture layer combine functions are now hard coded to GL_COMBINE
instead of GL_MODULATE. The combine function can be customized with
all the parameters of GL_COMBINE. A shader is generated to implement
the given parameters.
Currently it will try to generate code for the constant color but it
will use a uniform which does not exist.
The GLES2 backend for Cogl is failing to compile because
GL_MAX_TEXTURE_UNITS is not defined. Let's define it and provide a
wrapper which uses GL_MAX_TEXTURE_IMAGE_UNITS or
COGL_GLES2_MAX_TEXTURE_UNITS, whichever is the smallest.
We've had complaints that our Cogl code/headers are a bit "special" so
this is a first pass at tidying things up by giving them some
consistency. These changes are all consistent with how new code in Cogl
is being written, but the style isn't consistently applied across all
code yet.
There are two parts to this patch; but since each one required a large
amount of effort to maintain tidy indenting it made sense to combine the
changes to reduce the time spent re indenting the same lines.
The first change is to use a consistent style for declaring function
prototypes in headers. Cogl headers now consistently use this style for
prototypes:
return_type
cogl_function_name (CoglType arg0,
CoglType arg1);
Not everyone likes this style, but it seems that most of the currently
active Cogl developers agree on it.
The second change is to constrain the use of redundant glib data types
in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all
been replaced with int, unsigned int, float, long, unsigned long and char
respectively. When talking about pixel data; use of guchar has been
replaced with guint8, otherwise unsigned char can be used.
The glib types that we continue to use for portability are gboolean,
gint{8,16,32,64}, guint{8,16,32,64} and gsize.
The general intention is that Cogl should look palatable to the widest
range of C programmers including those outside the Gnome community so
- especially for the public API - we want to minimize the number of
foreign looking typedefs.
OpenGL is an implementation detail for Cogl so it's not appropriate to
expose OpenGL extensions through the Cogl API.
Note: Clutter is currently still using this API, because it is still
doing raw GL calls in ClutterGLXTexturePixmap, so this introduces a
couple of (legitimate) build warnings while compiling Clutter.
First, let's add a new public feature called, surprisingly,
COGL_FEATURE_PBOS to check the availability of PBOs and provide a
fallback path when running on older GL implementations or on OpenGL ES
In case the underlying OpenGL implementation does not provide PBOs, we
need a fallback path (a malloc'ed buffer). The CoglPixelBufer
constructors will instanciate a subclass of CoglBuffer that handles
map/unmap and set_data() with a malloc'ed buffer.
The public feature is useful to check before using set_data() on a
buffer as it will mean doing a memcpy() when not supporting PBOs (in
that case, it's better to create the texture directly instead of using a
CoglBuffer).
The only way the user has to set the mipmap filters is through the
material/layer API. This API defaults to GL_LINEAR/GL_LINEAR for the max
and min filters. With the main use case of cogl being 2D interfaces, it
makes sense do default to GL_LINEAR for the min filter.
When creating new textures, we did not set any filter on them, using
OpenGL defaults': GL_NEAREST_MIPMAP_LINEAR for the min filter and
GL_LINEAR for the max filter. This will make the driver allocate memory
for the mipmap tree, memory that will not be used in the nominal case
(as the material API defaults to GL_LINEAR).
This patch tries to ensure that the min filter is set to GL_LINEAR
before any glTexImage*() call is done on the texture by setting the
filter when generating new OpenGL handles.
These macros used to define Cogl wrappers for the GLenum values. There are
now Cogl enums everywhere in the API where these were required so we
shouldn't need them anymore. They were in the public headers but as
they are not neccessary and were not in the API docs for Clutter 1.0
it should be safe to remove them.
This provides a way to upload the entire data for a texture without
having to first call glTexImage and then glTexSubImage. This should be
faster especially with indirect rendering where it would needlessy
send the data for the texture twice.
The CoglTexture struct previously contained some fields which are only
used to upload data such as the CoglBitmap and the source GL
format. These are now moved to a separate CoglTextureUploadData struct
which only exists for the duration of one of the cogl_texture_*_new
functions. In cogl-texture there are utility functions which operate
on this new struct rather than on CoglTexture directly.
Some of the fields that were previously stored in the CoglBitmap
struct are now copied to the CoglTexture such as the width, height,
format and internal GL format.
The rowstride was previously stored in CoglTexture and this was
publicly accessible with the cogl_texture_get_rowstride
function. However this doesn't seem to be a useful function because
there is no need to use the same rowstride again when uploading or
downloading new data. Instead cogl_texture_get_rowstride now just
calculates a suitable rowstride from the format and width of the
texture.
_cogl_feature_check expects the array of function names to be
terminated with a NULL pointer but I forgot to add this. This was
causing crashes depending on what happened to be in memory after the
array.
For VBOs, we don't need to check for the extension if the GL version
is greater than 1.5. Non-power-of-two textures are given in 2.0.
We could also assume shader support in GL 2.0 except that the function
names are different from those in the extension so it wouldn't work
well with the current mechanism.
Previously if you need to depend on a new GL feature you had to:
- Add typedefs for all of the functions in cogl-defines.h.in
- Add function pointers for each of the functions in
cogl-context-driver.h
- Add an initializer for the function pointers in
cogl-context-driver.c
- Add a check for the extension and all of the functions in
cogl_features_init. If the extension is available under multiple
names then you have to duplicate the checks.
This is quite tedious and error prone. This patch moves all of the
features and their functions into a list of macro invocations in
cogl-feature-functions.h. The macros can be redefined to implement all
of the above tasks from the same header.
The features are described in a struct with a pointer to a table of
functions. A new function takes the feature description from this
struct and checks for its availability. The feature can take a list of
extension names with a list of alternate namespaces (such as "EXT" or
"ARB"). It can also detect the feature from a particular version of
GL.
The typedefs are now gone and instead the function pointer in the Cogl
context just directly contains the type.
Some of the functions in the context were previously declared with the
'ARB' extension. This has been removed so that now all the functions
have no suffix. This makes more sense when the extension could
potentially be merged into GL core as well.
There is a new internal Cogl function called _cogl_check_driver_valid
which looks at the value of the GL_VERSION string to determine whether
the driver is supported. Clutter now calls this after the stage is
realized. If it fails then the stage is marked as unrealized and a
warning is shown.
_cogl_features_init now also checks the version number before getting
the function pointers for glBlendFuncSeparate and
glBlendEquationSeparate. It is not safe to just check for the presence
of the functions because some drivers may define the function without
fully implementing the spec.
The GLES version of _cogl_check_driver_valid just always returns TRUE
because there are no version requirements yet.
Eventually the function could also check for mandatory extensions if
there were any.
http://bugzilla.openedhand.com/show_bug.cgi?id=1875
These files were practically identical, except the gles code had additional
support for filling paths without a stencil buffer. All the driver code has
now been moved into cogl/cogl-primitives.c
Cogl's support for offscreen rendering was originally written just to support
the clutter_texture_new_from_actor API and due to lack of documentation and
several confusing - non orthogonal - side effects of using the API it wasn't
really possible to use directly.
This commit does a number of things:
- It removes {gl,gles}/cogl-fbo.{c,h} and adds shared cogl-draw-buffer.{c,h}
files instead which should be easier to maintain.
- internally CoglFbo objects are now called CoglDrawBuffers. A
CoglDrawBuffer is an abstract base class that is inherited from to
implement CoglOnscreen and CoglOffscreen draw buffers. CoglOffscreen draw
buffers will initially be used to support the
cogl_offscreen_new_to_texture API, and CoglOnscreen draw buffers will
start to be used internally to represent windows as we aim to migrate some
of Clutter's backend code to Cogl.
- It makes draw buffer objects the owners of the following state:
- viewport
- projection matrix stack
- modelview matrix stack
- clip state
(This means when you switch between draw buffers you will automatically be
switching to their associated viewport, matrix and clip state)
Aside from hopefully making cogl_offscreen_new_to_texture be more useful
short term by having simpler and well defined semantics for
cogl_set_draw_buffer, as mentioned above this is the first step for a couple
of other things:
- Its a step toward moving ownership for windows down from Clutter backends
into Cogl, by (internally at least) introducing the CoglOnscreen draw
buffer. Note: the plan is that cogl_set_draw_buffer will accept on or
offscreen draw buffer handles, and the "target" argument will become
redundant since we will instead query the type of the given draw buffer
handle.
- Because we have a common type for on and offscreen framebuffers we can
provide a unified API for framebuffer management. Things like:
- blitting between buffers
- managing ancillary buffers (e.g. attaching depth and stencil buffers)
- size requisition
- clearing
Over time the two cogl-fbo.c files have needlessly diverged as bug fixes or
cleanups went into one version but not the other. This tries to bring them
back in line with each other. It should actually be simple enough to move
cogl-fbo.c to be a common file, and simply not build it for GLES 1.1, so
maybe I'll follow up with such a patch soon.
The comment just said: "Some implementation require a clear before drawing
to an fbo. Luckily it is affected by scissor test." and did a scissored
clear, which is clearly a driver bug workaround, but for what driver? The
fact that it was copied into the gles backend (or vica versa is also
suspicious since it seems unlikely that the workaround is necessary for both
backends.)
We can easily restore the workaround with a better comment if this problem
really still exists on current drivers, but for now I'd rather minimize
hand-wavey workaround code that can't be tested.
Since we no longer depend on the GL matrix API in Cogl we can remove a lot
of wrapper code from the GLES 2 backend. This is particularly nice given
that there was no code shared between the cogl-matrix-stack API and gles2
wrappers so we had a lot of duplicated logic.
The indirection through this API isn't necessary since we no longer
arbitrate between the OpenGL matrix API and Cogl's client side API. Also it
doesn't help to maintain an OpenGL style matrix mode API for internal use
since it's awkward to keep restoring the MODELVIEW mode and easy enough to
directly work with the matrix stacks of interest.
This replaces use of the _cogl_current_matrix API with direct use of the
_cogl_matrix_stack API. All the unused cogl_current_matrix API is removed
and the matrix utility code left in cogl-current-matrix.c was moved to
cogl.c.
cogl-texture-2d-sliced provides an implementation of CoglTexture and this
seperation lays the foundation for potentially supporting atlas textures,
pixmap textures (as in GLX_EXT_texture_from_pixmap) and fast-path
GL_TEXTURE_{1D,2D,3D,RECTANGLE} textures in a maintainable fashion.
cogl-primitives.c was previously digging right into CoglTextures so it could
manually iterate the texture slices for texturing quads and polygons and
because we were missing some state getters we were lazily just poking into
the structures directly.
This adds some extra state getter functions, and adds a higher level
_cogl_texture_foreach_slice () API that hopefully simplifies the way in
which sliced textures may be used to render primitives. This lets you
specify a rectangle in "virtual" texture coords and it will call a given
callback for each slice that intersects that rectangle giving the virtual
coords of the current slice and corresponding "real" texture coordinates for
the underlying gl texture.
At the same time a noteable bug in how we previously iterated sliced
textures was fixed, whereby we weren't correctly handling inverted texture
coordinates. E.g. with the previous code if you supplied texture coords of
tx1=100,ty1=0,tx2=0,ty2=100 (inverted along y axis) that would result in a
back-facing quad, which could be discarded if using back-face culling.
As part of an incremental process to have Cogl be a standalone project we
want to re-consider how we organise the Cogl source code.
Currently this is the structure I'm aiming for:
cogl/
cogl/
<put common source here>
winsys/
cogl-glx.c
cogl-wgl.c
driver/
gl/
gles/
os/ ?
utils/
cogl-fixed
cogl-matrix-stack?
cogl-journal?
cogl-primitives?
pango/
The new winsys component is a starting point for migrating window system
code (i.e. x11,glx,wgl,osx,egl etc) from Clutter to Cogl.
The utils/ and pango/ directories aren't added by this commit, but they are
noted because I plan to add them soon.
Overview of the planned structure:
* The winsys/ API is the API that binds OpenGL to a specific window system,
be that X11 or win32 etc. Example are glx, wgl and egl. Much of the logic
under clutter/{glx,osx,win32 etc} should migrate here.
* Note there is also the idea of a winsys-base that may represent a window
system for which there are multiple winsys APIs. An example of this is
x11, since glx and egl may both be used with x11. (currently only Clutter
has the idea of a winsys-base)
* The driver/ represents a specific varient of OpenGL. Currently we have "gl"
representing OpenGL 1.4-2.1 (mostly fixed function) and "gles" representing
GLES 1.1 (fixed funciton) and 2.0 (fully shader based)
* Everything under cogl/ should fundamentally be supporting access to the
GPU. Essentially Cogl's most basic requirement is to provide a nice GPU
Graphics API and drawing a line between this and the utility functionality
we add to support Clutter should help keep this lean and maintainable.
* Code under utils/ as suggested builds on cogl/ adding more convenient
APIs or mechanism to optimize special cases. Broadly speaking you can
compare cogl/ to OpenGL and utils/ to GLU.
* clutter/pango will be moved to clutter/cogl/pango
How some of the internal configure.ac/pkg-config terminology has changed:
backendextra -> CLUTTER_WINSYS_BASE # e.g. "x11"
backendextralib -> CLUTTER_WINSYS_BASE_LIB # e.g. "x11/libclutter-x11.la"
clutterbackend -> {CLUTTER,COGL}_WINSYS # e.g. "glx"
CLUTTER_FLAVOUR -> {CLUTTER,COGL}_WINSYS
clutterbackendlib -> CLUTTER_WINSYS_LIB
CLUTTER_COGL -> COGL_DRIVER # e.g. "gl"
Note: The CLUTTER_FLAVOUR and CLUTTER_COGL defines are kept for apps
As the first thing to take advantage of the new winsys component in Cogl;
cogl_get_proc_address() has been moved from cogl/{gl,gles}/cogl.c into
cogl/common/cogl.c and this common implementation first trys
_cogl_winsys_get_proc_address() but if that fails then it falls back to
gmodule.