void _st_paint_shadow_with_opacity (StShadow *shadow_spec, CoglPipeline *shadow_pipeline, ClutterActorBox *box, guint8 paint_opacity) { CoglFramebuffer *fb = cogl_get_draw_framebuffer (); ClutterActorBox shadow_box; CoglColor color; g_return_if_fail (shadow_spec != NULL); g_return_if_fail (shadow_pipeline != NULL); st_shadow_get_box (shadow_spec, box, &shadow_box); cogl_color_init_from_4ub (&color, shadow_spec->color.red * paint_opacity / 255, shadow_spec->color.green * paint_opacity / 255, shadow_spec->color.blue * paint_opacity / 255, shadow_spec->color.alpha * paint_opacity / 255); cogl_color_premultiply (&color); cogl_pipeline_set_layer_combine_constant (shadow_pipeline, 0, &color); cogl_framebuffer_draw_rectangle (fb, shadow_pipeline, shadow_box.x1, shadow_box.y1, shadow_box.x2, shadow_box.y2); }
static void paint_scene (RigPaintContext *paint_ctx) { RutPaintContext *rut_paint_ctx = &paint_ctx->_parent; RigEngine *engine = paint_ctx->engine; CoglContext *ctx = engine->ctx->cogl_context; CoglFramebuffer *fb = rut_camera_get_framebuffer (rut_paint_ctx->camera); if (paint_ctx->pass == RIG_PASS_COLOR_UNBLENDED) { CoglPipeline *pipeline = cogl_pipeline_new (ctx); cogl_pipeline_set_color4f (pipeline, engine->background_color.red, engine->background_color.green, engine->background_color.blue, engine->background_color.alpha); cogl_framebuffer_draw_rectangle (fb, pipeline, 0, 0, engine->device_width, engine->device_height); //0, 0, engine->pane_width, engine->pane_height); cogl_object_unref (pipeline); } rut_graphable_traverse (engine->scene, RUT_TRAVERSE_DEPTH_FIRST, entitygraph_pre_paint_cb, entitygraph_post_paint_cb, paint_ctx); rig_journal_flush (engine->journal, paint_ctx); }
static void _cogl_path_fill_nodes_with_clipped_rectangle (CoglPath *path, CoglFramebuffer *framebuffer, CoglPipeline *pipeline) { /* We need at least three stencil bits to combine clips */ if (_cogl_framebuffer_get_stencil_bits (framebuffer) >= 3) { static CoglBool seen_warning = FALSE; if (!seen_warning) { g_warning ("Paths can not be filled using materials with " "sliced textures unless there is a stencil " "buffer"); seen_warning = TRUE; } } cogl_framebuffer_push_path_clip (framebuffer, path); cogl_framebuffer_draw_rectangle (framebuffer, pipeline, path->data->path_nodes_min.x, path->data->path_nodes_min.y, path->data->path_nodes_max.x, path->data->path_nodes_max.y); cogl_framebuffer_pop_clip (framebuffer); }
static void paint (TestState *state) { CoglPipeline *pipeline; paint_test_backface_culling (state, test_fb); /* * Now repeat the test but rendered to an offscreen * framebuffer. Note that by default the conformance tests are * always run to an offscreen buffer but we might as well have this * check anyway in case it is being run with COGL_TEST_ONSCREEN=1 */ paint_test_backface_culling (state, state->offscreen); /* Copy the result of the offscreen rendering for validation and * also so we can have visual feedback. */ pipeline = cogl_pipeline_new (test_ctx); cogl_pipeline_set_layer_texture (pipeline, 0, state->offscreen_tex); cogl_framebuffer_draw_rectangle (test_fb, pipeline, 0, TEXTURE_RENDER_SIZE * 16, state->width, state->height + TEXTURE_RENDER_SIZE * 16); cogl_object_unref (pipeline); validate_result (test_fb, 0); validate_result (test_fb, 16); }
void test_path_clip (void) { CoglPath *path; CoglPipeline *pipeline; int fb_width, fb_height; fb_width = cogl_framebuffer_get_width (test_fb); fb_height = cogl_framebuffer_get_height (test_fb); cogl_framebuffer_orthographic (test_fb, 0, 0, fb_width, fb_height, -1, 100); path = cogl_path_new (); cogl_framebuffer_clear4f (test_fb, COGL_BUFFER_BIT_COLOR, 1.0f, 0.0f, 0.0f, 1.0f); /* Make an L-shape with the top right corner left untouched */ cogl_path_move_to (path, 0, fb_height); cogl_path_line_to (path, fb_width, fb_height); cogl_path_line_to (path, fb_width, fb_height / 2); cogl_path_line_to (path, fb_width / 2, fb_height / 2); cogl_path_line_to (path, fb_width / 2, 0); cogl_path_line_to (path, 0, 0); cogl_path_close (path); cogl_framebuffer_push_path_clip (test_fb, path); /* Try to fill the framebuffer with a blue rectangle. This should be * clipped to leave the top right quadrant as is */ pipeline = cogl_pipeline_new (test_ctx); cogl_pipeline_set_color4ub (pipeline, 0, 0, 255, 255); cogl_framebuffer_draw_rectangle (test_fb, pipeline, 0, 0, fb_width, fb_height); cogl_framebuffer_pop_clip (test_fb); cogl_object_unref (pipeline); cogl_object_unref (path); /* Check each of the four quadrants */ test_utils_check_pixel (test_fb, fb_width / 4, fb_height / 4, 0x0000ffff); test_utils_check_pixel (test_fb, fb_width * 3 / 4, fb_height / 4, 0xff0000ff); test_utils_check_pixel (test_fb, fb_width / 4, fb_height * 3 / 4, 0x0000ffff); test_utils_check_pixel (test_fb, fb_width * 3 / 4, fb_height * 3 / 4, 0x0000ffff); if (cogl_test_verbose ()) g_print ("OK\n"); }
void _cogl_pango_display_list_render (CoglFramebuffer *fb, CoglPangoDisplayList *dl, const CoglColor *color) { GSList *l; for (l = dl->nodes; l; l = l->next) { CoglPangoDisplayListNode *node = l->data; CoglColor draw_color; if (node->pipeline == NULL) { if (node->type == COGL_PANGO_DISPLAY_LIST_TEXTURE) node->pipeline = _cogl_pango_pipeline_cache_get (dl->pipeline_cache, node->d.texture.texture); else node->pipeline = _cogl_pango_pipeline_cache_get (dl->pipeline_cache, NULL); } if (node->color_override) /* Use the override color but preserve the alpha from the draw color */ cogl_color_init_from_4ub (&draw_color, cogl_color_get_red_byte (&node->color), cogl_color_get_green_byte (&node->color), cogl_color_get_blue_byte (&node->color), cogl_color_get_alpha_byte (color)); else draw_color = *color; cogl_color_premultiply (&draw_color); cogl_pipeline_set_color (node->pipeline, &draw_color); switch (node->type) { case COGL_PANGO_DISPLAY_LIST_TEXTURE: _cogl_framebuffer_draw_display_list_texture (fb, node->pipeline, node); break; case COGL_PANGO_DISPLAY_LIST_RECTANGLE: cogl_framebuffer_draw_rectangle (fb, node->pipeline, node->d.rectangle.x_1, node->d.rectangle.y_1, node->d.rectangle.x_2, node->d.rectangle.y_2); break; case COGL_PANGO_DISPLAY_LIST_TRAPEZOID: cogl_primitive_draw (node->d.trapezoid.primitive, fb, node->pipeline); break; } } }
static void create_pipelines (CoglPipeline **pipelines, int n_pipelines) { int i; for (i = 0; i < n_pipelines; i++) { char *source = g_strdup_printf (" cogl_color_out = " "vec4 (%f, 0.0, 0.0, 1.0);\n", i / 255.0f); CoglSnippet *snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, NULL, /* declarations */ source); g_free (source); pipelines[i] = cogl_pipeline_new (test_ctx); cogl_pipeline_add_snippet (pipelines[i], snippet); cogl_object_unref (snippet); } /* Test that drawing with them works. This should create the entries * in the cache */ for (i = 0; i < n_pipelines; i++) { cogl_framebuffer_draw_rectangle (test_fb, pipelines[i], i, 0, i + 1, 1); test_utils_check_pixel_rgb (test_fb, i, 0, i, 0, 0); } }
static void test_multi_texture (TestState *state) { CoglPipeline *pipeline; CoglTexture3D *tex_3d; CoglTexture2D *tex_2d; uint8_t tex_data[4]; cogl_framebuffer_clear4f (test_fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1); /* Tests a pipeline that is using multi-texturing to combine a 3D texture with a 2D texture. The texture from another layer is sampled with TEXTURE_? just to pick up a specific bug that was happening with the ARBfp fragend */ pipeline = cogl_pipeline_new (test_ctx); tex_data[0] = 0xff; tex_data[1] = 0x00; tex_data[2] = 0x00; tex_data[3] = 0xff; tex_2d = cogl_texture_2d_new_from_data (test_ctx, 1, 1, /* width/height */ COGL_PIXEL_FORMAT_RGBA_8888_PRE, 4, /* rowstride */ tex_data, NULL); cogl_pipeline_set_layer_texture (pipeline, 0, tex_2d); tex_data[0] = 0x00; tex_data[1] = 0xff; tex_data[2] = 0x00; tex_data[3] = 0xff; tex_3d = cogl_texture_3d_new_from_data (test_ctx, 1, 1, 1, /* width/height/depth */ COGL_PIXEL_FORMAT_RGBA_8888_PRE, 4, /* rowstride */ 4, /* image_stride */ tex_data, NULL); cogl_pipeline_set_layer_texture (pipeline, 1, tex_3d); cogl_pipeline_set_layer_combine (pipeline, 0, "RGBA = REPLACE(PREVIOUS)", NULL); cogl_pipeline_set_layer_combine (pipeline, 1, "RGBA = ADD(TEXTURE_0, TEXTURE_1)", NULL); cogl_framebuffer_draw_rectangle (test_fb, pipeline, 0, 0, 10, 10); test_utils_check_pixel (test_fb, 5, 5, 0xffff00ff); cogl_object_unref (tex_2d); cogl_object_unref (tex_3d); cogl_object_unref (pipeline); }
void test_primitive_and_journal (void) { CoglPrimitive *primitives[2]; CoglPipeline *pipeline; setup_orthographic_modelview (); create_primitives (primitives); pipeline = create_pipeline (); /* Set a clip to clip all three rectangles to just the bottom half. * The journal flushes its own clip state so this verifies that the * clip state is correctly restored for the second primitive. */ cogl_framebuffer_push_rectangle_clip (test_fb, 0, 50, 300, 100); cogl_primitive_draw (primitives[0], test_fb, pipeline); /* Draw a rectangle using the journal in-between the two primitives. * This should test that the journal gets flushed correctly and that * the modelview matrix is restored. Half of the rectangle should be * overriden by the second primitive */ cogl_framebuffer_draw_rectangle (test_fb, pipeline, 100, 0, /* x1/y1 */ 300, 100 /* x2/y2 */); cogl_primitive_draw (primitives[1], test_fb, pipeline); /* Check the three rectangles */ test_utils_check_region (test_fb, 1, 51, 98, 48, 0xff0000ff); test_utils_check_region (test_fb, 101, 51, 98, 48, 0x00ff00ff); test_utils_check_region (test_fb, 201, 51, 98, 48, 0x0000ffff); /* Check that the top half of all of the rectangles was clipped */ test_utils_check_region (test_fb, 1, 1, 298, 48, 0x000000ff); cogl_framebuffer_pop_clip (test_fb); if (cogl_test_verbose ()) g_print ("OK\n"); }
static void _rut_rectangle_paint (RutObject *object, RutPaintContext *paint_ctx) { RutRectangle *rectangle = object; RutCamera *camera = paint_ctx->camera; cogl_framebuffer_draw_rectangle (camera->fb, rectangle->pipeline, 0, 0, rectangle->width, rectangle->height); }
static void paint (CoglFramebuffer *fb, const CoglGstRectangle *video_output, void *user_data) { Data *data = user_data; CoglPipeline *pipeline; pipeline = cogl_pipeline_copy (data->pipeline); cogl_gst_video_sink_attach_frame (data->sink, pipeline); cogl_object_unref (data->pipeline); data->pipeline = pipeline; if (data->last_output_width != video_output->width || data->last_output_height != video_output->height) { int location = cogl_pipeline_get_uniform_location (pipeline, "pixel_step"); if (location != -1) { float value[2] = { 1.0f / video_output->width, 1.0f / video_output->height }; cogl_pipeline_set_uniform_float (pipeline, location, 2, /* n_components */ 1, /* count */ value); } data->last_output_width = video_output->width; data->last_output_height = video_output->height; } borders_draw (data->borders, fb, video_output); cogl_framebuffer_draw_rectangle (fb, pipeline, video_output->x, video_output->y, video_output->x + video_output->width, video_output->y + video_output->height); }
void test_alpha_test (void) { CoglTexture *tex = COGL_TEXTURE (create_texture (test_ctx)); CoglPipeline *pipeline = cogl_pipeline_new (test_ctx); int fb_width = cogl_framebuffer_get_width (test_fb); int fb_height = cogl_framebuffer_get_height (test_fb); CoglColor clear_color; cogl_pipeline_set_layer_texture (pipeline, 0, tex); cogl_pipeline_set_layer_filters (pipeline, 0, COGL_PIPELINE_FILTER_NEAREST, COGL_PIPELINE_FILTER_NEAREST); cogl_pipeline_set_alpha_test_function (pipeline, COGL_PIPELINE_ALPHA_FUNC_GEQUAL, 254 / 255.0f /* alpha reference */); cogl_color_init_from_4ub (&clear_color, 0x00, 0x00, 0xff, 0xff); cogl_framebuffer_clear (test_fb, COGL_BUFFER_BIT_COLOR, &clear_color); cogl_framebuffer_draw_rectangle (test_fb, pipeline, -1, -1, 1, 1); cogl_object_unref (pipeline); cogl_object_unref (tex); /* The left side of the framebuffer should use the first pixel from * the texture which is red */ test_utils_check_region (test_fb, 2, 2, fb_width / 2 - 4, fb_height - 4, 0xff0000ff); /* The right side of the framebuffer should use the clear color * because the second pixel from the texture is clipped from the * alpha test */ test_utils_check_region (test_fb, fb_width / 2 + 2, 2, fb_width / 2 - 4, fb_height - 4, 0x0000ffff); if (cogl_test_verbose ()) g_print ("OK\n"); }
static void test_color (CoglPipeline *pipeline, uint32_t color, int pos) { cogl_framebuffer_draw_rectangle (test_fb, pipeline, pos * TEST_SQUARE_SIZE, 0, pos * TEST_SQUARE_SIZE + TEST_SQUARE_SIZE, TEST_SQUARE_SIZE); test_utils_check_pixel (test_fb, pos * TEST_SQUARE_SIZE + TEST_SQUARE_SIZE / 2, TEST_SQUARE_SIZE / 2, color); }
static CoglBool paint_cb (void *user_data) { CoglandCompositor *compositor = user_data; GList *l; for (l = compositor->outputs; l; l = l->next) { CoglandOutput *output = l->data; CoglFramebuffer *fb = output->onscreen; GList *l2; cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1); cogl_primitive_draw (compositor->triangle, fb, compositor->triangle_pipeline); for (l2 = compositor->surfaces; l2; l2 = l2->next) { CoglandSurface *surface = l2->data; if (surface->texture) { CoglTexture2D *texture = surface->texture; CoglPipeline *pipeline = cogl_pipeline_new (compositor->cogl_context); cogl_pipeline_set_layer_texture (pipeline, 0, texture); cogl_framebuffer_draw_rectangle (fb, pipeline, -1, 1, 1, -1); cogl_object_unref (pipeline); } } cogl_onscreen_swap_buffers (COGL_ONSCREEN (fb)); } while (!wl_list_empty (&compositor->frame_callbacks)) { CoglandFrameCallback *callback = wl_container_of (compositor->frame_callbacks.next, callback, link); wl_callback_send_done (callback->resource, get_time ()); wl_resource_destroy (callback->resource); } compositor->redraw_idle = 0; return G_SOURCE_REMOVE; }
void _cogl_path_fill_nodes (CoglPath *path, CoglFramebuffer *framebuffer, CoglPipeline *pipeline, CoglDrawFlags flags) { if (path->data->path_nodes->len == 0) return; /* If the path is a simple rectangle then we can divert to using cogl_framebuffer_draw_rectangle which should be faster because it can go through the journal instead of uploading the geometry just for two triangles */ if (path->data->is_rectangle && flags == 0) { float x_1, y_1, x_2, y_2; _cogl_path_get_bounds (path, &x_1, &y_1, &x_2, &y_2); cogl_framebuffer_draw_rectangle (framebuffer, pipeline, x_1, y_1, x_2, y_2); } else { CoglBool needs_fallback = FALSE; CoglPrimitive *primitive; _cogl_pipeline_foreach_layer_internal (pipeline, validate_layer_cb, &needs_fallback); if (needs_fallback) { _cogl_path_fill_nodes_with_clipped_rectangle (path, framebuffer, pipeline); return; } primitive = _cogl_path_get_fill_primitive (path); _cogl_primitive_draw (primitive, framebuffer, pipeline, flags); } }
static CoglBool paint_cb (void *user_data) { CoglandCompositor *compositor = user_data; GList *l; for (l = compositor->outputs; l; l = l->next) { CoglandOutput *output = l->data; CoglFramebuffer *fb = COGL_FRAMEBUFFER (output->onscreen); GList *l2; cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1); cogl_framebuffer_draw_primitive (fb, compositor->triangle_pipeline, compositor->triangle); for (l2 = compositor->surfaces; l2; l2 = l2->next) { CoglandSurface *surface = l2->data; if (surface->buffer) { CoglTexture2D *texture = surface->buffer->texture; CoglPipeline *pipeline = cogl_pipeline_new (compositor->cogl_context); cogl_pipeline_set_layer_texture (pipeline, 0, COGL_TEXTURE (texture)); cogl_framebuffer_draw_rectangle (fb, pipeline, -1, 1, 1, -1); cogl_object_unref (pipeline); } } cogl_onscreen_swap_buffers (COGL_ONSCREEN (fb)); } while (!g_queue_is_empty (&compositor->frame_callbacks)) { CoglandFrameCallback *callback = g_queue_peek_head (&compositor->frame_callbacks); wl_resource_post_event (&callback->resource, WL_CALLBACK_DONE, get_time ()); wl_resource_destroy (&callback->resource, 0); } return TRUE; }
void test_texture_rg (void) { CoglPipeline *pipeline; CoglTexture2D *tex; int fb_width, fb_height; int x, y; fb_width = cogl_framebuffer_get_width (test_fb); fb_height = cogl_framebuffer_get_height (test_fb); tex = make_texture (); g_assert (cogl_texture_get_components (tex) == COGL_TEXTURE_COMPONENTS_RG); pipeline = cogl_pipeline_new (test_ctx); cogl_pipeline_set_layer_texture (pipeline, 0, tex); cogl_pipeline_set_layer_filters (pipeline, 0, COGL_PIPELINE_FILTER_NEAREST, COGL_PIPELINE_FILTER_NEAREST); cogl_framebuffer_draw_rectangle (test_fb, pipeline, -1.0f, 1.0f, 1.0f, -1.0f); for (y = 0; y < TEX_HEIGHT; y++) for (x = 0; x < TEX_WIDTH; x++) { test_utils_check_pixel_rgb (test_fb, x * fb_width / TEX_WIDTH + fb_width / (TEX_WIDTH * 2), y * fb_height / TEX_HEIGHT + fb_height / (TEX_HEIGHT * 2), x * 256 / TEX_WIDTH, y * 256 / TEX_HEIGHT, 0); } cogl_object_unref (pipeline); cogl_object_unref (tex); }
static void meta_overlay_paint (MetaOverlay *overlay) { if (!overlay->enabled) return; g_assert (meta_is_wayland_compositor ()); cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (), overlay->pipeline, overlay->current_rect.x, overlay->current_rect.y, overlay->current_rect.x + overlay->current_rect.width, overlay->current_rect.y + overlay->current_rect.height); overlay->previous_rect = overlay->current_rect; overlay->previous_is_valid = TRUE; }
static void clutter_colorize_effect_paint_target (ClutterOffscreenEffect *effect) { ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect); CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer (); ClutterActor *actor; guint8 paint_opacity; actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); paint_opacity = clutter_actor_get_paint_opacity (actor); cogl_pipeline_set_color4ub (self->pipeline, paint_opacity, paint_opacity, paint_opacity, paint_opacity); cogl_framebuffer_draw_rectangle (framebuffer, self->pipeline, 0, 0, self->tex_width, self->tex_height); }
static void shell_anamorphosis_effect_paint_target (ClutterOffscreenEffect *effect) { ShellAnamorphosisEffect *self = SHELL_ANAMORPHOSIS_EFFECT (effect); ShellAnamorphosisEffectPrivate *priv = shell_anamorphosis_effect_get_instance_private (self); CoglFramebuffer *fb = cogl_get_draw_framebuffer (); ClutterActor *actor; guint8 paint_opacity; actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); paint_opacity = clutter_actor_get_paint_opacity (actor); cogl_pipeline_set_color4ub (priv->pipeline, paint_opacity, paint_opacity, paint_opacity, paint_opacity); cogl_framebuffer_draw_rectangle (fb, priv->pipeline, 0, 0, priv->tex_width, priv->tex_height); }
static void shell_glsl_quad_paint (ClutterActor *actor) { ShellGLSLQuad *self = SHELL_GLSL_QUAD (actor); ShellGLSLQuadPrivate *priv; guint8 paint_opacity; ClutterActorBox box; priv = shell_glsl_quad_get_instance_private (self); paint_opacity = clutter_actor_get_paint_opacity (actor); clutter_actor_get_allocation_box (actor, &box); cogl_pipeline_set_color4ub (priv->pipeline, paint_opacity, paint_opacity, paint_opacity, paint_opacity); cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (), priv->pipeline, box.x1, box.y1, box.x2, box.y2); }
int main (int argc, char **argv) { CoglOnscreenTemplate *onscreen_template; CoglDisplay *display; CoglContext *ctx; CoglOnscreen *onscreen; CoglFramebuffer *fb; CoglError *error = NULL; CoglVertexP2C4 triangle_vertices[] = { {0, 0.7, 0xff, 0x00, 0x00, 0x80}, {-0.7, -0.7, 0x00, 0xff, 0x00, 0xff}, {0.7, -0.7, 0x00, 0x00, 0xff, 0xff} }; CoglPrimitive *triangle; CoglTexture *tex; CoglOffscreen *offscreen; CoglFramebuffer *offscreen_fb; CoglPipeline *pipeline; onscreen_template = cogl_onscreen_template_new (NULL); cogl_onscreen_template_set_samples_per_pixel (onscreen_template, 4); display = cogl_display_new (NULL, onscreen_template); if (!cogl_display_setup (display, &error)) { fprintf (stderr, "Platform doesn't support onscreen 4x msaa rendering: %s\n", error->message); return 1; } ctx = cogl_context_new (display, &error); if (!ctx) { fprintf (stderr, "Failed to create context: %s\n", error->message); return 1; } onscreen = cogl_onscreen_new (ctx, 640, 480); fb = COGL_FRAMEBUFFER (onscreen); cogl_framebuffer_set_samples_per_pixel (fb, 4); if (!cogl_framebuffer_allocate (fb, &error)) { fprintf (stderr, "Failed to allocate 4x msaa offscreen framebuffer, " "disabling msaa for onscreen rendering: %s\n", error->message); cogl_error_free (error); cogl_framebuffer_set_samples_per_pixel (fb, 0); error = NULL; if (!cogl_framebuffer_allocate (fb, &error)) { fprintf (stderr, "Failed to allocate framebuffer: %s\n", error->message); return 1; } } cogl_onscreen_show (onscreen); tex = cogl_texture_new_with_size (ctx, 320, 480, COGL_TEXTURE_NO_SLICING, COGL_PIXEL_FORMAT_ANY); offscreen = cogl_offscreen_new_to_texture (tex); offscreen_fb = COGL_FRAMEBUFFER (offscreen); cogl_framebuffer_set_samples_per_pixel (offscreen_fb, 4); if (!cogl_framebuffer_allocate (offscreen_fb, &error)) { cogl_error_free (error); error = NULL; fprintf (stderr, "Failed to allocate 4x msaa offscreen framebuffer, " "disabling msaa for offscreen rendering"); cogl_framebuffer_set_samples_per_pixel (offscreen_fb, 0); } triangle = cogl_primitive_new_p2c4 (ctx, COGL_VERTICES_MODE_TRIANGLES, 3, triangle_vertices); pipeline = cogl_pipeline_new (ctx); for (;;) { CoglPollFD *poll_fds; int n_poll_fds; int64_t timeout; CoglPipeline *texture_pipeline; cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1); cogl_framebuffer_push_matrix (fb); cogl_framebuffer_scale (fb, 0.5, 1, 1); cogl_framebuffer_translate (fb, -1, 0, 0); cogl_framebuffer_draw_primitive (fb, pipeline, triangle); cogl_framebuffer_pop_matrix (fb); cogl_framebuffer_draw_primitive (fb, pipeline, triangle); cogl_framebuffer_resolve_samples (offscreen_fb); texture_pipeline = cogl_pipeline_new (ctx); cogl_pipeline_set_layer_texture (texture_pipeline, 0, tex); cogl_framebuffer_draw_rectangle (fb, texture_pipeline, 0, 1, 1, -1); cogl_object_unref (texture_pipeline); cogl_onscreen_swap_buffers (onscreen); cogl_poll_get_info (ctx, &poll_fds, &n_poll_fds, &timeout); g_poll ((GPollFD *) poll_fds, n_poll_fds, 0); cogl_poll_dispatch (ctx, poll_fds, n_poll_fds); } return 0; }
static void paint_pipeline (CoglPipeline *pipeline, int pos) { cogl_framebuffer_draw_rectangle (test_fb, pipeline, pos * 10, 0, pos * 10 + 10, 10); }
void test_alpha_textures (void) { CoglTexture *tex1, *tex2; CoglPipeline *pipeline1, *pipeline2; int fb_width = cogl_framebuffer_get_width (test_fb); int fb_height = cogl_framebuffer_get_height (test_fb); uint8_t replacement_data[1] = { 0xff }; create_pipeline (&tex1, &pipeline1); cogl_framebuffer_draw_rectangle (test_fb, pipeline1, -1.0f, 1.0f, /* x1/y1 */ 1.0f, 0.0f /* x2/y2 */); create_pipeline (&tex2, &pipeline2); cogl_texture_set_region (tex2, 1, 1, /* width / height */ COGL_PIXEL_FORMAT_A_8, 1, /* rowstride */ replacement_data, 1, 1, /* dst_x/y */ 0, /* level */ NULL); /* abort on error */ cogl_framebuffer_draw_rectangle (test_fb, pipeline2, -1.0f, 0.0f, /* x1/y1 */ 1.0f, -1.0f /* x2/y2 */); cogl_object_unref (tex1); cogl_object_unref (tex2); cogl_object_unref (pipeline1); cogl_object_unref (pipeline2); /* Unmodified texture */ test_utils_check_pixel (test_fb, fb_width / 4, fb_height / 8, 0x000000ff); test_utils_check_pixel (test_fb, fb_width * 3 / 4, fb_height / 8, 0x444444ff); test_utils_check_pixel (test_fb, fb_width / 4, fb_height * 3 / 8, 0x888888ff); test_utils_check_pixel (test_fb, fb_width * 3 / 4, fb_height * 3 / 8, 0xccccccff); /* Modified texture */ test_utils_check_pixel (test_fb, fb_width / 4, fb_height * 5 / 8, 0x000000ff); test_utils_check_pixel (test_fb, fb_width * 3 / 4, fb_height * 5 / 8, 0x444444ff); test_utils_check_pixel (test_fb, fb_width / 4, fb_height * 7 / 8, 0x888888ff); test_utils_check_pixel (test_fb, fb_width * 3 / 4, fb_height * 7 / 8, 0xffffffff); if (cogl_test_verbose ()) g_print ("OK\n"); }
CoglTexture * rut_gaussian_blurrer_blur (RutGaussianBlurrer *blurrer, CoglTexture *source) { unsigned int src_w, src_h; CoglPixelFormat format; CoglOffscreen *offscreen; /* create the first FBO to render the x pass */ src_w = cogl_texture_get_width (source); src_h = cogl_texture_get_height (source); format = cogl_texture_get_format (source); if (blurrer->width != src_w || blurrer->height != src_h || blurrer->format != format) { _rut_gaussian_blurrer_free_buffers (blurrer); } if (!blurrer->x_pass) { CoglError *error = NULL; CoglTexture2D *texture_2d = cogl_texture_2d_new_with_size (blurrer->ctx->cogl_context, src_w, src_h, format); if (error) { g_warning ("blurrer: could not create x pass texture: %s", error->message); } blurrer->x_pass = COGL_TEXTURE (texture_2d); blurrer->width = src_w; blurrer->height = src_h; blurrer->format = format; offscreen = cogl_offscreen_new_to_texture (blurrer->x_pass); blurrer->x_pass_fb = COGL_FRAMEBUFFER (offscreen); cogl_framebuffer_orthographic (blurrer->x_pass_fb, 0, 0, src_w, src_h, -1, 100); } if (!blurrer->y_pass) { /* create the second FBO (final destination) to render the y pass */ CoglTexture2D *texture_2d = cogl_texture_2d_new_with_size (blurrer->ctx->cogl_context, src_w, src_h, format); blurrer->destination = COGL_TEXTURE (texture_2d); blurrer->y_pass = blurrer->destination; offscreen = cogl_offscreen_new_to_texture (blurrer->destination); blurrer->y_pass_fb = COGL_FRAMEBUFFER (offscreen); cogl_framebuffer_orthographic (blurrer->y_pass_fb, 0, 0, src_w, src_h, -1, 100); } set_blurrer_pipeline_texture (blurrer->x_pass_pipeline, source, 1.0f / src_w, 0); set_blurrer_pipeline_texture (blurrer->y_pass_pipeline, blurrer->x_pass, 0, 1.0f / src_h); /* x pass */ cogl_framebuffer_draw_rectangle (blurrer->x_pass_fb, blurrer->x_pass_pipeline, 0, 0, blurrer->width, blurrer->height); /* y pass */ cogl_framebuffer_draw_rectangle (blurrer->y_pass_fb, blurrer->y_pass_pipeline, 0, 0, blurrer->width, blurrer->height); return cogl_object_ref (blurrer->destination); }
static void _draw (Data *data) { /* The cogl pipeline needs to be retrieved from the sink before every draw. This is due to the cogl-gst sink creating a new cogl pipeline for each frame by copying the previous one and attaching the new frame to it. */ CoglPipeline* current = cogl_gst_video_sink_get_pipeline (data->sink); data->video_pipeline = current; if (data->video_output.x) { int x = data->video_output.x; /* Letterboxed with vertical borders */ cogl_framebuffer_draw_rectangle (data->fb, data->border_pipeline, 0, 0, x, data->onscreen_height); cogl_framebuffer_draw_rectangle (data->fb, data->border_pipeline, data->onscreen_width - x, 0, data->onscreen_width, data->onscreen_height); cogl_framebuffer_draw_rectangle (data->fb, data->video_pipeline, x, 0, x + data->video_output.width, data->onscreen_height); } else if (data->video_output.y) { int y = data->video_output.y; /* Letterboxed with horizontal borders */ cogl_framebuffer_draw_rectangle (data->fb, data->border_pipeline, 0, 0, data->onscreen_width, y); cogl_framebuffer_draw_rectangle (data->fb, data->border_pipeline, 0, data->onscreen_height - y, data->onscreen_width, data->onscreen_height); cogl_framebuffer_draw_rectangle (data->fb, data->video_pipeline, 0, y, data->onscreen_width, y + data->video_output.height); } else { cogl_framebuffer_draw_rectangle (data->fb, data->video_pipeline, 0, 0, data->onscreen_width, data->onscreen_height); } cogl_onscreen_swap_buffers (COGL_ONSCREEN (data->fb)); }
static CoglBool draw_rectangle (TestState *state, int x, int y, TestDepthState *rect_state, CoglBool legacy_mode) { uint8_t Cr = MASK_RED (rect_state->color); uint8_t Cg = MASK_GREEN (rect_state->color); uint8_t Cb = MASK_BLUE (rect_state->color); uint8_t Ca = MASK_ALPHA (rect_state->color); CoglPipeline *pipeline; CoglDepthState depth_state; cogl_depth_state_init (&depth_state); cogl_depth_state_set_test_enabled (&depth_state, rect_state->test_enable); cogl_depth_state_set_test_function (&depth_state, rect_state->test_function); cogl_depth_state_set_write_enabled (&depth_state, rect_state->write_enable); cogl_depth_state_set_range (&depth_state, rect_state->range_near, rect_state->range_far); pipeline = cogl_pipeline_new (test_ctx); if (!cogl_pipeline_set_depth_state (pipeline, &depth_state, NULL)) { cogl_object_unref (pipeline); return FALSE; } if (!legacy_mode) { cogl_pipeline_set_color4ub (pipeline, Cr, Cg, Cb, Ca); cogl_framebuffer_set_depth_write_enabled (test_fb, rect_state->fb_write_enable); cogl_framebuffer_push_matrix (test_fb); cogl_framebuffer_translate (test_fb, 0, 0, rect_state->depth); cogl_framebuffer_draw_rectangle (test_fb, pipeline, x * QUAD_WIDTH, y * QUAD_WIDTH, x * QUAD_WIDTH + QUAD_WIDTH, y * QUAD_WIDTH + QUAD_WIDTH); cogl_framebuffer_pop_matrix (test_fb); } else { cogl_push_framebuffer (test_fb); cogl_push_matrix (); cogl_set_source_color4ub (Cr, Cg, Cb, Ca); cogl_translate (0, 0, rect_state->depth); cogl_rectangle (x * QUAD_WIDTH, y * QUAD_WIDTH, x * QUAD_WIDTH + QUAD_WIDTH, y * QUAD_WIDTH + QUAD_WIDTH); cogl_pop_matrix (); cogl_pop_framebuffer (); } cogl_object_unref (pipeline); return TRUE; }
static void paint_test_backface_culling (TestState *state, CoglFramebuffer *framebuffer) { int draw_num; CoglPipeline *base_pipeline = cogl_pipeline_new (test_ctx); cogl_framebuffer_orthographic (framebuffer, 0, 0, state->width, state->height, -1, 100); cogl_framebuffer_clear4f (framebuffer, COGL_BUFFER_BIT_COLOR | COGL_BUFFER_BIT_STENCIL, 0, 0, 0, 1); cogl_pipeline_set_layer_texture (base_pipeline, 0, state->texture); cogl_pipeline_set_layer_filters (base_pipeline, 0, COGL_PIPELINE_FILTER_NEAREST, COGL_PIPELINE_FILTER_NEAREST); /* Render the scene eight times to test all of the combinations of cull face mode and winding orders */ for (draw_num = 0; draw_num < 8; draw_num++) { float x1 = 0, x2, y1 = 0, y2 = (float)(TEXTURE_RENDER_SIZE); CoglTextureVertex verts[4]; CoglPipeline *pipeline; cogl_framebuffer_push_matrix (framebuffer); cogl_framebuffer_translate (framebuffer, 0, TEXTURE_RENDER_SIZE * draw_num, 0); pipeline = cogl_pipeline_copy (base_pipeline); cogl_pipeline_set_front_face_winding (pipeline, FRONT_WINDING (draw_num)); cogl_pipeline_set_cull_face_mode (pipeline, CULL_FACE_MODE (draw_num)); memset (verts, 0, sizeof (verts)); x2 = x1 + (float)(TEXTURE_RENDER_SIZE); /* Draw a front-facing texture */ cogl_framebuffer_draw_rectangle (framebuffer, pipeline, x1, y1, x2, y2); x1 = x2; x2 = x1 + (float)(TEXTURE_RENDER_SIZE); /* Draw a front-facing texture with flipped texcoords */ cogl_framebuffer_draw_textured_rectangle (framebuffer, pipeline, x1, y1, x2, y2, 1.0, 0.0, 0.0, 1.0); x1 = x2; x2 = x1 + (float)(TEXTURE_RENDER_SIZE); /* Draw a back-facing texture */ cogl_framebuffer_draw_rectangle (framebuffer, pipeline, x2, y1, x1, y2); cogl_framebuffer_pop_matrix (framebuffer); cogl_object_unref (pipeline); } cogl_object_unref (base_pipeline); }
static void test_tex_combine (TestState *state, int x, int y, uint32_t tex0_color, uint32_t tex1_color, uint32_t combine_constant, const char *combine_string, uint32_t expected_result) { CoglTexture *tex0, *tex1; /* combine constant - when applicable */ uint8_t Cr = MASK_RED (combine_constant); uint8_t Cg = MASK_GREEN (combine_constant); uint8_t Cb = MASK_BLUE (combine_constant); uint8_t Ca = MASK_ALPHA (combine_constant); CoglColor combine_const_color; CoglPipeline *pipeline; CoglBool status; CoglError *error = NULL; int y_off; int x_off; tex0 = make_texture (tex0_color); tex1 = make_texture (tex1_color); pipeline = cogl_pipeline_new (test_ctx); cogl_pipeline_set_color4ub (pipeline, 0x80, 0x80, 0x80, 0x80); cogl_pipeline_set_blend (pipeline, "RGBA = ADD (SRC_COLOR, 0)", NULL); cogl_pipeline_set_layer_texture (pipeline, 0, tex0); cogl_pipeline_set_layer_combine (pipeline, 0, "RGBA = REPLACE (TEXTURE)", NULL); cogl_pipeline_set_layer_texture (pipeline, 1, tex1); status = cogl_pipeline_set_layer_combine (pipeline, 1, combine_string, &error); if (!status) { /* It's not strictly a test failure; you need a more capable GPU or * driver to test this texture combine string. */ g_debug ("Failed to test texture combine string %s: %s", combine_string, error->message); } cogl_color_init_from_4ub (&combine_const_color, Cr, Cg, Cb, Ca); cogl_pipeline_set_layer_combine_constant (pipeline, 1, &combine_const_color); cogl_framebuffer_draw_rectangle (test_fb, pipeline, x * QUAD_WIDTH, y * QUAD_WIDTH, x * QUAD_WIDTH + QUAD_WIDTH, y * QUAD_WIDTH + QUAD_WIDTH); cogl_object_unref (pipeline); cogl_object_unref (tex0); cogl_object_unref (tex1); /* See what we got... */ y_off = y * QUAD_WIDTH + (QUAD_WIDTH / 2); x_off = x * QUAD_WIDTH + (QUAD_WIDTH / 2); if (cogl_test_verbose ()) { g_print ("test_tex_combine (%d, %d):\n%s\n", x, y, combine_string); g_print (" texture 0 color = 0x%08lX\n", (unsigned long)tex0_color); g_print (" texture 1 color = 0x%08lX\n", (unsigned long)tex1_color); if (combine_constant != TEX_CONSTANT_UNUSED) g_print (" combine constant = %02x, %02x, %02x, %02x\n", Cr, Cg, Cb, Ca); else g_print (" combine constant = UNUSED\n"); } test_utils_check_pixel (test_fb, x_off, y_off, expected_result); }
static void test_blend (TestState *state, int x, int y, uint32_t src_color, uint32_t dst_color, const char *blend_string, uint32_t blend_constant, uint32_t expected_result) { /* src color */ uint8_t Sr = MASK_RED (src_color); uint8_t Sg = MASK_GREEN (src_color); uint8_t Sb = MASK_BLUE (src_color); uint8_t Sa = MASK_ALPHA (src_color); /* dest color */ uint8_t Dr = MASK_RED (dst_color); uint8_t Dg = MASK_GREEN (dst_color); uint8_t Db = MASK_BLUE (dst_color); uint8_t Da = MASK_ALPHA (dst_color); /* blend constant - when applicable */ uint8_t Br = MASK_RED (blend_constant); uint8_t Bg = MASK_GREEN (blend_constant); uint8_t Bb = MASK_BLUE (blend_constant); uint8_t Ba = MASK_ALPHA (blend_constant); CoglColor blend_const_color; CoglPipeline *pipeline; CoglBool status; CoglError *error = NULL; int y_off; int x_off; /* First write out the destination color without any blending... */ pipeline = cogl_pipeline_new (test_ctx); cogl_pipeline_set_color4ub (pipeline, Dr, Dg, Db, Da); cogl_pipeline_set_blend (pipeline, "RGBA = ADD (SRC_COLOR, 0)", NULL); cogl_framebuffer_draw_rectangle (test_fb, pipeline, x * QUAD_WIDTH, y * QUAD_WIDTH, x * QUAD_WIDTH + QUAD_WIDTH, y * QUAD_WIDTH + QUAD_WIDTH); cogl_object_unref (pipeline); /* * Now blend a rectangle over our well defined destination: */ pipeline = cogl_pipeline_new (test_ctx); cogl_pipeline_set_color4ub (pipeline, Sr, Sg, Sb, Sa); status = cogl_pipeline_set_blend (pipeline, blend_string, &error); if (!status) { /* It's not strictly a test failure; you need a more capable GPU or * driver to test this blend string. */ if (cogl_test_verbose ()) { g_debug ("Failed to test blend string %s: %s", blend_string, error->message); g_print ("Skipping\n"); } return; } cogl_color_init_from_4ub (&blend_const_color, Br, Bg, Bb, Ba); cogl_pipeline_set_blend_constant (pipeline, &blend_const_color); cogl_framebuffer_draw_rectangle (test_fb, pipeline, x * QUAD_WIDTH, y * QUAD_WIDTH, x * QUAD_WIDTH + QUAD_WIDTH, y * QUAD_WIDTH + QUAD_WIDTH); cogl_object_unref (pipeline); /* See what we got... */ y_off = y * QUAD_WIDTH + (QUAD_WIDTH / 2); x_off = x * QUAD_WIDTH + (QUAD_WIDTH / 2); if (cogl_test_verbose ()) { g_print ("test_blend (%d, %d):\n%s\n", x, y, blend_string); g_print (" src color = %02x, %02x, %02x, %02x\n", Sr, Sg, Sb, Sa); g_print (" dst color = %02x, %02x, %02x, %02x\n", Dr, Dg, Db, Da); if (blend_constant != BLEND_CONSTANT_UNUSED) g_print (" blend constant = %02x, %02x, %02x, %02x\n", Br, Bg, Bb, Ba); else g_print (" blend constant = UNUSED\n"); } test_utils_check_pixel (test_fb, x_off, y_off, expected_result); }