As you may have heard already, the OpenGL 3.0 specification is out. This is great news, since it allows us to draw the last conclusions for the 0.9 clanDisplay render abstraction, so we can target both OpenGL 2.0, 3.0, Direct3D 9 and 10.

For those of you that have been browsing other forums and news sites like slashdot, don't fall for the trolling about OpenGL 3.0. In my opinion the changes made to OpenGL 3.0 do bring the library up to speed when compared to Direct3D 10. It is pretty common that backwards compatibility is loathed upon by write-and-forget coders (typically consultants doing web site development or game writers that restart their code base with each new game), a very large and loud community within coders. But don't let their loudness fool you - if you ignore the parts marked as deprecated in 3.0 specification, then you actually get a standard with an API not so bad. The only real shame with OpenGL is actually the way Microsoft refuses to update their WGL implementation, so to see the API as it really is, you need to use wrappers such as the ClanLib glwrap.h header, or other libraries on the net that does the same thing.

Anyway, this post wasn't about the OpenGL standard, but how it will affect the API in ClanLib 0.9. The deprecated parts of OpenGL when mapped to 0.9 objects are:

PrimitiveArray changes:

  • edge flags gone
  • all fixed function attributes gone: pos, normal, texcoords etc
  • client memory arrays are gone (but we may want to simulate them for convenience and for CL_Draw)


GraphicContext changes:

  • projection and modelview matrixes are gone
  • All light related states are gone (light sources, materials, colorsum)
  • draw_primitives: polygons, quads and quad strips gone
  • draw_pixels: gone (eventually along with their 2.1 buffer objects I guess)


Texture changes:

  • borders gone
  • texture arrays added
  • integer and other internal formats added
  • clamp wrap mode gone (since it clamps to border)
  • automatic mipmap generation state gone, replaced with a function


State object changes:

  • CL_TextureUnit gone
  • alpha test, fog gone (which state object?)
  • CL_PolygonRasterizer: PolygonMode and PolygonStipple states gone
  • CL_Pen: LineWidth only 1.0 or less now, LineStipple gone
  • CL_Point: only point sprites now


DisplayWindow changes:

  • Accumulation buffers gone


The things above are all fixed pipeline functionality, or functionality that work with data placed in system memory. Most of this isn't that surprising, since this is exactly the same parts that Microsoft stripped out for Direct3D 10, except in this case the OpenGL people didn't force people to rewrite all their code and read up on a completely new API from scratch.

The client memory issue

Because OpenGL intends to remove the client memory vertex and element arrays, we are left with three options:

  • Do the same, remove all client memory pointers from CL_PrimitivesArray
  • Implement client memory support ourselves, by creating a vertex buffer we stream to when draw_primitives is called
  • Improve the API of CL_VertexArrayBuffer


Obviously the first option is the easiest. However, I kinda like that feature when I want to draw something quick'n'lazy. On the other hand, we are already being forced to simulate it with Direct3D, and simulating it is a bit tricky if the user specifies the element indicies in a GPU buffer (we have to download that buffer to system memory then).

The ideal solution would probably be if we can change the API of vertex array buffers to become so convenient that the user might as well just upload it to the GPU themselves prior to the draw_primitives call.

The fixed function pipeline

The second issue we get is a bit more global in nature. Our current 2D rendering functionality depends on the fixed function pipeline in three ways:

  1. CL_GraphicContext contains function that work on the projection and modelview matrices. However a vertex shader is free to calculate the output vertex position any way it see fit from its input
  2. CL_Draw and CL_Sprite use the projection and modelview matrices, along with a simple fixed-function shader setup
  3. Our 2D mapping modes uses the fixed function matrices to do their mapping


I think the best way of solving this is to define a set of standard shaders offered by the clanDisplay abstraction. Those shaders will then use predefined vertex attribute indexes and uniform variables to do their thing. From this we effectively define our own limited fixed-function pipeline, optimized only for our own 2D rendering needs and with the potential that limited targets (such as a GDI or SDL target) can choose only to support these program objects.

DrawPixels

I'm not entirely sure why they fancy to deprecate this function, since in some situations you might want to just render something once and keep the image in system memory. The easiest way to workaround this issue is to upload the image to a texture before drawing it, then destroy the texture afterwards. Just seems bit like a waste of memory and maybe also performance doing it that way.