summaryrefslogtreecommitdiff
path: root/cogl/cogl-vertex-buffer.h
blob: 383077128092b6d8ef26f20cf2dae9912365e587 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
/*
 * Cogl
 *
 * An object oriented GL/GLES Abstraction/Utility Layer
 *
 * Copyright (C) 2008,2009 Intel Corporation.
 *
 * 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 <http://www.gnu.org/licenses/>.
 *
 *
 *
 * Authors:
 *   Robert Bragg <robert@linux.intel.com>
 */

#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <cogl/cogl.h> can be included directly."
#endif

#ifndef __COGL_VERTEX_BUFFER_H__
#define __COGL_VERTEX_BUFFER_H__

#include <glib.h>
#include <cogl/cogl-defines.h>
#include <cogl/cogl-types.h>

G_BEGIN_DECLS

/**
 * SECTION:cogl-vertex-buffer
 * @short_description: An API for submitting extensible arrays of vertex
 *   attributes to be mapped into the GPU for fast drawing.
 *
 * For example to describe a textured triangle, you could create a new cogl
 * vertex buffer with 3 vertices, and then you might add 2 attributes for each
 * vertex:
 * <orderedlist>
 * <listitem>
 * a "gl_Position" describing the (x,y,z) position for each vertex.
 * </listitem>
 * <listitem>
 * a "gl_MultiTexCoord0" describing the (tx,ty) texture coordinates for each
 * vertex.
 * </listitem>
 * </orderedlist>
 *
 * The Vertex 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 mapped into your GPU for fast
 * re-use. It is designed to avoid repeated validation of the attributes by the
 * driver; to minimize transport costs (e.g. considering indirect GLX
 * use-cases) and to potentially avoid repeated format conversions when
 * attributes are supplied in a format that is not natively supported by the
 * GPU.
 *
 * Although this API does allow you to modify attributes after they have been
 * submitted to the GPU you should be aware that modification is not that
 * cheap, since it implies validating the new data and potentially the
 * OpenGL driver will need to reformat it for the GPU.
 *
 * If at all possible think of tricks that let you re-use static attributes,
 * and if you do need to repeatedly update attributes (e.g. for some kind of
 * morphing geometry) then only update and re-submit the specific attributes
 * that have changed.
 */

/**
 * cogl_vertex_buffer_new:
 * @n_vertices: The number of vertices that your attributes will correspond to.
 *
 * Creates a new vertex buffer that you can use to add attributes.
 *
 * Return value: a new #CoglHandle
 */
CoglHandle
cogl_vertex_buffer_new (unsigned int n_vertices);

/**
 * cogl_vertex_buffer_get_n_vertices:
 * @handle: A vertex buffer handle
 *
 * Retrieves the number of vertices that @handle represents
 *
 * Return value: the number of vertices
 */
unsigned int
cogl_vertex_buffer_get_n_vertices (CoglHandle handle);

/**
 * CoglAttributeType:
 * @COGL_ATTRIBUTE_TYPE_BYTE: Data is the same size of a byte
 * @COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE: Data is the same size of an
 *   unsigned byte
 * @COGL_ATTRIBUTE_TYPE_SHORT: Data is the same size of a short integer
 * @COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT: Data is the same size of
 *   an unsigned short integer
 * @COGL_ATTRIBUTE_TYPE_FLOAT: Data is the same size of a float
 *
 * Data types for the components of cogl_vertex_buffer_add()
 *
 * Since: 1.0
 */
typedef enum {
  COGL_ATTRIBUTE_TYPE_BYTE = GL_BYTE,
  COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE = GL_UNSIGNED_BYTE,
  COGL_ATTRIBUTE_TYPE_SHORT = GL_SHORT,
  COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT = GL_UNSIGNED_SHORT,
  COGL_ATTRIBUTE_TYPE_FLOAT = GL_FLOAT
} CoglAttributeType;

