Difference between revisions of "FAQ"

From OpenGL Wiki
Jump to: navigation, search
m (Immediate mode, display lists, vertex arrays, VBO)
(Fixing redlinks.)
 
(133 intermediate revisions by 17 users not shown)
Line 1: Line 1:
Welcome to the FAQ
+
{{inaccurate}}
 +
{{cleanup}}
 +
 
 +
Welcome to the FAQ.
 +
 
  
 
=== What is OpenGL? ===
 
=== What is OpenGL? ===
OpenGL stands for Open Graphics Library. It is an API for doing 3D graphics.<br>
 
In more specific terms, it is an API that is used to "draw triangles on your scene". In this age of GPUs, it is about talking to the GPU
 
so that it does the job of drawing. It does not deal with file formats. It does not open bmp, png and any image format. It does not
 
open 3d object formats like obj, max, maya. It does not do animation. It does not handle keyboard, mouse and any input devices. It does not
 
create a window, and so on.<br>
 
All that stuff should be handled by an external library (GLUT is one example that is used for creating and destroying a window and handling mouse and keyboard).<br>
 
GL has gone through several versions : 1.0, 1.1, 1.2, 1.2.1, 1.3, 1.4, 1.5, 2.0, 2.1, 3.0<br>
 
At each versions, extensions of interest are introduced into the core. Usually, they are all <b>ARB</b> extensions.<br>
 
  
=== Who maintains? ===
+
[[OpenGL]] is the name for the [[OpenGL Specification|specification that describes the behavior]] of a rasterization-based rendering system. It defines the API through which a client application can control this system. The OpenGL rendering system is carefully specified to make hardware implementations allowable.
GL is created at SGI. Later on, the Architectural Review Board (ARB) controlled it which is a collection of major graphics companies.<br>
+
 
Control was transfered to Khronos, which is another collection of major graphics companies. Their website is at http://www.khronos.org
+
Hardware vendors, the people who make GPUs, are responsible for writing implementations of the OpenGL rendering system. Their implementations, commonly called "drivers", translate OpenGL API commands into GPU commands. If a particular piece of hardware is unable to implement all of the OpenGL specification via hardware, the hardware vendor must still provide this functionality, typically via a software-based implementation of the features missing from hardware.
and they are specially known for OpenGL ES in which the ES means Embeded System (cellphones, PDA, consoles such as the Playstation 3 (PS3)) and other Open Spec
+
 
APIs. You can find the list of companies at Khronos' website.
+
=== 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? ===
 +
 
 +
