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; }