void _cogl_path_fill_nodes (CoglPath *path, CoglDrawFlags flags) { gboolean needs_fallback = FALSE; CoglPipeline *pipeline = cogl_get_source (); _cogl_pipeline_foreach_layer_internal (pipeline, validate_layer_cb, &needs_fallback); if (needs_fallback) { _cogl_path_fill_nodes_with_clipped_rectangle (path); return; } _cogl_path_build_fill_attribute_buffer (path); _cogl_framebuffer_draw_indexed_attributes (cogl_get_draw_framebuffer (), pipeline, COGL_VERTICES_MODE_TRIANGLES, 0, /* first_vertex */ path->data->fill_vbo_n_indices, path->data->fill_vbo_indices, path->data->fill_attributes, COGL_PATH_N_ATTRIBUTES, flags); }
void cogl_begin_gl (void) { CoglPipeline *pipeline; _COGL_GET_CONTEXT (ctx, NO_RETVAL); if (ctx->in_begin_gl_block) { static CoglBool shown = FALSE; if (!shown) g_warning ("You should not nest cogl_begin_gl/cogl_end_gl blocks"); shown = TRUE; return; } ctx->in_begin_gl_block = TRUE; /* Flush all batched primitives */ cogl_flush (); /* Flush framebuffer state, including clip state, modelview and * projection matrix state * * NB: _cogl_framebuffer_flush_state may disrupt various state (such * as the pipeline state) when flushing the clip stack, so should * always be done first when preparing to draw. */ _cogl_framebuffer_flush_state (cogl_get_draw_framebuffer (), _cogl_get_read_framebuffer (), COGL_FRAMEBUFFER_STATE_ALL); /* Setup the state for the current pipeline */ /* We considered flushing a specific, minimal pipeline here to try and * simplify the GL state, but decided to avoid special cases and second * guessing what would be actually helpful. * * A user should instead call cogl_set_source_color4ub() before * cogl_begin_gl() to simplify the state flushed. * * XXX: note defining n_tex_coord_attribs using * cogl_pipeline_get_n_layers is a hack, but the problem is that * n_tex_coord_attribs is usually defined when drawing a primitive * which isn't happening here. * * Maybe it would be more useful if this code did flush the * opaque_color_pipeline and then call into cogl-pipeline-opengl.c to then * restore all state for the material's backend back to default OpenGL * values. */ pipeline = cogl_get_source (); _cogl_pipeline_flush_gl_state (ctx, pipeline, cogl_get_draw_framebuffer (), FALSE, FALSE); /* Disable any cached vertex arrays */ _cogl_gl_disable_all_attributes (ctx); }
/* TODO: Update to the protoype used in the Cogl master branch. * This is experimental API but not in sync with the cogl_path_fill() * api in Cogl master which takes explicit framebuffer and pipeline * arguments */ void cogl2_path_fill (CoglPath *path) { _COGL_RETURN_IF_FAIL (cogl_is_path (path)); _cogl_path_fill_nodes (path, cogl_get_draw_framebuffer (), cogl_get_source (), 0 /* flags */); }
static void _cogl_rectangles_with_multitexture_coords ( CoglMultiTexturedRect *rects, int n_rects) { _cogl_framebuffer_draw_multitextured_rectangles (cogl_get_draw_framebuffer (), cogl_get_source (), rects, n_rects, FALSE); }
/* TODO: Update to the protoype used in the Cogl master branch. * This is experimental API but not in sync with the cogl_path_fill() * api in Cogl master which takes explicit framebuffer and pipeline * arguments */ void cogl2_path_stroke (CoglPath *path) { _COGL_RETURN_IF_FAIL (cogl_is_path (path)); if (path->data->path_nodes->len == 0) return; _cogl_path_stroke_nodes (path, cogl_get_draw_framebuffer (), cogl_get_source ()); }
static void _cogl_path_stroke_nodes (CoglPath *path) { CoglPathData *data = path->data; CoglPipeline *copy = NULL; CoglPipeline *source; unsigned int path_start; int path_num = 0; CoglPathNode *node; _COGL_GET_CONTEXT (ctx, NO_RETVAL); source = cogl_get_source (); if (cogl_pipeline_get_n_layers (source) != 0) { copy = cogl_pipeline_copy (source); _cogl_pipeline_prune_to_n_layers (copy, 0); source = copy; } _cogl_path_build_stroke_attribute_buffer (path); cogl_push_source (source); for (path_start = 0; path_start < data->path_nodes->len; path_start += node->path_size) { node = &g_array_index (data->path_nodes, CoglPathNode, path_start); cogl_framebuffer_vdraw_attributes (cogl_get_draw_framebuffer (), source, COGL_VERTICES_MODE_LINE_STRIP, 0, node->path_size, data->stroke_attributes[path_num], NULL); path_num++; } cogl_pop_source (); if (copy) cogl_object_unref (copy); }
void cogl_polygon (const CoglTextureVertex *vertices, unsigned int n_vertices, CoglBool use_color) { CoglPipeline *pipeline; ValidateState validate_state; int n_layers; int n_attributes; CoglAttribute **attributes; int i; unsigned int stride; size_t stride_bytes; CoglAttributeBuffer *attribute_buffer; float *v; _COGL_GET_CONTEXT (ctx, NO_RETVAL); pipeline = cogl_get_source (); validate_state.original_pipeline = pipeline; validate_state.pipeline = pipeline; cogl_pipeline_foreach_layer (pipeline, _cogl_polygon_validate_layer_cb, &validate_state); pipeline = validate_state.pipeline; n_layers = cogl_pipeline_get_n_layers (pipeline); n_attributes = 1 + n_layers + (use_color ? 1 : 0); attributes = g_alloca (sizeof (CoglAttribute *) * n_attributes); /* Our data is arranged like: * [X, Y, Z, TX0, TY0, TX1, TY1..., R, G, B, A,...] */ stride = 3 + (2 * n_layers) + (use_color ? 1 : 0); stride_bytes = stride * sizeof (float); /* Make sure there is enough space in the global vertex array. This * is used so we can render the polygon with a single call to OpenGL * but still support any number of vertices */ g_array_set_size (ctx->polygon_vertices, n_vertices * stride); attribute_buffer = cogl_attribute_buffer_new (ctx, n_vertices * stride_bytes, NULL); attributes[0] = cogl_attribute_new (attribute_buffer, "cogl_position_in", stride_bytes, 0, 3, COGL_ATTRIBUTE_TYPE_FLOAT); for (i = 0; i < n_layers; i++) { static const char *names[] = { "cogl_tex_coord0_in", "cogl_tex_coord1_in", "cogl_tex_coord2_in", "cogl_tex_coord3_in", "cogl_tex_coord4_in", "cogl_tex_coord5_in", "cogl_tex_coord6_in", "cogl_tex_coord7_in" }; char *allocated_name = NULL; const char *name; if (i < 8) name = names[i]; else name = allocated_name = g_strdup_printf ("cogl_tex_coord%d_in", i); attributes[i + 1] = cogl_attribute_new (attribute_buffer, name, stride_bytes, /* NB: [X,Y,Z,TX,TY...,R,G,B,A,...] */ 12 + 8 * i, 2, COGL_ATTRIBUTE_TYPE_FLOAT); g_free (allocated_name); } if (use_color) { attributes[n_attributes - 1] = cogl_attribute_new (attribute_buffer, "cogl_color_in", stride_bytes, /* NB: [X,Y,Z,TX,TY...,R,G,B,A,...] */ 12 + 8 * n_layers, 4, COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); } /* Convert the vertices into an array of float vertex attributes */ v = (float *)ctx->polygon_vertices->data; for (i = 0; i < n_vertices; i++) { AppendTexCoordsState append_tex_coords_state; uint8_t *c; /* NB: [X,Y,Z,TX,TY...,R,G,B,A,...] */ v[0] = vertices[i].x; v[1] = vertices[i].y; v[2] = vertices[i].z; append_tex_coords_state.vertices_in = vertices; append_tex_coords_state.vertex = i; append_tex_coords_state.layer = 0; append_tex_coords_state.vertices_out = v; cogl_pipeline_foreach_layer (pipeline, append_tex_coord_attributes_cb, &append_tex_coords_state); if (use_color) { /* NB: [X,Y,Z,TX,TY...,R,G,B,A,...] */ c = (uint8_t *) (v + 3 + 2 * n_layers); c[0] = cogl_color_get_red_byte (&vertices[i].color); c[1] = cogl_color_get_green_byte (&vertices[i].color); c[2] = cogl_color_get_blue_byte (&vertices[i].color); c[3] = cogl_color_get_alpha_byte (&vertices[i].color); } v += stride; } v = (float *)ctx->polygon_vertices->data; cogl_buffer_set_data (COGL_BUFFER (attribute_buffer), 0, v, ctx->polygon_vertices->len * sizeof (float)); /* XXX: although this may seem redundant, we need to do this since * cogl_polygon() can be used with legacy state and its the source stack * which track whether legacy state is enabled. * * (We only have a CoglDrawFlag to disable legacy state not one * to enable it) */ cogl_push_source (pipeline); _cogl_framebuffer_draw_attributes (cogl_get_draw_framebuffer (), pipeline, COGL_VERTICES_MODE_TRIANGLE_FAN, 0, n_vertices, attributes, n_attributes, 0 /* no draw flags */); cogl_pop_source (); if (pipeline != validate_state.original_pipeline) cogl_object_unref (pipeline); cogl_object_unref (attribute_buffer); for (i = 0; i < n_attributes; i++) cogl_object_unref (attributes[i]); }