OpenGL stands for Open Graphics Library. It is a specification of an API for rendering graphics, usually in 3D.

−

Many graphic cards have an OpenGL API implementation.

+

OpenGL stands for Open Graphics Library. It is a specification of an API for rendering graphics, usually in 3D. OpenGL implementations are libraries that implement the API defined by the specification.

−

That means that it is possible to write an application that will be possible to use against many different types of graphics cards.

+

−

It also increases the chance that the application will continue to work when new hardware will become available.

+

Graphics cards usually have an OpenGL implementation. Because the OpenGL specification is not platform-specific, it is possible to write an application that will be possible to use against many different types of graphics cards. It also increases the chance that the application will continue to work when new hardware will become available.

=== What is NOT OpenGL? ===

=== What is NOT OpenGL? ===

Line 16:

Line 16:

GLUT is not OpenGL. It is not a part of OpenGL; it is simply a library that is used by some users to create an OpenGL window.

GLUT is not OpenGL. It is not a part of OpenGL; it is simply a library that is used by some users to create an OpenGL window.

−

=== Who maintains? ===

+

=== Who maintains the OpenGL specification? ===

The specification is maintained by [[OpenGL Architectural Review Board]] or ARB.

The specification is maintained by [[OpenGL Architectural Review Board]] or ARB.

Line 23:

Line 23:

No, OpenGL doesn't have any source code. GL is a specification which can be found on this website. It describes the interface the programmer uses and expected behavior. OpenGL is an open ''specification''. Anyone can download the spec for free. This is as opposed to ISO standards and specifications, which cost money to access.

No, OpenGL doesn't have any source code. GL is a specification which can be found on this website. It describes the interface the programmer uses and expected behavior. OpenGL is an open ''specification''. Anyone can download the spec for free. This is as opposed to ISO standards and specifications, which cost money to access.

−

There is an implementation of GL that is Open Source and it is called Mesa3D http://www.mesa3d.org Its announcing itself as [[History_of_OpenGL#OpenGL_2.1_.282006.29|OpenGL 2.1]] compliant.

+

There is an implementation of GL that is Open Source and it is called [http://www.mesa3d.org Mesa3D] It [http://www.mesa3d.org/intro.html announces itself] as implementing [[History_of_OpenGL#OpenGL_3.0_.282008.29|OpenGL 3.0]] and [[GLSL]] 1.30.

−

=== Where can I download? ===

+

=== Where can I download OpenGL? ===

Just like the "Open Source?" section explains, OpenGL is not a software product. it is a specification.

Just like the "Open Source?" section explains, OpenGL is not a software product. it is a specification.

Line 32:

Line 32:

On Windows, companies like nVidia and AMD/ATI use the spec to write their own implementation, so OpenGL is included in the drivers that they supply. For laptop owners, however, you'll need to visit the manufacturer of your laptop and download the drivers from them.

On Windows, companies like nVidia and AMD/ATI use the spec to write their own implementation, so OpenGL is included in the drivers that they supply. For laptop owners, however, you'll need to visit the manufacturer of your laptop and download the drivers from them.

−

=== Where can I download? #2 ===

+

=== Where can I download OpenGL? #2 ===

Updating your graphics drivers is usually enough to get the latest OpenGL implementation for your graphics hardware. This is sufficient for those who want to use applications that require OpenGL.

Updating your graphics drivers is usually enough to get the latest OpenGL implementation for your graphics hardware. This is sufficient for those who want to use applications that require OpenGL.

Line 50:

Line 50:

OpenGL ES is often supported on embedded systems, but OpenGL ES is a different API from regular OpenGL.

OpenGL ES is often supported on embedded systems, but OpenGL ES is a different API from regular OpenGL.

−

=== What is an OpenGL context? ===

+

=== What is an OpenGL context and why do you need a window to do GL rendering? ===

{{main|OpenGL context}}

{{main|OpenGL context}}

−

And why do you need a window to do GL rendering?

−

The GL context comprises resources (driver resources in RAM, texture IDs assigned, VBO IDs assigned, enabled states (GL_BLEND, GL_DEPTH_TEST) and many other things). Think of the GL context as some memory allocated by the driver to store some information about the state of your GL program.

+

+

The GL context comprises resources (driver resources in RAM, texture IDs assigned, VBO IDs assigned, enabled states ({{enum|GL_BLEND}}, {{enum|GL_DEPTH_TEST}}) and many other things). Think of the GL context as some memory allocated by the driver to store some information about the state of your GL program.

You must create a GL context in order for your GL function calls to make sense. You can't just write a minimal program such as this:

You must create a GL context in order for your GL function calls to make sense. You can't just write a minimal program such as this:

+

<source lang="cpp">

<source lang="cpp">

int main(int argc, char **argv)

int main(int argc, char **argv)

Line 66:

Line 67:

}

}

</source>

</source>

−

