I've just started to learn OpenGL 3 and I'm using freeglut for the context. I ask for a 3.3 context using:


I then query the version I'm using with:

int glVersion[2] = {0,0};
glGetIntegerv(GL_MAJOR_VERSION, &glVersion[0]);
glGetIntegerv(GL_MINOR_VERSION, &glVersion[1]);

Furthermore in my simple program, I create a triangle using a VBO. When I compile and run, the triangle is not rendered.

There are three ways that fix the problem and I don't understand why. The first method is to uncomment the first two lines of code I posted. In this case, the 3 next lines I posted, still report that I'm using OpenGL 3.3.

The second method it to wrap the VBO in a VAO.

The third one is to ask for a 2.1 context but in this case a version 3.3 is being reported again.

Could you help me understand this behaviour? Is it specified somewhere in the OpenGL specification that a VBO needs to be wrapped in a VAO in versions 3.x?


2 Answers 2


Never, ever, ever, EVER use FORWARD_COMPATIBLE for ANYTHING.

If you want a core OpenGL context in FreeGLUT, ask for it with the right function:


You never need the FORWARD_COMPATIBLE bit set. I know that a lot of code does it, and if I could, I would scour the Internet and blacklist every webpage that says to use this flag.

The FORWARD_COMPATIBLE flag should never mean anything to a compatibility context. FOWARD_COMPATIBLE means that features marked deprecated aren't available; nothing is marked deprecated in a compatibility context, so therefore it should have no effect.

When used with a core context, it will remove the few features that have been marked deprecated but were never actually removed (wide lines and a couple of other things). But there's no point in doing that; if the ARB were going to remove them, they'd have done so already.

Therefore, the flag no longer serves a purpose. It meant something in 3.0, before core contexts. But it means nothing now.

In any event, the lack of the VAO is the problem. Once you have a core context (which I think you get by default when asking for a specific version number), you must use a VAO to store your vertex array bindings.

  • \$\begingroup\$ Hi, thanks, for your answer. Could you or some one else, point to where in the OpenGL specification it is stated that even if you have a single VBO you have to wrap it in a VAO? \$\endgroup\$ May 1, 2012 at 14:37
  • \$\begingroup\$ @user1294203: The standard doesn't talk about "VBO"s; there are simply buffer objects, which may be used for vertex data. But the particular part of the standard you want is section 2.8 of the 4.2 core spec: "An INVALID_OPERATION is generated [...] if no vertex array object is currently bound." This is talking about the use of glVertexAttribPointer. Similar terminology exists for glEnable/DisableVertexAttribArray and other functions. \$\endgroup\$ May 1, 2012 at 19:56
  • \$\begingroup\$ Thanks a lot! I read that section and also the sections 2.9 and 2.10 but I still don't completely get it. It will probably take some more experience to understand the specs fully. \$\endgroup\$ May 2, 2012 at 1:44

Since OpenGL 3.1 there are actually different types of contexts (called profiles):

  • There is the compatibility profile, which is completely backward compatible down to OpenGL 1.0 and thus includes all deprecated functionality (like glBegin/glEnd or the fixed function pipeline).

  • Then there is the core profile, which has all deprecated functionality removed and concentrates on modern features only (like VBOs, VAOs and shaders). You can use all those from the compatibility profile, too, but in the core profile you have to use them over their deprecated counterparts.

Now your actual problem is, that the core profile indeed requires you to wrap your vertex array state in a VAO. When you don't take any specific measures (like in your two code lines) you usually get the highest available OpenGL version (3.3 in your case) with a compatibility profile (which would allow non-VAO arrays). But in your second line you are actually requesting a forward-compatible context. This is a special kind of core profile context, which is even further restricted and doesn't even support features that are just planned to be deprecated in the future (only glLineWidth at the moment, I think).

So when commenting those lines you get a compatibility context and are allowed to use VBOs (or even client arrays) without VAOs. Requesting a 2.1 context seems in this case to be equal to just requesting an as high as possible context (3.3) with compatibility profile, as this is a superset of 2.1, anyway.

But to overcome this I suggest you to use VAOs and stay with the forward-compatible core context, as it is in general a good idea to concentrate on modern and future-ready OpenGL without deprecated features.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .