4 * An object oriented GL/GLES Abstraction/Utility Layer
6 * Copyright (C) 2010 Intel Corporation.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library. If not, see
20 * <http://www.gnu.org/licenses/>.
25 * Robert Bragg <robert@linux.intel.com>
26 * Neil Roberts <neil@linux.intel.com>
33 #include "cogl-util.h"
34 #include "cogl-object-private.h"
35 #include "cogl-context-private.h"
36 #include "cogl-indices.h"
37 #include "cogl-indices-private.h"
38 #include "cogl-index-buffer.h"
42 static void _cogl_indices_free (CoglIndices *indices);
44 COGL_OBJECT_DEFINE (Indices, indices);
47 sizeof_indices_type (CoglIndicesType type)
51 case COGL_INDICES_TYPE_UNSIGNED_BYTE:
53 case COGL_INDICES_TYPE_UNSIGNED_SHORT:
55 case COGL_INDICES_TYPE_UNSIGNED_INT:
58 g_return_val_if_reached (0);
62 cogl_indices_new_for_buffer (CoglIndicesType type,
63 CoglIndexBuffer *buffer,
66 CoglIndices *indices = g_slice_new (CoglIndices);
68 indices->buffer = cogl_object_ref (buffer);
69 indices->offset = offset;
73 indices->immutable_ref = 0;
75 return _cogl_indices_object_new (indices);
79 cogl_indices_new (CoglContext *context,
81 const void *indices_data,
84 size_t buffer_bytes = sizeof_indices_type (type) * n_indices;
85 CoglIndexBuffer *index_buffer = cogl_index_buffer_new (context, buffer_bytes);
86 CoglBuffer *buffer = COGL_BUFFER (index_buffer);
89 cogl_buffer_set_data (buffer,
94 indices = cogl_indices_new_for_buffer (type, index_buffer, 0);
95 cogl_object_unref (index_buffer);
101 cogl_indices_get_buffer (CoglIndices *indices)
103 return indices->buffer;
107 cogl_indices_get_type (CoglIndices *indices)
109 _COGL_RETURN_VAL_IF_FAIL (cogl_is_indices (indices),
110 COGL_INDICES_TYPE_UNSIGNED_BYTE);
111 return indices->type;
115 cogl_indices_get_offset (CoglIndices *indices)
117 _COGL_RETURN_VAL_IF_FAIL (cogl_is_indices (indices), 0);
119 return indices->offset;
123 warn_about_midscene_changes (void)
125 static gboolean seen = FALSE;
128 g_warning ("Mid-scene modification of indices has "
129 "undefined results\n");
135 cogl_indices_set_offset (CoglIndices *indices,
138 _COGL_RETURN_IF_FAIL (cogl_is_indices (indices));
140 if (G_UNLIKELY (indices->immutable_ref))
141 warn_about_midscene_changes ();
143 indices->offset = offset;
147 _cogl_indices_free (CoglIndices *indices)
149 cogl_object_unref (indices->buffer);
150 g_slice_free (CoglIndices, indices);
154 _cogl_indices_immutable_ref (CoglIndices *indices)
156 _COGL_RETURN_VAL_IF_FAIL (cogl_is_indices (indices), NULL);
158 indices->immutable_ref++;
159 _cogl_buffer_immutable_ref (COGL_BUFFER (indices->buffer));
164 _cogl_indices_immutable_unref (CoglIndices *indices)
166 _COGL_RETURN_IF_FAIL (cogl_is_indices (indices));
167 _COGL_RETURN_IF_FAIL (indices->immutable_ref > 0);
169 indices->immutable_ref--;
170 _cogl_buffer_immutable_unref (COGL_BUFFER (indices->buffer));
174 cogl_get_rectangle_indices (CoglContext *ctx, int n_rectangles)
176 int n_indices = n_rectangles * 6;
178 /* Check if the largest index required will fit in a byte array... */
179 if (n_indices <= 256 / 4 * 6)
181 /* Generate the byte array if we haven't already */
182 if (ctx->rectangle_byte_indices == NULL)
184 guint8 *byte_array = g_malloc (256 / 4 * 6 * sizeof (guint8));
185 guint8 *p = byte_array;
188 for (i = 0; i < 256 / 4; i++)
190 *(p++) = vert_num + 0;
191 *(p++) = vert_num + 1;
192 *(p++) = vert_num + 2;
193 *(p++) = vert_num + 0;
194 *(p++) = vert_num + 2;
195 *(p++) = vert_num + 3;
199 ctx->rectangle_byte_indices
200 = cogl_indices_new (ctx,
201 COGL_INDICES_TYPE_UNSIGNED_BYTE,
208 return ctx->rectangle_byte_indices;
212 if (ctx->rectangle_short_indices_len < n_indices)
214 guint16 *short_array;
218 if (ctx->rectangle_short_indices != NULL)
219 cogl_object_unref (ctx->rectangle_short_indices);
220 /* Pick a power of two >= MAX (512, n_indices) */
221 if (ctx->rectangle_short_indices_len == 0)
222 ctx->rectangle_short_indices_len = 512;
223 while (ctx->rectangle_short_indices_len < n_indices)
224 ctx->rectangle_short_indices_len *= 2;
226 /* Over-allocate to generate a whole number of quads */
227 p = short_array = g_malloc ((ctx->rectangle_short_indices_len
231 /* Fill in the complete quads */
232 for (i = 0; i < ctx->rectangle_short_indices_len; i += 6)
234 *(p++) = vert_num + 0;
235 *(p++) = vert_num + 1;
236 *(p++) = vert_num + 2;
237 *(p++) = vert_num + 0;
238 *(p++) = vert_num + 2;
239 *(p++) = vert_num + 3;
243 ctx->rectangle_short_indices
244 = cogl_indices_new (ctx,
245 COGL_INDICES_TYPE_UNSIGNED_SHORT,
247 ctx->rectangle_short_indices_len);
249 g_free (short_array);
252 return ctx->rectangle_short_indices;