Difference between revisions of "Multisampling"

From OpenGL.org
Jump to: navigation, search
(Multisampling)
Line 4: Line 4:
 
Before GL_ARB_multisample extension, the edges of lines, polygons, and points could be selectively antialiased using using glEnable(GL_LINE_SMOOTH), glEnable(GL_POLYGON_SMOOTH), glEnable(GL_POINT_SMOOTH) respectively, combined with a blending function, such as glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA). Such features were typically not implemented in hardware in early consumer graphics cards at the time, and were done in software resulting in poor performance. More expensive "workstation" graphics cards from HP, Sun, and SGI at the time did implement these features in hardware. Modern programs should not make use of these features.
 
Before GL_ARB_multisample extension, the edges of lines, polygons, and points could be selectively antialiased using using glEnable(GL_LINE_SMOOTH), glEnable(GL_POLYGON_SMOOTH), glEnable(GL_POINT_SMOOTH) respectively, combined with a blending function, such as glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA). Such features were typically not implemented in hardware in early consumer graphics cards at the time, and were done in software resulting in poor performance. More expensive "workstation" graphics cards from HP, Sun, and SGI at the time did implement these features in hardware. Modern programs should not make use of these features.
  
== Multisampling ==
+
== Enabling Multisampling ==
The problem is that this part of OpenGL is platform specific. If you use freeGLUT, SDL or some other library, they hide this platform specific stuff. Here, we will talk about Windows and the platform specific API.
+
Multisampling is a platform-specific feature and requires interaction with the window system.
  
This is what you must do :
 
  
1. Start your program, open a dummy window for getting function pointers. You would use CreateWindowEx to create your window.
+
=== Windows using wgl ===
 +