/**
 * 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 built-in names of GLSL)
 *   <itemizedlist>
 *     <listitem>"gl_Color"</listitem>
 *     <listitem>"gl_Normal"</listitem>
 *     <listitem>"gl_MultiTexCoord0, gl_MultiTexCoord1, ..."</listitem>
 *     <listitem>"gl_Vertex"</listitem>
 *   </itemizedlist>
 *   To support adding multiple variations of the same attribute the name
 *   can have a detail component, E.g. "gl_Color::active" or
 *   "gl_Color::inactive"
 * @n_components: The number of components per attribute and must be 1, 2,
 *   3 or 4
 * @type: a #CoglAttributeType specifying the data type of each component.
 * @normalized: If %TRUE, this specifies that values stored in an integer
 *   format should be mapped into the range [-1.0, 1.0] or [0.0, 1.0]
 *   for unsigned values. If %FALSE they are converted to floats
 *   directly.
 * @stride: This specifies the number of bytes from the start of one attribute
 *   value to the start of the next value (for the same attribute). So, for
 *   example, with a position interleved with color like this:
 *   XYRGBAXYRGBAXYRGBA, then if each letter represents a byte, the
 *   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 either call cogl_vertex_buffer_submit() or
 *   issue a draw call.
 *
 * Adds an attribute to a buffer.
 *
 * You either can use one of the built-in names such as "gl_Vertex", or
 * "gl_MultiTexCoord0" to add standard attributes, like positions, colors
 * and normals, or you can add custom attributes for use in shaders.
 *
 * The number of vertices declared when calling cogl_vertex_buffer_new()
 * determines how many attribute values will be read from the supplied
 * @pointer.
 *
 * The data for your attribute isn't copied anywhere until you call
 * cogl_vertex_buffer_submit(), or issue a draw call which automatically
 * submits pending attribute changes. so the supplied pointer must remain
 * valid until then. If you are updating an existing attribute (done by
 * re-adding it) then you still 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 each interleaved
 * attribute starts no farther than +- stride bytes from the other attributes
 * it is interleved with. I.e. this is ok:
 * <programlisting>
 * |-0-0-0-0-0-0-0-0-0-0|
 * </programlisting>
 * This is not ok:
 * <programlisting>
 * |- - - - -0-0-0-0-0-0 0 0 0 0|
 * </programlisting>
 * (Though you can have multiple groups of interleved attributes)</note>
 */
void
cogl_vertex_buffer_add (CoglHandle         handle,
		        const char        *attribute_name,
			guint8             n_components,
			CoglAttributeType  type,
			gboolean           normalized,
			guint16            stride,
			const void        *pointer);

/**
 * cogl_vertex_buffer_delete:
 * @handle: A vertex buffer handle
 * @attribute_name: The name of a previously added attribute
 *
 * Deletes an attribute from a buffer. You will need to call
 * cogl_vertex_buffer_submit() or issue a draw call to commit this
 * change to the GPU.
 */
void
cogl_vertex_buffer_delete (CoglHandle   handle,
			   const char  *attribute_name);

/**
 * cogl_vertex_buffer_submit:
 * @handle: A vertex buffer handle
 *
 * Submits all the user added attributes to the GPU; once submitted, the
 * attributes can be used for drawing.
 *
 * You should aim to minimize calls to this function since it implies
 * validating your data; it potentially incurs a transport cost (especially if
 * you are using GLX indirect rendering) and potentially a format conversion
 * cost if the GPU doesn't natively support any of the given attribute formats.
 */
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
 *
 * Disables a previosuly added attribute.
 *
 * 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.
 *
 * You don't need to call cogl_vertex_buffer_submit() after using this
 * function.
 */
void
cogl_vertex_buffer_disable (CoglHandle  handle,
			    const char *attribute_name);

/**
 * cogl_vertex_buffer_enable:
 * @handle: A vertex buffer handle
 * @attribute_name: The name of the attribute you want to enable
 *
 * Enables a previosuly disabled attribute.
 *
 * 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.
 *
 * You don't need to call cogl_vertex_buffer_submit() after using this function
 */
void
cogl_vertex_buffer_enable (CoglHandle  handle,
			   const char *attribute_name);

