Cogl is a modern 3D graphics API with associated utility APIs designed to expose the features of 3D graphics hardware using a direct state access API design, as opposed to the state-machine style of OpenGL. It is implemented in the C programming language but we want to provide bindings for everyone's favorite language too.
Features
- We build on OpenGL
- Although we started Cogl because we wanted to address the problems we saw with developing using OpenGL we still decided to build on OpenGL ourselves. Although OpenGL isn't perfect it is at least an open standard supported on many platforms so it makes sense that we would want to build on that instead of starting from scratch. Cogl lets us build on OpenGL 1.x - 3.x and OpenGLES 1.x - 2.x and many window system binding APIs (such as EGL, GLX, WGL etc) with a single consistent API that can target many platforms. Eventually the aim is to break down that OpenGL abstraction so that Cogl can drive the GPU more directly but we had to start somewhere.
- One open source implementation
- Cogl is a single open source library which gives us one place to go when we need to fix bugs and add features.
- One of the difficulties with OpenGL is that it's an API specification for hardware vendors to implement and each different implementation has different quirks, extensions and bugs. As Cogl is a library not a specification; once a problem is solved in code, it's solved! That means we are in a position to provide better platform integration which would be too complex to standardize in a vendor neutral specification.
- Related to this we also note that while the trend for OpenGL[ES] to simplify the API is good because hardware vendors don't have to spend effort maintaining legacy APIs that aren't accelerated by their GPUs; it also means that OpenGL[ES] on its own won't provide even basic utilities - such as matrix manipulation. To use OpenGL[ES] for serious application development you need to build a framework around it. Because code in Cogl only needs to be written once and maintained in one library it's much more practical for us to support these utility APIs.
- Direct state access
- Cogl encapsulates state in objects so that writing orthogonal drawing routines is easy. This is in contrast to OpenGL's fairly flat state machine model which is difficult to share. Note: the object model implementation is very low-fi; we don't for instance use GObject as we want the API to be palatable to the widest range of high level framework/toolkit/application developers.
- Maths 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 buffers).
- Textures
- Cogl provides a texture interface for two classes of texture.
- Native textures
- These are the low level textures that the hardware understands (2D, 3D, Rectangle, CubeMap etc as you might be familiar with from using OpenGL).
- 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. We don't try to be too clever here and pretend that meta textures can be used just like native textures but it's useful for them to share a common interface with native textures e.g. for querying their width/height. If you want to draw something with a meta texture then that drawing api needs to manually iterate the underlying native textures with a range of virtual texture coordinates, but Cogl handles most of the tricky stuff for you.
- 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.
- Adaptable Clipping API
- Cogl can optimize clipping depending on the complexity of your clip regions. The GPU's scissoring hardware can be used for screen aligned rectangles; clip planes can be used for non screen aligned rectangles and the stencil buffer can be used for complex shaped clips.
- 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.
- Submit vertex data just how the GPU wants it
- Cogl allows you to map vertices directly into your GPU and reference these vertex buffers for very efficient redrawing of complex models. Use this for geometry that you will re-use multiple times for best performance. You can use this to render models from Blender or 3Ds Max.
- 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.
- Pango text renderer
- Cogl provides an optional extension library called cogl-pango. Cogl-pango provides a pango text renderer that builds on our primitives API; our attribute buffer API and our texture atlas code to provide fast text rendering. Glyphs are cached together in a texture atlas to avoid state changes and we cache vertex data with pre-computed text layouts so e.g. re-rendering the same paragraph multiple times has very little overhead.
- Traceable for performance analysis
- Applications built on top of Cogl can be traced such that we log all Cogl commands to disk allowing us to replay the traces removing all application logic from the equation so that we - and upstream driver developers - can directly analyze the rendering bottlenecks of Cogl applications.
Documentation
- C API Reference Manual
- Read this when you need a no-fuss reference for how to use the C API.
- Cogl Programming Guide (but we need your help!)
- Read this for a broader introduction to using Cogl. This starts by introducing GPU programming concepts but jumps in fairly quickly to show how geometry is drawn using the Cogl API. It follows on with an introduction to 3D graphics transformations and then starts to cover more intermediate topics like texture mapping, blending and framebuffers.
- Call for help!
- I don't think this is going to be easy to provide without help, so everyone please feel free to contribute to this programming guide. Especially if you are new to graphics programming your input will be invaluable for us!
- Anyone who has a copy of the OpenGL Programming Guide should have a pretty good idea of the range of topics we want to cover in this document and we'd be happy to follow a very similar layout. Obviously; please don't copy verbatim text but you may find it is a good meta guide to start with.
Examples
- Spinning Cube
- How to draw a spinning cube using the Cogl API.
http://git.gnome.org/browse/cogl/tree/examples/cogl-crate.c
We still need more good examples for Cogl but you can find a couple of other examples in the examples/ directory that comes with the Cogl source code.
Cogl 2.0
We are currently working towards the Cogl 2.0 API...
If you're experienced with OpenGL and/or D3D development and have a good grasp of modern GPU architectures we'd love to hear your opinions and feedback about the Cogl API. Even without the aforementioned input about the API style and usability are also important to us. You can track some of our current design work on the CoglDesign page and you can also talk to use on #clutter or the cogl mailinglist: https://groups.google.com/forum/?hl=en#!forum/cogl3d
See also