static void do_test (CoglBool check_orientation) { int fb_width = cogl_framebuffer_get_width (test_fb); int fb_height = cogl_framebuffer_get_height (test_fb); CoglPrimitive *prim; CoglError *error = NULL; CoglTexture2D *tex_2d; CoglPipeline *pipeline, *solid_pipeline; CoglBool res; int tex_height; cogl_framebuffer_orthographic (test_fb, 0, 0, /* x_1, y_1 */ fb_width, /* x_2 */ fb_height /* y_2 */, -1, 100 /* near/far */); cogl_framebuffer_clear4f (test_fb, COGL_BUFFER_BIT_COLOR, 1.0f, 1.0f, 1.0f, 1.0f); /* If we're not checking the orientation of the point sprite then * we'll set the height of the texture to 1 so that the vertical * orientation does not matter */ if (check_orientation) tex_height = 2; else tex_height = 1; tex_2d = cogl_texture_2d_new_from_data (test_ctx, 2, tex_height, /* width/height */ COGL_PIXEL_FORMAT_RGB_888, COGL_PIXEL_FORMAT_ANY, 6, /* row stride */ tex_data, &error); g_assert (tex_2d != NULL); g_assert (error == NULL); pipeline = cogl_pipeline_new (test_ctx); cogl_pipeline_set_layer_texture (pipeline, 0, COGL_TEXTURE (tex_2d)); res = cogl_pipeline_set_layer_point_sprite_coords_enabled (pipeline, /* layer_index */ 0, /* enable */ TRUE, &error); g_assert (res == TRUE); g_assert (error == NULL); cogl_pipeline_set_layer_filters (pipeline, 0, /* layer_index */ COGL_PIPELINE_FILTER_NEAREST, COGL_PIPELINE_FILTER_NEAREST); cogl_pipeline_set_point_size (pipeline, POINT_SIZE); prim = cogl_primitive_new_p2t2 (test_ctx, COGL_VERTICES_MODE_POINTS, 1, /* n_vertices */ &point); cogl_primitive_draw (prim, test_fb, pipeline); /* Render the primitive again without point sprites to make sure disabling it works */ solid_pipeline = cogl_pipeline_copy (pipeline); cogl_pipeline_set_layer_point_sprite_coords_enabled (solid_pipeline, /* layer_index */ 0, /* enable */ FALSE, &error); cogl_framebuffer_push_matrix (test_fb); cogl_framebuffer_translate (test_fb, POINT_SIZE * 2, /* x */ 0.0f, /* y */ 0.0f /* z */); cogl_primitive_draw (prim, test_fb, solid_pipeline); cogl_framebuffer_pop_matrix (test_fb); cogl_object_unref (prim); cogl_object_unref (solid_pipeline); cogl_object_unref (pipeline); cogl_object_unref (tex_2d); test_utils_check_pixel (test_fb, POINT_SIZE - POINT_SIZE / 4, POINT_SIZE - POINT_SIZE / 4, 0x0000ffff); test_utils_check_pixel (test_fb, POINT_SIZE + POINT_SIZE / 4, POINT_SIZE - POINT_SIZE / 4, 0x00ff00ff); test_utils_check_pixel (test_fb, POINT_SIZE - POINT_SIZE / 4, POINT_SIZE + POINT_SIZE / 4, check_orientation ? 0x00ffffff : 0x0000ffff); test_utils_check_pixel (test_fb, POINT_SIZE + POINT_SIZE / 4, POINT_SIZE + POINT_SIZE / 4, check_orientation ? 0xff0000ff : 0x00ff00ff); /* When rendering without the point sprites all of the texture coordinates should be 0,0 so it should get the top-left texel which is blue */ test_utils_check_region (test_fb, POINT_SIZE * 3 - POINT_SIZE / 2 + 1, POINT_SIZE - POINT_SIZE / 2 + 1, POINT_SIZE - 2, POINT_SIZE - 2, 0x0000ffff); if (cogl_test_verbose ()) g_print ("OK\n"); }
void cogl_push_matrix (void) { cogl_framebuffer_push_matrix (cogl_get_draw_framebuffer ()); }
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; }
int main (int argc, char **argv) { CoglOnscreenTemplate *onscreen_template; CoglDisplay *display; CoglContext *ctx; CoglOnscreen *onscreen; CoglFramebuffer *fb; GError *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); g_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 (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)) { g_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 do_test (CoglBool check_orientation, CoglBool use_glsl) { int fb_width = cogl_framebuffer_get_width (test_fb); int fb_height = cogl_framebuffer_get_height (test_fb); CoglPrimitive *prim; CoglError *error = NULL; CoglTexture2D *tex_2d; CoglPipeline *pipeline, *solid_pipeline; int tex_height; cogl_framebuffer_orthographic (test_fb, 0, 0, /* x_1, y_1 */ fb_width, /* x_2 */ fb_height /* y_2 */, -1, 100 /* near/far */); cogl_framebuffer_clear4f (test_fb, COGL_BUFFER_BIT_COLOR, 1.0f, 1.0f, 1.0f, 1.0f); /* If we're not checking the orientation of the point sprite then * we'll set the height of the texture to 1 so that the vertical * orientation does not matter */ if (check_orientation) tex_height = 2; else tex_height = 1; tex_2d = cogl_texture_2d_new_from_data (test_ctx, 2, tex_height, /* width/height */ COGL_PIXEL_FORMAT_RGB_888, COGL_PIXEL_FORMAT_ANY, 6, /* row stride */ tex_data, &error); g_assert (tex_2d != NULL); g_assert (error == NULL); pipeline = cogl_pipeline_new (test_ctx); cogl_pipeline_set_layer_texture (pipeline, 0, tex_2d); cogl_pipeline_set_layer_filters (pipeline, 0, /* layer_index */ COGL_PIPELINE_FILTER_NEAREST, COGL_PIPELINE_FILTER_NEAREST); cogl_pipeline_set_point_size (pipeline, POINT_SIZE); /* If we're using GLSL then we don't need to enable point sprite * coords and we can just directly reference cogl_point_coord in the * snippet */ if (use_glsl) { CoglSnippet *snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP, NULL, /* declarations */ NULL /* post */); static const char source[] = " cogl_texel = texture2D (cogl_sampler, cogl_point_coord);\n"; cogl_snippet_set_replace (snippet, source); /* Keep a reference to the original pipeline because there is no * way to remove a snippet in order to recreate the solid * pipeline */ solid_pipeline = cogl_pipeline_copy (pipeline); cogl_pipeline_add_layer_snippet (pipeline, 0, snippet); cogl_object_unref (snippet); } else { CoglBool res = cogl_pipeline_set_layer_point_sprite_coords_enabled (pipeline, /* layer_index */ 0, /* enable */ TRUE, &error); g_assert (res == TRUE); g_assert (error == NULL); solid_pipeline = cogl_pipeline_copy (pipeline); res = cogl_pipeline_set_layer_point_sprite_coords_enabled (solid_pipeline, /* layer_index */ 0, /* enable */ FALSE, &error); g_assert (res == TRUE); g_assert (error == NULL); } prim = cogl_primitive_new_p2t2 (test_ctx, COGL_VERTICES_MODE_POINTS, 1, /* n_vertices */ &point); cogl_primitive_draw (prim, test_fb, pipeline); /* Render the primitive again without point sprites to make sure disabling it works */ cogl_framebuffer_push_matrix (test_fb); cogl_framebuffer_translate (test_fb, POINT_SIZE * 2, /* x */ 0.0f, /* y */ 0.0f /* z */); cogl_primitive_draw (prim, test_fb, solid_pipeline); cogl_framebuffer_pop_matrix (test_fb); cogl_object_unref (prim); cogl_object_unref (solid_pipeline); cogl_object_unref (pipeline); cogl_object_unref (tex_2d); test_utils_check_pixel (test_fb, POINT_SIZE - POINT_SIZE / 4, POINT_SIZE - POINT_SIZE / 4, 0x0000ffff); test_utils_check_pixel (test_fb, POINT_SIZE + POINT_SIZE / 4, POINT_SIZE - POINT_SIZE / 4, 0x00ff00ff); test_utils_check_pixel (test_fb, POINT_SIZE - POINT_SIZE / 4, POINT_SIZE + POINT_SIZE / 4, check_orientation ? 0x00ffffff : 0x0000ffff); test_utils_check_pixel (test_fb, POINT_SIZE + POINT_SIZE / 4, POINT_SIZE + POINT_SIZE / 4, check_orientation ? 0xff0000ff : 0x00ff00ff); /* When rendering without the point sprites all of the texture coordinates should be 0,0 so it should get the top-left texel which is blue */ test_utils_check_region (test_fb, POINT_SIZE * 3 - POINT_SIZE / 2 + 1, POINT_SIZE - POINT_SIZE / 2 + 1, POINT_SIZE - 2, POINT_SIZE - 2, 0x0000ffff); if (cogl_test_verbose ()) g_print ("OK\n"); }
static void rig_journal_flush (GArray *journal, RigPaintContext *paint_ctx) { RutPaintContext *rut_paint_ctx = &paint_ctx->_parent; RutCamera *camera = rut_paint_ctx->camera; CoglFramebuffer *fb = rut_camera_get_framebuffer (camera); int start, dir, end; int i; /* TODO: use an inline qsort implementation */ g_array_sort (journal, (void *)sort_entry_cb); /* We draw opaque geometry front-to-back so we are more likely to be * able to discard later fragments earlier by depth testing. * * We draw transparent geometry back-to-front so it blends * correctly. */ if ( paint_ctx->pass == RIG_PASS_COLOR_BLENDED) { start = 0; dir = 1; end = journal->len; } else { start = journal->len - 1; dir = -1; end = -1; } cogl_framebuffer_push_matrix (fb); for (i = start; i != end; i += dir) { RigJournalEntry *entry = &g_array_index (journal, RigJournalEntry, i); RutEntity *entity = entry->entity; RutComponent *geometry = rut_entity_get_component (entity, RUT_COMPONENT_TYPE_GEOMETRY); CoglPipeline *pipeline; CoglPrimitive *primitive; float normal_matrix[9]; RutMaterial *material; pipeline = get_entity_pipeline (paint_ctx->engine, entity, geometry, paint_ctx->pass); if (paint_ctx->pass == RIG_PASS_DOF_DEPTH || paint_ctx->pass == RIG_PASS_SHADOW) { /* FIXME: avoid updating these uniforms for every primitive if * the focal parameters haven't change! */ set_focal_parameters (pipeline, camera->focal_distance, camera->depth_of_field); } else if (paint_ctx->pass == RIG_PASS_COLOR_UNBLENDED || paint_ctx->pass == RIG_PASS_COLOR_BLENDED) { int location; RutLight *light = rut_entity_get_component (paint_ctx->engine->light, RUT_COMPONENT_TYPE_LIGHT); /* FIXME: only update the lighting uniforms when the light has * actually moved! */ rut_light_set_uniforms (light, pipeline); /* FIXME: only update the material uniforms when the material has * actually changed! */ material = rut_entity_get_component (entity, RUT_COMPONENT_TYPE_MATERIAL); if (material) rut_material_flush_uniforms (material, pipeline); get_normal_matrix (&entry->matrix, normal_matrix); location = cogl_pipeline_get_uniform_location (pipeline, "normal_matrix"); cogl_pipeline_set_uniform_matrix (pipeline, location, 3, /* dimensions */ 1, /* count */ FALSE, /* don't transpose again */ normal_matrix); } if (rut_object_is (geometry, RUT_INTERFACE_ID_PRIMABLE)) { primitive = rut_primable_get_primitive (geometry); cogl_framebuffer_set_modelview_matrix (fb, &entry->matrix); cogl_framebuffer_draw_primitive (fb, pipeline, primitive); } else if (rut_object_get_type (geometry) == &rut_text_type && paint_ctx->pass == RIG_PASS_COLOR_BLENDED) { cogl_framebuffer_set_modelview_matrix (fb, &entry->matrix); rut_paintable_paint (geometry, rut_paint_ctx); } cogl_object_unref (pipeline); rut_refable_unref (entry->entity); } cogl_framebuffer_pop_matrix (fb); g_array_set_size (journal, 0); }