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 _cogl_path_fill_nodes_with_clipped_rectangle (CoglPath *path) { CoglFramebuffer *fb; _COGL_GET_CONTEXT (ctx, NO_RETVAL); if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_STENCIL_BUFFER)) { static gboolean 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; } } fb = cogl_get_draw_framebuffer (); cogl_framebuffer_push_path_clip (fb, path); cogl_rectangle (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 (fb); }
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 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"); }
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) // If text or lines are blurry when integrating ImGui in your engine: // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) void ImGui_ImplGtk3Cogl_RenderDrawData(ImDrawData* draw_data) { // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) ImGuiIO& io = ImGui::GetIO(); int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); if (fb_width == 0 || fb_height == 0) return; draw_data->ScaleClipRects(io.DisplayFramebufferScale); cogl_framebuffer_orthographic(g_Framebuffer, 0, 0, io.DisplaySize.x, io.DisplaySize.y, -1, 1); CoglContext *context = cogl_framebuffer_get_context(g_Framebuffer); for (int n = 0; n < draw_data->CmdListsCount; n++) { const ImDrawList* cmd_list = draw_data->CmdLists[n]; int idx_buffer_offset = 0; CoglAttributeBuffer *vertices = cogl_attribute_buffer_new(context, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), cmd_list->VtxBuffer.Data); #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) CoglAttribute *attrs[3] = { cogl_attribute_new(vertices, "cogl_position_in", sizeof(ImDrawVert), OFFSETOF(ImDrawVert, pos), 2, COGL_ATTRIBUTE_TYPE_FLOAT), cogl_attribute_new(vertices, "cogl_tex_coord0_in", sizeof(ImDrawVert), OFFSETOF(ImDrawVert, uv), 2, COGL_ATTRIBUTE_TYPE_FLOAT), cogl_attribute_new(vertices, "cogl_color_in", sizeof(ImDrawVert), OFFSETOF(ImDrawVert, col), 4, COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE) }; #undef OFFSETOF CoglPrimitive *primitive = cogl_primitive_new_with_attributes(COGL_VERTICES_MODE_TRIANGLES, cmd_list->VtxBuffer.Size, attrs, 3); CoglIndices *indices = cogl_indices_new(context, sizeof(ImDrawIdx) == 2 ? COGL_INDICES_TYPE_UNSIGNED_SHORT : COGL_INDICES_TYPE_UNSIGNED_INT, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size); for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; cogl_indices_set_offset(indices, sizeof(ImDrawIdx) * idx_buffer_offset); cogl_primitive_set_indices(primitive, indices, pcmd->ElemCount); if (pcmd->UserCallback) { pcmd->UserCallback(cmd_list, pcmd); } else { bool has_texture = pcmd->TextureId != NULL; CoglPipeline *pipeline = has_texture ? (cogl_is_pipeline(pcmd->TextureId) ? (CoglPipeline *) pcmd->TextureId : g_ImagePipeline) : g_ColorPipeline; if (has_texture && pipeline == g_ImagePipeline) { cogl_pipeline_set_layer_texture(g_ImagePipeline, 0, COGL_TEXTURE(pcmd->TextureId)); } cogl_framebuffer_push_scissor_clip(g_Framebuffer, pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z - pcmd->ClipRect.x, pcmd->ClipRect.w - pcmd->ClipRect.y); cogl_primitive_draw(primitive, g_Framebuffer, pipeline); cogl_framebuffer_pop_clip(g_Framebuffer); } idx_buffer_offset += pcmd->ElemCount; } for (int i = 0; i < 3; i++) cogl_object_unref(attrs[i]); cogl_object_unref(primitive); cogl_object_unref(vertices); cogl_object_unref(indices); } }