Example #1
0
cg_indices_t *
cg_get_rectangle_indices(cg_device_t *dev, int n_rectangles)
{
    int n_indices = n_rectangles * 6;

    /* Check if the largest index required will fit in a byte array... */
    if (n_indices <= 256 / 4 * 6) {
        /* Generate the byte array if we haven't already */
        if (dev->rectangle_byte_indices == NULL) {
            uint8_t *byte_array = c_malloc(256 / 4 * 6 * sizeof(uint8_t));
            uint8_t *p = byte_array;
            int i, vert_num = 0;

            for (i = 0; i < 256 / 4; i++) {
                *(p++) = vert_num + 0;
                *(p++) = vert_num + 1;
                *(p++) = vert_num + 2;
                *(p++) = vert_num + 0;
                *(p++) = vert_num + 2;
                *(p++) = vert_num + 3;
                vert_num += 4;
            }

            dev->rectangle_byte_indices = cg_indices_new(dev,
                                                         CG_INDICES_TYPE_UNSIGNED_BYTE,
                                                         byte_array,
                                                         256 / 4 * 6);

            c_free(byte_array);
        }

        return dev->rectangle_byte_indices;
    } else {
        if (dev->rectangle_short_indices_len < n_indices) {
            uint16_t *short_array;
            uint16_t *p;
            int i, vert_num = 0;

            if (dev->rectangle_short_indices != NULL)
                cg_object_unref(dev->rectangle_short_indices);
            /* Pick a power of two >= MAX (512, n_indices) */
            if (dev->rectangle_short_indices_len == 0)
                dev->rectangle_short_indices_len = 512;
            while (dev->rectangle_short_indices_len < n_indices)
                dev->rectangle_short_indices_len *= 2;

            /* Over-allocate to generate a whole number of quads */
            p = short_array = c_malloc((dev->rectangle_short_indices_len + 5) /
                                       6 * 6 * sizeof(uint16_t));

            /* Fill in the complete quads */
            for (i = 0; i < dev->rectangle_short_indices_len; i += 6) {
                *(p++) = vert_num + 0;
                *(p++) = vert_num + 1;
                *(p++) = vert_num + 2;
                *(p++) = vert_num + 0;
                *(p++) = vert_num + 2;
                *(p++) = vert_num + 3;
                vert_num += 4;
            }

            dev->rectangle_short_indices =
                cg_indices_new(dev,
                               CG_INDICES_TYPE_UNSIGNED_SHORT,
                               short_array,
                               dev->rectangle_short_indices_len);

            c_free(short_array);
        }

        return dev->rectangle_short_indices;
    }
}
Example #2
0
cg_primitive_t *
rut_mesh_create_primitive(rut_shell_t *shell, rut_mesh_t *mesh)
{
    int n_attributes = mesh->n_attributes;
    rut_buffer_t **buffers;
    int n_buffers = 0;
    cg_attribute_buffer_t **attribute_buffers;
    cg_attribute_buffer_t **attribute_buffers_map;
    cg_attribute_t **attributes;
    cg_primitive_t *primitive;
    int i;

    buffers = c_alloca(sizeof(void *) * n_attributes);
    attribute_buffers = c_alloca(sizeof(void *) * n_attributes);
    attribute_buffers_map = c_alloca(sizeof(void *) * n_attributes);

    /* NB:
     * attributes may refer to shared buffers so we need to first
     * figure out how many unique buffers the mesh refers too...
     */

    for (i = 0; i < n_attributes; i++) {
        int j;

        if (!mesh->attributes[i]->is_buffered)
            continue;

        for (j = 0; i < n_buffers; j++)
            if (buffers[j] == mesh->attributes[i]->buffered.buffer)
                break;

        if (j < n_buffers)
            attribute_buffers_map[i] = attribute_buffers[j];
        else {
            attribute_buffers[n_buffers] =
                cg_attribute_buffer_new(shell->cg_device,
                                        mesh->attributes[i]->buffered.buffer->size,
                                        mesh->attributes[i]->buffered.buffer->data);

            attribute_buffers_map[i] = attribute_buffers[n_buffers];
            buffers[n_buffers++] = mesh->attributes[i]->buffered.buffer;
        }
    }

    attributes = c_alloca(sizeof(void *) * mesh->n_attributes);
    for (i = 0; i < n_attributes; i++) {
        if (mesh->attributes[i]->is_buffered) {
            cg_attribute_type_t type =
                get_cg_attribute_type(mesh->attributes[i]->buffered.type);

            attributes[i] = cg_attribute_new(attribute_buffers_map[i],
                                             mesh->attributes[i]->name,
                                             mesh->attributes[i]->buffered.stride,
                                             mesh->attributes[i]->buffered.offset,
                                             mesh->attributes[i]->buffered.n_components,
                                             type);
        } else {
            attributes[i] = cg_attribute_new_const(shell->cg_device,
                                                   mesh->attributes[i]->name,
                                                   mesh->attributes[i]->constant.n_components,
                                                   mesh->attributes[i]->constant.n_columns,
                                                   mesh->attributes[i]->constant.transpose,
                                                   mesh->attributes[i]->constant.value);
        }

        cg_attribute_set_normalized(attributes[i], mesh->attributes[i]->normalized);
        cg_attribute_set_instance_stride(attributes[i], mesh->attributes[i]->instance_stride);
    }

    for (i = 0; i < n_buffers; i++)
        cg_object_unref(attribute_buffers[i]);

    primitive = cg_primitive_new_with_attributes(
        mesh->mode, mesh->n_vertices, attributes, mesh->n_attributes);

    for (i = 0; i < n_attributes; i++)
        cg_object_unref(attributes[i]);

    if (mesh->indices_buffer) {
        cg_indices_t *indices = cg_indices_new(shell->cg_device,
                                               mesh->indices_type,
                                               mesh->indices_buffer->data,
                                               mesh->n_indices);
        cg_primitive_set_indices(primitive, indices, mesh->n_indices);
        cg_object_unref(indices);
    }

    return primitive;
}