static void create_gles2_context (CoglTexture **offscreen_texture, CoglOffscreen **offscreen, CoglPipeline **pipeline, CoglGLES2Context **gles2_ctx, const CoglGLES2Vtable **gles2) { GError *error = NULL; *offscreen_texture = COGL_TEXTURE ( cogl_texture_2d_new_with_size (test_ctx, cogl_framebuffer_get_width (test_fb), cogl_framebuffer_get_height (test_fb), COGL_PIXEL_FORMAT_ANY, NULL)); *offscreen = cogl_offscreen_new_to_texture (*offscreen_texture); *pipeline = cogl_pipeline_new (test_ctx); cogl_pipeline_set_layer_texture (*pipeline, 0, *offscreen_texture); *gles2_ctx = cogl_gles2_context_new (test_ctx, NULL); if (!*gles2_ctx) g_error ("Failed to create GLES2 context: %s\n", error->message); *gles2 = cogl_gles2_context_get_vtable (*gles2_ctx); }
int main (int argc, char **argv) { Data data; CoglOnscreen *onscreen; CoglError *error = NULL; CoglVertexP2C4 triangle_vertices[] = { {0, 0.7, 0xff, 0x00, 0x00, 0xff}, {-0.7, -0.7, 0x00, 0xff, 0x00, 0xff}, {0.7, -0.7, 0x00, 0x00, 0xff, 0xff} }; GSource *cogl_source; GMainLoop *loop; CoglRenderer *renderer; CoglDisplay *display; renderer = cogl_renderer_new (); cogl_renderer_add_constraint (renderer, COGL_RENDERER_CONSTRAINT_SUPPORTS_COGL_GLES2); display = cogl_display_new (renderer, NULL); data.ctx = cogl_context_new (display, NULL); onscreen = cogl_onscreen_new (data.ctx, 640, 480); cogl_onscreen_show (onscreen); data.fb = COGL_FRAMEBUFFER (onscreen); /* Prepare onscreen primitive */ data.triangle = cogl_primitive_new_p2c4 (data.ctx, COGL_VERTICES_MODE_TRIANGLES, 3, triangle_vertices); data.pipeline = cogl_pipeline_new (data.ctx); data.offscreen_texture = COGL_TEXTURE ( cogl_texture_2d_new_with_size (data.ctx, OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT, COGL_PIXEL_FORMAT_ANY)); data.offscreen = cogl_offscreen_new_to_texture (data.offscreen_texture); data.gles2_ctx = cogl_gles2_context_new (data.ctx, &error); if (!data.gles2_ctx) { g_error ("Failed to create GLES2 context: %s\n", error->message); } data.gles2_vtable = cogl_gles2_context_get_vtable (data.gles2_ctx); /* Draw scene with GLES2 */ if (!cogl_push_gles2_context (data.ctx, data.gles2_ctx, data.fb, data.fb, &error)) { g_error ("Failed to push gles2 context: %s\n", error->message); } cogl_pop_gles2_context (data.ctx); cogl_source = cogl_glib_source_new (data.ctx, G_PRIORITY_DEFAULT); g_source_attach (cogl_source, NULL); cogl_onscreen_add_frame_callback (COGL_ONSCREEN (data.fb), frame_event_cb, &data, NULL); /* destroy notify */ g_idle_add (paint_cb, &data); loop = g_main_loop_new (NULL, TRUE); g_main_loop_run (loop); return 0; }
static void test_push_pop_single_context (void) { CoglTexture *offscreen_texture; CoglOffscreen *offscreen; CoglPipeline *pipeline; CoglGLES2Context *gles2_ctx; const CoglGLES2Vtable *gles2; GError *error = NULL; offscreen_texture = COGL_TEXTURE ( cogl_texture_2d_new_with_size (test_ctx, cogl_framebuffer_get_width (test_fb), cogl_framebuffer_get_height (test_fb), COGL_PIXEL_FORMAT_ANY, NULL)); offscreen = cogl_offscreen_new_to_texture (offscreen_texture); pipeline = cogl_pipeline_new (test_ctx); cogl_pipeline_set_layer_texture (pipeline, 0, offscreen_texture); gles2_ctx = cogl_gles2_context_new (test_ctx, &error); if (!gles2_ctx) g_error ("Failed to create GLES2 context: %s\n", error->message); gles2 = cogl_gles2_context_get_vtable (gles2_ctx); /* Clear onscreen to 0xffff00 using GLES2 */ if (!cogl_push_gles2_context (test_ctx, gles2_ctx, test_fb, test_fb, &error)) { g_error ("Failed to push gles2 context: %s\n", error->message); } gles2->glClearColor (1, 1, 0, 1); gles2->glClear (GL_COLOR_BUFFER_BIT); cogl_pop_gles2_context (test_ctx); test_utils_check_pixel (test_fb, 0, 0, 0xffff00ff); /* Clear offscreen to 0xff0000 using GLES2 and then copy the result * onscreen. * * If we fail to bind the new context here then we'd probably end up * clearing onscreen to 0xff0000 and copying 0xffff00 to onscreen * instead. */ if (!cogl_push_gles2_context (test_ctx, gles2_ctx, COGL_FRAMEBUFFER (offscreen), COGL_FRAMEBUFFER (offscreen), &error)) { g_error ("Failed to push gles2 context: %s\n", error->message); } gles2->glClearColor (1, 0, 0, 1); gles2->glClear (GL_COLOR_BUFFER_BIT); cogl_pop_gles2_context (test_ctx); cogl_framebuffer_draw_rectangle (test_fb, pipeline, -1, 1, 1, -1); /* NB: Cogl doesn't automatically support mid-scene modifications * of textures and so we explicitly flush the drawn rectangle to the * framebuffer now otherwise it may be batched until after the * offscreen texture has been modified again. */ cogl_flush (); /* Clear the offscreen framebuffer to blue using GLES2 before * reading back from the onscreen framebuffer in case we mistakenly * read from the offscreen framebuffer and get a false positive */ if (!cogl_push_gles2_context (test_ctx, gles2_ctx, COGL_FRAMEBUFFER (offscreen), COGL_FRAMEBUFFER (offscreen), &error)) { g_error ("Failed to push gles2 context: %s\n", error->message); } gles2->glClearColor (0, 0, 1, 1); gles2->glClear (GL_COLOR_BUFFER_BIT); cogl_pop_gles2_context (test_ctx); test_utils_check_pixel (test_fb, 0, 0, 0xff0000ff); /* Now copy the offscreen blue clear to the onscreen framebufer and * check that too */ cogl_framebuffer_draw_rectangle (test_fb, pipeline, -1, 1, 1, -1); test_utils_check_pixel (test_fb, 0, 0, 0x0000ffff); if (!cogl_push_gles2_context (test_ctx, gles2_ctx, test_fb, test_fb, &error)) { g_error ("Failed to push gles2 context: %s\n", error->message); } gles2->glClearColor (1, 0, 1, 1); gles2->glClear (GL_COLOR_BUFFER_BIT); cogl_pop_gles2_context (test_ctx); test_utils_check_pixel (test_fb, 0, 0, 0xff00ffff); cogl_object_unref (gles2_ctx); cogl_object_unref (pipeline); }