Introduction To COGL
Introduction To COGL
Introduction To COGL
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
COGL is ...
A modern 3D graphics APIs + Some useful utility APIs.
Direct state access API design, as opposed to the state-machine style of OpenGL.
Implemented in C language, but will provide several other languages binding.
Basic information about COGL project.
- Reference manual
http://developer.gnome.org/cogl/1.9/
- Wiki
http://wiki.clutter-project.org/wiki/Cogl
- Getting the source
git clone git://git.gnome.org/cogl
git clone http://git.gnome.org/browse/cogl
- Browse:
http://git.gnome.org/browse/cogl
- Mailing list
http://lists.freedesktop.org/mailman/listinfo/cogl
- Cogl Bugzilla
https://bugzilla.gnome.org/enter_bug.cgi?product=cogl
Features
Math utilities
Cogl provides an optimized matrix stack API that can internally classify matrices so as to optimize
operations such as invert.
Cogl also provides Eular, Quaternion and Vector APIs to simplify the development of complex 3D
applications.
Framebuffer management
Cogl is able to provide a consistent framebuffer API to manage both on and off screen framebuffers in
a way not possible with OpenGL.
Framebuffers in Cogl own the projection matrix, the viewport state, a modelview matrix stack and a
clip stack. Each framebuffer can have optional ancillary buffers attached such as color, depth and
stencil buffer.
Textures
Native textures
These are the low level textures that the hardware understands.
Meta textures
These are high level textures that allow us to define virtual textures comprised of native textures. We
use these to support slice textures, sub-textures, atlas textures and texture-from pixmap textures.
Here's an overview of the some of these meta texture types:
Sliced textures
Cogl supports textures larger than your hardware limits by "slicing" into multiple GPU
textures. Sliced textures can also be used with GPUs only supporting power-of-two
textures to avoid wasting memory.
Atlas textures
Cogl can pack multiple textures into one large GPU texture so we can avoid repeatedly
binding new textures and forcing us to split our geometry into multiple draw commands.
Sub textures
Cogl allows you to create textures derived from sub-regions of other textures, similar to
OpenVG child images.
Pipelines
Cogl separates geometry from the GPU processing pipeline including vertex transform, rasterizing, per
fragment processing, depth testing and blending.
CoglPipelines encapsulate all the state to setup a GPU pipeline - this can be compared to a full GL
context. Internally CoglPipeline is designed as a sparse representation of state though so they have
some interesting properties including being extremely cheap to copy and compare.
Unlike OpenGL where you would avoid creating multiple GL contexts with Cogl you wouldn't think
twice about copying a pipeline from a template and tweaking it to draw something.
Shaders
Cogl provides access to GLSL shaders for advanced fragment and vertex shading effects. We are
also working on a new framework to allow you to hook into small sections of the pipeline with shader
snippets and also provide portability across multiple versions of GLSL.
Primitives
Since many user interfaces are predominantly built from many simple primitives Cogl provides an
optimized path for batching tiny primitives such as rectangles and polygons that would normally have
an excessive overhead if passed directly to the hardware as lots of tiny drawing requests.
The Cogl Journal
Internally Cogl queues primitives into a "journal" which optimizes how they are submitted to the GPU
by batching the geometry together, minimizing state changes and reducing expensive draw calls.
Pixel buffers
Cogl provides a means to allocate GPU memory to hold pixel data and to map that memory into the
CPU. This can be used to achieve zero copy uploads of texture or video data.
CoglMatrix view;
CoglIndices* indices;
CoglPrimitive* prim;
CoglTexture* texture;
CoglPipeline* cratePipeline;
CoglPangoFontMap* pangoFontMap;
PangoContext* pangoContext;
PangoFontDescription* pangoFontDesc;
int hellLabelWidth;
int helloLabelHeight;
GTimer* timer;
gboolean swapReady;
} Data;
Create Window
/* Cogl provides a easier way to create host window
* than the way using native OpenGL & GLX */
// Create a new CoglContext.
CoglContext* ctx = cogl_context_new(NULL, &error);
// Instantiates an "unallocated" CoglOnscreen, Its width and height are 640, 480.
int width = 640, height = 480;
CoglOnscreen* onscreen = cogl_onscreen_new(ctx, width, height);
// Type casting.
CoglFramebuffer* fb = COGL_FRAMEBUFFER(onscreen);
data.fb = fb;
data.framebufferWidth = cogl_framebuffer_get_width(fb);
data.framebufferHeight = cogl_framebuffer_get_height(fb);
// Replaces the current projection matrix with a perspective matrix based on the provied
values.
float fovy = 60, aspect = (float)width / (float)height, z_near = 0.1, z_far = 2000;
cogl_perspective (fovy, aspect, z_near, z_far);
// Multiplies matrix by a view transform that maps the 2D coordinates(0, 0) top-left and
(width, height) bottom-right the full viewport size.
cogl_matrix_view_2d_in_perspective(&view, fovy, aspect, z_near, z_2d, width, height);
cogl_set_modelview_matrix(&view);
//Restores the framebuffer that was previously at the top of the stack.
// All subsequent drawing will be redirected to this framebuffer.
cogl_pop_framebuffer();
Set up a cube
/* Define an index buffer & primitive vertex buffer */
// Rectangle indices allow the GPU to interpret a list of quads as a list of triangles.
// This is a convenience function for accessing internal index buffers that can be
shared.
CoglIndices* indices = cogl_get_rectangle_indices(6);
Prepare a texture
/* Cogl provides a convenient method to create a texture from jpg, png etc.
* If you use the native OpenGL then you need to handle your own-self to do it
* or find an another library to load specific image formats. */
// Since the box is made of multiple triangles that will overlap when drawn
// and we don't control the order they are drawn in, we enable depth testing
// to make sure that triangles that shouldn't be visible get culled by the GPU.
CoglDepthState depthState;
cogl_depth_state_init(&depthState);
cogl_depth_state_set(test)enabled(&depthState, TRUE);
// This commits all the depth state configured in @state struct to the given pipeline.
cogl_pipeline_set_depth_state(cratePipeline, &depthState, NULL);
PangoRectangle helloLabelSize;
pango_layout_get_extents (helloLabel, NULL, &helloLabelSize);
Ready to paint
// Change a target to fb
cogl_push_framebuffer(fb);
Loop
while (1) {
CoglPollFD* pollFds; int numPollFds; gint64 timeout;
if (data.swapReady) {
paint(&data);
// Swaps the current back buffer being rendered too, to the front for display.
cogl_framebuffer_swap_buffers(fb);
}
// This should be called whenever an application is about to go idle
// so that Cogl has a chance to describe what state it needs to be woken up on.
// timeout will contain a maximum amount of time to wait in microseconds before the
// application should wake up or -1 if the application should wait indefinitely.
cogl_poll_get_info(ctx, &pollFds, &numPollFds, &timeout);
if (!hasSwapNotify) {
data.swapReady = TRUE;
timeout = 0;
}
g_poll((GpollFD*)pllFds, numPollFds, timeout == -1 ? -1 : timeout / 1000);
// This should be called whenever an application is woken up from going idle
// in its main loop.
cogl_poll_dispatch(ctx, pollFds, numPollFds);
}
Paint (1/3)
static void paint(Data* data)
{
int framebufferWidth = data->framebufferWidth;
int framebufferHeight = data->framebufferHeight;
int helloLabelWidth = data->helloLabelWidth;
int helloLabelHeight = data->helloLabelHeight;
...
}
Paint (2/3)
/* Translate, scale and rotate the view.
* And then apply the given texture and depth test.
* Finally draw the primitive with the given all states */
static void paint(Data* data)
{
...
cogl_push_matrix();
cogl_translate(framebufferWidth / 2, framebufferHeight / 2, 0);
cogl_scale(75, 75, 75);
cogl_primitive_draw(data->prim);
...
}
Paint (3/3)
static void paint(Data* data)
{
...
// Pop a matrix for the state to draw a previous primitive.
cogl_pop_matrix();
// We don't need a depth test since we're going to draw 2D text here.
cogl_set_depth_test_enabled(FALSE);
Thank you
any Question?