The OpenGL specification is maintained by the [https://www.khronos.org/ Khronos Group] committee called the [[OpenGL Architectural Review Board]] (ARB). Originally, the ARB was an organization sponsored by SGI, but it was adopted by the Khronos Group.
 +
 
 +
=== 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.
 +
 
 +
[http://www.mesa3d.org Mesa3D] is an open source software implementation of the OpenGL specification. The latest versions implement [[History_of_OpenGL#OpenGL_4.3_.282012.29|OpenGL 4.3]], [[OpenGL_ES|OpenGL ES]] 2.0, [[GLSL]] 3.30 (and several extensions) and [[EGL]] 1.4.
 +
 
 +
=== 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 in the OS.
 +
 
 +
On Windows, hardware vendors (such as NVIDIA or 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.
  
=== Open Source? ===
+
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.
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 Open Spec. Anyone can download the spec for free.<br>
 
There is an implementation of GL that is Open Source and it is called Mesa3D http://www.mesa3d.org<br>
 
It doesn't have the license to call itself OpenGL, but it does follow the spec very well.
 
  
=== Where can I download? ===
+
For programmers, installing drivers is generally insufficient. You will need to load the OpenGL function pointers, either [[Load OpenGL Functions|manually]] or [[OpenGL Loading Library|automatically with a library]]. More information on this can be found in the [[Getting started]] page.
Just like the "Open Source?" section explains, GL is not a software product. GL is a specification.<br>
 
Companies like nVidia and AMD/ATI use the spec to write their drivers, so OpenGL is in fact included in the drivers that they supply.<br>
 
For laptop owners, you need to visit the manufacturer of your laptop and download the drivers from them.
 
  
=== Where can I download? #2 ===
+
=== Is there an OpenGL SDK? ===
When you update your video driver, this is good enough for people who want to play games or run some application.<br>
+
There is no actual OpenGL SDK. There is a collection of websites, some (outdated) documentation, and links to tutorials, all found [[Getting_started#SDK| here]]. But it is not an SDK of the kind you are thinking about.
For programmers, installing drivers will not give you a gl.h file. It will not give you opengl32.lib. Those are files that come with your compiler (on Windows, your compiler might need opengl32.lib or perhaps opengl32.a).<br>
 
Also, there are no updated gl.h and opengl32.lib file. These are stuck at GL 1.1 and will be forever. Read the Getting Started section to learn what you must do. http://www.opengl.org/wiki/Getting_started<br>
 
Also, installing a video driver will not replace opengl32.dll. It is a system file and belongs to Windows. Only Microsoft may update it.<br>
 
When you install a video driver, another file will be copied to your system (nvoglv32.dll in the case of nVidia) and the registry will be modified.<br>
 
opengl32.dll will call into the real GL driver (nvoglv32.dll).
 
  
=== SDK ===
+
NVIDIA and AMD have their own SDKs, both of which have various example code for OpenGL.
See this page<br>
 
http://www.opengl.org/wiki/Getting_started#SDK
 
<br>
 
There isn't an official SDK from http://www.opengl.org however 3rd party individuals have made great websites and tutorials, companies like nVidia and ATI/AMD have made available many small projects that demonstrate GL features.<br>
 
If you are new and want to understand what you must do, the 2 most important pages on this Wiki are : this FAQ page and also http://www.opengl.org/wiki/Getting_started
 
  
 
=== What platforms have GL? ===
 
=== What platforms have GL? ===
Windows : 95 and above<br>
+
* Windows: 95 and above
Mac OSX : all versions<br>
+
* Mac OSX: all versions
Linux : this depends on the distributions. Distros meant for desktop usage come with Gnome, KDE or some windows manager and OpenGL
+
* Linux: OpenGL is provided by open source drivers and MESA library, or by proprietary drivers.
is either supplied as Mesa (software rasterizer) or they provide proper drivers.<br>
+
* FreeBSD: OpenGL is provided by open source drivers and MESA library or proprietary Nvidia drivers.
FreeBSD : unknown<br>
+
 
Cellphones, PDA, consoles such as the Playstation 3 (PS3) have OpenGL ES.<br>
+
OpenGL ES is often supported on embedded systems, but OpenGL ES is a different API from regular OpenGL.
OpenGL ES  is a subset of OpenGL. For example, it has VBO suppport but glBegin and glEnd have been removed.<br>
+
 
Despite the fact that PS3 offers GL ES and Cg, most games don't use it. Instead, the companies use the more low level libraries available on that platform.
+
=== What is an OpenGL context and why do you need a window to do GL rendering? ===
 +
{{main|OpenGL Context}}
 +
 
 +
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:
 +
 
 +
<source lang="cpp">
 +
int main(int argc, char **argv)
 +
{
 +
    char *GL_version=(char *)glGetString(GL_VERSION);
 +
    char *GL_vendor=(char *)glGetString(GL_VENDOR);
 +
    char *GL_renderer=(char *)glGetString(GL_RENDERER);
 +
    return 0;
 +
}
 +
</source>
 +
 
 +
In the above, the programmer simply wants to get information about this system (without rendering anything) but it simply won't work because no communication has been established with the GL driver.
 +
 
 +
You must create a window and correctly initialize an OpenGL context from it. Then you must make the GL context current ({{code|wglMakeCurrent}} for Windows and {{code|glXMakeCurrent}} for *nix).
 +
 
 +
=== How do I do offscreen rendering? ===
 +
Some people want to do offscreen rendering without showing a window.
 +
 
 +
The most obvious solution is to create a window as would be normal for an OpenGL application but not show it. Once the window and context are created, you can make GL function calls as normal.
 +
 
 +
However, due to the [[Pixel Ownership Test]], all rendering to the [[Default Framebuffer]] of a hidden window will have undefined pixel values. As such, 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.
  
=== Which 3D API is better? ===
+
There are OpenGL extensions that allow you to create contexts that do not have a window or a [[Default Framebuffer]].
This question is asked by newcomers. They want to know whether they should chose OpenGL or DirectX.<br>
 
It should be noted that GL can't be compared to DX since DX has additional features like DirectSound, DirectPlay, DirectInput, DirectMusic, DirectDraw, the DirectX Utility.<br>
 
GL should be compared only to Direct3D.<br>
 
If you need sound support, you can use FMod, Bass, OpenAL and others.<br>
 
For a math library, there are many. For image loaders, there are many as well.<br>
 
For a complete list, visit the Alternative Game Libraries forum at http://www.gamedev.net/community/forums<br>
 
<br>
 
For D3D vs GL, there are many discussions on forums. This is one such example<br>
 
http://www.gamedev.net/community/forums/topic.asp?topic_id=510845
 
<br>
 
<br>
 
In general, the more you know, the better, so it is recommended that you start with one or the other. Learning the other later on will be easy.<br>
 
  
 
=== How Does It Work On Windows? ===
 
=== How Does It Work On Windows? ===
All Windows versions support OpenGL.<br>
+
All Windows versions support OpenGL.
When you compile an application, you link with opengl32.dll (even on Win64).<br>
+
 
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 change from release versions.<br>
+
When you compile an application, you link with {{code|opengl32.dll}} (even on Win64).
opengl32.dll is limited to 1.1. When you make a call like glBindTexture, it jumps to opengl32.dll and it checks if there is a driver. If there is, it calls the true driver bind function. There are many GL 1.1 functions such as glLoadMatrixf, glPushMatrix, glOrtho, glEnable, glTexEnvi.<br>
+
 
<br>
+
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.
For GL >=1.2 functions, you get a function pointer with wglGetProcAddress. Examples are glActiveTexture, glBindBuffer, glVertexAttribPointer. wglGetProcAddress returns an address from the real driver in these cases.<br>
+
 
<br>
+
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]].
The above is just to inform you how it works under the hood. It has no impact on you as a programmer. It has no performance impact.<br>
+
 
To compare with Direct3D, in direct3D, you get a COM object to something called the device. This COM object has a table of pointers for every function so that you can call d3ddevice->SetRenderState(). Again, there is no performance impact. GL and D3D don't have an advantage one over the other.<br>
+
There are several helper libraries for this, doing what is commonly called [[Extension Loading Library|Extension Loading Libraries]].
The only important thing to know is that opengl32.dll belongs to Microsoft. No one can modify it. You <b>must not</b> replace it. You <b>must not</b> ship your application with this file. You must not ship nvoglv32.dll or any other system file either.<br>
+
 
It is the responsibility of the user to install the driver made available from Dell, HP, nVidia, ATI/AMD, Intel, SiS, and whatever.
+
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.
 +
 
 +
=== How do I tell what version of OpenGL I'm using? ===
 +
 
 +
Once an OpenGL context is created, [[Get Context Info|information about it can be queried through a number of APIs]]. {{apifunc|glGetString}} can be used with {{enum|GL_VERSION}} to get the version as a string. However, the {{apifunc|glGetIntegerv}} function with {{enum|GL_MAJOR_VERSION}} and {{enum|GL_MINOR_VERSION}} can be used to fetch the version number as integers. The latter requires GL 3.0+.
 +
 
 +
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? 1.3? 1.2? ===
+
There are three reasons you may get an unexpectedly low OpenGL version.
When you install the driver for your video card, it provides the GL driver written specifically for it by the IHV.<br>
 
The IHV might be Intel, nVidia, ATI/AMD, SiS, etc.<br>
 
No, you can't get a higher GL version. That's simply the way it is.<br>
 
This is a problem for people with integrated chipsets such as Intel. Intel's driver are terrible according to many forum users on this site and also other websites. It can't be considered a "gaming GPU".<br>
 
You are best off developing and testing on something good like nVidia and ATI/AMD.<br>
 
The alternative way is to use a software renderer such as Mesa which can be found at http://www.mesa3d.org but this is very slow.<br>
 
This Wiki will get updated once Intel releases some descently stable drivers with at least GL 2.0.<br>
 
<b>Bottom line, integrated chipsets are only good for playing tic-tac-toe and reading websites such as this Wiki.</b>
 
  
=== glTranslate, glRotate, glScale ===
+
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.
Are these hardware accelerated?<br>
 
No, there are no known GPUs that execute this. The driver computes the matrix on the CPU and uploads it to the GPU.<br>
 
All the other matrix operations are done on the CPU as well : glPushMatrix, glPopMatrix, glLoadIdentity, glFrustum, glOrtho.<br>
 
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.<br>
 
A list of various libraries is at "Alternative Game Libraries" http://www.gamedev.net/community/forums/topic.asp?topic_id=291432<br>
 
One such library is glhlib http://www.geocities.com/vmelkon/glhlibrary.html<br>
 
It has a software matrix implementation.<br>
 
Code example 1 :
 
  float mymatrix[16];
 
  glhLoadIdentityf2(mymatrix);
 
  glhPerspectivef2(mymatrix, 45.0, aspectRatio, zNear, zFar);  //The matrix is in mymatrix now. Do whatever you want with it
 
  
Code example 2 :
+
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.
  float mymatrix[16];
 
  glhLoadIdentityf2(mymatrix);
 
  glhTranslatef2(mymatrix, 0.0, 0.0, 1.0);
 
  glhRotateAboutYf2(mymatrix, 45.0//YOU MUST CONVERT TO RADIANS);
 
  glhRotateAboutZf2(mymatrix, 45.0//YOU MUST CONVERT TO RADIANS);
 
  
YOU MUST CONVERT TO RADIANS means that instead of 45.0, you need to put 0.78539816. The library uses radians in general.<br>
+
The other reason for a low OpenGL version 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.
glhPerspectivef2 is a special exception.
 
  
=== Fixed function and modern GPUs ===
+
Intel tends to phase out their integrated GPUs relatively quickly, dropping support for integrated GPUs that were released only a few years before. Once they drop support, they will not provide new drivers that expose higher versions of OpenGL. NVIDIA and AMD provide longer-term support for their GPUs.
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 ===
+
Another reason is that you haven't installed your video card drivers after installing your OS.
There are 2 ways to do it
 
1. 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 you
 
  glMatrixMode(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).<br>
+
Be sure to query OpenGL with {{apifunc|glGetString}} and make sure the returned values make sense.
<br>
 
2. The second method is to use glWindowPos which ignores the projection and modelview matrices.<br>
 
You can use glWindowPos2f or glWindowPos3f so perhaps the z component doesn't matter for you and you can set it to 0.0.<br>
 
You can try glWindowPos2i, glWindowPos3i, glWindowPos2d, glWindowPos3d, glWindowPos2s, glWindowPos3s but that depends on what format the GPU supports. http://www.opengl.org/wiki/Common_Mistakes#Unsupported_formats_.231<br>
 
glWindowPos basically changes the raster position. Then you would need to call glBitmap or glDrawPixels to render. Keep in mind that glBitmap or glDrawPixels are not recommended for rendering. It's always best to render polygons since that's what GPUs prefer.
 
  
 
=== Multi indexed rendering ===
 
=== Multi indexed rendering ===
You want to have an index array for each vertex attribute : vertex, normal, texcoord.<br>
 
Perhaps you have 20 vertices, 35 normals, 20 texcoords and you have 3 index arrays.<br>
 
Does GL support multi index rendering? No and this is because GPUs don't support it (nVidia, ATI, Intel).<br>
 
There are of course exceptions such as certain consoles where multiple index arrays are supported by the GPU.<br>
 
<br>
 
Anyway, you would have to duplicate some vertices and texcoords and yes, it will waste some memory.<br>
 
<br>
 
Quite often, people asking this question are people who want to use the OBJ file format.
 
  v 1.52284 39.3701 1.01523
 
  v 36.7365 17.6068 1.01523
 
  v 12.4045 17.6068 -32.475
 
  and so on ...
 
  n 0.137265 0.985501 -0.0997287
 
  n 0.894427 0.447214 -8.16501e-08
 
  n 0.276393 0.447214 -0.850651
 
  and so on ...
 
  t 0.6 1
 
  t 0.5 0.647584
 
  t 0.7 0.647584
 
  and so on ...
 
  f 102//102//102 84//84//84 158//158//158
 
  f 158//158//158 84//84//84 83//83//83
 
  f 158//158//158 83//83//83 159//159//159
 
  and so on ...
 
  
The lines that start with an f are the faces. As you can see, each vertex has 3 index, one for vertex, normal, texcoord.<br>
+
What this means is that each [[Vertex Attribute]] (position, normal, etc) has its own index array. OpenGL (and Direct3D, for that matter) do not directly support this; they only allow one index array, which indexes all [[Vertex Specification|attribute arrays]] equally (except for [[Instanced Array]]s).
The problem is that the OBJ format is ancient pre-GPU junk.<br>
+
 
GPUs prefer 1 index list. They also prefer vertex, normal, texcoord to be interleaved rather than be in their own array. They prefer floating point format most of the time for vertex, normals, etc so that part the OBJ format got right. Faces should be in unsigned short format.<br>
+
When dealing with this kind of data, you have two choices. You either adjust the data to fit OpenGL's single index model, or you do something different. The former is the traditional approach.
You should probably use your own file format instead of using OBJ.<br>
+
 
For more info (as far as GL programming is concerned), Vertex arrays http://www.opengl.org/wiki/Vertex_Arrays<br>
+
Quite often, this issue comes up from those wanting to use the OBJ file format:
Vertex formats http://www.opengl.org/wiki/Vertex_Formats<br>
+
 
VBO http://www.opengl.org/wiki/VBO<br>
+
<code>
More about VBOs http://www.opengl.org/wiki/VBO_-_more<br>
+
v 1.52284 39.3701 1.01523
 +
v 36.7365 17.6068 1.01523
 +
v 12.4045 17.6068 -32.475
 +
and so on ...
 +
vn 0.137265 0.985501 -0.0997287
 +
vn 0.894427 0.447214 -8.16501e-08
 +
vn 0.276393 0.447214 -0.850651
 +
and so on ...
 +
vt 0.6 1
 +
vt 0.5 0.647584
 +
vt 0.7 0.647584
 +
and so on ...
 +
f 102/102/102 84/84/84 158/158/158
 +
f 158/158/158 84/84/84 83/83/83
 +
f 158/158/158 83/83/83 159/159/159
 +
and so on ...
 +
</code>
 +
 
 +
The {{code|v}} lines define an array of positions ("vertex", but that is a misnomer). The {{code|vn}} lines define an array of normals. And the {{code|vt}} lines define an array of texture coordinates.
 +
 
 +
The {{code|f}} lines define polygon faces. Each set of numbers represents a single vertex: a combination of position, normal, and texture coordinate (in this case). So each face here has 3 vertices.
 +
 
 +
The values of the {{code|f}} lines are 1-based indices into the previously defined arrays. The first index goes to the first array defined, the second index to the next, and so on.
 +
 
 +
In this case, for each face vertex, all three indices are the same. But the OBJ format does not require this:
 +
 
 +
<code>
 +
f 1/1/1 2/2/2 3/2/2
 +
f 5/5/5 6/6/6 3/4/5
 +
</code>
 +
 
 +
Here, the vertices 3/2/2 and 3/4/5 are different vertices, despite both using position index 3.
  
=== 2 component textures ===
+
The normal thing to do is convert the face index sets into actual single indices. This requires duplicating some of the data in the various attribute arrays, so that they all have the same length.
Formats such as GL_LUMINANCE4_ALPHA4, GL_LUMINANCE6_ALPHA2, GL_LUMINANCE8_ALPHA8, GL_LUMINANCE12_ALPHA4, GL_LUMINANCE12_ALPHA12, GL_LUMINANCE16_ALPHA16 are 2 component formats. The only way to know if the GPU actually supports it is to read the IHV manuals. For example, nVidia has a doc called nv_ogl_texture_formats.pdf at http://developer.nvidia.com that says that Gf6 supports GL_LUMINANCE16_ALPHA16.<br>
 
Also, the GPU should be able to render to them in case FBO is supported.<br>
 
There are other formats special to nVidia : GL_SIGNED_LUMINANCE8_ALPHA8, GL_HILO8, GL_HILO16, GL_FLOAT_RG16, GL_FLOAT_RG32.<br>
 
Those tokens probably needs a _NV postfix and they should be defined in glext.h<br>
 
Also visit http://www.opengl.org/registry to see which extensions define them.<br>
 
<br>
 
Additional :<br>
 
GL 3.0 introduces some new formats that the GPU must exactly support (it must not use another format of equal or higher capability)<br>
 
GL_RG32F, GL_RG32I, GL_RG32UI, GL_RG16, and many others. See Required Texture Formats in the spec file.
 
  
=== Immediate mode, display lists, vertex arrays, VBO ===
+
Alternatively, it is possible using shader mechanisms to use this data directly. To do this, instead of passing the position/normal/etc data directly, you pass [[Vertex Attribute]]s that are the face indices. The [[Vertex Shader]] would then use these indices to fetch the actual positions/normals/etc from the arrays by itself.
Immediate mode means glBegin(), glVertex(), glEnd() and the related calls like glTexCoord, glNormal, glColor.<br>
 
This method is outdated and slow.<br>
 
Display lists and vertex arrays are also outdated now that VBO is available, since 2000.<br>
 
There is very little reason to not use VBOs for everything however you should use them correctly in order to get good performance.<br>
 
http://www.opengl.org/wiki/VBO<br>
 
http://www.opengl.org/wiki/VBO_-_more<br>
 
http://www.opengl.org/wiki/Vertex_Arrays<br>
 
http://www.opengl.org/wiki/Vertex_Formats<br>
 
  
=== glGetString(GL_VERSION) ===
+
The actual arrays can be provided to the VS via a number of tools. [[Texture]]s are usually too difficult to work with for this purpose, but [[Buffer Texture]]s provide a serviceable way to access a buffer arbitrarily from within the VS. [[UBO]]s are too small for decent-sided models, but [[|Ssbo|SSBO]]s can usually be arbitrarily sized.
This returns a string which may look something like "2.0.6914 WinXP SSE/SSE2/SSE3/3DNow!"<br>
 
2.0 is the actual version number of GL supported. All the rest depends on what information the IHV wants to convey and is not part of the GL standard. 6914 would be the driver version. WinXP is the OS. SSE/SSE2/SSE3/3DNow! are CPU features that the driver can use in case it runs in software mode.<br>
 
In glhlib http://www.geocities.com/vmelkon/glhlibrary.html<br>
 
glhGetIntegerv(GLH_OPENGL_VERSION, version) can return the major and minor version. That is to say, version[0] would be an integer (2) and version[1] is an integer (0). This is a utility library similar to GLU to make programming easier.<br>
 
Also note that at times glGetString(GL_VERSION) returns also the bus type used such as AGP or PCI or PCIEx.
 
  
 
=== glClear and glScissor ===
 
=== glClear and glScissor ===
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).<br>
 
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.
 
  
=== glGetError (or "How do I check for GL errors?) ===
+
The [[Scissor Test]] affects [[Framebuffer Clearing]] operations. If you want to clear only a region of the back buffer, then you can enable {{enum|GL_SCISSOR_TEST}} and call {{apifunc|glScissor}} to set the region to clear.
 +
 
 +
Alternatively, if you have used the scissor test and forgot to call {{apifunc|glDisable|(GL_SCISSOR_TEST)}}, then the current scissor box will still clip the clearing functionality.
 +
 
 +
=== Masking ===
 +
{{main|Write Mask}}
 +
 
 +
Write masking state ({{apifunc|glColorMask}}, {{apifunc|glStencilMask}} and {{apifunc|glDepthMask}}) can affect [[Framebuffer Clearing]] functionality. For example, if you disable depth writes by calling {{apifunc|glDepthMask|(GL_FALSE)}}, then calls to {{apifunc|glClear}} ''will not'' clear the depth buffer.
 +
 
 +
=== How do I check for GL errors? ===
 +
{{main|OpenGL Error}}
 +
 
 +
OpenGL keeps a queue of accumulated OpenGL error codes generated by calls to its APIs.  When an OpenGL API fails to execute, it pushes an OpenGL error code onto this queue.
 +
 
 +
There are two alternative methods the application can use to detect when OpenGL errors are generated and to localize their source: 
 +
# Utilize [[OpenGL_Error#Catching_errors_.28the_easy_way.29|debug output callbacks]], or
 +
# Call [[OpenGL_Error#Catching_errors_.28the_hard_way.29|{{enum|glGetError}} after every OpenGL function call]] (or group of function calls).
 +
 
 +
The former is much simpler.  For details on both, see: [[OpenGL Error]]
 +
 
 +
=== What 3D file format should I use? ===
 +
 
 +
Newcomers often wonder what 3D file format for their mesh data to use for their project.
 +
 
 +
OpenGL does not load files; therefore, you can use any mesh format you wish. This also means that you must provide the appropriate loading code yourself; OpenGL won't help you.
 +
 
 +
There are several file format alternatives, with different capabilities. All of these formats (and more) can be loaded by the [[Open Asset Import]] library.
 +
 
 +
; [http://en.wikipedia.org/wiki/Wavefront_.obj_file Wavefront .obj]
 +
: This is a simple text format for mesh data. Each .obj file holds a single mesh. Obj files can reference material files, stored in the less-frequently-used [http://en.wikipedia.org/wiki/Wavefront_.obj_file#Material_template_library .mtl format]. Meshes in this format may only contain positions, normals and optionally a single texture coordinate.
 +
; [http://en.wikipedia.org/wiki/.3ds Autodesk .3ds]
 +
: This is a binary mesh format. This format contains materials and can store multiple named meshes in a single file.
 +
; [http://en.wikipedia.org/wiki/MD2_%28file_format%29 Quake 2 .md2] and [http://en.wikipedia.org/wiki/MD3_%28file_format%29 Quake 3 .md3]
 +
: These are binary mesh formats. The formats do not contain material information, and they only technically store a single mesh. They do have support for keyframe animation, so a single mesh file would contain all of the animation keyframes, as well as animation data.
 +
; [http://en.wikipedia.org/wiki/COLLADA COLLADA]
 +
: This is an XML-based mesh file format. It can store pretty much ''anything''; it is primarily used for document exchange between different 3D modelling packages.
 +
 
 +
=== 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
 +
<source lang="cpp">
 +
  glClear(...);
 +
  SwapBuffers(...);
 +
</source>
 +
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 {{apifunc|glDeleteTextures}} or {{code|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 Object|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 {{enum|GL_OUT_OF_MEMORY}} when you call {{apifunc|glGetError}}. It might even return a {{enum|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.
 +
 
 +
=== What does ''Unresolved External Symbol'' mean? ===
 +
Some newcomers try to compile their GL program and get linker errors such as:
 +
 
 +
<code>
 +
error LNK2001: unresolved external symbol _glBegin
 +
</code>
 +
 
 +
and similar linker errors related to other GL functions and perhaps GLU functions and other functions from other libraries.
  
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>. So use a little helper function like this to check for GL errors:
+
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.
  
<sup><pre>
+
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.
  #include <stdio.h>
 
  #include <GL/gl.h>
 
  #include <GL/glu.h>
 
  
   int checkForGLErrors( const char *s )
+
Alternatively, you can add these lines:
 +
 
 +
<source lang="cpp">
 +
#pragma comment(lib, "opengl32.lib")
 +
#pragma comment(lib, "glu32.lib")
 +
</source>
 +
 
 +
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.
 +
 
 +
In the case of gcc, a user types this command on the CLI:
 +
 
 +
  gcc -lGL -lglut myprogram.c -o myprogram
 +
 
 +
and CLI shows
 +
 
 +
   /tmp/ccCQkTKm.o:myprogram.c:function display: error: undefined reference to 'gluLookAt'
 +
 
 +
That's because you are using GLU and you did not link again the GLU library. The command you should type is:
 +
 
 +
  gcc -lGL -lGLU -lglut myprogram.c -o myprogram
 +
 
 +
=== What does ''Not Declared In This Scope'' mean? ===
 +
 
 +
Some newcomers try to compile their GL program and get compile errors such as:
 +
 
 +
<code>
 +
GL_TEXTURE_3D was not declared in this scope
 +
</code>
 +
 
 +
This happens because the compiler has no idea what GL_TEXTURE_3D is since it was not declared anywhere.
 +
 
 +
You probably have not included a proper OpenGL header. {{code|gl.h}} may not include all of the stuff you need. You should use an [[OpenGL Loading Library]]; otherwise, you will have to use {{code|glext.h}}, found in [http://www.opengl.org/registry/#headers the OpenGL Registry]. This also means you need to [[Load OpenGL Functions|manually load OpenGL functions]].
 +
 
 +
=== Can I precompile my shaders? ===
 +
 
 +
GL 4.1 adds the ability to compile a program and download the program binary from the GL driver. However, these binaries are GPU and driver specific. There is no guarantee they will work on other GPUs. Indeed, there is no guarantee that they will work on the ''same'' GPU; driver changes can render the old binary incompatible. The purpose of this feature is to compile once and store on the hard drive for future runs, but with the option to use the original source if a driver update takes place.
 +
 
 +
OpenGL {{require|4.6|gl_spirv}} provides the ability to use shaders that are in the [[SPIR-V]] language rather than [[GLSL]]. This allows you to precompile your GLSL shader to SPIR-V, then load it via the SPIR-V interface. You can also precompile your shader from other languages, or even invent your own so long as they generate OpenGL-consumable SPIR-V.
 +
 
 +
=== 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 [[Array Texture|2D array textures]]. This solves the problem that is present in the case of using a 3D texture as described above. The array layers in the texture must all be the same size and format.
 +
 
 +
=== 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 words or full sentences, which you can render via a quad.
 +
 
 +
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 wglUseFontBitmaps and wglUseFontOutlines.
 +
 
 +
== Legacy OpenGL questions ==
 +
{{main|Legacy OpenGL}}
 +
 
 +
All of these answers deal with removed [[Legacy OpenGL]] features.
 +
 
 +
=== 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. {{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.
 +
 
 +
=== Are glTranslate/glRotate/glScale hardware accelerated? ===
 +
 
 +
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.
 +
 
 +
=== How to render in pixel space ===
 +
 
 +
Setup a certain projection matrix:
 +
<source lang="cpp">
 +
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 you
 +
glMatrixMode(GL_MODELVIEW);
 +
glLoadIdentity();
 +
</source>
 +
 
 +
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
 +
 
 +
  #version 110
 +
  void main()
 
   {
 
   {
     int errors = 0 ;
+
     gl_Position = gl_Vertex;  //Just output the incoming vertex
 +
  }
 +
 
 +
The vertices for your quad (or 2 triangles) need to be {-1.0, -1.0, 0.0}, {1.0, -1.0, 0.0}, {1.0, 1.0, 0.0}, {-1.0, 1.0, 0.0}.
 +
 
 +
=== Should I use display lists, vertex arrays or vertex buffer objects? ===
 +
{{main|Vertex Specification}}
  
    while ( 1 )
+
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:
    {
 
      GLenum x = glGetError() ;
 
  
      if ( x == GL_NO_ERROR )
+
* 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.
        return errors ;
 
  
      fprintf( stderr, "%s: OpenGL error: %s [%08x]\n", s ? s : "", gluErrorString ( x ), errcnt++ ) ;
+
* 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.
      errors++ ;
+
 
    }
+
* 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.
  }
+
 
</pre></sup>
+
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.
 +
 
 +
'''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.
 +
 
 +
=== 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 (<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).
 +
 
 +
=== What is GLU? ===
 +
GLU stands for ''OpenGL utility library'' and provides convenience functions layered on [[Legacy OpenGL|legacy OpenGL]] features. Popular examples of GLU functionality are
 +
 
 +
gluLooktAt()
 +
 
 +
and
 +
 +
gluPerspective()
 +
 
 +
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.

Latest revision as of 15:20, 22 April 2019

Welcome to the FAQ.


What is OpenGL?

OpenGL is the name for the specification that describes the behavior of a rasterization-based rendering system. It defines the API through which a client application can control this system. The OpenGL rendering system is carefully specified to make hardware implementations allowable.

Hardware vendors, the people who make GPUs, are responsible for writing implementations of the OpenGL rendering system. Their implementations, commonly called "drivers", translate OpenGL API commands into GPU commands. If a particular piece of hardware is unable to implement all of the OpenGL specification via hardware, the hardware vendor must still provide this functionality, typically via a software-based implementation of the features missing from hardware.

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?

The OpenGL specification is maintained by the Khronos Group committee called the OpenGL Architectural Review Board (ARB). Originally, the ARB was an organization sponsored by SGI, but it was adopted by the Khronos Group.

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.

Mesa3D is an open source software implementation of the OpenGL specification. The latest versions implement OpenGL 4.3, OpenGL ES 2.0, GLSL 3.30 (and several extensions) and EGL 1.4.

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 in the OS.

On Windows, hardware vendors (such as NVIDIA or 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.

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.

For programmers, installing drivers is generally insufficient. You will need to load the OpenGL function pointers, either manually or automatically with a library. More information on this can be found in the Getting started page.

Is there an OpenGL SDK?

There is no actual OpenGL SDK. There is a collection of websites, some (outdated) documentation, and links to tutorials, all found here. But it is not an SDK of the kind you are thinking about.

NVIDIA and AMD have their own SDKs, both of which have various example code for OpenGL.

What platforms have GL?

  • Windows: 95 and above
  • Mac OSX: all versions
  • Linux: OpenGL is provided by open source drivers and MESA library, or by proprietary drivers.
  • FreeBSD: OpenGL is provided by open source drivers and MESA library or proprietary Nvidia drivers.

OpenGL ES is often supported on embedded systems, but OpenGL ES is a different API from regular 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:

int main(int argc, char **argv)
{
    char *GL_version=(char *)glGetString(GL_VERSION);
    char *GL_vendor=(char *)glGetString(GL_VENDOR);
    char *GL_renderer=(char *)glGetString(GL_RENDERER);
    return 0;
}

In the above, the programmer simply wants to get information about this system (without rendering anything) but it simply won't work because no communication has been established with the GL driver.

You must create a window and correctly initialize an OpenGL context from it. Then 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 without showing a window.

The most obvious solution is to create a window as would be normal for an OpenGL application but not show it. Once the window and context are created, you can make GL function calls as normal.

However, due to the Pixel Ownership Test, all rendering to the Default Framebuffer of a hidden window will have undefined pixel values. As such, 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.

There are OpenGL extensions that allow you to create contexts that do not have a window or a Default Framebuffer.

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.

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

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?

Once an OpenGL context is created, information about it can be queried through a number of APIs. glGetString can be used with GL_VERSION to get the version as a string. However, the glGetIntegerv function with GL_MAJOR_VERSION and GL_MINOR_VERSION can be used to fetch the version number as integers. The latter requires GL 3.0+.

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 for a low OpenGL version 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 tends to phase out their integrated GPUs relatively quickly, dropping support for integrated GPUs that were released only a few years before. Once they drop support, they will not provide new drivers that expose higher versions of OpenGL. NVIDIA and AMD provide longer-term support for their 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.

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 directly support this; they only allow one index array, which indexes all attribute arrays equally (except for Instanced Arrays).

When dealing with this kind of data, you have two choices. You either adjust the data to fit OpenGL's single index model, or you do something different. The former is the traditional approach.

Quite often, this issue comes up from those wanting to use the OBJ file format:

v 1.52284 39.3701 1.01523 v 36.7365 17.6068 1.01523 v 12.4045 17.6068 -32.475 and so on ... vn 0.137265 0.985501 -0.0997287 vn 0.894427 0.447214 -8.16501e-08 vn 0.276393 0.447214 -0.850651 and so on ... vt 0.6 1 vt 0.5 0.647584 vt 0.7 0.647584 and so on ... f 102/102/102 84/84/84 158/158/158 f 158/158/158 84/84/84 83/83/83 f 158/158/158 83/83/83 159/159/159 and so on ...

The v lines define an array of positions ("vertex", but that is a misnomer). The vn lines define an array of normals. And the vt lines define an array of texture coordinates.

The f lines define polygon faces. Each set of numbers represents a single vertex: a combination of position, normal, and texture coordinate (in this case). So each face here has 3 vertices.

The values of the f lines are 1-based indices into the previously defined arrays. The first index goes to the first array defined, the second index to the next, and so on.

In this case, for each face vertex, all three indices are the same. But the OBJ format does not require this:

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

Here, the vertices 3/2/2 and 3/4/5 are different vertices, despite both using position index 3.

The normal thing to do is convert the face index sets into actual single indices. This requires duplicating some of the data in the various attribute arrays, so that they all have the same length.

Alternatively, it is possible using shader mechanisms to use this data directly. To do this, instead of passing the position/normal/etc data directly, you pass Vertex Attributes that are the face indices. The Vertex Shader would then use these indices to fetch the actual positions/normals/etc from the arrays by itself.

The actual arrays can be provided to the VS via a number of tools. Textures are usually too difficult to work with for this purpose, but Buffer Textures provide a serviceable way to access a buffer arbitrarily from within the VS. UBOs are too small for decent-sided models, but [[|Ssbo|SSBO]]s can usually be arbitrarily sized.

glClear and glScissor

The Scissor Test affects Framebuffer Clearing operations. If you want to clear only a region of the back buffer, then you can enable GL_SCISSOR_TEST and call glScissor to set the region to clear.

Alternatively, if you have used the scissor test and forgot to call glDisable(GL_SCISSOR_TEST), then the current scissor box will still clip the clearing functionality.

Masking

Write masking state (glColorMask, glStencilMask and glDepthMask) can affect Framebuffer Clearing functionality. For example, if you disable depth writes by calling glDepthMask(GL_FALSE), then calls to glClear will not clear the depth buffer.

How do I check for GL errors?

OpenGL keeps a queue of accumulated OpenGL error codes generated by calls to its APIs. When an OpenGL API fails to execute, it pushes an OpenGL error code onto this queue.

There are two alternative methods the application can use to detect when OpenGL errors are generated and to localize their source:

  1. Utilize debug output callbacks, or
  2. Call glGetError after every OpenGL function call (or group of function calls).

The former is much simpler. For details on both, see: OpenGL Error

What 3D file format should I use?

Newcomers often wonder what 3D file format for their mesh data to use for their project.

OpenGL does not load files; therefore, you can use any mesh format you wish. This also means that you must provide the appropriate loading code yourself; OpenGL won't help you.

There are several file format alternatives, with different capabilities. All of these formats (and more) can be loaded by the Open Asset Import library.

Wavefront .obj
This is a simple text format for mesh data. Each .obj file holds a single mesh. Obj files can reference material files, stored in the less-frequently-used .mtl format. Meshes in this format may only contain positions, normals and optionally a single texture coordinate.
Autodesk .3ds
This is a binary mesh format. This format contains materials and can store multiple named meshes in a single file.
Quake 2 .md2 and Quake 3 .md3
These are binary mesh formats. The formats do not contain material information, and they only technically store a single mesh. They do have support for keyframe animation, so a single mesh file would contain all of the animation keyframes, as well as animation data.
COLLADA
This is an XML-based mesh file format. It can store pretty much anything; it is primarily used for document exchange between different 3D modelling packages.

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.

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.

In the case of gcc, a user types this command on the CLI:

  gcc -lGL -lglut myprogram.c -o myprogram

and CLI shows

 /tmp/ccCQkTKm.o:myprogram.c:function display: error: undefined reference to 'gluLookAt'

That's because you are using GLU and you did not link again the GLU library. The command you should type is:

  gcc -lGL -lGLU -lglut myprogram.c -o myprogram

What does Not Declared In This Scope mean?

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

GL_TEXTURE_3D was not declared in this scope

This happens because the compiler has no idea what GL_TEXTURE_3D is since it was not declared anywhere.

You probably have not included a proper OpenGL header. gl.h may not include all of the stuff you need. You should use an OpenGL Loading Library; otherwise, you will have to use glext.h, found in the OpenGL Registry. This also means you need to manually load OpenGL functions.

Can I precompile my shaders?

GL 4.1 adds the ability to compile a program and download the program binary from the GL driver. However, these binaries are GPU and driver specific. There is no guarantee they will work on other GPUs. Indeed, there is no guarantee that they will work on the same GPU; driver changes can render the old binary incompatible. The purpose of this feature is to compile once and store on the hard drive for future runs, but with the option to use the original source if a driver update takes place.

OpenGL OpenGL 4.6 or ARB_gl_spirv provides the ability to use shaders that are in the SPIR-V language rather than GLSL. This allows you to precompile your GLSL shader to SPIR-V, then load it via the SPIR-V interface. You can also precompile your shader from other languages, or even invent your own so long as they generate OpenGL-consumable SPIR-V.

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 array textures. This solves the problem that is present in the case of using a 3D texture as described above. The array layers in the texture must all be the same size and format.

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 words or full sentences, which you can render via a quad.

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 wglUseFontBitmaps and wglUseFontOutlines.

Legacy OpenGL questions

All of these answers deal with removed Legacy OpenGL features.

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.

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.

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 you
glMatrixMode(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

 #version 110
 void main()
 {
   gl_Position = gl_Vertex;   //Just output the incoming vertex
 }

The vertices for your quad (or 2 triangles) need to be {-1.0, -1.0, 0.0}, {1.0, -1.0, 0.0}, {1.0, 1.0, 0.0}, {-1.0, 1.0, 0.0}.

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.

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).

What is GLU?

GLU stands for OpenGL utility library and provides convenience functions layered on legacy OpenGL features. Popular examples of GLU functionality are

gluLooktAt()

and

gluPerspective()

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.