RutPointalismGrid * rut_pointalism_grid_new (RutContext *ctx, float size, int tex_width, int tex_height) { RutPointalismGrid *grid = g_slice_new0 (RutPointalismGrid); RutBuffer *buffer = rut_buffer_new (sizeof (CoglVertexP3) * 6); RutMesh *pick_mesh = rut_mesh_new_from_buffer_p3 (COGL_VERTICES_MODE_TRIANGLES, 6, buffer); CoglVertexP3 *pick_vertices = (CoglVertexP3 *)buffer->data; float half_tex_width; float half_tex_height; rut_object_init (&grid->_parent, &rut_pointalism_grid_type); grid->ref_count = 1; grid->component.type = RUT_COMPONENT_TYPE_GEOMETRY; grid->ctx = rut_refable_ref (ctx); rut_list_init (&grid->updated_cb_list); grid->slice = pointalism_grid_slice_new (tex_width, tex_height, size); half_tex_width = tex_width / 2.0f; half_tex_height = tex_height / 2.0f; pick_vertices[0].x = -half_tex_width; pick_vertices[0].y = -half_tex_height; pick_vertices[1].x = -half_tex_width; pick_vertices[1].y = half_tex_height; pick_vertices[2].x = half_tex_width; pick_vertices[2].y = half_tex_height; pick_vertices[3] = pick_vertices[0]; pick_vertices[4] = pick_vertices[2]; pick_vertices[5].x = half_tex_width; pick_vertices[5].y = -half_tex_height; grid->pick_mesh = pick_mesh; grid->pointalism_scale = 1; grid->pointalism_z = 1; grid->pointalism_lighter = TRUE; grid->cell_size = size; grid->tex_width = tex_width; grid->tex_height = tex_height; rut_simple_introspectable_init (grid, _rut_pointalism_grid_prop_specs, grid->properties); return grid; }
RutDiamond * rut_diamond_new (RutContext *ctx, float size, int tex_width, int tex_height) { RutDiamond *diamond = g_slice_new0 (RutDiamond); RutBuffer *buffer = rut_buffer_new (sizeof (CoglVertexP3) * 6); RutMesh *pick_mesh = rut_mesh_new_from_buffer_p3 (COGL_VERTICES_MODE_TRIANGLES, 6, buffer); CoglVertexP3 *pick_vertices = (CoglVertexP3 *)buffer->data; rut_object_init (&diamond->_parent, &rut_diamond_type); diamond->ref_count = 1; diamond->component.type = RUT_COMPONENT_TYPE_GEOMETRY; diamond->ctx = rut_refable_ref (ctx); diamond->size = size; /* XXX: It could be worth maintaining a cache of diamond slices * indexed by the <size, tex_width, tex_height> tuple... */ diamond->slice = diamond_slice_new (ctx, size, tex_width, tex_height); pick_vertices[0].x = 0; pick_vertices[0].y = 0; pick_vertices[1].x = 0; pick_vertices[1].y = size; pick_vertices[2].x = size; pick_vertices[2].y = size; pick_vertices[3] = pick_vertices[0]; pick_vertices[4] = pick_vertices[2]; pick_vertices[5].x = size; pick_vertices[5].y = 0; cogl_matrix_transform_points (&diamond->slice->rotate_matrix, 2, sizeof (CoglVertexP3), pick_vertices, sizeof (CoglVertexP3), pick_vertices, 6); diamond->pick_mesh = pick_mesh; return diamond; }
static RutShapeModel * shape_model_new (RutContext *ctx, CoglBool shaped, float tex_width, float tex_height) { RutShapeModel *shape_model = g_slice_new (RutShapeModel); RutBuffer *buffer = rut_buffer_new (sizeof (CoglVertexP3) * 6); RutMesh *pick_mesh = rut_mesh_new_from_buffer_p3 (COGL_VERTICES_MODE_TRIANGLES, 6, buffer); CoglVertexP3 *pick_vertices = (CoglVertexP3 *)buffer->data; CoglMatrix matrix; float tex_aspect; float size_x; float size_y; float half_size_x; float half_size_y; float geom_size_x; float geom_size_y; float half_geom_size_x; float half_geom_size_y; rut_object_init (&shape_model->_parent, &rut_shape_model_type); shape_model->ref_count = 1; if (shaped) { /* In this case we are using a shape mask texture which is has a * square size and is padded with transparent pixels to provide * antialiasing. The shape mask is half the size of the texture * itself so we make the geometry twice as large to compensate. */ size_x = MIN (tex_width, tex_height); size_y = size_x; geom_size_x = size_x * 2.0; geom_size_y = geom_size_x; } else { size_x = tex_width; size_y = tex_height; geom_size_x = tex_width; geom_size_y = tex_height; } half_size_x = size_x / 2.0; half_size_y = size_y / 2.0; half_geom_size_x = geom_size_x / 2.0; half_geom_size_y = geom_size_y / 2.0; { int n_vertices; int i; VertexP2T2T2 vertices[] = { { -half_geom_size_x, -half_geom_size_y, 0, 0, 0, 0 }, { -half_geom_size_x, half_geom_size_y, 0, 1, 0, 1 }, { half_geom_size_x, half_geom_size_y, 1, 1, 1, 1 }, { -half_geom_size_x, -half_geom_size_y, 0, 0, 0, 0 }, { half_geom_size_x, half_geom_size_y, 1, 1, 1, 1 }, { half_geom_size_x, -half_geom_size_y, 1, 0, 1, 0 }, }; cogl_matrix_init_identity (&matrix); tex_aspect = (float)tex_width / (float)tex_height; if (shaped) { float s_scale, t_scale; float s0, t0; /* NB: The circle mask texture has a centered circle that is * half the width of the texture itself. We want the primary * texture to be mapped to this center circle. */ s_scale = 2; t_scale = 2; if (tex_aspect < 1) /* taller than it is wide */ t_scale *= tex_aspect; else /* wider than it is tall */ { float inverse_aspect = 1.0f / tex_aspect; s_scale *= inverse_aspect; } s0 = 0.5 - (s_scale / 2.0); t0 = 0.5 - (t_scale / 2.0); cogl_matrix_translate (&matrix, s0, t0, 0); cogl_matrix_scale (&matrix, s_scale, t_scale, 1); } n_vertices = sizeof (vertices) / sizeof (VertexP2T2T2); for (i = 0; i < n_vertices; i++) { float z = 0, w = 1; cogl_matrix_transform_point (&matrix, &vertices[i].s1, &vertices[i].t1, &z, &w); #ifdef MESA_CONST_ATTRIB_BUG_WORKAROUND vertices[i].Nx = 0; vertices[i].Ny = 0; vertices[i].Nz = 1; vertices[i].Tx = 1; vertices[i].Ty = 0; vertices[i].Tz = 0; #endif } shape_model->primitive = primitive_new_p2t2t2 (ctx->cogl_context, COGL_VERTICES_MODE_TRIANGLES, n_vertices, vertices); } shape_model->shape_texture = cogl_object_ref (ctx->circle_texture); pick_vertices[0].x = -half_size_x; pick_vertices[0].y = -half_size_y; pick_vertices[1].x = -half_size_x; pick_vertices[1].y = half_size_y; pick_vertices[2].x = half_size_x; pick_vertices[2].y = half_size_y; pick_vertices[3] = pick_vertices[0]; pick_vertices[4] = pick_vertices[2]; pick_vertices[5].x = half_size_x; pick_vertices[5].y = -half_size_y; shape_model->pick_mesh = pick_mesh; return shape_model; }
rut_mesh_t * rut_mesh_copy(rut_mesh_t *mesh) { rut_buffer_t **buffers; int n_buffers = 0; rut_buffer_t **attribute_buffers; rut_buffer_t **attribute_buffers_map; rut_attribute_t **attributes; rut_mesh_t *copy; int i; buffers = c_alloca(sizeof(void *) * mesh->n_attributes); attribute_buffers = c_alloca(sizeof(void *) * mesh->n_attributes); attribute_buffers_map = c_alloca(sizeof(void *) * mesh->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 < mesh->n_attributes; i++) { int j; 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] = rut_buffer_new(mesh->attributes[i]->buffered.buffer->size); memcpy(attribute_buffers[n_buffers]->data, mesh->attributes[i]->buffered.buffer->data, mesh->attributes[i]->buffered.buffer->size); 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 < mesh->n_attributes; i++) { if (mesh->attributes[i]->is_buffered) { attributes[i] = rut_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, mesh->attributes[i]->buffered.type); } else { attributes[i] = rut_attribute_new_const(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); } attributes[i]->normalized = mesh->attributes[i]->normalized; attributes[i]->instance_stride = mesh->attributes[i]->instance_stride; } copy = rut_mesh_new(mesh->mode, mesh->n_vertices, attributes, mesh->n_attributes); for (i = 0; i < mesh->n_attributes; i++) rut_object_unref(attributes[i]); if (mesh->indices_buffer) { rut_buffer_t *indices_buffer = rut_buffer_new(mesh->indices_buffer->size); memcpy(indices_buffer->data, mesh->indices_buffer->data, mesh->indices_buffer->size); rut_mesh_set_indices( copy, mesh->indices_type, indices_buffer, mesh->n_indices); rut_object_unref(indices_buffer); } return copy; }
static RutMesh * mesh_new_grid (CoglVerticesMode mode, int n_vertices, int n_indices, GridVertex *vertices, unsigned int *indices) { RutMesh *mesh; RutAttribute *attributes[10]; RutBuffer *vertex_buffer; RutBuffer *index_buffer; vertex_buffer = rut_buffer_new (sizeof (GridVertex) * n_vertices); index_buffer = rut_buffer_new (sizeof (unsigned int) * n_indices); memcpy (vertex_buffer->data, vertices, sizeof (GridVertex) * n_vertices); memcpy (index_buffer->data, indices, sizeof (unsigned int) * n_indices); attributes[0] = rut_attribute_new (vertex_buffer, "cogl_position_in", sizeof (GridVertex), offsetof (GridVertex, x0), 2, RUT_ATTRIBUTE_TYPE_FLOAT); attributes[1] = rut_attribute_new (vertex_buffer, "cogl_tex_coord0_in", sizeof (GridVertex), offsetof (GridVertex, s0), 2, RUT_ATTRIBUTE_TYPE_FLOAT); attributes[2] = rut_attribute_new (vertex_buffer, "cogl_tex_coord1_in", sizeof (GridVertex), offsetof (GridVertex, s3), 2, RUT_ATTRIBUTE_TYPE_FLOAT); attributes[3] = rut_attribute_new (vertex_buffer, "cogl_tex_coord4_in", sizeof (GridVertex), offsetof (GridVertex, s3), 2, RUT_ATTRIBUTE_TYPE_FLOAT); attributes[4] = rut_attribute_new (vertex_buffer, "cogl_tex_coord7_in", sizeof (GridVertex), offsetof (GridVertex, s3), 2, RUT_ATTRIBUTE_TYPE_FLOAT); attributes[5] = rut_attribute_new (vertex_buffer, "cogl_tex_coord11_in", sizeof (GridVertex), offsetof (GridVertex, s0), 2, RUT_ATTRIBUTE_TYPE_FLOAT); attributes[6] = rut_attribute_new (vertex_buffer, "cogl_normal_in", sizeof (GridVertex), offsetof (GridVertex, nx), 3, RUT_ATTRIBUTE_TYPE_FLOAT); attributes[7] = rut_attribute_new (vertex_buffer, "tangent_in", sizeof (GridVertex), offsetof (GridVertex, tx), 3, RUT_ATTRIBUTE_TYPE_FLOAT); attributes[8] = rut_attribute_new (vertex_buffer, "cell_xy", sizeof (GridVertex), offsetof (GridVertex, x1), 2, RUT_ATTRIBUTE_TYPE_FLOAT); attributes[9] = rut_attribute_new (vertex_buffer, "cell_st", sizeof (GridVertex), offsetof (GridVertex, s1), 4, RUT_ATTRIBUTE_TYPE_FLOAT); mesh = rut_mesh_new (mode, n_vertices, attributes, 10); rut_mesh_set_indices (mesh, COGL_INDICES_TYPE_UNSIGNED_INT, index_buffer, n_indices); g_free (vertices); g_free (indices); return mesh; }