From de41fdd9d128325c243715ae7ddea219587163a5 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Tue, 20 Jan 2009 21:12:44 +0000 Subject: [PATCH] Renames the mesh api to the "vertex buffer api". This better reflects the fact that the api manages sets of vertex attributes, and the attributes really have no implied form. It is only when you use the attributes to draw that they become mesh like; when you specify how they should be interpreted, e.g. as triangle lists or fans etc. This rename frees up the term "mesh", which can later be applied to a concept slightly more fitting. E.g. at some point it would be nice to have a higher level abstraction that sits on top of cogl vertex buffers that adds the concept of faces. (Somthing like Blender's mesh objects.) There have also been some discussions over particle engines, and these can be defined in terms of emitter faces; so some other kind of mesh abstraction might be usefull here. --- cogl-mesh.h => cogl-vertex-buffer.h | 241 +++--- cogl.h.in | 2 +- common/Makefile.am | 3 +- common/cogl-mesh-private.h | 143 ---- common/cogl-vertex-buffer-private.h | 142 ++++ common/{cogl-mesh.c => cogl-vertex-buffer.c} | 815 ++++++++++--------- doc/reference/cogl/cogl-docs.sgml | 2 +- doc/reference/cogl/cogl-sections.txt | 25 +- gl/Makefile.am | 2 +- gl/cogl-context.c | 2 +- gl/cogl-context.h | 4 +- gles/Makefile.am | 2 +- gles/cogl-context.c | 2 +- gles/cogl-context.h | 4 +- 14 files changed, 706 insertions(+), 683 deletions(-) rename cogl-mesh.h => cogl-vertex-buffer.h (52%) delete mode 100644 common/cogl-mesh-private.h create mode 100644 common/cogl-vertex-buffer-private.h rename common/{cogl-mesh.c => cogl-vertex-buffer.c} (63%) diff --git a/cogl-mesh.h b/cogl-vertex-buffer.h similarity index 52% rename from cogl-mesh.h rename to cogl-vertex-buffer.h index e0c8f00c2..5bf85887c 100644 --- a/cogl-mesh.h +++ b/cogl-vertex-buffer.h @@ -1,9 +1,13 @@ -/* cogl-mesh.h: Handle extensible arrays of vertex attributes - * This file is part of Clutter +/* + * Cogl. + * + * An OpenGL/GLES Abstraction/Utility Layer + * + * Vertex Buffer API: Handle extensible arrays of vertex attributes * * Copyright (C) 2008 Intel Corporation. * - * Authored by: Robert Bragg + * Authored by: Robert Bragg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,8 +27,8 @@ #error "Only can be included directly." #endif -#ifndef __COGL_MESH_H__ -#define __COGL_MESH_H__ +#ifndef __COGL_VERTEX_BUFFER_H__ +#define __COGL_VERTEX_BUFFER_H__ #include #include @@ -32,42 +36,42 @@ G_BEGIN_DECLS /** - * SECTION:cogl-mesh + * SECTION:cogl-vertex-buffer * @short_description: An API for submitting extensible arrays of vertex * attributes to OpenGL in a way that aims to minimise * copying or reformatting of the original data. * - * The Mesh API is designed to be a fairly raw mechanism for developers - * to be able to submit geometry to Cogl in a format that can be directly - * consumed by an OpenGL driver and with awareness of the specific hardware - * being used then costly format conversion can also be avoided. + * The Attributes Buffer API is designed to be a fairly raw mechanism for + * developers to be able to submit geometry to Cogl in a format that can be + * directly consumed by an OpenGL driver and with awareness of the specific + * hardware being used then costly format conversion can also be avoided. * * They are designed to work on top of buffer objects and developers should - * understand that mesh objects are not cheap to create but once they - * have been submitted they are stored in GPU addressable memory and can + * understand that attribute buffers are not that cheap to create but once they + * have been submitted they can be stored in GPU addressable memory and can * be quickly reused. * - * Although this API does allow you to modify mesh objects after they have - * been submitted to the GPU you must note that modification is still - * not cheap, so if at all possible think of tricks that let you reuse - * a static buffer. To help with this, it is possible to enable and disable - * individual attributes cheaply. + * Although this API does allow you to modify attribute buffers after they have + * been submitted to the GPU you must note that modification is also not that + * cheap, so if at all possible think of tricks that let you reuse a static + * buffer. To help with this, it is possible to enable and disable individual + * attributes cheaply. * - * Take for example a mesh representing an elipse. If you were to submit - * a mesh with color attributes, texture coordinates and normals, then - * you would be able to draw an elipses in the following different ways - * without creating a new mesh: + * Take for example attributes representing an elipse. If you were to submit + * color attributes, texture coordinates and normals, then you would be able + * to draw an elipses in the following different ways without modifying + * the vertex buffer, only by changing your source material. * * Flat colored elipse * Textured elipse * Smoothly lit textured elipse blended with the color. * - * - * Another trick that can be used is submitting a highly detailed mesh - * and then using cogl_mesh_draw_range_elements to sample lower resolution - * geometry out from a fixed mesh. * - * The API doesn't currently give you any control over the actual buffer + * Another trick that can be used is submitting highly detailed vertices and + * then using cogl_vertex_buffer_draw_range_elements to sample sub-sets of + * the geometry or lower resolution geometry out from a fixed buffer. + * + * The API doesn't currently give you any control over the actual OpenGL buffer * objects that are created, but you can expect that when you first submit * your attributes they start off in one or more GL_STATIC_DRAW buffers. * If you then update some of your attributes; then these attributes will @@ -75,18 +79,18 @@ G_BEGIN_DECLS */ /** - * cogl_mesh_new: - * @n_vertices: The number of vertices that will make up your mesh. + * cogl_vertex_buffer_new: + * @n_vertices: The number of vertices that your attributes will correspond to. * - * This creates a Cogl handle for a new mesh that you can then start to add - * attributes too. + * This creates a Cogl handle for a new vertex buffer that you can then start + * to add attributes too. */ CoglHandle -cogl_mesh_new (guint n_vertices); +cogl_vertex_buffer_new (guint n_vertices); /** - * cogl_mesh_add_attribute: - * @handle: A Cogl mesh handle + * cogl_vertex_buffer_add: + * @handle: A vertex buffer handle * @attribute_name: The name of your attribute. It should be a valid GLSL * variable name and standard attribute types must use one * of following built-in names: (Note: they correspond to the @@ -115,90 +119,106 @@ cogl_mesh_new (guint n_vertices); * stride for both attributes is 6. The special value 0 means the * values are stored sequentially in memory. * @pointer: This addresses the first attribute in the vertex array. (This - * must remain valid until you call cogl_mesh_submit) + * must remain valid until you call cogl_vertex_buffer_submit) * - * This function lets you add an attribute to a mesh. You either use one + * This function lets you add an attribute to a buffer. You either use one * of the built-in names to add standard attributes, like positions, colors * and normals or you can add custom attributes for use in shaders. * - * Note: The number of vertices declared when creating the mesh is used to - * determine how many attribute values will be read from the supplied pointer. + * Note: The number of vertices declared when first creating the vertex + * buffer is used to determine how many attribute values will be read from the + * supplied pointer. * * Note: the data supplied here isn't copied anywhere until you call - * cogl_mesh_submit, so the supplied pointer must remain valid until then. - * (This is an important optimisation since we can't create a buffer - * object until we know about all the attributes, and repeatedly copying - * large buffers of vertex data may be very costly) If you add attributes - * after submitting then you will need to re-call cogl_mesh_submit to - * commit the changes to the GPU. (Be carefull to minimize the number of - * calls to cogl_mesh_submit though) + * cogl_vertex_buffer_submit, so the supplied pointer must remain valid + * until then. + * (This is an important optimisation since we can't create the underlying + * OpenGL buffer object until we know about all the attributes, and repeatedly + * copying large buffers of vertex data may be very costly) If you add + * attributes after submitting then you will need to re-call + * cogl_vertex_buffer_submit to commit the changes to the GPU. (Be carefull + * to minimize the number of calls to cogl_vertex_buffer_submit though) * * Note: If you are interleving attributes it is assumed that that each - * interleaved attribute starts no farther than +- stride bytes from - * the other attributes it is interleved with. I.e. this is ok: + * interleaved attribute starts no farther than +- stride bytes from the other + * attributes it is interleved with. I.e. this is ok: * |-0-0-0-0-0-0-0-0-0-0| * This is not ok: * |- - - - -0-0-0-0-0-0 0 0 0 0| * (Though you can have multiple groups of interleved attributes) */ void -cogl_mesh_add_attribute (CoglHandle handle, - const char *attribute_name, - guint8 n_components, - GLenum gl_type, - gboolean normalized, - guint16 stride, - const void *pointer); +cogl_vertex_buffer_add (CoglHandle handle, + const char *attribute_name, + guint8 n_components, + GLenum gl_type, + gboolean normalized, + guint16 stride, + const void *pointer); /** - * cogl_mesh_delete_attribute: - * @handle: A Cogl mesh handle + * cogl_vertex_buffer_delete: + * @handle: A vertex buffer handle * @attribute_name: The name of a previously added attribute * - * This function deletes an attribute from a mesh. You will need to - * call cogl_mesh_submit to commit this change to the GPU. + * This function deletes an attribute from a buffer. You will need to + * call cogl_vertex_buffer_submit to commit this change to the GPU. */ void -cogl_mesh_delete_attribute (CoglHandle handle, - const char *attribute_name); +cogl_vertex_buffer_delete (CoglHandle handle, + const char *attribute_name); /** - * cogl_mesh_enable_attribute: - * @handle: A Cogl mesh handle + * cogl_vertex_buffer_enable: + * @handle: A vertex buffer handle * @attribute_name: The name of the attribute you want to enable * * This function enables a previosuly added attribute * - * Since it is costly to create new mesh objects, then to make individual mesh - * objects more reuseable it is possible to enable and disable attributes - * before using a mesh for drawing. + * Since it can be costly to add and remove new attributes to buffers; to make + * individual buffers more reuseable it is possible to enable and disable + * attributes before using a buffer for drawing. * - * Note: You don't need to call cogl_mesh_submit after using this function + * Note: You don't need to call cogl_vertex_buffer_submit after using this + * function */ void -cogl_mesh_enable_attribute (CoglHandle handle, - const char *attribute_name); +cogl_vertex_buffer_enable (CoglHandle handle, + const char *attribute_name); /** - * cogl_mesh_disable_attribute: - * @handle: A Cogl mesh handle + * cogl_vertex_buffer_submit: + * @handle: A vertex buffer handle + * + * This function copies all the user added attributes into buffer objects + * managed by the OpenGL driver. + * + * You should aim to minimize calls to this function. + */ +void +cogl_vertex_buffer_submit (CoglHandle handle); + +/** + * cogl_vertex_buffer_disable: + * @handle: A vertex buffer handle * @attribute_name: The name of the attribute you want to disable * * This function disables a previosuly added attribute * - * Since it is costly to create new mesh objects, then to make individual mesh - * objects more reuseable it is possible to enable and disable attributes - * before using a mesh for drawing. + * Since it can be costly to add and remove new attributes to buffers; to make + * individual buffers more reuseable it is possible to enable and disable + * attributes before using a buffer for drawing. * - * Note: You don't need to call cogl_mesh_submit after using this function + * Note: You don't need to call cogl_vertex_buffer_submit after using this + * function */ void -cogl_mesh_disable_attribute (CoglHandle handle, - const char *attribute_name); +cogl_vertex_buffer_disable (CoglHandle handle, + const char *attribute_name); /** - * cogl_mesh_draw_arrays: - * @handle: A Cogl mesh handle + * cogl_vertex_buffer_draw: + * @handle: A vertex buffer handle * @mode: Specifies how the vertices should be interpreted, and should be * a valid GL primitive type: * @@ -215,17 +235,17 @@ cogl_mesh_disable_attribute (CoglHandle handle, * @count: Specifies the number of vertices you want to draw. * * This function lets you draw geometry using all or a subset of the - * vertices in a mesh object. + * vertices in a vertex buffer. */ void -cogl_mesh_draw_arrays (CoglHandle handle, - GLenum mode, - GLint first, - GLsizei count); +cogl_vertex_buffer_draw (CoglHandle handle, + GLenum mode, + GLint first, + GLsizei count); /** - * cogl_mesh_draw_range_elements: - * @handle: A Cogl mesh handle + * cogl_vertex_buffer_draw_range_elements: + * @handle: A vertex buffer handle * @mode: Specifies how the vertices should be interpreted, and should be * a valid GL primitive type: * @@ -238,11 +258,11 @@ cogl_mesh_draw_arrays (CoglHandle handle, * GL_TRIANGLES * * (Note: only types available in GLES are listed) - * @start: Specifies the minimum vertex index contained in indices - * @end: Specifies the maximum vertex index contained in indices + * @min_index: Specifies the minimum vertex index contained in indices + * @max_index: Specifies the maximum vertex index contained in indices * @count: Specifies the number of vertices you want to draw. - * @type: Specifies the data type used for the indices, and must be - * one of: + * @indices_typetype: Specifies the data type used for the indices, and must be + * one of: * * GL_UNSIGNED_BYTE * GL_UNSIGNED_SHORT @@ -251,49 +271,38 @@ cogl_mesh_draw_arrays (CoglHandle handle, * @indices: Specifies the address of your array of indices * * This function lets you use an array of indices to specify the vertices - * within your mesh pbject that you want to draw. + * within your vertex buffer that you want to draw. */ void -cogl_mesh_draw_range_elements (CoglHandle handle, - GLenum mode, - GLuint start, - GLuint end, - GLsizei count, - GLenum type, - const GLvoid *indices); +cogl_vertex_buffer_draw_range_elements (CoglHandle handle, + GLenum mode, + GLuint min_index, + GLuint max_index, + GLsizei count, + GLenum indices_type, + const GLvoid *indices); /** - * cogl_mesh_submit: - * @handle: A Cogl mesh handle - * - * This function copies all the user added attributes into a buffer object - * managed by the OpenGL driver. - * - * After the attributes have been submitted, then you may no longer add or - * remove attributes from a mesh, though you can enable or disable them. - */ -void -cogl_mesh_submit (CoglHandle handle); - -/** - * cogl_mesh_ref: + * cogl_vertex_buffer_ref: * @handle: a @CoglHandle. * - * Increment the reference count for a cogl mesh. + * Increment the reference count for a vertex buffer * * Returns: the @handle. */ -CoglHandle cogl_mesh_ref (CoglHandle handle); +CoglHandle +cogl_vertex_buffer_ref (CoglHandle handle); /** - * cogl_mesh_unref: + * cogl_vertex_buffer_unref: * @handle: a @CoglHandle. * - * Deccrement the reference count for a cogl mesh. + * Decrement the reference count for a vertex buffer */ -void cogl_mesh_unref (CoglHandle handle); +void +cogl_vertex_buffer_unref (CoglHandle handle); G_END_DECLS -#endif /* __COGL_MESH_H__ */ +#endif /* __COGL_VERTEX_BUFFER_H__ */ diff --git a/cogl.h.in b/cogl.h.in index f8d574524..5fa6399b1 100644 --- a/cogl.h.in +++ b/cogl.h.in @@ -32,7 +32,7 @@ #include -#include +#include #include #include #include diff --git a/common/Makefile.am b/common/Makefile.am index fb2adf28f..bfedc2e59 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -30,4 +30,5 @@ libclutter_cogl_common_la_SOURCES = \ cogl-clip-stack.c \ cogl-fixed.c \ cogl-color.c \ - cogl-mesh.c + cogl-vertex-buffer-private.h \ + cogl-vertex-buffer.c diff --git a/common/cogl-mesh-private.h b/common/cogl-mesh-private.h deleted file mode 100644 index db014c3bd..000000000 --- a/common/cogl-mesh-private.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Clutter COGL - * - * A basic GL/GLES Abstraction/Utility Layer - * - * Authored By Robert Bragg - * - * Copyright (C) 2008 Intel - * - * 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_MESH_H -#define __COGL_MESH_H - -/* Note we put quite a bit into the flags here to help keep - * the down size of the CoglMeshAttribute struct below. */ -typedef enum _CoglMeshAttributeFlags -{ - /* Types */ - /* NB: update the _TYPE_MASK below if these are changed */ - COGL_MESH_ATTRIBUTE_FLAG_COLOR_ARRAY = 1<<0, - COGL_MESH_ATTRIBUTE_FLAG_NORMAL_ARRAY = 1<<1, - COGL_MESH_ATTRIBUTE_FLAG_TEXTURE_COORD_ARRAY = 1<<2, - COGL_MESH_ATTRIBUTE_FLAG_VERTEX_ARRAY = 1<<3, - COGL_MESH_ATTRIBUTE_FLAG_CUSTOM_ARRAY = 1<<4, - COGL_MESH_ATTRIBUTE_FLAG_INVALID = 1<<5, - - COGL_MESH_ATTRIBUTE_FLAG_NORMALIZED = 1<<6, - COGL_MESH_ATTRIBUTE_FLAG_ENABLED = 1<<7, - - /* Usage hints */ - /* FIXME - flatten into one flag, since its used as a boolean */ - COGL_MESH_ATTRIBUTE_FLAG_INFREQUENT_RESUBMIT = 1<<8, - COGL_MESH_ATTRIBUTE_FLAG_FREQUENT_RESUBMIT = 1<<9, - - /* GL Data types */ - /* NB: Update the _GL_TYPE_MASK below if these are changed */ - COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_BYTE = 1<<10, - COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_BYTE = 1<<11, - COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_SHORT = 1<<12, - COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_SHORT = 1<<13, - COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_INT = 1<<14, - COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_INT = 1<<15, - COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_FLOAT = 1<<16, - COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_DOUBLE = 1<<17, - - COGL_MESH_ATTRIBUTE_FLAG_SUBMITTED = 1<<18, - COGL_MESH_ATTRIBUTE_FLAG_UNUSED = 1<<19 - - /* XXX NB: If we need > 24 bits then look at changing the layout - * of struct _CoglMeshAttribute below */ -} CoglMeshAttributeFlags; - -#define COGL_MESH_ATTRIBUTE_FLAG_TYPE_MASK \ - (COGL_MESH_ATTRIBUTE_FLAG_COLOR_ARRAY \ - | COGL_MESH_ATTRIBUTE_FLAG_NORMAL_ARRAY \ - | COGL_MESH_ATTRIBUTE_FLAG_TEXTURE_COORD_ARRAY \ - | COGL_MESH_ATTRIBUTE_FLAG_VERTEX_ARRAY \ - | COGL_MESH_ATTRIBUTE_FLAG_CUSTOM_ARRAY \ - | COGL_MESH_ATTRIBUTE_FLAG_INVALID) - -#define COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_MASK \ - (COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_BYTE \ - | COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_BYTE \ - | COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_SHORT \ - | COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_SHORT \ - | COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_INT \ - | COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_INT \ - | COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_FLOAT \ - | COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_DOUBLE) - - -typedef struct _CoglMeshAttribute -{ - /* TODO: look at breaking up the flags into seperate - * bitfields and seperate enums */ - CoglMeshAttributeFlags flags:24; - guint8 id; - GQuark name; - union _u - { - const void *pointer; - gsize vbo_offset; - } u; - gsize span_bytes; - guint16 stride; - guint8 n_components; - guint8 texture_unit; - -} CoglMeshAttribute; - -typedef enum _CoglMeshVBOFlags -{ - COGL_MESH_VBO_FLAG_UNSTRIDED = 1<<0, - COGL_MESH_VBO_FLAG_STRIDED = 1<<1, - COGL_MESH_VBO_FLAG_MULTIPACK = 1<<2, - - /* FIXME - flatten into one flag, since its used as a boolean */ - COGL_MESH_VBO_FLAG_INFREQUENT_RESUBMIT = 1<<3, - COGL_MESH_VBO_FLAG_FREQUENT_RESUBMIT = 1<<4, - - COGL_MESH_VBO_FLAG_SUBMITTED = 1<<5 -} CoglMeshVBOFlags; - -/* - * A CoglMeshVBO represents one or more attributes in a single buffer object - */ -typedef struct _CoglMeshVBO -{ - CoglMeshVBOFlags flags; - GLuint vbo_name; /*!< The name of the corresponding buffer object */ - gsize vbo_bytes; /*!< The lengh of the allocated buffer object in bytes */ - GList *attributes; -} CoglMeshVBO; - - -typedef struct _CoglMesh -{ - guint ref_count; - guint n_vertices; /*!< The number of vertices in the mesh */ - GList *submitted_vbos; /* The VBOs currently submitted to the GPU */ - - /* Note: new_attributes is normally NULL and only valid while - * modifying a mesh object. */ - GList *new_attributes; /*!< attributes pending submission */ -} CoglMesh; - -#endif /* __COGL_MESH_H */ - diff --git a/common/cogl-vertex-buffer-private.h b/common/cogl-vertex-buffer-private.h new file mode 100644 index 000000000..fc285a6a9 --- /dev/null +++ b/common/cogl-vertex-buffer-private.h @@ -0,0 +1,142 @@ +/* + * Cogl. + * + * An OpenGL/GLES Abstraction/Utility Layer + * + * Copyright (C) 2008 Intel Corporation. + * + * Authored By: Robert Bragg + * + * 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, see . + */ + +#ifndef __COGL_VERTEX_BUFFER_H +#define __COGL_VERTEX_BUFFER_H + +/* Note we put quite a bit into the flags here to help keep + * the down size of the CoglVertexBufferAttrib struct below. */ +typedef enum _CoglVertexBufferAttribFlags +{ + /* Types */ + /* NB: update the _TYPE_MASK below if these are changed */ + COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY = 1<<0, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY = 1<<1, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY = 1<<2, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY = 1<<3, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_CUSTOM_ARRAY = 1<<4, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID = 1<<5, + + COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMALIZED = 1<<6, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED = 1<<7, + + /* Usage hints */ + /* FIXME - flatten into one flag, since its used as a boolean */ + COGL_VERTEX_BUFFER_ATTRIB_FLAG_INFREQUENT_RESUBMIT = 1<<8, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_FREQUENT_RESUBMIT = 1<<9, + + /* GL Data types */ + /* NB: Update the _GL_TYPE_MASK below if these are changed */ + COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_BYTE = 1<<10, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_BYTE = 1<<11, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_SHORT = 1<<12, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_SHORT = 1<<13, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_INT = 1<<14, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_INT = 1<<15, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_FLOAT = 1<<16, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_DOUBLE = 1<<17, + + COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED = 1<<18, + COGL_VERTEX_BUFFER_ATTRIB_FLAG_UNUSED = 1<<19 + + /* XXX NB: If we need > 24 bits then look at changing the layout + * of struct _CoglVertexBufferAttrib below */ +} CoglVertexBufferAttribFlags; + +#define COGL_VERTEX_BUFFER_ATTRIB_FLAG_TYPE_MASK \ + (COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_CUSTOM_ARRAY \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID) + +#define COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_MASK \ + (COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_BYTE \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_BYTE \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_SHORT \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_SHORT \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_INT \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_INT \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_FLOAT \ + | COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_DOUBLE) + + +typedef struct _CoglVertexBufferAttrib +{ + /* TODO: look at breaking up the flags into seperate + * bitfields and seperate enums */ + CoglVertexBufferAttribFlags flags:24; + guint8 id; + GQuark name; + union _u + { + const void *pointer; + gsize vbo_offset; + } u; + gsize span_bytes; + guint16 stride; + guint8 n_components; + guint8 texture_unit; + +} CoglVertexBufferAttrib; + +typedef enum _CoglVertexBufferVBOFlags +{ + COGL_VERTEX_BUFFER_VBO_FLAG_UNSTRIDED = 1<<0, + COGL_VERTEX_BUFFER_VBO_FLAG_STRIDED = 1<<1, + COGL_VERTEX_BUFFER_VBO_FLAG_MULTIPACK = 1<<2, + + /* FIXME - flatten into one flag, since its used as a boolean */ + COGL_VERTEX_BUFFER_VBO_FLAG_INFREQUENT_RESUBMIT = 1<<3, + COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT = 1<<4, + + COGL_VERTEX_BUFFER_VBO_FLAG_SUBMITTED = 1<<5 +} CoglVertexBufferVBOFlags; + +/* + * A CoglVertexBufferVBO represents one or more attributes in a single + * buffer object + */ +typedef struct _CoglVertexBufferVBO +{ + CoglVertexBufferVBOFlags flags; + GLuint vbo_name; /*!< The name of the corresponding buffer object */ + gsize vbo_bytes; /*!< The lengh of the allocated buffer object in bytes */ + GList *attributes; +} CoglVertexBufferVBO; + + +typedef struct _CoglVertexBuffer +{ + guint ref_count; + guint n_vertices; /*!< The number of vertices in the buffer */ + GList *submitted_vbos; /* The VBOs currently submitted to the GPU */ + + /* Note: new_attributes is normally NULL and only valid while + * modifying a buffer. */ + GList *new_attributes; /*!< attributes pending submission */ +} CoglVertexBuffer; + +#endif /* __COGL_VERTEX_BUFFER_H */ + diff --git a/common/cogl-mesh.c b/common/cogl-vertex-buffer.c similarity index 63% rename from common/cogl-mesh.c rename to common/cogl-vertex-buffer.c index f7287f953..45833cdd6 100644 --- a/common/cogl-mesh.c +++ b/common/cogl-vertex-buffer.c @@ -1,8 +1,13 @@ -/* Mesh API: Handle extensible arrays of vertex attributes +/* + * Cogl. + * + * An OpenGL/GLES Abstraction/Utility Layer + * + * Vertex Buffer API: Handle extensible arrays of vertex attributes * * Copyright (C) 2008 Intel Corporation. * - * Authored by: Robert Bragg + * Authored by: Robert Bragg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,14 +24,14 @@ */ /* XXX: For an overview of the functionality implemented here, please - * see cogl.h.in, which contains the gtk-doc section overview for the - * Mesh API. + * see cogl-vertex-buffer.h, which contains the gtk-doc section overview + * for the Vertex Buffers API. */ -/* +/* * TODO: We need to do a better job of minimizing when we call glVertexPointer - * and pals in enable_state_for_drawing_mesh - * + * and pals in enable_state_for_drawing_attributes_buffer + * * We should have an internal 2-tuple cache of (VBO, offset) for each of them * so we can avoid some GL calls. We could have cogl wrappers for the * gl*Pointer funcs that look like this: @@ -38,9 +43,9 @@ * arrays. * * TODO: - * Actually hook this up to the cogl shaders infrastructure. The mesh API has - * been designed to allow adding of arbitrary attributes for use with shaders, - * but this has yet to be actually plumbed together and tested. + * Actually hook this up to the cogl shaders infrastructure. The vertex + * buffer API has been designed to allow adding of arbitrary attributes for use + * with shaders, but this has yet to be actually plumbed together and tested. * The bits we are missing: * - cogl_program_use doesn't currently record within ctx-> which program * is currently in use so a.t.m only Clutter knows the current shader. @@ -48,19 +53,19 @@ * (using glGetAttribLocation) so that we can call glEnableVertexAttribArray * with those indices. * (currently we just make up consecutive indices) - * - some dirty flag meshanims to know when the shader program has changed - * so we don't need to re-query it each time we draw a mesh. - * + * - some dirty flag mechanims to know when the shader program has changed + * so we don't need to re-query it each time we draw a buffer. + * * TODO: - * There is currently no API for querying back info about a mesh, E.g.: - * cogl_mesh_get_n_vertices (mesh_handle); - * cogl_mesh_attribute_get_n_components (mesh_handle, "attrib_name"); - * cogl_mesh_attribute_get_stride (mesh_handle, "attrib_name"); - * cogl_mesh_attribute_get_normalized (mesh_handle, "attrib_name"); - * cogl_mesh_attribute_map (mesh_handle, "attrib_name"); - * cogl_mesh_attribute_unmap (mesh_handle, "attrib_name"); - * (Realistically I wouldn't expect anyone to use such an API examine the - * contents of a mesh for modification, since you'd need to handle too many + * There is currently no API for querying back info about a buffer, E.g.: + * cogl_vertex_buffer_get_n_vertices (buffer_handle); + * cogl_vertex_buffer_get_n_components (buffer_handle, "attrib_name"); + * cogl_vertex_buffer_get_stride (buffer_handle, "attrib_name"); + * cogl_vertex_buffer_get_normalized (buffer_handle, "attrib_name"); + * cogl_vertex_buffer_map (buffer_handle, "attrib_name"); + * cogl_vertex_buffer_unmap (buffer_handle, "attrib_name"); + * (Realistically I wouldn't expect anyone to use such an API to examine the + * contents of a buffer for modification, since you'd need to handle too many * possibilities, but never the less there might be other value in these.) * TODO: @@ -74,47 +79,45 @@ * cogl_vbo_set_usage_hint (COGL_VBO_FLAG_DYNAMIC); * * TODO: - * Experiment with wider use of the mesh API internally to Cogl. + * Experiment with wider use of the vertex buffers API internally to Cogl. * - There is potential, I think, for this API to become a work-horse API * within COGL for submitting geometry to the GPU, and could unify some of * the GL/GLES code paths. * E.g.: - * - Try creating a per-context mesh cache for cogl_texture_rectangle to sit - * on top of. - * - Try saving the tesselation of paths/polygons into mesh objects internally. + * - Try creating a per-context vertex buffer cache for cogl_texture_rectangle + * to sit on top of. + * - Try saving the tesselation of paths/polygons into vertex buffers + * internally. * * TODO - * Expose API that lets developers get back a mesh handle for a particular + * Expose API that lets developers get back a buffer handle for a particular * polygon so they may add custom attributes to them. - * - It should be possible to query/modify a mesh efficiently, in place, + * - It should be possible to query/modify attributes efficiently, in place, * avoiding copies. It would not be acceptable to simply require that - * developers must query back the n_vertices of a mesh and then the - * n_components, type and stride etc of each component since there + * developers must query back the n_vertices of a buffer and then the + * n_components, type and stride etc of each attribute since there * would be too many combinations to realistically handle. - * + * * - In practice, some cases might be best solved with a higher level * EditableMesh API, (see futher below) but for many cases I think an * API like this might be appropriate: * - * cogl_mesh_foreach_vertex (mesh_handle, (MeshIteratorFunc)callback, - * "gl_Vertex", "gl_Color", NULL); - * void callback (CoglMeshVertex *vert) + * cogl_vertex_buffer_foreach_vertex (buffer_handle, + * (AttributesBufferIteratorFunc)callback, + * "gl_Vertex", "gl_Color", NULL); + * static void callback (CoglVertexBufferVertex *vert) * { * GLfloat *pos = vert->attrib[0]; * GLubyte *color = vert->attrib[1]; * GLfloat *new_attrib = buf[vert->index]; - * + * * new_attrib = pos*color; * } * * TODO - * Think about a higher level EditableMesh API for building/modifying mesh - * objects. - * - E.g. look at Blender for inspiration here. They can build a mesh - * from "MVert", "MFace" and "MEdge" primitives. - * - It would be possible to bake an EditableMesh into a regular Mesh, and - * vica versa - * + * Think about a higher level Mesh API for building/modifying attribute buffers + * - E.g. look at Blender for inspiration here. They can build a mesh from + * "MVert", "MFace" and "MEdge" primitives. */ #ifdef HAVE_CONFIG_H @@ -130,13 +133,13 @@ #include "cogl-util.h" #include "cogl-context.h" #include "cogl-handle.h" -#include "cogl-mesh-private.h" +#include "cogl-vertex-buffer-private.h" #define PAD_FOR_ALIGNMENT(VAR, TYPE_SIZE) \ (VAR = TYPE_SIZE + ((VAR - 1) & ~(TYPE_SIZE - 1))) -/* +/* * GL/GLES compatability defines for VBO thingies: */ @@ -166,7 +169,7 @@ #endif -/* +/* * GL/GLES compatability defines for shader things: */ @@ -199,34 +202,27 @@ #endif /* HAVE_COGL_GL */ -static void _cogl_mesh_free (CoglMesh *mesh); +static void _cogl_vertex_buffer_free (CoglVertexBuffer *buffer); -COGL_HANDLE_DEFINE (Mesh, mesh, mesh_handles); +COGL_HANDLE_DEFINE (VertexBuffer, + vertex_buffer, + vertex_buffer_handles); -/** - * cogl_mesh_new: - * @n_vertices: The number of vertices that will make up your mesh. - * - * This creates a Cogl handle for a new mesh that you can then start to add - * attributes too. - * - * Return value: a new #CoglHandle - */ CoglHandle -cogl_mesh_new (guint n_vertices) +cogl_vertex_buffer_new (guint n_vertices) { - CoglMesh *mesh = g_slice_alloc (sizeof (CoglMesh)); + CoglVertexBuffer *buffer = g_slice_alloc (sizeof (CoglVertexBuffer)); - mesh->ref_count = 1; - COGL_HANDLE_DEBUG_NEW (mesh, mesh); - - mesh->n_vertices = n_vertices; - - mesh->submitted_vbos = NULL; - mesh->new_attributes = NULL; + buffer->ref_count = 1; + COGL_HANDLE_DEBUG_NEW (CoglVertexBuffer, buffer); + + buffer->n_vertices = n_vertices; + + buffer->submitted_vbos = NULL; + buffer->new_attributes = NULL; /* return COGL_INVALID_HANDLE; */ - return _cogl_mesh_handle_new (mesh); + return _cogl_vertex_buffer_handle_new (buffer); } /* There are a number of standard OpenGL attributes that we deal with @@ -234,12 +230,12 @@ cogl_mesh_new (guint n_vertices) * so we should catch any typos instead of silently adding a custom * attribute. */ -static CoglMeshAttributeFlags +static CoglVertexBufferAttribFlags validate_gl_attribute (const char *gl_attribute, guint8 *n_components, guint8 *texture_unit) { - CoglMeshAttributeFlags type; + CoglVertexBufferAttribFlags type; char *detail_seperator = NULL; int name_len; @@ -251,18 +247,18 @@ validate_gl_attribute (const char *gl_attribute, if (strncmp (gl_attribute, "Vertex", name_len) == 0) { - type = COGL_MESH_ATTRIBUTE_FLAG_VERTEX_ARRAY; + type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY; } else if (strncmp (gl_attribute, "Color", name_len) == 0) { - type = COGL_MESH_ATTRIBUTE_FLAG_COLOR_ARRAY; + type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY; } else if (strncmp (gl_attribute, "MultiTexCoord", strlen ("MultiTexCoord")) == 0) { unsigned int unit; - + if (sscanf (gl_attribute, "MultiTexCoord%u", &unit) != 1) { g_warning ("gl_MultiTexCoord attributes should include a\n" @@ -271,17 +267,17 @@ validate_gl_attribute (const char *gl_attribute, } /* FIXME: validate any '::' delimiter for this case */ *texture_unit = unit; - type = COGL_MESH_ATTRIBUTE_FLAG_TEXTURE_COORD_ARRAY; + type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY; } else if (strncmp (gl_attribute, "Normal", name_len) == 0) { *n_components = 1; - type = COGL_MESH_ATTRIBUTE_FLAG_NORMAL_ARRAY; + type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY; } else { g_warning ("Unknown gl_* attribute name gl_%s\n", gl_attribute); - type = COGL_MESH_ATTRIBUTE_FLAG_INVALID; + type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID; } return type; @@ -290,7 +286,7 @@ validate_gl_attribute (const char *gl_attribute, /* This validates that a custom attribute name is a valid GLSL variable name * * NB: attribute names may have a detail component delimited using '::' E.g. - * custom_attrib::foo or custom_atrib::bar + * custom_attrib::foo or custom_attrib::bar * * maybe I should hang a compiled regex somewhere to handle this */ @@ -311,7 +307,7 @@ validate_custom_attribute_name (const char *attribute_name) || !g_ascii_isalpha (attribute_name[0]) || attribute_name[0] != '_') return FALSE; - + for (i = 1; i < name_len; i++) if (!g_ascii_isalnum (attribute_name[i]) || attribute_name[i] != '_') return FALSE; @@ -319,26 +315,27 @@ validate_custom_attribute_name (const char *attribute_name) return TRUE; } -/* Iterates the the CoglMeshVBOs of a mesh and create a flat list of all the - * submitted attributes +/* Iterates the CoglVertexBufferVBOs of a buffer and creates a flat list + * of all the submitted attributes * - * Note: The CoglMeshAttribute structs are deep copied. + * Note: The CoglVertexBufferAttrib structs are deep copied. */ static GList * -copy_submitted_attributes_list (CoglMesh *mesh) +copy_submitted_attributes_list (CoglVertexBuffer *buffer) { GList *tmp; GList *submitted_attributes = NULL; - for (tmp = mesh->submitted_vbos; tmp != NULL; tmp = tmp->next) + for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next) { - CoglMeshVBO *cogl_vbo = tmp->data; + CoglVertexBufferVBO *cogl_vbo = tmp->data; GList *tmp2; - + for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) { - CoglMeshAttribute *attribute = tmp2->data; - CoglMeshAttribute *copy = g_slice_alloc (sizeof (CoglMeshAttribute)); + CoglVertexBufferAttrib *attribute = tmp2->data; + CoglVertexBufferAttrib *copy = + g_slice_alloc (sizeof (CoglVertexBufferAttrib)); *copy = *attribute; submitted_attributes = g_list_prepend (submitted_attributes, copy); } @@ -346,59 +343,60 @@ copy_submitted_attributes_list (CoglMesh *mesh) return submitted_attributes; } -static CoglMeshAttributeFlags +static CoglVertexBufferAttribFlags get_attribute_gl_type_flag_from_gl_type (GLenum gl_type) { switch (gl_type) { case GL_BYTE: - return COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_BYTE; + return COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_BYTE; case GL_UNSIGNED_BYTE: - return COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_BYTE; + return COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_BYTE; case GL_SHORT: - return COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_SHORT; + return COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_SHORT; case GL_UNSIGNED_SHORT: - return COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_SHORT; + return COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_SHORT; case GL_FLOAT: - return COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_FLOAT; + return COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_FLOAT; #if HAVE_COGL_GL case GL_INT: - return COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_INT; + return COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_INT; case GL_UNSIGNED_INT: - return COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_INT; + return COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_INT; case GL_DOUBLE: - return COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_DOUBLE; + return COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_DOUBLE; #endif default: - g_warning ("Mesh API: Unrecognised OpenGL type enum 0x%08x\n", gl_type); + g_warning ("Attribute Buffers API: " + "Unrecognised OpenGL type enum 0x%08x\n", gl_type); return 0; } } static gsize -get_gl_type_size (CoglMeshAttributeFlags flags) +get_gl_type_size (CoglVertexBufferAttribFlags flags) { - CoglMeshAttributeFlags gl_type = - flags & COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_MASK; + CoglVertexBufferAttribFlags gl_type = + flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_MASK; switch (gl_type) { - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_BYTE: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_BYTE: return sizeof (GLbyte); - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_BYTE: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_BYTE: return sizeof (GLubyte); - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_SHORT: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_SHORT: return sizeof (GLshort); - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_SHORT: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_SHORT: return sizeof (GLushort); - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_FLOAT: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_FLOAT: return sizeof (GLfloat); #if HAVE_COGL_GL - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_INT: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_INT: return sizeof (GLint); - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_INT: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_INT: return sizeof (GLuint); - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_DOUBLE: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_DOUBLE: return sizeof (GLdouble); #endif default: @@ -408,39 +406,39 @@ get_gl_type_size (CoglMeshAttributeFlags flags) } void -cogl_mesh_add_attribute (CoglHandle handle, - const char *attribute_name, - guint8 n_components, - GLenum gl_type, - gboolean normalized, - guint16 stride, - const void *pointer) +cogl_vertex_buffer_add (CoglHandle handle, + const char *attribute_name, + guint8 n_components, + GLenum gl_type, + gboolean normalized, + guint16 stride, + const void *pointer) { - CoglMesh *mesh; + CoglVertexBuffer *buffer; GQuark name_quark = g_quark_from_string (attribute_name); gboolean modifying_an_attrib = FALSE; - CoglMeshAttribute *attribute; - CoglMeshAttributeFlags flags = 0; + CoglVertexBufferAttrib *attribute; + CoglVertexBufferAttribFlags flags = 0; guint8 texture_unit = 0; GList *tmp; - if (!cogl_is_mesh (handle)) + if (!cogl_is_vertex_buffer (handle)) return; - mesh = _cogl_mesh_pointer_from_handle (handle); + buffer = _cogl_vertex_buffer_pointer_from_handle (handle); /* The submit function works by diffing between submitted_attributes * and new_attributes to minimize the upload bandwidth + cost of * allocating new VBOs, so if there isn't already a list of new_attributes * we create one: */ - if (!mesh->new_attributes) - mesh->new_attributes = copy_submitted_attributes_list (mesh); - + if (!buffer->new_attributes) + buffer->new_attributes = copy_submitted_attributes_list (buffer); + /* Note: we first look for an existing attribute that we are modifying * so we may skip needing to validate the name */ - for (tmp = mesh->new_attributes; tmp != NULL; tmp = tmp->next) + for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next) { - CoglMeshAttribute *submitted_attribute = tmp->data; + CoglVertexBufferAttrib *submitted_attribute = tmp->data; if (submitted_attribute->name == name_quark) { modifying_an_attrib = TRUE; @@ -449,7 +447,8 @@ cogl_mesh_add_attribute (CoglHandle handle, /* since we will skip validate_gl_attribute in this case, we need * to pluck out the attribute type before overwriting the flags: */ - flags |= attribute->flags & COGL_MESH_ATTRIBUTE_FLAG_TYPE_MASK; + flags |= + attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_TYPE_MASK; break; } } @@ -462,81 +461,81 @@ cogl_mesh_add_attribute (CoglHandle handle, flags |= validate_gl_attribute (attribute_name + 3, &n_components, &texture_unit); - if (flags & COGL_MESH_ATTRIBUTE_FLAG_INVALID) + if (flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID) return; } else { - flags |= COGL_MESH_ATTRIBUTE_FLAG_CUSTOM_ARRAY; + flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_CUSTOM_ARRAY; if (validate_custom_attribute_name (attribute_name)) return; } - attribute = g_slice_alloc (sizeof (CoglMeshAttribute)); + attribute = g_slice_alloc (sizeof (CoglVertexBufferAttrib)); } attribute->name = g_quark_from_string (attribute_name); attribute->n_components = n_components; - attribute->stride = mesh->n_vertices > 1 ? stride : 0; + attribute->stride = buffer->n_vertices > 1 ? stride : 0; attribute->u.pointer = pointer; attribute->texture_unit = texture_unit; flags |= get_attribute_gl_type_flag_from_gl_type (gl_type); - flags |= COGL_MESH_ATTRIBUTE_FLAG_ENABLED; + flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED; /* Note: We currently just assume, if an attribute is *ever* updated * then it should be taged as frequently changing. */ if (modifying_an_attrib) - flags |= COGL_MESH_ATTRIBUTE_FLAG_FREQUENT_RESUBMIT; + flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_FREQUENT_RESUBMIT; else - flags |= COGL_MESH_ATTRIBUTE_FLAG_INFREQUENT_RESUBMIT; + flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_INFREQUENT_RESUBMIT; if (normalized) - flags |= COGL_MESH_ATTRIBUTE_FLAG_NORMALIZED; + flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMALIZED; attribute->flags = flags; - + /* NB: get_gl_type_size must be called after setting the type * flags, above. */ if (attribute->stride) - attribute->span_bytes = mesh->n_vertices * attribute->stride; + attribute->span_bytes = buffer->n_vertices * attribute->stride; else - attribute->span_bytes = mesh->n_vertices + attribute->span_bytes = buffer->n_vertices * attribute->n_components * get_gl_type_size (attribute->flags); if (!modifying_an_attrib) - mesh->new_attributes = - g_list_prepend (mesh->new_attributes, attribute); + buffer->new_attributes = + g_list_prepend (buffer->new_attributes, attribute); } void -cogl_mesh_delete_attribute (CoglHandle handle, - const char *attribute_name) +cogl_vertex_buffer_delete (CoglHandle handle, + const char *attribute_name) { - CoglMesh *mesh; + CoglVertexBuffer *buffer; GQuark name = g_quark_from_string (attribute_name); GList *tmp; - if (!cogl_is_mesh (handle)) + if (!cogl_is_vertex_buffer (handle)) return; - mesh = _cogl_mesh_pointer_from_handle (handle); + buffer = _cogl_vertex_buffer_pointer_from_handle (handle); /* The submit function works by diffing between submitted_attributes * and new_attributes to minimize the upload bandwidth + cost of * allocating new VBOs, so if there isn't already a list of new_attributes * we create one: */ - if (!mesh->new_attributes) - mesh->new_attributes = copy_submitted_attributes_list (mesh); - - for (tmp = mesh->new_attributes; tmp != NULL; tmp = tmp->next) + if (!buffer->new_attributes) + buffer->new_attributes = copy_submitted_attributes_list (buffer); + + for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next) { - CoglMeshAttribute *submitted_attribute = tmp->data; + CoglVertexBufferAttrib *submitted_attribute = tmp->data; if (submitted_attribute->name == name) { - mesh->new_attributes = - g_list_delete_link (mesh->new_attributes, tmp); - g_slice_free (CoglMeshAttribute, submitted_attribute); + buffer->new_attributes = + g_list_delete_link (buffer->new_attributes, tmp); + g_slice_free (CoglVertexBufferAttrib, submitted_attribute); return; } } @@ -550,46 +549,46 @@ set_attribute_enable (CoglHandle handle, const char *attribute_name, gboolean state) { - CoglMesh *mesh; + CoglVertexBuffer *buffer; GQuark name_quark = g_quark_from_string (attribute_name); GList *tmp; - if (!cogl_is_mesh (handle)) + if (!cogl_is_vertex_buffer (handle)) return; - mesh = _cogl_mesh_pointer_from_handle (handle); - - /* NB: If a mesh is currently being edited, then there can be two seperate - * lists of attributes; those that are currently submitted and a new - * list yet to be submitted, we need to modify both. */ + buffer = _cogl_vertex_buffer_pointer_from_handle (handle); - for (tmp = mesh->new_attributes; tmp != NULL; tmp = tmp->next) + /* NB: If a buffer is currently being edited, then there can be two seperate + * lists of attributes; those that are currently submitted and a new list yet + * to be submitted, we need to modify both. */ + + for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next) { - CoglMeshAttribute *attribute = tmp->data; + CoglVertexBufferAttrib *attribute = tmp->data; if (attribute->name == name_quark) { if (state) - attribute->flags |= COGL_MESH_ATTRIBUTE_FLAG_ENABLED; + attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED; else - attribute->flags &= ~COGL_MESH_ATTRIBUTE_FLAG_ENABLED; + attribute->flags &= ~COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED; break; } } - - for (tmp = mesh->submitted_vbos; tmp != NULL; tmp = tmp->next) + + for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next) { - CoglMeshVBO *cogl_vbo = tmp->data; + CoglVertexBufferVBO *cogl_vbo = tmp->data; GList *tmp2; for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) { - CoglMeshAttribute *attribute = tmp2->data; + CoglVertexBufferAttrib *attribute = tmp2->data; if (attribute->name == name_quark) { if (state) - attribute->flags |= COGL_MESH_ATTRIBUTE_FLAG_ENABLED; + attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED; else - attribute->flags &= ~COGL_MESH_ATTRIBUTE_FLAG_ENABLED; + attribute->flags &= ~COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED; return; } } @@ -601,23 +600,23 @@ set_attribute_enable (CoglHandle handle, } void -cogl_mesh_enable_attribute (CoglHandle handle, - const char *attribute_name) +cogl_vertex_buffer_enable (CoglHandle handle, + const char *attribute_name) { set_attribute_enable (handle, attribute_name, TRUE); } void -cogl_mesh_disable_attribute (CoglHandle handle, - const char *attribute_name) +cogl_vertex_buffer_disable (CoglHandle handle, + const char *attribute_name) { set_attribute_enable (handle, attribute_name, FALSE); } static void -free_mesh_attribute (CoglMeshAttribute *attribute) +cogl_vertex_buffer_attribute_free (CoglVertexBufferAttrib *attribute) { - g_slice_free (CoglMeshAttribute, attribute); + g_slice_free (CoglVertexBufferAttrib, attribute); } /* Given an attribute that we know has already been submitted before, this @@ -627,7 +626,7 @@ free_mesh_attribute (CoglMeshAttribute *attribute) * VBO has been found. */ static void -filter_already_submitted_attribute (CoglMeshAttribute *attribute, +filter_already_submitted_attribute (CoglVertexBufferAttrib *attribute, GList **reuse_vbos, GList **submitted_vbos) { @@ -637,38 +636,41 @@ filter_already_submitted_attribute (CoglMeshAttribute *attribute, * are more likley to get a match here */ for (tmp = *reuse_vbos; tmp != NULL; tmp = tmp->next) { - CoglMeshVBO *cogl_vbo = tmp->data; + CoglVertexBufferVBO *cogl_vbo = tmp->data; GList *tmp2; for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) { - CoglMeshAttribute *vbo_attribute = tmp2->data; + CoglVertexBufferAttrib *vbo_attribute = tmp2->data; if (vbo_attribute->name == attribute->name) { - vbo_attribute->flags &= ~COGL_MESH_ATTRIBUTE_FLAG_UNUSED; + vbo_attribute->flags &= + ~COGL_VERTEX_BUFFER_ATTRIB_FLAG_UNUSED; /* Note: we don't free the redundant attribute here, since it - * will be freed after all filtering in cogl_mesh_submit */ + * will be freed after all filtering in + * cogl_vertex_buffer_submit */ return; } } } - + for (tmp = *submitted_vbos; tmp != NULL; tmp = tmp->next) { - CoglMeshVBO *cogl_vbo = tmp->data; - CoglMeshAttribute *reuse_attribute = NULL; + CoglVertexBufferVBO *cogl_vbo = tmp->data; + CoglVertexBufferAttrib *reuse_attribute = NULL; GList *tmp2; for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) { - CoglMeshAttribute *vbo_attribute = tmp2->data; + CoglVertexBufferAttrib *vbo_attribute = tmp2->data; if (vbo_attribute->name == attribute->name) { reuse_attribute = vbo_attribute; /* Note: we don't free the redundant attribute here, since it - * will be freed after all filtering in cogl_mesh_submit */ - + * will be freed after all filtering in + * cogl_vertex_buffer_submit */ + *submitted_vbos = g_list_remove_link (*submitted_vbos, tmp); tmp->next = *reuse_vbos; *reuse_vbos = tmp; @@ -678,15 +680,15 @@ filter_already_submitted_attribute (CoglMeshAttribute *attribute, if (!reuse_attribute) continue; - + /* Mark all but the matched attribute as UNUSED, so that when we * finish filtering all our attributes any attrributes still * marked as UNUSED can be removed from the their cogl_vbo */ for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) { - CoglMeshAttribute *vbo_attribute = tmp2->data; - if (vbo_attribute != reuse_attribute) - vbo_attribute->flags |= COGL_MESH_ATTRIBUTE_FLAG_UNUSED; + CoglVertexBufferAttrib *vbo_attribute = tmp2->data; + if (vbo_attribute != reuse_attribute) + vbo_attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_UNUSED; } return; @@ -696,56 +698,56 @@ filter_already_submitted_attribute (CoglMeshAttribute *attribute, "attribute that had apparently already been submitted!"); } -/* When we first mark a CoglMeshVBO to be reused, we mark the attributes - * as unsed, so that when filtering of attributes into VBOs is done +/* When we first mark a CoglVertexBufferVBO to be reused, we mark the + * attributes as unsed, so that when filtering of attributes into VBOs is done * we can then prune the now unsed attributes. */ static void -remove_unused_attributes (CoglMeshVBO *cogl_vbo) +remove_unused_attributes (CoglVertexBufferVBO *cogl_vbo) { GList *tmp; GList *next; for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = next) { - CoglMeshAttribute *attribute = tmp->data; + CoglVertexBufferAttrib *attribute = tmp->data; next = tmp->next; - if (attribute->flags & COGL_MESH_ATTRIBUTE_FLAG_UNUSED) + if (attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_UNUSED) { cogl_vbo->attributes = g_list_delete_link (cogl_vbo->attributes, tmp); - g_slice_free (CoglMeshAttribute, attribute); + g_slice_free (CoglVertexBufferAttrib, attribute); } } } /* Give a newly added, strided, attribute, this function looks for a - * CoglMeshVBO that the attribute is interleved with. If it can't find - * one then a new CoglMeshVBO is allocated and added to the list of - * new_strided_vbos + * CoglVertexBufferVBO that the attribute is interleved with. If it can't + * find one then a new CoglVertexBufferVBO is allocated and added to the + * list of new_strided_vbos. */ static void -filter_strided_attribute (CoglMeshAttribute *attribute, +filter_strided_attribute (CoglVertexBufferAttrib *attribute, GList **new_vbos) { GList *tmp; - CoglMeshVBO *new_cogl_vbo; + CoglVertexBufferVBO *new_cogl_vbo; for (tmp = *new_vbos; tmp != NULL; tmp = tmp->next) { - CoglMeshVBO *cogl_vbo = tmp->data; + CoglVertexBufferVBO *cogl_vbo = tmp->data; GList *tmp2; - - if (!cogl_vbo->flags & COGL_MESH_VBO_FLAG_STRIDED) + + if (!cogl_vbo->flags & COGL_VERTEX_BUFFER_VBO_FLAG_STRIDED) continue; for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) { - CoglMeshAttribute *vbo_attribute = tmp2->data; + CoglVertexBufferAttrib *vbo_attribute = tmp2->data; const char *attribute_start = attribute->u.pointer; const char *vbo_attribute_start = vbo_attribute->u.pointer; - /* NB: All attributes have mesh->n_vertices values which + /* NB: All attributes have buffer->n_vertices values which * simplifies determining which attributes are interleved * since we assume they will start no farther than +- a * stride away from each other: @@ -758,27 +760,30 @@ filter_strided_attribute (CoglMeshAttribute *attribute, cogl_vbo->attributes = g_list_prepend (cogl_vbo->attributes, attribute); - if (attribute->flags & COGL_MESH_ATTRIBUTE_FLAG_FREQUENT_RESUBMIT) + if (attribute->flags & + COGL_VERTEX_BUFFER_ATTRIB_FLAG_FREQUENT_RESUBMIT) { - cogl_vbo->flags &= ~COGL_MESH_VBO_FLAG_INFREQUENT_RESUBMIT; - cogl_vbo->flags |= COGL_MESH_VBO_FLAG_FREQUENT_RESUBMIT; + cogl_vbo->flags &= + ~COGL_VERTEX_BUFFER_VBO_FLAG_INFREQUENT_RESUBMIT; + cogl_vbo->flags |= + COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT; } return; } } - new_cogl_vbo = g_slice_alloc (sizeof (CoglMeshVBO)); + new_cogl_vbo = g_slice_alloc (sizeof (CoglVertexBufferVBO)); new_cogl_vbo->vbo_name = 0; new_cogl_vbo->attributes = NULL; new_cogl_vbo->attributes = g_list_prepend (new_cogl_vbo->attributes, attribute); /* Any one of the interleved attributes will have the same span_bytes */ new_cogl_vbo->vbo_bytes = attribute->span_bytes; - new_cogl_vbo->flags = COGL_MESH_VBO_FLAG_STRIDED; - - if (attribute->flags & COGL_MESH_ATTRIBUTE_FLAG_INFREQUENT_RESUBMIT) - new_cogl_vbo->flags |= COGL_MESH_VBO_FLAG_INFREQUENT_RESUBMIT; + new_cogl_vbo->flags = COGL_VERTEX_BUFFER_VBO_FLAG_STRIDED; + + if (attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_INFREQUENT_RESUBMIT) + new_cogl_vbo->flags |= COGL_VERTEX_BUFFER_VBO_FLAG_INFREQUENT_RESUBMIT; else - new_cogl_vbo->flags |= COGL_MESH_VBO_FLAG_FREQUENT_RESUBMIT; + new_cogl_vbo->flags |= COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT; *new_vbos = g_list_prepend (*new_vbos, new_cogl_vbo); return; @@ -788,21 +793,21 @@ filter_strided_attribute (CoglMeshAttribute *attribute, * contains attribute. If found the list *link* is removed and returned */ static GList * unlink_submitted_vbo_containing_attribute (GList **submitted_vbos, - CoglMeshAttribute *attribute) + CoglVertexBufferAttrib *attribute) { GList *tmp; GList *next = NULL; for (tmp = *submitted_vbos; tmp != NULL; tmp = next) { - CoglMeshVBO *submitted_vbo = tmp->data; + CoglVertexBufferVBO *submitted_vbo = tmp->data; GList *tmp2; next = tmp->next; for (tmp2 = submitted_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) { - CoglMeshAttribute *submitted_attribute = tmp2->data; + CoglVertexBufferAttrib *submitted_attribute = tmp2->data; if (submitted_attribute->name == attribute->name) { @@ -818,7 +823,8 @@ unlink_submitted_vbo_containing_attribute (GList **submitted_vbos, /* Unlinks all the submitted VBOs that conflict with the new cogl_vbo and * returns them as a list. */ static GList * -get_submitted_vbo_conflicts (GList **submitted_vbos, CoglMeshVBO *cogl_vbo) +get_submitted_vbo_conflicts (GList **submitted_vbos, + CoglVertexBufferVBO *cogl_vbo) { GList *tmp; GList *conflicts = NULL; @@ -840,25 +846,25 @@ get_submitted_vbo_conflicts (GList **submitted_vbos, CoglMeshVBO *cogl_vbo) /* Any attributes in cogl_vbo gets removed from conflict_vbo */ static void -disassociate_conflicting_attributes (CoglMeshVBO *conflict_vbo, - CoglMeshVBO *cogl_vbo) +disassociate_conflicting_attributes (CoglVertexBufferVBO *conflict_vbo, + CoglVertexBufferVBO *cogl_vbo) { GList *tmp; - + /* NB: The attributes list in conflict_vbo will be shrinking so * we iterate those in the inner loop. */ for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) { - CoglMeshAttribute *attribute = tmp->data; + CoglVertexBufferAttrib *attribute = tmp->data; GList *tmp2; for (tmp2 = conflict_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) { - CoglMeshAttribute *conflict_attribute = tmp2->data; + CoglVertexBufferAttrib *conflict_attribute = tmp2->data; if (conflict_attribute->name == attribute->name) { - free_mesh_attribute (conflict_attribute); + cogl_vertex_buffer_attribute_free (conflict_attribute); conflict_vbo->attributes = g_list_delete_link (conflict_vbo->attributes, tmp2); break; @@ -868,7 +874,8 @@ disassociate_conflicting_attributes (CoglMeshVBO *conflict_vbo, } static void -free_cogl_mesh_vbo (CoglMeshVBO *cogl_vbo, gboolean delete_gl_vbo) +cogl_vertex_buffer_vbo_free (CoglVertexBufferVBO *cogl_vbo, + gboolean delete_gl_vbo) { GList *tmp; @@ -876,14 +883,15 @@ free_cogl_mesh_vbo (CoglMeshVBO *cogl_vbo, gboolean delete_gl_vbo) for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) { - free_mesh_attribute (tmp->data); + cogl_vertex_buffer_attribute_free (tmp->data); } g_list_free (cogl_vbo->attributes); - if (delete_gl_vbo && cogl_vbo->flags & COGL_MESH_VBO_FLAG_SUBMITTED) + if (delete_gl_vbo && cogl_vbo->flags & + COGL_VERTEX_BUFFER_VBO_FLAG_SUBMITTED) GE (glDeleteBuffers (1, &cogl_vbo->vbo_name)); - g_slice_free (CoglMeshVBO, cogl_vbo); + g_slice_free (CoglVertexBufferVBO, cogl_vbo); } /* This figures out the lowest attribute client pointer. (This pointer is used @@ -893,33 +901,33 @@ free_cogl_mesh_vbo (CoglMeshVBO *cogl_vbo, gboolean delete_gl_vbo) * offset, and marks the attribute as submitted. */ static const void * -prep_strided_vbo_for_upload (CoglMeshVBO *cogl_vbo) +prep_strided_vbo_for_upload (CoglVertexBufferVBO *cogl_vbo) { GList *tmp; const char *lowest_pointer = NULL; for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) { - CoglMeshAttribute *attribute = tmp->data; + CoglVertexBufferAttrib *attribute = tmp->data; const char *client_pointer = attribute->u.pointer; if (!lowest_pointer || client_pointer < lowest_pointer) lowest_pointer = client_pointer; } - + for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) { - CoglMeshAttribute *attribute = tmp->data; + CoglVertexBufferAttrib *attribute = tmp->data; const char *client_pointer = attribute->u.pointer; attribute->u.vbo_offset = client_pointer - lowest_pointer; - attribute->flags |= COGL_MESH_ATTRIBUTE_FLAG_SUBMITTED; + attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED; } return lowest_pointer; } static gboolean -upload_multipack_vbo_via_map_buffer (CoglMeshVBO *cogl_vbo) +upload_multipack_vbo_via_map_buffer (CoglVertexBufferVBO *cogl_vbo) { #if HAVE_COGL_GL GList *tmp; @@ -935,7 +943,7 @@ upload_multipack_vbo_via_map_buffer (CoglMeshVBO *cogl_vbo) for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) { - CoglMeshAttribute *attribute = tmp->data; + CoglVertexBufferAttrib *attribute = tmp->data; gsize attribute_size = attribute->span_bytes; gsize gl_type_size = get_gl_type_size (attribute->flags); @@ -944,7 +952,7 @@ upload_multipack_vbo_via_map_buffer (CoglMeshVBO *cogl_vbo) memcpy (buf + offset, attribute->u.pointer, attribute_size); attribute->u.vbo_offset = offset; - attribute->flags |= COGL_MESH_ATTRIBUTE_FLAG_SUBMITTED; + attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED; offset += attribute_size; } glUnmapBuffer (GL_ARRAY_BUFFER); @@ -956,7 +964,7 @@ upload_multipack_vbo_via_map_buffer (CoglMeshVBO *cogl_vbo) } static void -upload_multipack_vbo_via_buffer_sub_data (CoglMeshVBO *cogl_vbo) +upload_multipack_vbo_via_buffer_sub_data (CoglVertexBufferVBO *cogl_vbo) { GList *tmp; guint offset = 0; @@ -965,7 +973,7 @@ upload_multipack_vbo_via_buffer_sub_data (CoglMeshVBO *cogl_vbo) for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) { - CoglMeshAttribute *attribute = tmp->data; + CoglVertexBufferAttrib *attribute = tmp->data; gsize attribute_size = attribute->span_bytes; gsize gl_type_size = get_gl_type_size (attribute->flags); @@ -976,13 +984,13 @@ upload_multipack_vbo_via_buffer_sub_data (CoglMeshVBO *cogl_vbo) attribute_size, attribute->u.pointer)); attribute->u.vbo_offset = offset; - attribute->flags |= COGL_MESH_ATTRIBUTE_FLAG_SUBMITTED; + attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED; offset += attribute_size; } } static void -upload_gl_vbo (CoglMeshVBO *cogl_vbo) +upload_gl_vbo (CoglVertexBufferVBO *cogl_vbo) { GLenum usage; @@ -990,14 +998,14 @@ upload_gl_vbo (CoglMeshVBO *cogl_vbo) g_return_if_fail (cogl_vbo->vbo_name != 0); - if (cogl_vbo->flags & COGL_MESH_VBO_FLAG_FREQUENT_RESUBMIT) + if (cogl_vbo->flags & COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT) usage = GL_DYNAMIC_DRAW; else usage = GL_STATIC_DRAW; GE (glBindBuffer (GL_ARRAY_BUFFER, cogl_vbo->vbo_name)); - - if (cogl_vbo->flags & COGL_MESH_VBO_FLAG_STRIDED) + + if (cogl_vbo->flags & COGL_VERTEX_BUFFER_VBO_FLAG_STRIDED) { const void *pointer = prep_strided_vbo_for_upload (cogl_vbo); @@ -1006,7 +1014,7 @@ upload_gl_vbo (CoglMeshVBO *cogl_vbo) pointer, usage)); } - else if (cogl_vbo->flags & COGL_MESH_VBO_FLAG_MULTIPACK) + else if (cogl_vbo->flags & COGL_VERTEX_BUFFER_VBO_FLAG_MULTIPACK) { /* First we make it obvious to the driver that we want to update the * whole buffer (without this, the driver is more likley to block @@ -1015,9 +1023,9 @@ upload_gl_vbo (CoglMeshVBO *cogl_vbo) cogl_vbo->vbo_bytes, NULL, usage)); - - /* I think it might depend on the specific driver/HW whether its better to - * use glMapBuffer here or glBufferSubData here. There is even a good + + /* I think it might depend on the specific driver/HW whether its better + * to use glMapBuffer here or glBufferSubData here. There is even a good * thread about this topic here: * http://www.mail-archive.com/dri-devel@lists.sourceforge.net/msg35004.html * For now I have gone with glMapBuffer, but the jury is still out. @@ -1028,7 +1036,7 @@ upload_gl_vbo (CoglMeshVBO *cogl_vbo) } else { - CoglMeshAttribute *attribute = cogl_vbo->attributes->data; + CoglVertexBufferAttrib *attribute = cogl_vbo->attributes->data; GE (glBufferData (GL_ARRAY_BUFFER, cogl_vbo->vbo_bytes, attribute->u.pointer, @@ -1036,21 +1044,21 @@ upload_gl_vbo (CoglMeshVBO *cogl_vbo) /* We forget this pointer now since the client will be free * to re-use this memory */ attribute->u.pointer = NULL; - attribute->flags |= COGL_MESH_ATTRIBUTE_FLAG_SUBMITTED; + attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED; } - cogl_vbo->flags |= COGL_MESH_VBO_FLAG_SUBMITTED; + cogl_vbo->flags |= COGL_VERTEX_BUFFER_VBO_FLAG_SUBMITTED; GE (glBindBuffer (GL_ARRAY_BUFFER, 0)); } -/* Note: although there ends up being quite a few inner loops involved - * with resolving buffers, the number of attributes will be low so I - * don't expect them to cause a problem. */ +/* Note: although there ends up being quite a few inner loops involved with + * resolving buffers, the number of attributes will be low so I don't expect + * them to cause a problem. */ static void -resolve_new_cogl_mesh_vbo (CoglMesh *mesh, - CoglMeshVBO *new_cogl_vbo, - GList **final_vbos) +cogl_vertex_buffer_vbo_resolve (CoglVertexBuffer *buffer, + CoglVertexBufferVBO *new_cogl_vbo, + GList **final_vbos) { GList *conflicts; GList *tmp; @@ -1058,16 +1066,16 @@ resolve_new_cogl_mesh_vbo (CoglMesh *mesh, gboolean found_target_vbo = FALSE; _COGL_GET_CONTEXT (ctx, NO_RETVAL); - + conflicts = - get_submitted_vbo_conflicts (&mesh->submitted_vbos, new_cogl_vbo); + get_submitted_vbo_conflicts (&buffer->submitted_vbos, new_cogl_vbo); for (tmp = conflicts; tmp != NULL; tmp = next) { - CoglMeshVBO *conflict_vbo = tmp->data; + CoglVertexBufferVBO *conflict_vbo = tmp->data; next = tmp->next; - + disassociate_conflicting_attributes (conflict_vbo, new_cogl_vbo); if (!conflict_vbo->attributes) @@ -1079,22 +1087,22 @@ resolve_new_cogl_mesh_vbo (CoglMesh *mesh, { found_target_vbo = TRUE; new_cogl_vbo->vbo_name = conflict_vbo->vbo_name; - free_cogl_mesh_vbo (conflict_vbo, FALSE); - + cogl_vertex_buffer_vbo_free (conflict_vbo, FALSE); + upload_gl_vbo (new_cogl_vbo); *final_vbos = g_list_prepend (*final_vbos, new_cogl_vbo); } else - free_cogl_mesh_vbo (conflict_vbo, TRUE); + cogl_vertex_buffer_vbo_free (conflict_vbo, TRUE); } else { - /* Relink the VBO back into mesh->submitted_vbos since it may + /* Relink the VBO back into buffer->submitted_vbos since it may * be involved in other conflicts later */ - tmp->next = mesh->submitted_vbos; + tmp->next = buffer->submitted_vbos; tmp->prev = NULL; - mesh->submitted_vbos = tmp; + buffer->submitted_vbos = tmp; } } @@ -1103,35 +1111,35 @@ resolve_new_cogl_mesh_vbo (CoglMesh *mesh, GE (glGenBuffers (1, &new_cogl_vbo->vbo_name)); /* FIXME: debug */ g_assert (glGetError() == GL_NO_ERROR); - + upload_gl_vbo (new_cogl_vbo); *final_vbos = g_list_prepend (*final_vbos, new_cogl_vbo); } } void -cogl_mesh_submit (CoglHandle handle) +cogl_vertex_buffer_submit (CoglHandle handle) { - CoglMesh *mesh; + CoglVertexBuffer *buffer; GList *tmp; - CoglMeshVBO *new_multipack_vbo; + CoglVertexBufferVBO *new_multipack_vbo; GList *new_multipack_vbo_link; GList *new_vbos = NULL; GList *reuse_vbos = NULL; GList *final_vbos = NULL; - - if (!cogl_is_mesh (handle)) + + if (!cogl_is_vertex_buffer (handle)) return; - - mesh = _cogl_mesh_pointer_from_handle (handle); - + + buffer = _cogl_vertex_buffer_pointer_from_handle (handle); + /* The objective now is to copy the attribute data supplied by the client - * into buffer objects, but it's important to minimize the amount of memory - * bandwidth we waste here. + * into buffer objects, but it's important to minimize the number of + * redundant data uploads. * - * We need to group together the attributes that are interleved so that the - * driver can use a single continguous memcpy for these. All BOs for - * interleved data are created as STATIC_DRAW_ARB. + * We obviously aim to group together the attributes that are interleved so + * that they can be delivered in one go to the driver. + * All BOs for interleved data are created as STATIC_DRAW_ARB. * * Non interleved attributes tagged as INFREQUENT_RESUBMIT will be grouped * together back to back in a single BO created as STATIC_DRAW_ARB @@ -1139,23 +1147,23 @@ cogl_mesh_submit (CoglHandle handle) * Non interleved attributes tagged as FREQUENT_RESUBMIT will be copied into * individual buffer objects, and the BO itself created DYNAMIC_DRAW_ARB * - * If we are modifying an submitted mesh object then we are carefull not - * to needlesly delete submitted buffer objects and replace with new ones, - * instead we upload new data to the submitted buffers. + * If we are modifying a previously submitted CoglVertexBuffer then we are + * carefull not to needlesly delete OpenGL buffer objects and replace with + * new ones, instead we upload new data to the existing buffers. */ - + /* NB: We must forget attribute->pointer after submitting since the user * is free to re-use that memory for other purposes now. */ /* Pseudo code: - * + * * Broadly speaking we start with a list of unsorted attributes, and filter - * those into 'new' and 're-use' CoglMeshVBO (CBO) lists. We then take the - * list of new CBO structs and compare with the CBOs that have already been - * submitted to the GPU (but ignoring those we already know will be re-used) - * to determine what other CBOs can be re-used, due to being superseded, - * and what new GL VBOs need to be created. - * + * those into 'new' and 're-use' CoglVertexBufferVBO (CBO) lists. We then + * take the list of new CBO structs and compare with the CBOs that have + * already been submitted to the GPU (but ignoring those we already know will + * be re-used) to determine what other CBOs can be re-used, due to being + * superseded, and what new GL VBOs need to be created. + * * We have three kinds of CBOs: * - Unstrided CBOs * These contain a single tightly packed attribute @@ -1193,7 +1201,7 @@ cogl_mesh_submit (CoglHandle handle) * else * add to the new-multipack-CBO * free list of unsorted-attribs - * + * * Next compare the new list of CBOs with the submitted set and try to * minimize the memory bandwidth required to upload the attributes and the * overhead of creating new GL-BOs. @@ -1207,7 +1215,7 @@ cogl_mesh_submit (CoglHandle handle) * (I.e. ones currently submitted to the GPU) * - The "final" CBOs * (The result of resolving the differences between the above sets) - * + * * The re-use CBOs are dealt with first, and we simply delete any remaining * attributes in these that are still marked as UNUSED, and move them * to the list of final CBOs. @@ -1220,11 +1228,11 @@ cogl_mesh_submit (CoglHandle handle) * based on the matches). If the CBO node is superseded it is freed, * if it is modified but may be needed for more descisions later it is * relinked back into the submitted list and if it's identical to a new - * CBO it will be linked into the final list. + * CBO it will be linked into the final list. * * At the end the list of submitted CBOs represents the attributes that were - * deleted from the mesh. - * + * deleted from the buffer. + * * Iterate re-use-CBOs: * Iterate attribs for each: * if attrib UNUSED: @@ -1260,11 +1268,12 @@ cogl_mesh_submit (CoglHandle handle) * delete the submitted GL-BO * free the submitted CBO struct */ - - new_multipack_vbo = g_slice_alloc (sizeof (CoglMeshVBO)); + + new_multipack_vbo = g_slice_alloc (sizeof (CoglVertexBufferVBO)); new_multipack_vbo->vbo_name = 0; - new_multipack_vbo->flags = COGL_MESH_VBO_FLAG_MULTIPACK - | COGL_MESH_VBO_FLAG_INFREQUENT_RESUBMIT; + new_multipack_vbo->flags = + COGL_VERTEX_BUFFER_VBO_FLAG_MULTIPACK + | COGL_VERTEX_BUFFER_VBO_FLAG_INFREQUENT_RESUBMIT; new_multipack_vbo->vbo_bytes = 0; new_multipack_vbo->attributes = NULL; new_vbos = g_list_prepend (new_vbos, new_multipack_vbo); @@ -1275,11 +1284,11 @@ cogl_mesh_submit (CoglHandle handle) /* Start with a list of unsorted attributes, and filter those into * potential new Cogl BO structs */ - for (tmp = mesh->new_attributes; tmp != NULL; tmp = tmp->next) + for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next) { - CoglMeshAttribute *attribute = tmp->data; - - if (attribute->flags & COGL_MESH_ATTRIBUTE_FLAG_SUBMITTED) + CoglVertexBufferAttrib *attribute = tmp->data; + + if (attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED) { /* If the attribute is already marked as submitted, then we need * to find the existing VBO that contains it so we dont delete it. @@ -1289,26 +1298,30 @@ cogl_mesh_submit (CoglHandle handle) */ filter_already_submitted_attribute (attribute, &reuse_vbos, - &mesh->submitted_vbos); + &buffer->submitted_vbos); } else if (attribute->stride) { - /* look for a CoglMeshVBO that the attribute is interleved with. If - * one can't be found then a new CoglMeshVBO is allocated and added - * to the list of new_vbos: */ + /* look for a CoglVertexBufferVBO that the attribute is + * interleved with. If one can't be found then a new + * CoglVertexBufferVBO is allocated and added to the list of + * new_vbos: */ filter_strided_attribute (attribute, &new_vbos); } - else if (attribute->flags & COGL_MESH_ATTRIBUTE_FLAG_FREQUENT_RESUBMIT) + else if (attribute->flags & + COGL_VERTEX_BUFFER_ATTRIB_FLAG_FREQUENT_RESUBMIT) { - CoglMeshVBO *cogl_vbo = g_slice_alloc (sizeof (CoglMeshVBO)); - + CoglVertexBufferVBO *cogl_vbo = + g_slice_alloc (sizeof (CoglVertexBufferVBO)); + /* attributes we expect will be frequently resubmitted are placed * in their own VBO so that updates don't impact other attributes */ cogl_vbo->vbo_name = 0; - cogl_vbo->flags = COGL_MESH_VBO_FLAG_UNSTRIDED - | COGL_MESH_VBO_FLAG_FREQUENT_RESUBMIT; + cogl_vbo->flags = + COGL_VERTEX_BUFFER_VBO_FLAG_UNSTRIDED + | COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT; cogl_vbo->attributes = NULL; cogl_vbo->attributes = g_list_prepend (cogl_vbo->attributes, attribute); @@ -1340,16 +1353,16 @@ cogl_mesh_submit (CoglHandle handle) } } - /* At this point all mesh->new_attributes have been filtered into - * CoglMeshVBOs... */ - g_list_free (mesh->new_attributes); - mesh->new_attributes = NULL; - + /* At this point all buffer->new_attributes have been filtered into + * CoglVertexBufferVBOs... */ + g_list_free (buffer->new_attributes); + buffer->new_attributes = NULL; + /* If the multipack vbo wasn't needed: */ if (new_multipack_vbo->attributes == NULL) { new_vbos = g_list_delete_link (new_vbos, new_multipack_vbo_link); - g_slice_free (CoglMeshVBO, new_multipack_vbo); + g_slice_free (CoglVertexBufferVBO, new_multipack_vbo); } for (tmp = reuse_vbos; tmp != NULL; tmp = tmp->next) @@ -1357,40 +1370,40 @@ cogl_mesh_submit (CoglHandle handle) final_vbos = g_list_concat (final_vbos, reuse_vbos); for (tmp = new_vbos; tmp != NULL; tmp = tmp->next) - resolve_new_cogl_mesh_vbo (mesh, tmp->data, &final_vbos); - - /* Anything left corresponds to deleted attributes: */ - for (tmp = mesh->submitted_vbos; tmp != NULL; tmp = tmp->next) - free_cogl_mesh_vbo (tmp->data, TRUE); - g_list_free (mesh->submitted_vbos); + cogl_vertex_buffer_vbo_resolve (buffer, tmp->data, &final_vbos); - mesh->submitted_vbos = final_vbos; + /* Anything left corresponds to deleted attributes: */ + for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next) + cogl_vertex_buffer_vbo_free (tmp->data, TRUE); + g_list_free (buffer->submitted_vbos); + + buffer->submitted_vbos = final_vbos; } static GLenum -get_gl_type_from_attribute_flags (CoglMeshAttributeFlags flags) +get_gl_type_from_attribute_flags (CoglVertexBufferAttribFlags flags) { - CoglMeshAttributeFlags gl_type = - flags & COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_MASK; + CoglVertexBufferAttribFlags gl_type = + flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_MASK; switch (gl_type) { - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_BYTE: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_BYTE: return GL_BYTE; - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_BYTE: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_BYTE: return GL_UNSIGNED_BYTE; - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_SHORT: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_SHORT: return GL_SHORT; - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_SHORT: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_SHORT: return GL_UNSIGNED_SHORT; - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_FLOAT: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_FLOAT: return GL_FLOAT; #if HAVE_COGL_GL - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_INT: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_INT: return GL_INT; - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_UNSIGNED_INT: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_INT: return GL_UNSIGNED_INT; - case COGL_MESH_ATTRIBUTE_FLAG_GL_TYPE_DOUBLE: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_DOUBLE: return GL_DOUBLE; #endif default: @@ -1401,7 +1414,7 @@ get_gl_type_from_attribute_flags (CoglMeshAttributeFlags flags) } static void -enable_state_for_drawing_mesh (CoglMesh *mesh) +enable_state_for_drawing_attributes_buffer (CoglVertexBuffer *buffer) { GList *tmp; GLenum gl_type; @@ -1412,26 +1425,26 @@ enable_state_for_drawing_mesh (CoglMesh *mesh) _COGL_GET_CONTEXT (ctx, NO_RETVAL); - for (tmp = mesh->submitted_vbos; tmp != NULL; tmp = tmp->next) + for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next) { - CoglMeshVBO *cogl_vbo = tmp->data; + CoglVertexBufferVBO *cogl_vbo = tmp->data; GList *tmp2; GE (glBindBuffer (GL_ARRAY_BUFFER, cogl_vbo->vbo_name)); for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) { - CoglMeshAttribute *attribute = tmp2->data; - CoglMeshAttributeFlags type = - attribute->flags & COGL_MESH_ATTRIBUTE_FLAG_TYPE_MASK; - - if (!(attribute->flags & COGL_MESH_ATTRIBUTE_FLAG_ENABLED)) + CoglVertexBufferAttrib *attribute = tmp2->data; + CoglVertexBufferAttribFlags type = + attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_TYPE_MASK; + + if (!(attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED)) continue; - + gl_type = get_gl_type_from_attribute_flags (attribute->flags); switch (type) { - case COGL_MESH_ATTRIBUTE_FLAG_COLOR_ARRAY: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY: /* FIXME: go through cogl cache to enable color array */ GE (glEnableClientState (GL_COLOR_ARRAY)); GE (glColorPointer (attribute->n_components, @@ -1439,14 +1452,14 @@ enable_state_for_drawing_mesh (CoglMesh *mesh) attribute->stride, (const GLvoid *)attribute->u.vbo_offset)); break; - case COGL_MESH_ATTRIBUTE_FLAG_NORMAL_ARRAY: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY: /* FIXME: go through cogl cache to enable normal array */ GE (glEnableClientState (GL_NORMAL_ARRAY)); GE (glNormalPointer (gl_type, attribute->stride, (const GLvoid *)attribute->u.vbo_offset)); break; - case COGL_MESH_ATTRIBUTE_FLAG_TEXTURE_COORD_ARRAY: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY: /* FIXME: set the active texture unit */ /* NB: Cogl currently manages unit 0 */ enable_flags |= (COGL_ENABLE_TEXCOORD_ARRAY @@ -1459,7 +1472,7 @@ enable_state_for_drawing_mesh (CoglMesh *mesh) attribute->stride, (const GLvoid *)attribute->u.vbo_offset)); break; - case COGL_MESH_ATTRIBUTE_FLAG_VERTEX_ARRAY: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY: enable_flags |= COGL_ENABLE_VERTEX_ARRAY; /* GE (glEnableClientState (GL_VERTEX_ARRAY)); */ GE (glVertexPointer (attribute->n_components, @@ -1467,15 +1480,16 @@ enable_state_for_drawing_mesh (CoglMesh *mesh) attribute->stride, (const GLvoid *)attribute->u.vbo_offset)); break; - case COGL_MESH_ATTRIBUTE_FLAG_CUSTOM_ARRAY: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_CUSTOM_ARRAY: { #ifdef MAY_HAVE_PROGRAMABLE_GL GLboolean normalized = GL_FALSE; - if (attribute->flags & COGL_MESH_ATTRIBUTE_FLAG_NORMALIZED) + if (attribute->flags & + COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMALIZED) normalized = GL_TRUE; /* FIXME: go through cogl cache to enable generic array */ GE (glEnableVertexAttribArray (generic_index++)); - GE (glVertexAttribPointer (generic_index, + GE (glVertexAttribPointer (generic_index, attribute->n_components, gl_type, normalized, @@ -1490,13 +1504,13 @@ enable_state_for_drawing_mesh (CoglMesh *mesh) } } } - + cogl_enable (enable_flags); } static void -disable_state_for_drawing_mesh (CoglMesh *mesh) +disable_state_for_drawing_buffer (CoglVertexBuffer *buffer) { GList *tmp; GLenum gl_type; @@ -1510,40 +1524,40 @@ disable_state_for_drawing_mesh (CoglMesh *mesh) GE (glBindBuffer (GL_ARRAY_BUFFER, 0)); generic_index = 0; - for (tmp = mesh->submitted_vbos; tmp != NULL; tmp = tmp->next) + for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next) { - CoglMeshVBO *cogl_vbo = tmp->data; + CoglVertexBufferVBO *cogl_vbo = tmp->data; GList *tmp2; for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) { - CoglMeshAttribute *attribute = tmp2->data; - CoglMeshAttributeFlags type = - attribute->flags & COGL_MESH_ATTRIBUTE_FLAG_TYPE_MASK; + CoglVertexBufferAttrib *attribute = tmp2->data; + CoglVertexBufferAttribFlags type = + attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_TYPE_MASK; - if (!(attribute->flags & COGL_MESH_ATTRIBUTE_FLAG_ENABLED)) + if (!(attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED)) continue; gl_type = get_gl_type_from_attribute_flags(attribute->flags); switch (type) { - case COGL_MESH_ATTRIBUTE_FLAG_COLOR_ARRAY: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY: /* FIXME: go through cogl cache to enable color array */ GE (glDisableClientState (GL_COLOR_ARRAY)); break; - case COGL_MESH_ATTRIBUTE_FLAG_NORMAL_ARRAY: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY: /* FIXME: go through cogl cache to enable normal array */ GE (glDisableClientState (GL_NORMAL_ARRAY)); break; - case COGL_MESH_ATTRIBUTE_FLAG_TEXTURE_COORD_ARRAY: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY: /* FIXME: set the active texture unit */ /* NB: Cogl currently manages unit 0 */ /* GE (glDisableClientState (GL_VERTEX_ARRAY)); */ break; - case COGL_MESH_ATTRIBUTE_FLAG_VERTEX_ARRAY: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY: /* GE (glDisableClientState (GL_VERTEX_ARRAY)); */ break; - case COGL_MESH_ATTRIBUTE_FLAG_CUSTOM_ARRAY: + case COGL_VERTEX_BUFFER_ATTRIB_FLAG_CUSTOM_ARRAY: #ifdef MAY_HAVE_PROGRAMABLE_GL /* FIXME: go through cogl cache to enable generic array */ GE (glDisableVertexAttribArray (generic_index++)); @@ -1557,62 +1571,63 @@ disable_state_for_drawing_mesh (CoglMesh *mesh) } void -cogl_mesh_draw_arrays (CoglHandle handle, - GLenum mode, - GLint first, - GLsizei count) +cogl_vertex_buffer_draw (CoglHandle handle, + GLenum mode, + GLint first, + GLsizei count) { - CoglMesh *mesh; - - if (!cogl_is_mesh (handle)) + CoglVertexBuffer *buffer; + + if (!cogl_is_vertex_buffer (handle)) return; - - mesh = _cogl_mesh_pointer_from_handle (handle); - - enable_state_for_drawing_mesh (mesh); + + buffer = _cogl_vertex_buffer_pointer_from_handle (handle); + + enable_state_for_drawing_attributes_buffer (buffer); /* FIXME: flush cogl cache */ GE (glDrawArrays (mode, first, count)); - - disable_state_for_drawing_mesh (mesh); + + disable_state_for_drawing_buffer (buffer); } void -cogl_mesh_draw_range_elements (CoglHandle handle, - GLenum mode, - GLuint start, - GLuint end, - GLsizei count, - GLenum type, - const GLvoid *indices) +cogl_vertex_buffer_draw_elements (CoglHandle handle, + GLenum mode, + GLuint min_index, + GLuint max_index, + GLsizei count, + GLenum indices_type, + const GLvoid *indices) { - CoglMesh *mesh; + CoglVertexBuffer *buffer; _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (!cogl_is_mesh (handle)) + + if (!cogl_is_vertex_buffer (handle)) return; - - mesh = _cogl_mesh_pointer_from_handle (handle); - - enable_state_for_drawing_mesh (mesh); + + buffer = _cogl_vertex_buffer_pointer_from_handle (handle); + + enable_state_for_drawing_attributes_buffer (buffer); /* FIXME: flush cogl cache */ - GE (glDrawRangeElements (mode, start, end, count, type, indices)); + GE (glDrawRangeElements (mode, min_index, max_index, + count, indices_type, indices)); - disable_state_for_drawing_mesh (mesh); + disable_state_for_drawing_buffer (buffer); } static void -_cogl_mesh_free (CoglMesh *mesh) +_cogl_vertex_buffer_free (CoglVertexBuffer *buffer) { GList *tmp; - for (tmp = mesh->submitted_vbos; tmp != NULL; tmp = tmp->next) - free_cogl_mesh_vbo (tmp->data, TRUE); - for (tmp = mesh->new_attributes; tmp != NULL; tmp = tmp->next) - free_mesh_attribute (tmp->data); + for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next) + cogl_vertex_buffer_vbo_free (tmp->data, TRUE); + for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next) + cogl_vertex_buffer_attribute_free (tmp->data); - g_slice_free (CoglMesh, mesh); + g_slice_free (CoglVertexBuffer, buffer); } diff --git a/doc/reference/cogl/cogl-docs.sgml b/doc/reference/cogl/cogl-docs.sgml index d1718437e..a7b433c06 100644 --- a/doc/reference/cogl/cogl-docs.sgml +++ b/doc/reference/cogl/cogl-docs.sgml @@ -60,7 +60,7 @@ - + diff --git a/doc/reference/cogl/cogl-sections.txt b/doc/reference/cogl/cogl-sections.txt index db4e16af6..d3e13b03a 100644 --- a/doc/reference/cogl/cogl-sections.txt +++ b/doc/reference/cogl/cogl-sections.txt @@ -279,18 +279,17 @@ cogl_color_get_alpha_float
-cogl-mesh -Mesh API -cogl_mesh_new -cogl_mesh_ref -cogl_mesh_unref -CoglMeshAttributeFlags -cogl_mesh_add_attribute -cogl_mesh_delete_attribute -cogl_mesh_enable_attribute -cogl_mesh_disable_attribute -cogl_mesh_draw_arrays -cogl_mesh_draw_range_elements -cogl_mesh_submit +cogl-attributes-buffer +Attributes Buffer API +cogl_attributes_buffer_new +cogl_attributes_buffer_ref +cogl_attributes_buffer_unref +cogl_attributes_buffer_add +cogl_attributes_buffer_delete +cogl_attributes_buffer_enable +cogl_attributes_buffer_disable +cogl_attributes_buffer_submit +cogl_attributes_buffer_draw +cogl_attributes_buffer_draw_range_elements
diff --git a/gl/Makefile.am b/gl/Makefile.am index 7635b1b90..b355b93d6 100644 --- a/gl/Makefile.am +++ b/gl/Makefile.am @@ -10,7 +10,7 @@ libclutterinclude_HEADERS = \ $(top_builddir)/clutter/cogl/cogl-shader.h \ $(top_builddir)/clutter/cogl/cogl-texture.h \ $(top_builddir)/clutter/cogl/cogl-types.h \ - $(top_builddir)/clutter/cogl/cogl-mesh.h + $(top_builddir)/clutter/cogl/cogl-vertex-buffer.h INCLUDES = \ -I$(top_srcdir) \ diff --git a/gl/cogl-context.c b/gl/cogl-context.c index e2421f4ff..486940711 100644 --- a/gl/cogl-context.c +++ b/gl/cogl-context.c @@ -71,7 +71,7 @@ cogl_create_context () _context->program_handles = NULL; - _context->mesh_handles = NULL; + _context->vertex_buffer_handles = NULL; _context->pf_glGenRenderbuffersEXT = NULL; _context->pf_glBindRenderbufferEXT = NULL; diff --git a/gl/cogl-context.h b/gl/cogl-context.h index ec8d85e03..3ed044421 100644 --- a/gl/cogl-context.h +++ b/gl/cogl-context.h @@ -85,8 +85,8 @@ typedef struct /* Clip stack */ CoglClipStackState clip; - /* Mesh */ - GArray *mesh_handles; + /* Vertex buffers */ + GArray *vertex_buffer_handles; /* Relying on glext.h to define these */ COGL_PFNGLGENRENDERBUFFERSEXTPROC pf_glGenRenderbuffersEXT; diff --git a/gles/Makefile.am b/gles/Makefile.am index 1731d2cb5..30deaf4ff 100644 --- a/gles/Makefile.am +++ b/gles/Makefile.am @@ -10,7 +10,7 @@ libclutterinclude_HEADERS = \ $(top_builddir)/clutter/cogl/cogl-shader.h \ $(top_builddir)/clutter/cogl/cogl-texture.h \ $(top_builddir)/clutter/cogl/cogl-types.h \ - $(top_builddir)/clutter/cogl/cogl-mesh.h + $(top_builddir)/clutter/cogl/cogl-vertex-buffer.h INCLUDES = \ -I$(top_srcdir) \ diff --git a/gles/cogl-context.c b/gles/cogl-context.c index e5c017e80..c3dc8c592 100644 --- a/gles/cogl-context.c +++ b/gles/cogl-context.c @@ -69,7 +69,7 @@ cogl_create_context () _context->shader_handles = NULL; _context->draw_buffer = COGL_WINDOW_BUFFER; - _context->mesh_handles = NULL; + _context->vertex_buffer_handles = NULL; _context->blend_src_factor = CGL_SRC_ALPHA; _context->blend_dst_factor = CGL_ONE_MINUS_SRC_ALPHA; diff --git a/gles/cogl-context.h b/gles/cogl-context.h index d941aaa57..812ce4657 100644 --- a/gles/cogl-context.h +++ b/gles/cogl-context.h @@ -82,8 +82,8 @@ typedef struct GArray *program_handles; GArray *shader_handles; - /* Mesh */ - GArray *mesh_handles; + /* Vertex buffers */ + GArray *vertex_buffer_handles; /* Clip stack */ CoglClipStackState clip;