OpenGL de-coupling / Renderer abstraction

So I’ve been looking into an OpenGL ES 2.0 rendering path for Openframeworks iOS, it lives here for now:
https://github.com/andreasmuller/openFrameworks/tree/develop-opengles2

It doesn’t do any of the fancy stuff yet, it uses http://code.google.com/p/gles2-bc/ to emulate the fixed function pipeline.

Looking into this brings up a lot of areas where OF is tightly bound to OpenGL 1.1, basically making straight OpenGL calls, without notifying the renderer, this works for some ES 2.0 stuff, crashes on others.

Now of course OpenGL 1.1 is not going anywhere anytime too soon (well, let’s hope), but I do think it doesn’t hurt to be prepared, desktop OpenGL is on version 4.1 at the moment and the inability to mix OpenGL ES 1.1 and shaders is a pain.

The renderer is also the perfect place for ray tracer scene exporters for example(!!), like the Cairo renderer is doing now for vector graphics.

What I’ve been doing is wrapping the calls I need, say glLightfv into an equivalent _ofLightfv that passes the command along to the renderer.

My thinking here is that the commands should look the same as their OpenGL equivalents to make any code you are porting or found on the internet simple to move over, while making it clear that this is not stuff you should normally be calling yourself (hence the underscore), but I’d love to hear how people feel about this. There should of course be functions more clearly named with their purpose that allow us to do the same thing (e.g setLightParameters).

Nothing would be stopping your from writing straight OpenGL 1.1 code as long as you have an GL 1.1 context, but it just wouldn’t be passed along to the renderer, so in your own app you would only need to think about it if you knew you wanted ES 2.0 capability or wanted to use some custom renderer.

Now OpenGL has a LOT of functions, but I think it’s a question of 10% of them being used 80% of the time (I made this numbers up just now.) It would be a long term thing, but it’s a slow process that might be good to start before we really NEED to for whatever reason.

It does make any OpenGL code in the core look a bit odd, the naming is of course a small issue, but how do people fel about this approach in general?

/A

I think its really important for the future of OF to start moving towards the ability to easily switch renderers, in the long term this has got to be a must.

It would be great to be able to use shaders on iOS sometime.

I’m looking at your implementation, and realizing that glu.h which is included in ofConstants.h is including gl.h which defines some GL1 constants that shouldn’t be there, indeed glu is not opengl ES2 or opengl3> compatible. If you remove it like:

  
#if defined( TARGET_OPENGLES ) && !defined(OPENGLES_VERSION_2)  
	#include "glu.h"  
#endif  

then lot’s of errors appear in ofGLRenderer, ofTexture and ofVbo

Ah thanks, will have a look!

It would crash if any of those functions are called, which hasn’t happened to me so far, but we should catch this at compile time of course.

I’ve got binding of custom shaders working (as opposed to the fixed pipeline emulation shaders of gles2-bc), will commit to my fork as soon as I figure out why I can’t get depth on FBOs in ES2.

Nothing significant to add other than: this is really great and I agree with Chris, getting away from too much fixed-pipeline stuff while keeping the API as friendly/intuitive/excellent is a really awesome thing to be working on.

andreas, can you push your changes to github? i’m testing this too and wouldn’t like to modify things that you’ve already done.

about the FBO, can it be related to:

http://forum.openframeworks.cc/t/fbo-in-ios—stencil-buffer/6837/0

Also once you remove glu.h there’s lots of things that are not there anymore like several functions that can be solved with your pattern of adding them like _ofGLFunction but also some defines that would probably need to include some header from gles2-bc or redefine them in OF similar to what is done with OF_PRIMITIVE_TRIANGLES…

Sure thing, will do as soon as possible.

I’m trying out moving gles2-bc into the libs folder at the moment as it has #defines for all this stuff, but this of course broke everything, will push up as soon as I have it compiling again.

The glu stuff in ofCamera for instance was a super easy fix with the core Matrix library and the ofLoadMatrix I added.

The glu stuff in ofCamera for instance was a super easy fix with the core Matrix library and the ofLoadMatrix I added.

yeah, i have that fixed too : ) btw, i’ve added versions of that functions that accept an ofMatrix4x4 instead of a float*

and yes, i think moving gles2-bc to libs is the best solution, with that the _functions are not even needed and all the functions that have no opengl2 version can just be called through gles2-bc directly in an ifdef for OPENGLES_VERSION_2. The renderer for opengles2 can have a getContext method that returns the gles2-bc context so you can do:

ofGetES2Renderer()->getContext()->glFunction(…)

or even

ofGetES2Context()->glFunction(…)

way more verbose but i think it’s cleaner than the _functions solution

this sounds like a prime example for our first feature-* branch :smiley:

Ok I’ve pushed it to: https://github.com/andreasmuller/openFrameworks/tree/develop-opengles2

Yes I think something like this would make a lot of sense, the tricky thing would be to make it generic, something like:

ofGetGraphicsContext()->glFunction(…)

,where a non OpenGL renderer (like a scene exporter) would just translate that into the closest command internally that makes sense.

Ok I’ve pushed it to: [https://github.com/andreasmuller/openFrameworks/tree/develop-opengles2

](https://github.com/andreasmuller/openFrameworks/tree/develop-opengles2)

great, going to take a look

Yes I think something like this would make a lot of sense, the tricky thing would be to make it generic…

i think this is super specific to mantain compatibility in opengl ES 2 with opengl ES 1 so i don’t think it should be made super generic.

At some point if we add more renderers there should be versions of ofTexture for example that work with those renderers, similar to what we’ve done with the swappable apis for video or sound.

calling glSomething from direct x code for example seems really confusing and since most of them are really low level functions probably won’t have a simple translation into other renderers.

There’s an example of this in ofGetGLRenderer() which returns the gl renderer if there’s one so an fbo can pass itself to the gl renderer when it’s binded. if the current renderer is not a gl one then that function returns NULL and the fbo does nothing.