/**
 * CoglVerticesMode:
 * @COGL_VERTICES_MODE_POINTS: FIXME, equivalent to %GL_POINTS
 * @COGL_VERTICES_MODE_LINE_STRIP: FIXME, equivalent to %GL_LINE_STRIP
 * @COGL_VERTICES_MODE_LINE_LOOP: FIXME, equivalent to %GL_LINE_LOOP
 * @COGL_VERTICES_MODE_LINES: FIXME, equivalent to %GL_LINES
 * @COGL_VERTICES_MODE_TRIANGLE_STRIP: FIXME, equivalent to %GL_TRIANGLE_STRIP
 * @COGL_VERTICES_MODE_TRIANGLE_FAN: FIXME, equivalent to %GL_TRIANGLE_FAN
 * @COGL_VERTICES_MODE_TRIANGLES: FIXME, equivalent to %GL_TRIANGLES
 *
 * How vertices passed to cogl_vertex_buffer_draw() and
 * cogl_vertex_buffer_draw_elements() should be interpreted
 *
 * Since: 1.0
 */
typedef enum {
  COGL_VERTICES_MODE_POINTS = GL_POINTS,
  COGL_VERTICES_MODE_LINE_STRIP = GL_LINE_STRIP,
  COGL_VERTICES_MODE_LINE_LOOP = GL_LINE_LOOP,
  COGL_VERTICES_MODE_LINES = GL_LINES,
  COGL_VERTICES_MODE_TRIANGLE_STRIP = GL_TRIANGLE_STRIP,
  COGL_VERTICES_MODE_TRIANGLE_FAN = GL_TRIANGLE_FAN,
  COGL_VERTICES_MODE_TRIANGLES = GL_TRIANGLES
} CoglVerticesMode;

/**
 * cogl_vertex_buffer_draw:
 * @handle: A vertex buffer handle
 * @mode: A #CoglVerticesMode specifying how the vertices should be
 *   interpreted.
 * @first: Specifies the index of the first vertex you want to draw with
 * @count: Specifies the number of vertices you want to draw.
 *
 * Allows you to draw geometry using all or a subset of the
 * vertices in a vertex buffer.
 *
 * Any un-submitted attribute changes are automatically submitted before
 * drawing.
 */
void
cogl_vertex_buffer_draw (CoglHandle       handle,
		         CoglVerticesMode mode,
		         int              first,
		         int              count);

/**
 * CoglIndicesType:
 * @COGL_INDICES_TYPE_UNSIGNED_BYTE: Your indices are unsigned bytes
 * @COGL_INDICES_TYPE_UNSIGNED_SHORT: Your indices are unsigned shorts
 * @COGL_INDICES_TYPE_UNSIGNED_INT: Your indices are unsigned ints
 *
 * You should aim to use the smallest data type that gives you enough
 * range, since it reduces the size of your index array and can help
 * reduce the demand on memory bandwidth.
 *
 * Note that %COGL_INDICES_TYPE_UNSIGNED_INT is only supported if the
 * %COGL_FEATURE_UNSIGNED_INT_INDICES feature is available. This
 * should always be available on OpenGL but on OpenGL ES it will only
 * be available if the GL_OES_element_index_uint extension is
 * advertized.
 */
typedef enum {
  COGL_INDICES_TYPE_UNSIGNED_BYTE,
  COGL_INDICES_TYPE_UNSIGNED_SHORT,
  COGL_INDICES_TYPE_UNSIGNED_INT
} CoglIndicesType;

/**
 * cogl_vertex_buffer_indices_new:
 * @indices_type: a #CoglIndicesType specifying the data type used for
 *    the indices.
 * @indices_array: (array length=indices_len): Specifies the address of
 *   your array of indices
 * @indices_len: The number of indices in indices_array
 *
 * Depending on how much geometry you are submitting it can be worthwhile
 * optimizing the number of redundant vertices you submit. Using an index
 * array allows you to reference vertices multiple times, for example
 * during triangle strips.
 *
 * Return value: A CoglHandle for the indices which you can pass to
 *   cogl_vertex_buffer_draw_elements().
 */
CoglHandle
cogl_vertex_buffer_indices_new (CoglIndicesType  indices_type,
                                const void      *indices_array,
                                int              indices_len);

/**
 * cogl_vertex_buffer_indices_get_type:
 * @handle: An indices handle
 *
 * Queries back the data type used for the given indices
 *
 * Returns: The CoglIndicesType used
 */
