Learning Modern OpenGL


I am confused about how to go about learning openGL.
I have got the latest opengl red book edition 7 and I managed to get up to chapter 9.

I then read the official openGL wiki and I see some horrible stuff like immediate mode is out of date, display lists are out of date, your better off just programming everything in shaders to start with. How am I supposed to go about this? Do I get the orange book (shader)? then that will be out of date also. I hear a lot of the functions will be removed next patch (3.1), so should I ignore these functions when I come across them in the red book?

If someone who knows a lot about the modern openGL please give me some sort of learning list that I could follow to get me started with VBO/shaders without using deprecated code, the modern openGL. I would be very grateful.


  1. The Orange Book is a great read and completely valid.
  2. Even if stuff is removed (not even sure of that yet) in GL 3.1, you can still choose to stay with GL 2/2.1 so no need to panic :slight_smile:

Pretty good tutorial on VBO :

Good introductions on GLSL shaders :

More on the Orange Book website, source code and useful tools :

Well I finally completed a program that renders a triangle on the screen via OpenGL 3.0 today! YAY!!!

I was also doing a lot of graphics programming via shaders, hdr, offscreen rendering, relief mapping, parallax mapping, fresnel effects, reflections and stuff few years ago in an old GL.

So now I have an opinion about all this :slight_smile:

When OpenGL 3.0 came out, everyone seemed to be very disappointed that it’s still OpenGL 2.1+, with all the legacy stuff in, and by no means a rewrite.

After completing OpenGL 3.0 triangle, I think it’s not quite true. If you go for OpenGL 3.0, AND you use forward compatible context, it’s completely different API. Fixed function pipeline is gone, matrix transforms are gone, all legacy ways to specify geometry have gone.

All you do is, you specify arrays and textures, and upload them via few mapping objects to GPU for processing via shaders and process them there. It’s not easy, and quite hostile for newbies, but the API has been simplified by a whole lot.

What I don’t like though, it’s the bloody mess of a documentation! OpenGL 3.0 spec is a patchwork with all the legacy stuff in it, and no easy way to pick out which functions are real, which ones are not.

The second thing I don’t like is the way you have to go to get 3.0 context. The thing is that GL 3.0 has some nice things that for example allow you to query extensions one by one, but they are completely useless because in order to get a 3.0 context you have to load 2.0 context, go through legacy, error prone extension querying mechanism, and only then you can switch to 3.0 context, where you have to start from scratch, because function pointers, for example, might have changed between contexts.

Also, for Windows wglGetProcAddress is a mess. Glext.h is huuuge, and you have no idea which functions to import and which ones you don’t for specific GL version. Remember, GL spec is a mess to go through. And then there are all those EXT, ARB functions. Seems that they are without extended suffixes in GL spec when they are promoted to the core, but in program you still have to query them via full names, and that’s crazy stuff to follow.

It took me 2 days to remember what the GL was like, since I wasn’t doing any programming in GL for 2 years, and to create a triangle program in GL 3.0. It wasn’t easy, changes are noticeable and GL 3.0 initialization is error prone and messy.

But if you start going GL 3.0 way, it’s a pretty decent, quite streamlined API now. I really like it if you go forward compatible way.

I will have to tidy up the GL 3.0 startup code, then I can post it if there is a need.


that would be great :slight_smile: please post it so I can compare it to the 2.1 code.

What I don’t like though, it’s the bloody mess of a documentation! OpenGL 3.0 spec is a patchwork with all the legacy stuff in it, and no easy way to pick out which functions are real, which ones are not.

I strongly agree, the 3.1 spec needs to be done as a separate document with every reference to obsolete functions and old OpenGL versions deleted, plus gl3 specific header files to match.
The old spec would still be there for people who need it, but all the confusion would be removed for people trying to learn OpenGL 3.1 and beyond.

Agree about the spec.

I noticed a few books in the pipeline that covers GL3, supposedly out soon (Beginning OpenGL Game Programming, Second Edition), and in August (OpenGL Programming Guide, 7th Edition).

No wide-lines and no asm makes 3.0 look like a downgrade to me. There’s no room for overabstraction in a performance-critical HAL. Namely the enforced GLSL. It takes a million calls to set-up uniforms. While it’s pretty clear cpus will not get any faster. This overabstraction lets newbie researchers write a hello-world in no time, but makes it harder for real developers to create performant management code for it. And burdens driver-developers, by leaving the compiler implementation in their hands.
Sometimes I wish Khronos stopped with the mindet “oh, tomorrow GPUs could start processing in vec5 instead of vec4”. I’m just waiting for the day they make everything string-and-script based:

gl4UseProgram(“select * from @LoadedPrograms where name=‘BasicTex’ and NumLights=‘6’ and detail=‘fullspecular’”);
gl4SetParam(“@CurrentShader”,“color1=vec4(0.5,1.000f,1.00000,1.00000), mytexture=@gl_AncientTex0_andRecompileShader, myBindableUniform7=pleaseRecompile(0x335513, as = vec4 pos at offset 0, vec3 color2 at offset 16)”);
gl4SetAttrib(“@CurrentShader::myNamedPositionWhichAnywayIs_gl_Vertex_AndNeedntBeAbstract”,“vec3”,“buffer17::manja”); // oh yes, you have to manually set .w=1

And then make VAO2 which again encapsulates only one attrib-ptr, but is limited to VBOs only. (as no-one needs encapsulation of all attrib-binds again and again for a given mesh, that’s unheard of)

As for the OP’s question, here is the list of several GL extensions you need for modern/high-performant code:
It’s all just shaders, occlusion-queries, FBOs, VBOs/PBOs/UBOs. (UBOs are still not mature yet, so skip them)
Additionally, you will use the following ever-existed API: the uploading and binding of textures, the glenable/disable for blending/culling/zbuffer/stencil.

Ilian, I agree 100% about the GLSL uniform setup cost, have run into this with our own apps frequently, and we made this a key item to resolve for GL 3.1.

Your string-based example is amusing but definitely not the direction things are going.

PS, wide lines went back in.

Do you mean by that last comment that in 3.1 they are back in, or that they were put back into the 3.0 spec.?

Rob, that is great news! I missed it somehow. I’ll try to create some 3.0 tutes once I get fluent.

Actually with my post I was over-exaggerating on how GL3.0 looks to me. Uniform-buffers are a great salvation, but they’re not advertised correctly, imho. Having a buffer per instance is unpalatable. Instead, this should be possible/advertised:
bindable uniform SOME_STRUCT g_constants[1];

vec4 color2 = g_constants[InstanceConstID].color2;
// above InstanceConstID is a uniform or varying, and can have value = 777

Meanwhile, glUniform should be able to upload a whole struct, that contains only vec4/mat4, or an array of vec4.

In a perfect world, maybe there’d be a glCopyUniforms(…,UBO buf,int vec4offset,int vec4count). I’ve got many ideas/solutions (they’re kind of obvious), but I don’t know NDA-class details on current gpus to choose the best one to propose. I.e whether there’s a cached range of constants in all gpus, or everything depends on general-purpose caches while loading constant-data dynamically.

Well note that 3.0 spec did not remove anything, it only marked things as deprecated.

Wide lines were marked. Now they are not.

Forgive me for asking, but to my knowledge the uniform buffer mechanism for GL 3.1 is not published yet. Which spec are you reading ?

Bindable uniforms is what I meant. And what’s exposed by nv_parameter_buffer_object. The latter is very neat stuff, probably precisely what most devs would need (specifying a range to be bound). Still, being down-to-the-metal (having semantics to specify which shader symbol takes which slot) is necessary for such stuff.