cg_texture_t * rig_downsampler_downsample(rig_downsampler_t *downsampler, cg_texture_t *source, int scale_factor_x, int scale_factor_y) { cg_texture_components_t components; int src_w, src_h; int dest_width, dest_height; cg_pipeline_t *pipeline; /* validation */ src_w = cg_texture_get_width(source); src_h = cg_texture_get_height(source); if (src_w % scale_factor_x != 0) { c_warning("downsample: the width of the texture (%d) is not a " "multiple of the scale factor (%d)", src_w, scale_factor_x); } if (src_h % scale_factor_y != 0) { c_warning("downsample: the height of the texture (%d) is not a " "multiple of the scale factor (%d)", src_h, scale_factor_y); } /* create the destination texture up front */ dest_width = src_w / scale_factor_x; dest_height = src_h / scale_factor_y; components = cg_texture_get_components(source); if (downsampler->dest == NULL || cg_texture_get_width(downsampler->dest) != dest_width || cg_texture_get_height(downsampler->dest) != dest_height || cg_texture_get_components(downsampler->dest) != components) { cg_offscreen_t *offscreen; cg_texture_2d_t *texture_2d = cg_texture_2d_new_with_size( downsampler->engine->shell->cg_device, dest_width, dest_height); cg_texture_set_components(texture_2d, components); _rig_downsampler_reset(downsampler); downsampler->dest = texture_2d; /* create the FBO to render the downsampled texture */ offscreen = cg_offscreen_new_with_texture(downsampler->dest); downsampler->fb = offscreen; /* create the camera that will setup the scene for the render */ downsampler->camera = rig_camera_new(downsampler->engine, dest_width, /* ortho width */ dest_height, /* ortho height */ downsampler->fb); rut_camera_set_near_plane(downsampler->camera, -1.f); rut_camera_set_far_plane(downsampler->camera, 1.f); } pipeline = cg_pipeline_copy(downsampler->pipeline); cg_pipeline_set_layer_texture(pipeline, 0, source); rut_camera_flush(downsampler->camera); cg_framebuffer_draw_rectangle( downsampler->fb, pipeline, 0, 0, dest_width, dest_height); rut_camera_end_frame(downsampler->camera); cg_object_unref(pipeline); return cg_object_ref(downsampler->dest); }
int main(int argc, char **argv) { Data data; cg_onscreen_t *onscreen; cg_error_t *error = NULL; cg_vertex_p2c4_t 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 } }; cg_renderer_t *renderer; cg_display_t *display; uv_loop_t *loop = uv_default_loop(); renderer = cg_renderer_new(); cg_renderer_add_constraint(renderer, CG_RENDERER_CONSTRAINT_SUPPORTS_CG_GLES2); if (!cg_renderer_connect(renderer, &error)) { c_error("%s", error->message); exit(1); } display = cg_display_new(renderer, NULL); data.dev = cg_device_new(); cg_device_set_display(data.dev, display); if (!cg_device_connect(data.dev, &error)) { c_error("%s", error->message); exit(1); } onscreen = cg_onscreen_new(data.dev, 640, 480); cg_onscreen_show(onscreen); data.fb = onscreen; /* Prepare onscreen primitive */ data.triangle = cg_primitive_new_p2c4( data.dev, CG_VERTICES_MODE_TRIANGLES, 3, triangle_vertices); data.pipeline = cg_pipeline_new(data.dev); data.offscreen_texture = cg_texture_2d_new_with_size( data.dev, OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT); data.offscreen = cg_offscreen_new_with_texture(data.offscreen_texture); data.gles2_ctx = cg_gles2_context_new(data.dev, &error); if (!data.gles2_ctx) { c_error("Failed to create GLES2 context: %s\n", error->message); } data.gles2_vtable = cg_gles2_context_get_vtable(data.gles2_ctx); /* Draw scene with GLES2 */ if (!cg_push_gles2_context( data.dev, data.gles2_ctx, data.fb, data.fb, &error)) { c_error("Failed to push gles2 context: %s\n", error->message); } cg_pop_gles2_context(data.dev); cg_onscreen_add_frame_callback( CG_ONSCREEN(data.fb), frame_event_cb, &data, NULL); /* destroy notify */ uv_idle_init(loop, &data.idle); data.idle.data = &data; uv_idle_start(&data.idle, paint_cb); cg_uv_set_mainloop(data.dev, loop); uv_run(loop, UV_RUN_DEFAULT); return 0; }