CoglIndicesType
cogl_vertex_buffer_indices_get_type (CoglHandle indices);

/**
 * cogl_vertex_buffer_draw_elements:
 * @handle: A vertex buffer handle
 * @mode: A #CoglVerticesMode specifying how the vertices should be
 *    interpreted.
 * @indices: A CoglHandle for a set of indices allocated via
 *    cogl_vertex_buffer_indices_new ()
 * @min_index: Specifies the minimum vertex index contained in indices
 * @max_index: Specifies the maximum vertex index contained in indices
 * @indices_offset: An offset into named indices. The offset marks the first
 *    index to use for drawing.
 * @count: Specifies the number of vertices you want to draw.
 *
 * This function lets you use an array of indices to specify the vertices
 * within your vertex buffer that you want to draw. The indices themselves
 * are created by calling cogl_vertex_buffer_indices_new ()
 *
 * Any un-submitted attribute changes are automatically submitted before
 * drawing.
 */
void
cogl_vertex_buffer_draw_elements (CoglHandle       handle,
			          CoglVerticesMode mode,
                                  CoglHandle       indices,
                                  int              min_index,
                                  int              max_index,
                                  int              indices_offset,
                                  int              count);

#ifndef COGL_DISABLE_DEPRECATED

/**
 * cogl_vertex_buffer_ref:
 * @handle: a @CoglHandle.
 *
 * Increment the reference count for a vertex buffer
 *
 * Return value: the @handle.
 *
 * Deprecated: 1.2: Use cogl_handle_ref() instead
 */
CoglHandle
cogl_vertex_buffer_ref (CoglHandle handle) G_GNUC_DEPRECATED;

/**
 * cogl_vertex_buffer_unref:
 * @handle: a @CoglHandle.
 *
 * Decrement the reference count for a vertex buffer
 *
 * Deprecated: 1.2: Use cogl_handle_unref() instead
 */
void
cogl_vertex_buffer_unref (CoglHandle handle) G_GNUC_DEPRECATED;

#endif /* COGL_DISABLE_DEPRECATED */

/**
 * cogl_vertex_buffer_indices_get_for_quads:
 * @n_indices: the number of indices in the vertex buffer.
 *
 * Creates a vertex buffer containing the indices needed to draw pairs
 * of triangles from a list of vertices grouped as quads. There will
 * be at least @n_indices entries in the buffer (but there may be
 * more).
 *
 * The indices will follow this pattern:
 *
 * 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7 ... etc
 *
 * For example, if you submit vertices for a quad like like that shown
 * in <xref linkend="quad-indices-order"/> then you can request 6
 * indices to render two triangles like those shown in <xref
 * linkend="quad-indices-triangles"/>.
 *
 * <figure id="quad-indices-order">
 *   <title>Example of vertices submitted to form a quad</title>
 *   <graphic fileref="quad-indices-order.png" format="PNG"/>
 * </figure>
 *
 * <figure id="quad-indices-triangles">
 *   <title>Illustration of the triangle indices that will be generated</title>
 *   <graphic fileref="quad-indices-triangles.png" format="PNG"/>
 * </figure>
 *
 * Returns: A %CoglHandle containing the indices. The handled is
 * owned by Cogl and should not be modified or unref'd.
 */
CoglHandle
cogl_vertex_buffer_indices_get_for_quads (unsigned int n_indices);

/**
 * cogl_is_vertex_buffer:
 * @handle: a #CoglHandle for a vertex buffer object
 *
 * Checks whether @handle is a Vertex Buffer Object
 *
 * Return value: %TRUE if the handle is a VBO, and %FALSE
 *   otherwise
 *
 * Since: 1.0
 */
gboolean
cogl_is_vertex_buffer (CoglHandle handle);

/**
 * cogl_is_vertex_buffer_indices:
 * @handle: a #CoglHandle
 *
 * Checks whether @handle is a handle to the indices for a vertex
 * buffer object
 *
 * Return value: %TRUE if the handle is indices, and %FALSE
 *   otherwise
 *
 * Since: 1.4
 */
gboolean
cogl_is_vertex_buffer_indices (CoglHandle handle);

G_END_DECLS

#endif /* __COGL_VERTEX_BUFFER_H__ */