The wgl functions required to create a multisampled OpenGL context are not available until a valid OpenGL context is made current to the thread. This leads to a [[Creating_an_OpenGL_Context#Proper_Context_Creation|temporary context]] code path which can get very involved with platform specific detailed. Users of libraries such as GLUT, GLEW, or GLee can significantly reduce the amount of effort required. The rest of this section assumes that valid context is present and all wgl extension function pointers have been obtained, if not, please see how to create a [[Creating_an_OpenGL_Context#Proper_Context_Creation|temporary context]].
  
2. Make the window invisible ShowWindow(window.HWnd, SW_HIDE)
+
A valid pixel format for the framebuffer is choose using the wglChoosePixelFormatARB function with a list of attributes to specify the multisampling properties. In order to choose a framebuffer format that incorporates multisampling, you must add it to the list of attributes. For example, this list of attributes ''does not'' select a multisampled pixel format:
  
3. You can then SetPixelFormat, create the GL context, make the GL context current (wglMakeCurrent(hdc, glrc))
+
<code c>
 +
    int attributes[] = {
 +
    WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
 +
    WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
 +
    WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
 +
    WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
 +
    WGL_COLOR_BITS_ARB, 32,
 +
    WGL_DEPTH_BITS_ARB, 24,
 +
    WGL_STENCIL_BITS_ARB, 8,
 +
    0
 +
    };
 +
</code>
  
4. Now you can get the function pointers. If you are using GLEW
+
To consider multisampled visuals, the WGL_SAMPLE_BUFFERS_ARB and WGL_SAMPLES_ARB attributes must be present. This attribute list considers 4x multisampled pixel formats
  GLenum err=glewInit();
+
  if(err!=GLEW_OK)
+
  {
+
    //Problem: glewInit failed, something is seriously wrong
+
    sprintf(pErrorMessage, "Error: %s", glewGetErrorString(err));
+
    return -1;
+
  }
+
  
5. Check to see if the function pointer (wglGetExtensionsStringARB) is not NULL. If it is not NULL, call wglGetExtensionsStringARB(hdc) to get a list of WGL extensions supported.
+
<code c>
 +
    int attributes[] = {
 +
    WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
 +
    WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
 +
    WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
 +
    WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
 +
    WGL_COLOR_BITS_ARB, 32,
 +
    WGL_DEPTH_BITS_ARB, 24,
 +
    WGL_STENCIL_BITS_ARB, 8,
 +
    WGL_SAMPLE_BUFFERS_ARB, 1,
 +
    WGL_SAMPLES_ARB, 4,
 +
    0
 +
    };
 +
</code c>
  
6. WGL_ARB_pixel_format and WGL_ARB_multisample should be in the list. If they are, set some variable to TRUE and then make GL context non-current, kill the GL context, destroy the temporary window.
 
 
7. Now, create your real window. Make it visible.
 
 
8. Now you must check that variable that you had set. Is it FALSE or TRUE? If it is TRUE, then you can setup a FSAA pixelformat.<br>
 
 
9. Since you have already called glewInit, you don't need to call it again. Use wglGetPixelFormatAttribivARB to collect information. Also keep in mind that a GL context is not needed for wgl functions to work such as wglGetPixelFormatAttribivARB.
 
 
10. When you find a pixelformat that you like, call the "traditional" SetPixelFormat. Make a GL context, make context current and now you are ready to render.
 
 
The most difficult part is choosing a suitable pixelformat. One that has the right color bits, depth bits, stencil bits, the right FSAA level.
 
  
 
You should also call glEnable(GL_MULTISAMPLE) but in reality this is useless since it is not possible to enable or disable FSAA once you have chosen a FSAA pixelformat.
 
You should also call glEnable(GL_MULTISAMPLE) but in reality this is useless since it is not possible to enable or disable FSAA once you have chosen a FSAA pixelformat.
Line 65: Line 71:
  
 
- http://www.opengl.org/registry/specs/NV/multisample_coverage.txt
 
- http://www.opengl.org/registry/specs/NV/multisample_coverage.txt
 
  
 
== Conclusion ==
 
== Conclusion ==

Revision as of 15:31, 24 July 2012

Multisampling is a method of achieving full-screen antialiasing, or FSAA for short. Unlike supersampling which can result in the same pixel being processed multiple times, multisampling runs the fragment program just once per pixel rasterized, however multiple depth/stencil values are computed.

History

Before GL_ARB_multisample extension, the edges of lines, polygons, and points could be selectively antialiased using using glEnable(GL_LINE_SMOOTH), glEnable(GL_POLYGON_SMOOTH), glEnable(GL_POINT_SMOOTH) respectively, combined with a blending function, such as glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA). Such features were typically not implemented in hardware in early consumer graphics cards at the time, and were done in software resulting in poor performance. More expensive "workstation" graphics cards from HP, Sun, and SGI at the time did implement these features in hardware. Modern programs should not make use of these features.

Enabling Multisampling

Multisampling is a platform-specific feature and requires interaction with the window system.


Windows using wgl

The wgl functions required to create a multisampled OpenGL context are not available until a valid OpenGL context is made current to the thread. This leads to a temporary context code path which can get very involved with platform specific detailed. Users of libraries such as GLUT, GLEW, or GLee can significantly reduce the amount of effort required. The rest of this section assumes that valid context is present and all wgl extension function pointers have been obtained, if not, please see how to create a temporary context.

A valid pixel format for the framebuffer is choose using the wglChoosePixelFormatARB function with a list of attributes to specify the multisampling properties. In order to choose a framebuffer format that incorporates multisampling, you must add it to the list of attributes. For example, this list of attributes does not select a multisampled pixel format:

   int attributes[] = {
   WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
   WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
   WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
   WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
   WGL_COLOR_BITS_ARB, 32,
   WGL_DEPTH_BITS_ARB, 24,
   WGL_STENCIL_BITS_ARB, 8,
   0
   };

To consider multisampled visuals, the WGL_SAMPLE_BUFFERS_ARB and WGL_SAMPLES_ARB attributes must be present. This attribute list considers 4x multisampled pixel formats

   int attributes[] = {
   WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
   WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
   WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
   WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
   WGL_COLOR_BITS_ARB, 32,
   WGL_DEPTH_BITS_ARB, 24,
   WGL_STENCIL_BITS_ARB, 8,
   WGL_SAMPLE_BUFFERS_ARB, 1,
   WGL_SAMPLES_ARB, 4,
   0
   };


You should also call glEnable(GL_MULTISAMPLE) but in reality this is useless since it is not possible to enable or disable FSAA once you have chosen a FSAA pixelformat.

In this entire document, we called it FSAA (Full Scene Anti-Aliasing) but it is also called MS (multisampling) since multiple samples are taken in various ways and the samples are blended together to give the resulting pixel. There is also another concept called supersampling and there are also nVidia specific GPU algorithms for sampling (see nVidia's documents on their developer website. http://developer.nvidia.com).


Here are the links to the extensions in question (Windows) :

- http://www.opengl.org/registry/specs/ARB/wgl_extensions_string.txt

- http://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt

These are for *nix systems :

- http://www.opengl.org/registry/specs/SGIS/multisample.txt (GL_SGIS_multisample and GLX_SGIS_multisample are on the same page)

These are for all platforms :

- http://www.opengl.org/registry/specs/ARB/multisample.txt


These might interest you :

- http://www.opengl.org/registry/specs/NV/multisample_filter_hint.txt

- http://www.opengl.org/registry/specs/NV/explicit_multisample.txt

- http://www.opengl.org/registry/specs/NV/multisample_coverage.txt

Conclusion

Setting up FSAA takes a few steps but it is worth it. Today's GPUs are very rapid and the user wants control over the quality of the game's graphics.
On Windows, the extension we are interested in are WGL_ARB_extensions_string which defines wglGetExtensionsStringARB, but the only way to check if this is available is to call wglGetExtensionsStringARB. So this is a chicken and egg situation. Just get the function pointer to wglGetExtensionsStringARB and use it to see if you have WGL_ARB_pixel_format and WGL_ARB_multisample.