In the above, the programmer simply wants to get information about this system (he doesn't want to render anything) but it simply won't work because no communication has been established with the GL driver. The GL driver also needs to allocate resources with respect to the window such as a backbuffer. Based on the pixelformat you have chosen, there can be a color buffer with some format such as <tt>BGRA8</tt>. There may or may not be a depth buffer. The depth might contain 24 bits. There might be a 8 bit stencil. There might be an accumulation buffer. Perhaps the pixelformat you have chosen can do multisampling. Up until now, no one has introduced a windowless context.

−

You must create a window. You must select a pixelformat. You must create a GL context. You must make the GL context current (<tt>wglMakeCurrent</tt> for Windows and <tt>glXMakeCurrent</tt> for *nix).

+

In the above, the programmer simply wants to get information about this system (he doesn't want to render anything) but it simply won't work because no communication has been established with the GL driver. The GL driver also needs to allocate resources with respect to the window such as a backbuffer. Based on the pixelformat you have chosen, there can be a color buffer with some format such as {{enum|GL_BGRA8}}. There may or may not be a depth buffer. The depth might contain 24 bits. There might be a 8 bit stencil. There might be an accumulation buffer. Perhaps the pixelformat you have chosen can do multisampling. Up until now, no one has introduced a windowless context.

−

=== Offscreen Rendering ===

+

You must create a window. You must select a pixelformat. You must create a GL context. You must make the GL context current ({{code|wglMakeCurrent}} for Windows and {{code|glXMakeCurrent}} for *nix).

−

Some people want to do offscreen rendering and they don't want to show a window to the user. The only solution is to create a window and make it invisible, select a pixelformat, create a GL context, make the context current. Now you can make GL function calls. You should make a FBO and render to that. If you chose to not create a FBO and you prefer to use the backbuffer, there is a risk that it won't work.

+

+

=== How do I do offscreen rendering? ===

+

Some people want to do offscreen rendering and they don't want to show a window to the user. The only solution is to create a window and make it invisible, select a pixelformat, create a GL context, make the context current. Now you can make GL function calls. You should make a [[Framebuffer Object|FBO]] and render to that. If you chose to not create a FBO and you prefer to use the backbuffer, there is a risk that it won't work.

When you compile an application, you link with <tt>opengl32.dll</tt> (even on Win64).

+

When you compile an application, you link with {{code|opengl32.dll}} (even on Win64).

−

When you run your program, <tt>opengl32.dll</tt> gets loaded and it checks in the Windows registry if there is a true GL driver. If there is, it will load it. For example, ATI's GL driver name starts with <tt>atioglxx.dll</tt> and [[nVidia|NVIDIA]]'s GL driver is <tt>nvoglv32.dll</tt>. The actual names change from release versions.

+

When you run your program, {{code|opengl32.dll}} gets loaded and it checks in the Windows registry if there is a true GL driver. If there is, it will load it. For example, ATI's GL driver name starts with {{code|atioglxx.dll}} and NVIDIA's GL driver is {{code|nvoglv32.dll}}. The actual names can change from release versions.

−

<tt>opengl32.dll</tt> is limited to '''OpenGL 1.1'''.

+

The Microsoft Windows DLL {{code|opengl32.dll}} only directly exposes '''OpenGL 1.1''' functions. To gain access to functions from higher GL versions, you must load these function pointers manually with {{code|wglGetProcAddress}}. The [[Load OpenGL Functions|details of this process is explained]].

−

Even though the supplier of the graphics card support later versions of OpenGL, it means you can't use that functionality directly.

−

For GL >=1.2 functions, you get a function pointer with <tt>wglGetProcAddress</tt>. Examples are <tt>glActiveTexture, glBindBuffer, glVertexAttribPointer</tt>. <tt>wglGetProcAddress</tt> returns an address from the real driver in these cases.

−

There are several helper libraries for this, doing what is commonly called "name mangling".

−

The only important thing to know is that <tt>opengl32.dll</tt> belongs to [[Microsoft]]. No one can modify it. You '''must not''' replace it. You '''must not''' ship your application with this file. You '''must not''' ship <tt>nvoglv32.dll</tt> or any other system file either.

+

There are several helper libraries for this, doing what is commonly called [[Extension Loading Library|Extension Loading Libraries]].

+

+

The important thing to know is that {{code|opengl32.dll}} belongs to Microsoft. No one can modify it. You ''must not'' replace it. You ''must not'' ship your application with this file. You ''must not'' ship {{code|nvoglv32.dll}} or any other system file either.

It is the responsibility of the user to install the driver made available from Dell, HP, nVidia, ATI/AMD, Intel, SiS, and whatever. Though feel free to remind them to do so.

It is the responsibility of the user to install the driver made available from Dell, HP, nVidia, ATI/AMD, Intel, SiS, and whatever. Though feel free to remind them to do so.

=== How do I tell what version of OpenGL I'm using? ===

=== How do I tell what version of OpenGL I'm using? ===

−

Use the function [[glGetString|glGetString]], with <code>GL_VERSION</code> passed as argument. This will return a null-terminated string. Be careful when copying this string into a fixed-length buffer, as it can be fairly long.

+

+

Use the function [[GLAPI/glGetString|glGetString]], with <code>GL_VERSION</code> passed as argument. This will return a null-terminated string. Be careful when copying this string into a fixed-length buffer, as it can be fairly long.

+

Alternatively, you can use <code>glGetIntegerv(GL_MAJOR_VERSION, *)</code> and <code>glGetIntegerv(GL_MINOR_VERSION, *)</code>. These require GL 3.0 or greater.

Alternatively, you can use <code>glGetIntegerv(GL_MAJOR_VERSION, *)</code> and <code>glGetIntegerv(GL_MINOR_VERSION, *)</code>. These require GL 3.0 or greater.

+

+

In order to get the latest version that your GPU supports, make sure that you update your video drivers. GL support is included in your video card's drivers. Also, you might notice that your GL version is for example 2.1. How can you get the latest version? It depends on your GPU. It is possible that your GPU doesn't support anything higher therefore the manufacturer of you video card doesn't provide a higher version. In that case, you can either buy a new video card or try Mesa3D (which is a software renderer) http://www.mesa3d.org

=== Why is my GL version only 1.4 or lower? ===

=== Why is my GL version only 1.4 or lower? ===

−

There are two reasons you may get an unexpectedly low OpenGL version.

+

There are three reasons you may get an unexpectedly low OpenGL version.

−

On Windows, you may be a low GL version if, during [[Creating an OpenGL Context|context creation]], you use an unaccelerated pixel format. This means you get the default implementation of OpenGL. Depending on whether you are using Windows Vista or earlier versions of Windows, this may mean you get a software GL 1.1 implementation, or a hardware GL 1.5 implementation.

+

On Windows, you might get a low GL version if, during [[Creating an OpenGL Context|context creation]], you use an unaccelerated pixel format. This means you get the default implementation of OpenGL which is version 1.1.

−

The solution to this is to be more careful in your pixel format selection.

+

The solution to this is to be more careful in your pixel format selection. More information can be found at [[Platform_specifics:_Windows|Platform_specifics:_Windows]] and other parts of the Wiki.

The other reason is that the makers of your video card (and therefore the makers of your video drivers) do not provide an up-to-date OpenGL implementation. There are a number of defunct graphics card vendors out there. However, of the non-defunct ones, this is most likely to happen with Intel's integrated GPUs.

The other reason is that the makers of your video card (and therefore the makers of your video drivers) do not provide an up-to-date OpenGL implementation. There are a number of defunct graphics card vendors out there. However, of the non-defunct ones, this is most likely to happen with Intel's integrated GPUs.

Intel does not provide a proper, up-to-date OpenGL implementation for their integrated GPUs. There is nothing that can be done about this. NVIDIA and ATI provide good support for their integrated GPUs.

Intel does not provide a proper, up-to-date OpenGL implementation for their integrated GPUs. There is nothing that can be done about this. NVIDIA and ATI provide good support for their integrated GPUs.

+

+

Another reason is that you haven't installed your video card drivers after installing your OS.

+

+

Be sure to query OpenGL with {{apifunc|glGetString}} and make sure the returned values make sense.

=== Are glTranslate/glRotate/glScale hardware accelerated? ===

=== Are glTranslate/glRotate/glScale hardware accelerated? ===

−

No, there are no known GPUs that execute this. The driver computes the matrix on the CPU and uploads it to the GPU. All the other matrix operations are done on the CPU as well : <tt>glPushMatrix, glPopMatrix, glLoadIdentity, glFrustum, glOrtho</tt>. This is the reason why these functions are considered deprecated in GL 3.0. You should have your own math library, build your own matrix, upload your matrix to the shader. There are some [[Related toolkits and APIs|libraries]] which you can use for this.

+

No, there are no known GPUs that execute this.

+

These functions are [[Legacy_OpenGL|deprecated in GL 3.0]]. You should have your own math library, build your own matrix, upload your matrix to the shader. There are some [[Related toolkits and APIs|libraries]] which you can use for this.

+

+

=== Do modern GPUs still support the fixed-function pipeline? ===

+

+

{{main|Legacy OpenGL}}

+

+

Modern GPUs no longer provide specialized hardware for the purpose of doing specific calculations in the OpenGL pipeline. Everything is done with shaders. In order to preserve compatibility, the GL driver generates a shader which emulates the fixed functionality.

−

=== Fixed function and modern GPUs ===

+

Among many others, a simple example is rendering a primitive using one function call to submit each vertex attribute separately, e.g. {{code|glVertex3f(1.f, 0.f, 0.f)}}, inside a {{code|glBegin()}} and {{code|glEnd()}} statement. Using shaders, you have to first define all vertex attributes in a local memory buffer, create a buffer object, and then transfer the vertex attributes using {{apifunc|glBufferData}}, {{apifunc|glBufferSubData}} or by mapping the buffer using {{apifunc|glMapBuffer}} or {{apifunc|glMapBufferRange}}. Shaders will then be able to use the data in the buffer object's data store for rendering.

−

Modern GPUs no longer support fixed function. Everything is done with shaders. In order to preserve compatibility, the GL driver generates a shader that simulates the fixed function. It is recommended that all new modern programs use shaders. New users need not learn fixed function related operations of GL such as glLight, glMaterial, glTexEnv and many others.

=== How to render in pixel space ===

=== How to render in pixel space ===

Line 144:

Line 159:

=== Multi indexed rendering ===

=== Multi indexed rendering ===

−

What this means is that each [[Vertex Attributes|vertex attribute]] (position, normal, etc) has its own index array. OpenGL (and Direct3D, for that matter) do not support this.

+

What this means is that each [[Vertex Attribute]] (position, normal, etc) has its own index array. OpenGL (and Direct3D, for that matter) do not support this.

It is up to you the user to adjust your data format so that there is only one index array, which samples from multiple attribute arrays. To do this, you will need to duplicate some attribute data so that all of the attribute lists are the same size.

It is up to you the user to adjust your data format so that there is only one index array, which samples from multiple attribute arrays. To do this, you will need to duplicate some attribute data so that all of the attribute lists are the same size.

Line 183:

Line 198:

* [[Vertex Array Objects]]

* [[Vertex Array Objects]]

* [[Vertex Specification]]

* [[Vertex Specification]]

+

+

=== Drawing A Cube ===

+

This question comes up often since there seems to be a lot of users rendering a lot of cubes. Just like the above section explains, OpenGL supports one index for a [[Vertex Attribute]] (a vertex attribute is position, normal, texcoord, etc).

+

+

Since a cube's face is flat, a user would want flat shading on each face. This means having 1 normal per face. However, GL wants 1 normal per vertex. The best solution is as the above section explains, duplicate the vertex because once one of the attributes is different, it is considered a completely different vertex. Another alternative is to do the following :

+

+

<source lang="cpp">

+

//The following code is for GL 2.0

+

//Render face 1

+

glNormal3fv(mynormal1); //Set your face normal

+

glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);

+

glEnableClientState(GL_VERTEX_ARRAY);

+

glVertexPointer(3, GL_FLOAT, sizeof(MyVertex), BUFFER_OFFSET(0)); //The starting point of the VBO, for the vertices

//We can just call glDrawElements since the rest of the setup is already done above

+

glDrawElements(GL_QUADS, 4, GL_UNSIGNED_SHORT, BUFFER_OFFSET(16));

+

+

//.... and render face 3 and 4 and 5 and 6

+

</source>

+

+

In the above code, the disadvantage becomes clear. We can only render 1 quad at a time. It requires 6 calls to glDrawElements just to render a single cube. Another problem is that you are using glNormal3fv which doesn't fetch its data from a VBO!

glScissor is one of the few functions that effect on how glClear operates. If you want to clear only a region of the back buffer, then call glScissor and also glEnable(GL_SCISSOR_TEST).

+

{{apifunc|glScissor}} is one of the few functions that affects on how {{apifunc|glClear}} operates. If you want to clear only a region of the back buffer, then call glScissor and also {{apifunc|glEnable|(GL_SCISSOR_TEST)}}.

Alternatively, if you have used the scissor test and forgot to glDisable(GL_SCISSOR_TEST), then you might wonder why glClear isn't working the way you want to.

Alternatively, if you have used the scissor test and forgot to glDisable(GL_SCISSOR_TEST), then you might wonder why glClear isn't working the way you want to.

Line 194:

Line 239:

=== glGetError (or "How do I check for GL errors?) ===

=== glGetError (or "How do I check for GL errors?) ===

{{main|GL Error Codes}}

{{main|GL Error Codes}}

−

OpenGL keeps a set of ''error flags'', and each call to <code>glGetError()</code> tests and clears one of those flags. When there are no more error flags set, then <code>glGetError()</code> returns <code>GL_NO_ERROR</code>.

+

OpenGL keeps a set of ''error flags'', and each call to <code>[[GLAPI/glGetError|glGetError()]]</code> tests and clears one of those flags. When there are no more error flags set, then <code>glGetError()</code> returns <code>GL_NO_ERROR</code>.

−

The problem with this is that you have to poll for errors.

+

−

In a production release of software, this poll should be kept to a minimum, as it results in a performance penalty.

+

This helper function can be used to query all previously fired OpenGL errors:

This requires active polling for errors. Doing so can incur a performance penalty, so it is best to limit this to debug builds where possible.

+

+

The extension [http://www.opengl.org/registry/specs/ARB/debug_output.txt ARB_debug_output] provides an alternative mechanism that can offer error handling without explicit polling. The overhead for this can be significant, and it is only available if the OpenGL context is created with the {{code|CONTEXT_DEBUG_BIT_ARB}} flag.

−

With OpenGL 4, it is possible to enable better debugging.

+

This became a core feature in OpenGL 4.3, with [http://www.opengl.org/registry/specs/KHR/debug.txt KHR_debug]. This feature is always available, but non-debug contexts are not required to actually log message.

−

See http://www.opengl.org/registry/specs/ARB/debug_output.txt for more information.

=== What 3D file format should I use? ===

=== What 3D file format should I use? ===

Line 234:

Line 296:

The purpose of this section is to answer those who want to know what happens when they allocate resources and the video card runs out of VRAM. This behavior is not documented in the GL specification because it doesn't concern itself with system resources and system design. System design can differ and GL tries to remain system neutral. Some systems don't have a video card. Some systems have an integrated CPU/GPU with shared RAM.

The purpose of this section is to answer those who want to know what happens when they allocate resources and the video card runs out of VRAM. This behavior is not documented in the GL specification because it doesn't concern itself with system resources and system design. System design can differ and GL tries to remain system neutral. Some systems don't have a video card. Some systems have an integrated CPU/GPU with shared RAM.

−

=== Display List or VA or VBO ===

+

=== Should I use display lists, vertex arrays or vertex buffer objects? ===

{{main|Vertex Specification}}

{{main|Vertex Specification}}

−

Display lists and VA (vertex array) have been with GL since the beginning. VBO was introduced with GL 1.5. Newcomers would like to know which to use since GL is a complicated API with multiple ways to do the same thing.

−

Display lists are great for static data. The driver probably stores them in video memory and it certainly performs well. The driver optimizes whatever vertex/normal/texcoord format you throw at it. On the otherhand, VBO was introduced into GL 1.5 for a reason. Display list is marked as deprecated in the GL 3.0 specification. In the end, it is up to you if you want to use it in your modern program. Yes, you can store additional function calls in a display list such as glBindTexture but it is best to avoid this. The original intention of display lists was for it to be a macro. The driver just piles up commands in RAM. When you call glCallList, the driver just sends the block of commands.

+

Display lists and vertex arrays have been with GL since the beginning. Vertex buffer objects were introduced with GL 1.5. Although they can all be used to render primitives, they are not the same and have disctinct properties:

−

Vertex arrays are stored in RAM. The driver will have to send it to video memory before processing them. The good news is that you can have a dynamic object in it. On the other hand, why would you use it if you have VBO?

+

* A display list is a series of well defined GL commands which may be optimized in terms of execution and data transfer to video memory when the list is created. Commands and data in the list stored in server or video memory and are retrieved and executed when the list is called. For instance, specifying vertex attributes using a vertex array will likely cause the GL to store the data in video memory for fast access. Display lists are static, so mapping display lists to dynamically changing data is not possible. The advantage is that execution time is generally very fast in comparison to some alternatives.

−

[[Buffer Object|Buffer objects]] were first introduced during the GL 1.4 era, via the GL_ARB_vertex_buffer_object extension. This extension allowed buffer objects to be used for vertex array and element array storage. It went into core in GL 1.5.

+

* Vertex arrays allow for vertex specification in one shot using an array of attributes. This avoid using immediate mode constructs which possibly pass each attribute vertex by vertex and thus lead to a high number of API call and to data transfer attribute by attribute. Vertex arrays allow for dynamic vertex specification. However, since data is stored in client memory, i.e. system memory managed by the application, it has to be transferred to the GL every time as well.

−

You can put vertex arrays in display lists.

+

* Vertex buffer objects are, if the GL can do so, stored in video memory - just like display lists. Thus you avoid having to re-transfer every frame. However, unlike display lists, you can dynamically updated vertex buffer objects. Also, you get the advantage of the very low number of API calls necessary to actually render.

−

<source lang="cpp">

+

Both display lists and vertex arrays are [[Legacy OpenGL|legacy OpenGL]] features. [[Vertex Specification|Vertex specification]] is now mostly done with vertex buffer objects and vertex array objects in modern OpenGL. As a general advice, you should refrain from using legacy constructs in new OpenGL applications.

−

glNewList(DisplayListID, GL_COMPILE);

−

glVertexPointer(.....);

−

glEnableClientState(....);

−

glNormalPointer(...);

−

glEnableClientState(....);

−

glDrawRangeElements or glDrawElements;

−

glEndList();

−

</source>

−

This bakes the vertex array data directly into the display list. Once <tt>glEndList</tt> is executed, changing the data in your vertex arrays will not change anything that was built into the display list. So you can free up that memory for other uses.

+

'''If and only if''' there is a requirement to maintain existing legacy code and there is no way to rewrite the rendering system, using display lists can be quite advantageous in comparison to vertex arrays for static data. If dynamic updates are required, there is no way arround vertex arrays. If immediate mode constructs like {{code|glBegin()}} are found, they can be replaces by either display lists or vertex arrays to improve performance in many real cases where the number of vertices is usually hundreds or thousands per object.

−

You can put VBOs in a display list as well. However, once your display list is created, changing the VBOs content will not change the content of the display list.

+

=== What does ''Unresolved External Symbol'' mean? ===

−

+

Some newcomers try to compile their GL program and get linker errors such as:

−

=== unresolved external symbol ===

+

error LNK2001: unresolved external symbol _glBegin

−

Some newcomers try to compile their GL program and get linker errors such as

−

<source lang="cpp">

−

error LNK2001: unresolved external symbol _glBegin

−

</source>

and similar linker errors related to other GL functions and perhaps GLU functions and other functions from other libraries.

and similar linker errors related to other GL functions and perhaps GLU functions and other functions from other libraries.

Line 272:

Line 321:

For VC++ 2010, you could click on Project from the menu. Select Properties. From that properties dialog box, on the left side, drop the Configuration Properties. Drop Linker. Click on Input. On the right side, it says Additional Dependencies. Type the name of the library file followed by a colon. For OpenGL, it would be opengl32.lib. For GLU, it would be glu32.lib.

For VC++ 2010, you could click on Project from the menu. Select Properties. From that properties dialog box, on the left side, drop the Configuration Properties. Drop Linker. Click on Input. On the right side, it says Additional Dependencies. Type the name of the library file followed by a colon. For OpenGL, it would be opengl32.lib. For GLU, it would be glu32.lib.

−

Alternatively, you can add this line

+

Alternatively, you can add these lines:

+

<source lang="cpp">

<source lang="cpp">

#pragma comment(lib, "opengl32.lib")

#pragma comment(lib, "opengl32.lib")

Line 278:

Line 328:

</source>

</source>

−

to your .cpp files.

+

to your .cpp files, which will force the libraries to be included. These only work on compilers that support this use of #pragma.

Obviously, we can't list what you need to do for each IDE. You need to search the internet or your manuals. You need to know how to use your IDE and your particular programming language.

Obviously, we can't list what you need to do for each IDE. You need to search the internet or your manuals. You need to know how to use your IDE and your particular programming language.

Instead of the above files, if you are using an extension loading library, make sure you download their latest version.

=== Why limit to 8 lights? ===

=== Why limit to 8 lights? ===

−

On the other hand, this limitation is only valid when you program in immediate mode and don't use shaders.

+

The OpenGL fixed-function pipeline has the concept of a maximum number of lights to render with. Shaders do not have any lights; you may use shaders to render any number of lights, but you must build this framework within the tools that shaders give you.

−

One the other hand, OpenGL immediate mode supports 8 lights as a minimum, not maximum.

+

+

Within fixed-function OpenGL, it is often asked why GL supports a maximum of 8 lights. That is not true, GL doesn't impose a maximum of 8 lights. It imposes a minimum of 8 lights. Your driver/GPU combo is allowed to support more than 8 but most of them limit themselves to 8. The reason for that is that it doesn't become noticeable when there are more than 3 or 4 lights shining on the same surface. So in fact, 8 is an excessive number.

+

+

Example, if you have a city and you have street lights, you probably need more than 8 street lights. The solution is to subdivide your city streets in sections where only 3 lights effect each surface. It is up to you, the artist, to make it look good.

+

+

Example, if you are doing particle effects where each particle is a light source and you have perhaps 1000 particles, that is actually an insane number of lights for a real time renderer for old hardware (example : hardware that supports GL 1.5). You can get away with it with just 1 light for the entire group of particles.

+

+

If you do really want to have more than 8 lights, you can do it with a multipass approach. Render your object with 8 lights on. Then enable blending and enable additive blending (<code>[[GLAPI/glBlendFunc|glBlendFunc]](GL_ONE, GL_ONE)</code>) and then render your object again. You might want to set your depth test to GL_LEQUAL.

+

+

Now let's look at it in a different perspective. Did old game use lights? Actually they did not. Many old games used light maps for static surfaces. For a moving object, they computed the lighting themselves or it was precomputed (aka. light volume).

=== Can I precompile my shaders? ===

=== Can I precompile my shaders? ===

−

No, you can't precompile shaders into some binary format and then ship them with your program.

+

GL 4.1 adds the ability to compile the shader and you get to download the shader binary from the GL driver, however, these binaries are GPU and driver specific. There is no guarantee they will work on other GPUs. There is no guarantee that they will work once the user upgrades or downgrades the driver. The purpose of this feature is to compile once and store on the hard drive for future runs. They avoid the compile and link time in future runs of your application. However, driver updates may change the version of these shaders, which will force you to recompile shaders from scratch.

+

+

If you ship your application with precompiled shaders, you have to include the source code format also.

+

That way you can do the compilation the usual way if loading of the precompiled files fails.

−

GL 4.1 adds the ability to compile the shader and you get to download the shader binary from the GL driver, however, these binaries are GPU and driver specific. There is no guarantee they will work on other GPUs. There is no guarantee that they will work once the user upgrades or downgrades the driver. The purpose of this feature is to compile once and store on the hard drive for future runs. They avoid the compile and link time in future runs of your application. Of course, once the drivers are changed, the shader binary upload will fail and your program must recompile all the shaders again.

+

Note that the extension to do this, [http://www.opengl.org/registry/specs/ARB/get_program_binary.txt ARB_get_program_binary], is widely available on pre-4.1 hardware. So you do not need 4.x-class hardware to use it.

=== Many Small 2D Textures ===

=== Many Small 2D Textures ===

Line 299:

Line 382:

Another solution is to make use of 2D texture array (GL_TEXTURE_2D_ARRAY which is part of GL 3.0 and above). This solves the problem that is present in the case of using a 3D texture as described above, however, the texture sizes must all be the same.

Another solution is to make use of 2D texture array (GL_TEXTURE_2D_ARRAY which is part of GL 3.0 and above). This solves the problem that is present in the case of using a 3D texture as described above, however, the texture sizes must all be the same.

+

+

=== Font Rendering and Text Rendering ===

+

GL doesn't render text because GL is a low level library. It handles the basics such as rendering points, lines and triangles and whatever technique that might get introduced in the future. For rendering text, you either need a 3rd party library or do it yourself.

+

+

One of the simplest methods is to create a texture with all the characters on it. Then, render many quads on your screen and texture map the characters.

+

+

You could also have a texture with full sentences. Then, render a quad and texture it.

+

+

You could also use the features of your OS and get access to the fonts and make texture out of it. Then, texture map some quads.

+

+

Windows offers certain functions for text rendering but these are old and should probably not be used these days. See {{apifunc|wglUseFontBitmaps}} and {{apifunc|wglUseFontOutlines}}.

+

+

The old FAQ explains the above well. It also has links to 3rd party libraries. http://www.opengl.org/archives/resources/faq/technical/#indx0170

which in principle ease the process of calculating a view- and projection matrix to be used during rendering. However, both functions use and/or are to be used in the context of a legacy feature called the matrix stack and corresponding matrix manipulation functions which make them unfit or illegal in modern OpenGL applications which don't intend to use deprecated or removed functionality.

+

+

If you're writing an application which uses modern OpenGL, i.e. core OpenGL 3.0 or higher, it is recommended to either write your own code or use a 3rd party library which either isn't layered on OpenGL at all or uses OpenGL 3.0 or higher core features. A list of suitable 3rd party libraries can be found [[Related_toolkits_and_APIs|here]].

+

+

If you still plan on using GLU, you should know that Windows provides glu32.dll. It provides GLU version 1.2. Your compiler should come with glu32.lib or glu32.a. You should also know that the latest version of GLU is 1.3. You can download the entire package that Mesa3D provides (http://www.mesa3d.org). Inside, you will find the source code for GLU 1.3 and you must compile it yourself. Remember that you must not replace Microsoft's glu32.dll. It is considered a system file and you must never overwrite system files.

Revision as of 03:04, 2 October 2012

This article contains inaccurate information. Further details can be found on the talk page.

This article needs proper formatting or improved descriptions. Further details can be found on the talk page.

What is OpenGL?

OpenGL stands for Open Graphics Library. It is a specification of an API for rendering graphics, usually in 3D. OpenGL implementations are libraries that implement the API defined by the specification.

Graphics cards usually have an OpenGL implementation. Because the OpenGL specification is not platform-specific, it is possible to write an application that will be possible to use against many different types of graphics cards. It also increases the chance that the application will continue to work when new hardware will become available.

What is NOT OpenGL?

The OpenGL API only deals with rendering graphics. OpenGL does not provide functions for animations, timing, file IO, image file format processing, GUI, and so forth. OpenGL is concerned only about rendering.

GLUT is not OpenGL. It is not a part of OpenGL; it is simply a library that is used by some users to create an OpenGL window.

Who maintains the OpenGL specification?

Is OpenGL Open Source?

No, OpenGL doesn't have any source code. GL is a specification which can be found on this website. It describes the interface the programmer uses and expected behavior. OpenGL is an open specification. Anyone can download the spec for free. This is as opposed to ISO standards and specifications, which cost money to access.

Where can I download OpenGL?

Just like the "Open Source?" section explains, OpenGL is not a software product. it is a specification.

On Mac OS X, Apple's OpenGL implementation is included.

On Windows, companies like nVidia and AMD/ATI use the spec to write their own implementation, so OpenGL is included in the drivers that they supply. For laptop owners, however, you'll need to visit the manufacturer of your laptop and download the drivers from them.

Where can I download OpenGL? #2

Updating your graphics drivers is usually enough to get the latest OpenGL implementation for your graphics hardware. This is sufficient for those who want to use applications that require OpenGL.

What is an OpenGL context and why do you need a window to do GL rendering?

The GL context comprises resources (driver resources in RAM, texture IDs assigned, VBO IDs assigned, enabled states (GL_BLEND, GL_DEPTH_TEST) and many other things). Think of the GL context as some memory allocated by the driver to store some information about the state of your GL program.

You must create a GL context in order for your GL function calls to make sense. You can't just write a minimal program such as this:

In the above, the programmer simply wants to get information about this system (he doesn't want to render anything) but it simply won't work because no communication has been established with the GL driver. The GL driver also needs to allocate resources with respect to the window such as a backbuffer. Based on the pixelformat you have chosen, there can be a color buffer with some format such as GL_BGRA8. There may or may not be a depth buffer. The depth might contain 24 bits. There might be a 8 bit stencil. There might be an accumulation buffer. Perhaps the pixelformat you have chosen can do multisampling. Up until now, no one has introduced a windowless context.

You must create a window. You must select a pixelformat. You must create a GL context. You must make the GL context current (wglMakeCurrent​ for Windows and glXMakeCurrent​ for *nix).

How do I do offscreen rendering?

Some people want to do offscreen rendering and they don't want to show a window to the user. The only solution is to create a window and make it invisible, select a pixelformat, create a GL context, make the context current. Now you can make GL function calls. You should make a FBO and render to that. If you chose to not create a FBO and you prefer to use the backbuffer, there is a risk that it won't work.

How Does It Work On Windows?

All Windows versions support OpenGL.

When you compile an application, you link with opengl32.dll​ (even on Win64).

When you run your program, opengl32.dll​ gets loaded and it checks in the Windows registry if there is a true GL driver. If there is, it will load it. For example, ATI's GL driver name starts with atioglxx.dll​ and NVIDIA's GL driver is nvoglv32.dll​. The actual names can change from release versions.

The Microsoft Windows DLL opengl32.dll​ only directly exposes OpenGL 1.1 functions. To gain access to functions from higher GL versions, you must load these function pointers manually with wglGetProcAddress​. The details of this process is explained.

The important thing to know is that opengl32.dll​ belongs to Microsoft. No one can modify it. You must not replace it. You must not ship your application with this file. You must not ship nvoglv32.dll​ or any other system file either.

It is the responsibility of the user to install the driver made available from Dell, HP, nVidia, ATI/AMD, Intel, SiS, and whatever. Though feel free to remind them to do so.

How do I tell what version of OpenGL I'm using?

Use the function glGetString, with GL_VERSION passed as argument. This will return a null-terminated string. Be careful when copying this string into a fixed-length buffer, as it can be fairly long.

Alternatively, you can use glGetIntegerv(GL_MAJOR_VERSION, *) and glGetIntegerv(GL_MINOR_VERSION, *). These require GL 3.0 or greater.

In order to get the latest version that your GPU supports, make sure that you update your video drivers. GL support is included in your video card's drivers. Also, you might notice that your GL version is for example 2.1. How can you get the latest version? It depends on your GPU. It is possible that your GPU doesn't support anything higher therefore the manufacturer of you video card doesn't provide a higher version. In that case, you can either buy a new video card or try Mesa3D (which is a software renderer) http://www.mesa3d.org

Why is my GL version only 1.4 or lower?

There are three reasons you may get an unexpectedly low OpenGL version.

On Windows, you might get a low GL version if, during context creation, you use an unaccelerated pixel format. This means you get the default implementation of OpenGL which is version 1.1.

The solution to this is to be more careful in your pixel format selection. More information can be found at Platform_specifics:_Windows and other parts of the Wiki.

The other reason is that the makers of your video card (and therefore the makers of your video drivers) do not provide an up-to-date OpenGL implementation. There are a number of defunct graphics card vendors out there. However, of the non-defunct ones, this is most likely to happen with Intel's integrated GPUs.

Intel does not provide a proper, up-to-date OpenGL implementation for their integrated GPUs. There is nothing that can be done about this. NVIDIA and ATI provide good support for their integrated GPUs.

Another reason is that you haven't installed your video card drivers after installing your OS.

Be sure to query OpenGL with glGetString​ and make sure the returned values make sense.

Are glTranslate/glRotate/glScale hardware accelerated?

No, there are no known GPUs that execute this.
These functions are deprecated in GL 3.0. You should have your own math library, build your own matrix, upload your matrix to the shader. There are some libraries which you can use for this.

Do modern GPUs still support the fixed-function pipeline?

Modern GPUs no longer provide specialized hardware for the purpose of doing specific calculations in the OpenGL pipeline. Everything is done with shaders. In order to preserve compatibility, the GL driver generates a shader which emulates the fixed functionality.

Among many others, a simple example is rendering a primitive using one function call to submit each vertex attribute separately, e.g. glVertex3f(1.f, 0.f, 0.f)​, inside a glBegin()​ and glEnd()​ statement. Using shaders, you have to first define all vertex attributes in a local memory buffer, create a buffer object, and then transfer the vertex attributes using glBufferData​, glBufferSubData​ or by mapping the buffer using glMapBuffer​ or glMapBufferRange​. Shaders will then be able to use the data in the buffer object's data store for rendering.

How to render in pixel space

Setup a certain projection matrix:

glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(0.0,WindowWidth,0.0,WindowHeight,-1.0,1.0);//Setup modelview to identity if you don't need GL to move around objects for youglMatrixMode(GL_MODELVIEW);glLoadIdentity();

Notice that y axis goes from bottom to top because of the glOrtho call. You can swap bottom and top parameters if you want y to go from top to bottom. make sure you render your polygons in the right order so that GL doesn't cull them or just call glDisable(GL_CULL_FACE).

Fullscreen quad

Users seem to ask often how to render a fullscreen quad. What should the projection matrix look like?

The projection matrix should be an identity matrix. In old GL, you can call glMatrixMode(GL_PROJECTION) and glLoadIdentity() and glMatrixMode(GL_MODELVIEW) and glLoadIdentity().

In shader based GL, the GLSL shader doesn't even need a matrix. You can just do this

Multi indexed rendering

What this means is that each Vertex Attribute (position, normal, etc) has its own index array. OpenGL (and Direct3D, for that matter) do not support this.

It is up to you the user to adjust your data format so that there is only one index array, which samples from multiple attribute arrays. To do this, you will need to duplicate some attribute data so that all of the attribute lists are the same size.

Quite often, this question is asked by those wanting to use the OBJ file format:

The lines that start with an f are the faces. As you can see, each vertex has 3 indices, one for vertex, normal, texcoord. In the example above, luckily the index for each {vertex, normal, texcoord} is identical but you will also encounter cases where they are not. You would have to expand such cases. Example :

f 1/1/1 2/2/2 3/2/2
f 5/5/5 6/6/6 3/4/5

so the group 3/2/2 and 3/4/5 are considered a difference vertex entirely even though they both access vertex 3.

You will need to do post-processing on OBJ files before you can use them. This means that the vertex count, the normal count, the texcoord count and whatever other attributes you have have, the count must be the same for all. Example : If you have 10 vertices, then you must have 10 normals to go along with them. You can't have 10 vertices and 7 normals.

You have 3 options : either you allocate separate arrays for each of your attributes or you create a single array for your attributes and you interleave the vertex and normals and texcoords or you create a single array and you don't interleave (example : you put all your vertices at the start of the array, then all the normals, then all the texcoords, etc). There are other pages on this Wiki that explain all that in more detail.

See also

Drawing A Cube

This question comes up often since there seems to be a lot of users rendering a lot of cubes. Just like the above section explains, OpenGL supports one index for a Vertex Attribute (a vertex attribute is position, normal, texcoord, etc).

Since a cube's face is flat, a user would want flat shading on each face. This means having 1 normal per face. However, GL wants 1 normal per vertex. The best solution is as the above section explains, duplicate the vertex because once one of the attributes is different, it is considered a completely different vertex. Another alternative is to do the following :

//The following code is for GL 2.0//Render face 1glNormal3fv(mynormal1);//Set your face normalglBindBuffer(GL_ARRAY_BUFFER,VertexVBOID);glEnableClientState(GL_VERTEX_ARRAY);glVertexPointer(3,GL_FLOAT,sizeof(MyVertex),BUFFER_OFFSET(0));//The starting point of the VBO, for the verticesglClientActiveTexture(GL_TEXTURE0);glEnableClientState(GL_TEXTURE_COORD_ARRAY);glTexCoordPointer(2,GL_FLOAT,sizeof(MyVertex),BUFFER_OFFSET(12));//The starting point of texcoords, 12 bytes awayglBindBuffer(GL_ELEMENT_ARRAY_BUFFER,IndexVBOID);//Bind the IBOglDrawElements(GL_QUADS,4,GL_UNSIGNED_SHORT,BUFFER_OFFSET(0));//Render face 2glNormal3fv(mynormal2);//Set your face normal//We can just call glDrawElements since the rest of the setup is already done aboveglDrawElements(GL_QUADS,4,GL_UNSIGNED_SHORT,BUFFER_OFFSET(16));//.... and render face 3 and 4 and 5 and 6

In the above code, the disadvantage becomes clear. We can only render 1 quad at a time. It requires 6 calls to glDrawElements just to render a single cube. Another problem is that you are using glNormal3fv which doesn't fetch its data from a VBO!

This requires active polling for errors. Doing so can incur a performance penalty, so it is best to limit this to debug builds where possible.

The extension ARB_debug_output provides an alternative mechanism that can offer error handling without explicit polling. The overhead for this can be significant, and it is only available if the OpenGL context is created with the CONTEXT_DEBUG_BIT_ARB​ flag.

This became a core feature in OpenGL 4.3, with KHR_debug. This feature is always available, but non-debug contexts are not required to actually log message.

What 3D file format should I use?

Newcomers often wonder what 3D file format, for their indices and vertices and texcoords and texture name, to use for their project.

GL doesn't offer any 3D file format because GL is just a low level library. You would either have to use someone else's library or write your own code. You have to decide whether to use an already existing file format or create your own. Newcomers don't want to reinvent the wheel but the fact is, in the games industry, it is very common to reinvent the wheel when it comes to 3D files.

In case you want to use an already existing format, the obj format is very popular because it is in ASCII text. This format is very limited. It is very old.

The 3ds format is also popular. There is even a open source library called lib3ds. It is old and limited. There is no official documentation from the company that created it.

DirectX has the x file format. It supports simple meshes and keyframes and multiple vertex attributes.

Some people use md2 (from Quake 2). md3 from Quake 3. BSP. POD. RAW. LWO. Milkshape. ASE. Some of them belong to the inventor (company) and you are not suppose to use them.

There is COLLADA which uses a XML style and it has become popular for content creators. This format can be read and exported by several 3D editors (example : Blender).

Memory Usage

It seems to be common to think that there is a memory leak in the OpenGL driver. Some users write simple programs such as this

glClear(...);SwapBuffers(...);

and they observe that their memory usage goes up each time their Display function is called. That is normal. The driver might allocate some memory space and since the driver is basically a black box, we don't know what it is doing. The driver might be doing some work at optimizing in a secondary thread or preparing some buffering area. We don't know what it is doing, but there is no memory leak.

Some users call glDeleteTextures or glDeleteLists or one of the other delete functions and they notice that memory usage doesn't go down. You can't do anything about it. The driver does its own memory management and it might choose not to deallocate for the time being. Therefore, this is not a memory leak either.

Who manages memory? How does OpenGL manage memory?

Graphics cards have limited memory, if you exceed it by allocating many buffer objects and textures and other GL resources, the driver can store some of it in system RAM. As you use those resources, the driver can swap in and out of VRAM resources as needed. Of course, this slows down rendering. The amount of RAM storage is also limited for the driver and it might return a GL_OUT_OF_MEMORY when you call glGetError(). It might even return a GL_OUT_OF_MEMORY if you have plenty of VRAM and RAM available and you try to allocate a really large buffer object that the driver doesn't like.

The purpose of this section is to answer those who want to know what happens when they allocate resources and the video card runs out of VRAM. This behavior is not documented in the GL specification because it doesn't concern itself with system resources and system design. System design can differ and GL tries to remain system neutral. Some systems don't have a video card. Some systems have an integrated CPU/GPU with shared RAM.

Should I use display lists, vertex arrays or vertex buffer objects?

Display lists and vertex arrays have been with GL since the beginning. Vertex buffer objects were introduced with GL 1.5. Although they can all be used to render primitives, they are not the same and have disctinct properties:

A display list is a series of well defined GL commands which may be optimized in terms of execution and data transfer to video memory when the list is created. Commands and data in the list stored in server or video memory and are retrieved and executed when the list is called. For instance, specifying vertex attributes using a vertex array will likely cause the GL to store the data in video memory for fast access. Display lists are static, so mapping display lists to dynamically changing data is not possible. The advantage is that execution time is generally very fast in comparison to some alternatives.

Vertex arrays allow for vertex specification in one shot using an array of attributes. This avoid using immediate mode constructs which possibly pass each attribute vertex by vertex and thus lead to a high number of API call and to data transfer attribute by attribute. Vertex arrays allow for dynamic vertex specification. However, since data is stored in client memory, i.e. system memory managed by the application, it has to be transferred to the GL every time as well.

Vertex buffer objects are, if the GL can do so, stored in video memory - just like display lists. Thus you avoid having to re-transfer every frame. However, unlike display lists, you can dynamically updated vertex buffer objects. Also, you get the advantage of the very low number of API calls necessary to actually render.

Both display lists and vertex arrays are legacy OpenGL features. Vertex specification is now mostly done with vertex buffer objects and vertex array objects in modern OpenGL. As a general advice, you should refrain from using legacy constructs in new OpenGL applications.

If and only if there is a requirement to maintain existing legacy code and there is no way to rewrite the rendering system, using display lists can be quite advantageous in comparison to vertex arrays for static data. If dynamic updates are required, there is no way arround vertex arrays. If immediate mode constructs like glBegin()​ are found, they can be replaces by either display lists or vertex arrays to improve performance in many real cases where the number of vertices is usually hundreds or thousands per object.

What does Unresolved External Symbol mean?

Some newcomers try to compile their GL program and get linker errors such as:

error LNK2001: unresolved external symbol _glBegin

and similar linker errors related to other GL functions and perhaps GLU functions and other functions from other libraries.

The example given above is specific to Microsoft Visual C++ but you can get linker errors from other linkers as well. In order for the linker to do its job, it needs to know which library file it should search.

For VC++ 2010, you could click on Project from the menu. Select Properties. From that properties dialog box, on the left side, drop the Configuration Properties. Drop Linker. Click on Input. On the right side, it says Additional Dependencies. Type the name of the library file followed by a colon. For OpenGL, it would be opengl32.lib. For GLU, it would be glu32.lib.

Alternatively, you can add these lines:

#pragma comment(lib, "opengl32.lib")#pragma comment(lib, "glu32.lib")

to your .cpp files, which will force the libraries to be included. These only work on compilers that support this use of #pragma.

Obviously, we can't list what you need to do for each IDE. You need to search the internet or your manuals. You need to know how to use your IDE and your particular programming language.

Instead of the above files, if you are using an extension loading library, make sure you download their latest version.

Why limit to 8 lights?

The OpenGL fixed-function pipeline has the concept of a maximum number of lights to render with. Shaders do not have any lights; you may use shaders to render any number of lights, but you must build this framework within the tools that shaders give you.

Within fixed-function OpenGL, it is often asked why GL supports a maximum of 8 lights. That is not true, GL doesn't impose a maximum of 8 lights. It imposes a minimum of 8 lights. Your driver/GPU combo is allowed to support more than 8 but most of them limit themselves to 8. The reason for that is that it doesn't become noticeable when there are more than 3 or 4 lights shining on the same surface. So in fact, 8 is an excessive number.

Example, if you have a city and you have street lights, you probably need more than 8 street lights. The solution is to subdivide your city streets in sections where only 3 lights effect each surface. It is up to you, the artist, to make it look good.

Example, if you are doing particle effects where each particle is a light source and you have perhaps 1000 particles, that is actually an insane number of lights for a real time renderer for old hardware (example : hardware that supports GL 1.5). You can get away with it with just 1 light for the entire group of particles.

If you do really want to have more than 8 lights, you can do it with a multipass approach. Render your object with 8 lights on. Then enable blending and enable additive blending (glBlendFunc(GL_ONE, GL_ONE)) and then render your object again. You might want to set your depth test to GL_LEQUAL.

Now let's look at it in a different perspective. Did old game use lights? Actually they did not. Many old games used light maps for static surfaces. For a moving object, they computed the lighting themselves or it was precomputed (aka. light volume).

Can I precompile my shaders?

GL 4.1 adds the ability to compile the shader and you get to download the shader binary from the GL driver, however, these binaries are GPU and driver specific. There is no guarantee they will work on other GPUs. There is no guarantee that they will work once the user upgrades or downgrades the driver. The purpose of this feature is to compile once and store on the hard drive for future runs. They avoid the compile and link time in future runs of your application. However, driver updates may change the version of these shaders, which will force you to recompile shaders from scratch.

If you ship your application with precompiled shaders, you have to include the source code format also.
That way you can do the compilation the usual way if loading of the precompiled files fails.

Note that the extension to do this, ARB_get_program_binary, is widely available on pre-4.1 hardware. So you do not need 4.x-class hardware to use it.

Many Small 2D Textures

This technique is also called a texture atlas.

Some users ask about putting together many smaller 2D textures inside one big 2D texture (1024 x 1024 or something larger). This way, you can avoid a call to glBindTexture and perhaps gain some performance. Yes, you can do that but you also have to watch out for the texture coordinates on your models. You also have to watch out for texture filtering because a linear filter can cause texel bleed (neighboring sub-texture gets sampled).

Another solution is to put those small textures in one 3D texture (GL_TEXTURE_3D which is part of GL 1.3 and above) as long as all the 2D textures are the same size. The problem of texture filtering still is present in this case in case you use linear filtering. There is no problem in the S and T direction but the problem is present between the texture layers.

Another solution is to make use of 2D texture array (GL_TEXTURE_2D_ARRAY which is part of GL 3.0 and above). This solves the problem that is present in the case of using a 3D texture as described above, however, the texture sizes must all be the same.

Font Rendering and Text Rendering

GL doesn't render text because GL is a low level library. It handles the basics such as rendering points, lines and triangles and whatever technique that might get introduced in the future. For rendering text, you either need a 3rd party library or do it yourself.

One of the simplest methods is to create a texture with all the characters on it. Then, render many quads on your screen and texture map the characters.

You could also have a texture with full sentences. Then, render a quad and texture it.

You could also use the features of your OS and get access to the fonts and make texture out of it. Then, texture map some quads.

What is GLU?

which in principle ease the process of calculating a view- and projection matrix to be used during rendering. However, both functions use and/or are to be used in the context of a legacy feature called the matrix stack and corresponding matrix manipulation functions which make them unfit or illegal in modern OpenGL applications which don't intend to use deprecated or removed functionality.

If you're writing an application which uses modern OpenGL, i.e. core OpenGL 3.0 or higher, it is recommended to either write your own code or use a 3rd party library which either isn't layered on OpenGL at all or uses OpenGL 3.0 or higher core features. A list of suitable 3rd party libraries can be found here.

If you still plan on using GLU, you should know that Windows provides glu32.dll. It provides GLU version 1.2. Your compiler should come with glu32.lib or glu32.a. You should also know that the latest version of GLU is 1.3. You can download the entire package that Mesa3D provides (http://www.mesa3d.org). Inside, you will find the source code for GLU 1.3 and you must compile it yourself. Remember that you must not replace Microsoft's glu32.dll. It is considered a system file and you must never overwrite system files.