int main(int argc, char **argv) { cg_onscreen_t *onscreen; cg_error_t *error = NULL; struct demo demo; float fovy, aspect, z_near, z_2d, z_far; uv_loop_t *loop = uv_default_loop(); demo.dev = cg_device_new (); if (!demo.dev || error != NULL) c_error("Failed to create Cogl context\n"); onscreen = cg_onscreen_new(demo.dev, WIDTH, HEIGHT); demo.fb = onscreen; demo.width = cg_framebuffer_get_width(demo.fb); demo.height = cg_framebuffer_get_height(demo.fb); cg_onscreen_show(onscreen); cg_framebuffer_set_viewport(demo.fb, 0, 0, demo.width, demo.height); fovy = 45; aspect = (float)demo.width / (float)demo.height; z_near = 0.1; z_2d = 1000; z_far = 2000; cg_framebuffer_perspective(demo.fb, fovy, aspect, z_near, z_far); c_matrix_init_identity(&demo.view); c_matrix_view_2d_in_perspective(&demo.view, fovy, aspect, z_near, z_2d, demo.width, demo.height); cg_framebuffer_set_modelview_matrix(demo.fb, &demo.view); demo.swap_ready = true; cg_onscreen_add_frame_callback(demo.fb, frame_event_cb, &demo, NULL); init_particle_emitters(&demo); demo.timer = c_timer_new(); demo.spin_rate = 0; demo.angle_between_emitters = 2 * M_PI / C_N_ELEMENTS(demo.emitter); uv_idle_init(loop, &demo.idle); demo.idle.data = &demo; uv_idle_start(&demo.idle, paint_cb); cg_uv_set_mainloop(demo.dev, loop); uv_run(loop, UV_RUN_DEFAULT); return 0; }
static void test_vertex_transform_hook(TestState *state) { cg_pipeline_t *pipeline; cg_snippet_t *snippet; c_matrix_t identity_matrix; c_matrix_t matrix; int location; /* Test the vertex transform hook */ c_matrix_init_identity(&identity_matrix); pipeline = cg_pipeline_new(test_dev); cg_pipeline_set_color4ub(pipeline, 255, 0, 255, 255); snippet = cg_snippet_new(CG_SNIPPET_HOOK_VERTEX_TRANSFORM, "uniform mat4 pmat;", NULL); cg_snippet_set_replace(snippet, "cg_position_out = " "pmat * cg_position_in;"); cg_pipeline_add_snippet(pipeline, snippet); cg_object_unref(snippet); /* Copy the current projection matrix to a uniform */ cg_framebuffer_get_projection_matrix(test_fb, &matrix); location = cg_pipeline_get_uniform_location(pipeline, "pmat"); cg_pipeline_set_uniform_matrix(pipeline, location, 4, /* dimensions */ 1, /* count */ false, /* don't transpose */ c_matrix_get_array(&matrix)); /* Replace the real projection matrix with the identity. This should mess up the drawing unless the snippet replacement is working */ cg_framebuffer_set_projection_matrix(test_fb, &identity_matrix); cg_framebuffer_draw_rectangle(test_fb, pipeline, 150, 0, 160, 10); cg_object_unref(pipeline); /* Restore the projection matrix */ cg_framebuffer_set_projection_matrix(test_fb, &matrix); test_cg_check_pixel(test_fb, 155, 5, 0xff00ffff); }
static void setup_orthographic_modelview (void) { c_matrix_t matrix; int fb_width = cg_framebuffer_get_width (test_fb); int fb_height = cg_framebuffer_get_height (test_fb); /* Set up a non-identity modelview matrix. When the journal is * flushed it will usually flush the identity matrix. Using the * non-default matrix ensures that we test that Cogl restores the * matrix we asked for. The matrix sets up an orthographic transform * in the modelview matrix */ c_matrix_init_identity (&matrix); c_matrix_orthographic (&matrix, 0.0f, 0.0f, /* x_1 y_1 */ fb_width, fb_height, -1.0f, /* nearval */ 1.0f /* farval */); cg_framebuffer_set_modelview_matrix (test_fb, &matrix); }
bool cg_device_connect(cg_device_t *dev, cg_error_t **error) { uint8_t white_pixel[] = { 0xff, 0xff, 0xff, 0xff }; const cg_winsys_vtable_t *winsys; int i; cg_error_t *internal_error = NULL; if (dev->connected) return true; /* Mark as connected now to avoid recursion issues, * but revert in error paths */ dev->connected = true; if (!dev->renderer) { cg_renderer_t *renderer = cg_renderer_new(); if (!cg_renderer_connect(renderer, error)) { cg_object_unref(renderer); dev->connected = false; return false; } cg_device_set_renderer(dev, renderer); } if (!dev->display) { cg_display_t *display = cg_display_new(dev->renderer, NULL); if (!cg_display_setup(display, error)) { cg_object_unref(display); dev->connected = false; return false; } cg_device_set_display(dev, display); } /* This is duplicated data, but it's much more convenient to have the driver attached to the context and the value is accessed a lot throughout CGlib */ dev->driver = dev->renderer->driver; /* Again this is duplicated data, but it convenient to be able * access these from the context. */ dev->driver_vtable = dev->renderer->driver_vtable; dev->texture_driver = dev->renderer->texture_driver; for (i = 0; i < C_N_ELEMENTS(dev->private_features); i++) dev->private_features[i] |= dev->renderer->private_features[i]; winsys = _cg_device_get_winsys(dev); if (!winsys->device_init(dev, error)) { dev->connected = false; return false; } dev->attribute_name_states_hash = c_hash_table_new_full(c_str_hash, c_str_equal, c_free, c_free); dev->attribute_name_index_map = NULL; dev->n_attribute_names = 0; /* The "cg_color_in" attribute needs a deterministic name_index * so we make sure it's the first attribute name we register */ _cg_attribute_register_attribute_name(dev, "cg_color_in"); dev->uniform_names = c_ptr_array_new_with_free_func((c_destroy_func_t)c_free); dev->uniform_name_hash = c_hash_table_new(c_str_hash, c_str_equal); dev->n_uniform_names = 0; /* Initialise the driver specific state */ _cg_init_feature_overrides(dev); /* XXX: ONGOING BUG: Intel viewport scissor * * Intel gen6 drivers don't currently correctly handle offset * viewports, since primitives aren't clipped within the bounds of * the viewport. To workaround this we push our own clip for the * viewport that will use scissoring to ensure we clip as expected. * * TODO: file a bug upstream! */ if (dev->gpu.driver_package == CG_GPU_INFO_DRIVER_PACKAGE_MESA && dev->gpu.architecture == CG_GPU_INFO_ARCHITECTURE_SANDYBRIDGE && !getenv("CG_DISABLE_INTEL_VIEWPORT_SCISSORT_WORKAROUND")) dev->needs_viewport_scissor_workaround = true; else dev->needs_viewport_scissor_workaround = false; dev->sampler_cache = _cg_sampler_cache_new(dev); _cg_pipeline_init_default_pipeline(); _cg_pipeline_init_default_layers(); _cg_pipeline_init_state_hash_functions(); _cg_pipeline_init_layer_state_hash_functions(); dev->current_clip_stack_valid = false; dev->current_clip_stack = NULL; c_matrix_init_identity(&dev->identity_matrix); c_matrix_init_identity(&dev->y_flip_matrix); c_matrix_scale(&dev->y_flip_matrix, 1, -1, 1); dev->texture_units = c_array_new(false, false, sizeof(cg_texture_unit_t)); if (_cg_has_private_feature(dev, CG_PRIVATE_FEATURE_ANY_GL)) { /* See cg-pipeline.c for more details about why we leave texture unit * 1 * active by default... */ dev->active_texture_unit = 1; GE(dev, glActiveTexture(GL_TEXTURE1)); } dev->opaque_color_pipeline = cg_pipeline_new(dev); dev->codegen_header_buffer = c_string_new(""); dev->codegen_source_buffer = c_string_new(""); dev->default_gl_texture_2d_tex = NULL; dev->default_gl_texture_3d_tex = NULL; dev->framebuffers = NULL; dev->current_draw_buffer = NULL; dev->current_read_buffer = NULL; dev->current_draw_buffer_state_flushed = 0; dev->current_draw_buffer_changes = CG_FRAMEBUFFER_STATE_ALL; c_list_init(&dev->onscreen_events_queue); c_list_init(&dev->onscreen_dirty_queue); c_queue_init(&dev->gles2_context_stack); dev->current_pipeline = NULL; dev->current_pipeline_changes_since_flush = 0; dev->current_pipeline_with_color_attrib = false; _cg_bitmask_init(&dev->enabled_custom_attributes); _cg_bitmask_init(&dev->enable_custom_attributes_tmp); _cg_bitmask_init(&dev->changed_bits_tmp); dev->max_texture_units = -1; dev->max_activateable_texture_units = -1; dev->current_gl_program = 0; dev->current_gl_dither_enabled = true; dev->current_gl_color_mask = CG_COLOR_MASK_ALL; dev->gl_blend_enable_cache = false; dev->depth_test_enabled_cache = false; dev->depth_test_function_cache = CG_DEPTH_TEST_FUNCTION_LESS; dev->depth_writing_enabled_cache = true; dev->depth_range_near_cache = 0; dev->depth_range_far_cache = 1; dev->pipeline_cache = _cg_pipeline_cache_new(); for (i = 0; i < CG_BUFFER_BIND_TARGET_COUNT; i++) dev->current_buffer[i] = NULL; dev->stencil_pipeline = cg_pipeline_new(dev); dev->rectangle_byte_indices = NULL; dev->rectangle_short_indices = NULL; dev->rectangle_short_indices_len = 0; dev->texture_download_pipeline = NULL; dev->blit_texture_pipeline = NULL; #if defined(CG_HAS_GL_SUPPORT) if ((dev->driver == CG_DRIVER_GL3)) { GLuint vertex_array; /* In a forward compatible context, GL 3 doesn't support rendering * using the default vertex array object. CGlib doesn't use vertex * array objects yet so for now we just create a dummy array * object that we will use as our own default object. Eventually * it could be good to attach the vertex array objects to * cg_primitive_ts */ dev->glGenVertexArrays(1, &vertex_array); dev->glBindVertexArray(vertex_array); } #endif dev->current_modelview_entry = NULL; dev->current_projection_entry = NULL; _cg_matrix_entry_identity_init(&dev->identity_entry); _cg_matrix_entry_cache_init(&dev->builtin_flushed_projection); _cg_matrix_entry_cache_init(&dev->builtin_flushed_modelview); /* Create default textures used for fall backs */ dev->default_gl_texture_2d_tex = cg_texture_2d_new_from_data(dev, 1, 1, CG_PIXEL_FORMAT_RGBA_8888_PRE, 0, /* rowstride */ white_pixel, NULL); /* abort on error */ /* If 3D or rectangle textures aren't supported then these will * return errors that we can simply ignore. */ internal_error = NULL; dev->default_gl_texture_3d_tex = cg_texture_3d_new_from_data(dev, 1, 1, 1, /* width, height, depth */ CG_PIXEL_FORMAT_RGBA_8888_PRE, 0, /* rowstride */ 0, /* image stride */ white_pixel, &internal_error); if (internal_error) cg_error_free(internal_error); dev->buffer_map_fallback_array = c_byte_array_new(); dev->buffer_map_fallback_in_use = false; c_list_init(&dev->fences); dev->atlas_set = cg_atlas_set_new(dev); cg_atlas_set_set_components(dev->atlas_set, CG_TEXTURE_COMPONENTS_RGBA); cg_atlas_set_set_premultiplied(dev->atlas_set, false); cg_atlas_set_add_atlas_callback(dev->atlas_set, _cg_atlas_texture_atlas_event_handler, NULL, /* user data */ NULL); /* destroy */ return true; }