Http://www.opengl.org/wiki/Creating_an_OpenGL_Context
OpenGL context CreationIs the part of initialization that creates a fully realized OpenGL implementation. You need to go through this process to use OpenGL.
Contents [Hide]
- 1 A Note on platforms
- 2 simple context Creation
- 2.1 The window itself
- 2.2 pixel format
- 2.3 create the context
- 2.4 Delete the context
- 3 proper context Creation
- 3.1 create a false Context
- 3.2 get WGL extensions
- 3.3 pixel format extensions
- 3.4 create context with attributes
- 4 See also
- 5 References
|
A Note on platforms
Because OpenGL doesn' t exist until you create an OpenGL context, OpenGL context creation is not governed by the OpenGL specification. it is instead governed by platform-specific APIs. the following discussion will cover Windows-based initialization. glx has its initialization functions as well; some of them have analogs in windows, and some do not. versions of the windows-specific initialization functions have the "WGL" prefix affixed to them.
This also assumes you know how to handle the Win32 API at some basic level of competence. you shoshould know what a window handle (hwnd) and a device context (DC) are, as well as how to create them. this is not a tutorial on how to create a window.
Simple context Creation
This section covers the basics of context creation.
The window itself
When you create your hwnd, you need to make sure that it has the cs_owndc set for its style.
Pixel format
Each window in MS windows has a device context (DC) associated with it. This object can store something calledPixel format. This is a generic structure that describes the properties of the default framebuffer that the OpenGL context you want to create shoshould have.
Setting up the pixel format is non-intuitive. the way you create a pixel format is that you fill out a struct that describes the features you want. then you give that struct to a function that will return a number that represents the closest match that it can find in the list of supported pixel formats. you then set this number to be the pixel format of the DC.
The struct described above isPIXELFORMATDESCRIPTOR
. A good way to set this up is as follows:
PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, //Flags PFD_TYPE_RGBA, //The kind of framebuffer. RGBA or palette. 32, //Colordepth of the framebuffer. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, //Number of bits for the depthbuffer 8, //Number of bits for the stencilbuffer 0, //Number of Aux buffers in the framebuffer. PFD_MAIN_PLANE, 0, 0, 0, 0 };
As you can see, attributes of the fields in the struct are set to 0. leave them that way. the ones we need to be concerned about, the ones you might want to use, are Labled abve with comments. there are more flags than are specified in this pixel format; more information on them can be found in the Windows SDK documentation. these will do for now.
Now that we havePIXELFORMATDESCRIPTOR
, We need to convert this into a pixel format number. We do this with the functionChoosePixelFormat
. This function takes a device context and PFD struct and returns a pixel format number. if it returns 0, then it cocould not find a pixel format that matches the description, or the PDF was not filled out correctly.
Once you have the pixel format number, you can set it into the DCSetPixelFormat
. This function takes the DC, The pixel format number, and a PFD struct pointer. don't get excited about being able to supply the PFD struct; it doesn' t read any important information out of it to set the pixel format into the context.
Create the context
Once you have set pixel format in the DC, creating the context is easy. You callwglCreateContext
. This function takes the DC as a parameter and returns a handle to the OpenGL context (of Type hglrc, for handle to GL rendering context ).
Before you can use OpenGL, the context you created must be made current. This is done withwglMakeCurrent
Function. this takes a DC and the hglrc context. if there is already a current context, then this function will cause the old context to be replaced with the new. openGL functions after this will refer to State in the new context, not the old one. if you pass NULL for the context, then the old one is removed and OpenGL functions will fail (or crash) as though you had never made a context current.
The current context is thread-specific; Each thread can have a different context current, and it's dangerous to have the same context current in multiple threads.
Delete the context
Technically not part of creation, but you should know how to delete a context.
The first step isAlwaysTo make sure that the context you want to delete isNotCurrent. CallwglMakeCurrent
With NULL for the context.
Now that the context is not current, you can callwglDeleteContext
On it.
Proper context Creation
Unless you are making a very simple application, you should not use the above simple context creation steps. there are a number of WGL extensions that give you greater power and flexibility in creating contexts. but to get access to those extensions, you have to make context creation a bit more complex.
Create a false Context
The key problem is this: the function you use to get WGL extensions is, itself, an OpenGL extension. thus like any OpenGL function, it requires an OpenGL context to call it. so in order to get the functions we need to create a context, we have... create a context.
Fortunately, this context does not need to be our final context. All we need to do is create a dummy context to get function pointers, then use those functions directly. Unfortunately, Windows doesNotAllow the user to change the pixel format of a window. you get to set it exactly once. therefore, if you want to use a different pixel format from the one your fake context used (for sRGB or multisample framebuffers, or just different bit-depths of buffers ), you must destroy the window entirely and recreate it after we are finished with the dummy context.
A good pixel format to choose for the dummy context is a simple 32-bit rgba color buffer, with a 24-bit depth buffer and 8-bit stencel, as we did in the above sample PFD. this will usually get a hardware accelerated pixel format.
So, this step means going through the above code to create a context. Make it current as well.
Get WGL extensionsmain article: Load OpenGL functions # windows 2
If you are using an extension loading library, now is the time to call whatever function is required to have it load function pointers of interest. if you are not using an extension loading library, then you will need to do this manually.
There are quite a few extensions of interest for doing advanced context creation. Most of them revolve around und pixel format creation, with one notable exception.
Pixel format extensions
The PFD struct is a nice way to describe your needs to the OpenGL implementation. but it does have one major flaw; It isn' t extensible. therefore, there is the wgl_arb_pixel_format extension. this extension defines a new mechanic for getting a pixel format number, one based on providing a list of attributes and values.
To use this, the extension must be defined. much like wgl_arb_extensions_string, this one has been around for a long time, and even old implementations will provide it. so if you 've gotten this far, it's a good bet that wgl_arb_pixel_format is implemented too.
There are several new functions in this extension, but the one we are interested in is this one:
BOOL wglChoosePixelFormatARB( HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
wglChoosePixelFormatARB
Is analogousChoosePixelFormat
. Instead of taking a fixed PFD struct, it takes a list of attributes and values. Attributes of these attributes have direct analogs to PFD struds CT fields, but some of them are new. Also, unlikeChoosePixelFormat
, This function can return multiple formats that fill the requested parameters. The order of these is in order from best fits to worst, though what constitutes "best" is implementation-defined.
In any case, the way it works is fairly simple.piAttribIList
Is a list of integer attributes. every two elements in the list is an attribute/value pair. the attribute "0" represents the end of the list, and it doesn' t need a value after it. you can pass null if you wish; this function will act as if you passed an empty list.
Similarly,pfAttribFList
Is a list of floating-point attributes. Every two elements in the list is an attribute/value pair. How do you put the attributes (which are integers) in a float list? Very carefully. you need to static-cast them (if you're using C ++) or do other trickery to make C keep the bit-pattern between the integer and float form the same.
ThenMaxFormats
Is the maximum number of formats that will be stored inpiFormats
. Therefore,piFormats
Shocould be a list of at least that has entries.nNumFormats
Is a return value, informing you how your entries were stored in the list.
If this function returns false (not gl_false, but the Windows False. both are just 0, though), then the Code failed to find an appropriate pixel format. despite not finding a pixel format,piFormats
List is left in an undefined state (Translation: The implementation is free to change stuff in it even if it failed ). if the return value is not false, the function worked and you have pixel format numbers.
Here is an example of this function that showould produce a near-equivalent list of pixel formats as our abve code:
const int attribList[] ={ 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, //End};int pixelFormat, numFormats;wglChoosePixelFormatARB(hdc, attribList, NULL, 1, &pixelFormat, &numFormats);
There are a number of extensions that have added new attributes for this function. The important ones that you might want to use are:
- Wgl_arb_pixel_format_float: allows for floating-point framebuffers.
- Wgl_arb_framebuffer_srgb: allows for color buffers to be in sRGB format.
- Wgl_arb_multisample: allows for multisampled framebuffers.
Once you have a pixel format number, you can set it just like any pixel formatSetPixelFormat
.
Create context with attributes
OpenGL 3.0 and above created a deprecation and Removal Model for getting rid of old, legacy functionality. however, it also created a bit of a problem. in previous OpenGL versions, the new version was a strict superset of the old. therefore, if you wanted a 1.5 context and got a 2.0 context, that was fine; you just got extra functionality you didn't use. once the possibility of removing Old functionality came into being, that was no longer viable.
Thus, the extension wgl_arb_create_context was made. It exposes a new function to replacewglCreateContext
. Much likewglChoosePixelFormatARB
, It adds an extensibility mechanic to the system that makes it possible to extend the options for context creation.
If the fake context does not expose this extension, then you cannot use this section. You must usewglCreateContext
As normal.
If it does advertise this extension, then there are a number of features that we can access that wowould normally not be available:
- Ensure getting an OpenGL 3.0 or greater context.
- Creating an OpenGL 3.2 or greater core context, without the compatibility features.
- Creating a context without a window, for off-screen rendering. This may not actually work.
-
Legacy note:Implementations that support GL 3.0 or 3.1, but not 3.2 used a slightly different scheme for context creation than those that support 3.2. pre 3.2 implementations were required to ask for a GL 3.0 or greater context in order to get one; thus, you
HadTo use the new creation API to get a higher GL version. 3.2 and above do not; they can get backwards-compatible profiles of 3.0 or greater versions (assuming the implementation supports them ). thus, the best way to ensure that you get 3.0 or above is to ask for it with this extension. as more drivers implement GL 3.2, this will become less of an issue.
-
You can tell the difference by checking the extensions. if wgl_arb_create_context_profile is defined, then it uses the above method. if it is not, then the only way to get a GL 3.0 or greater context is to use
wglCreateContext
Directly.
The signaturewglCreateContextAttribsARB
Is as follows:
HGLRC wglCreateContextAttribsARB(HDC hDC, HGLRC hshareContext, const int *attribList);
TheattribList
Works similarly to the one inwglChoosePixelFormatARB
. It is a series of attribute/value pairs, with a 0 attribute signaling the end of the list.
You can ask for a specific version of OpenGL by using the two attributesWGL_CONTEXT_MAJOR_VERSION_ARB
AndWGL_CONTEXT_MINOR_VERSION_ARB
. How this is resolved is complicated.
There are a number of rules that define what version you get back when you ask for a specific version. The rules are complicated, but boil down to two things:
- It will always return an OpenGL version equal to or greater than the one you ask.
- It will never return an OpenGL version and profile that does not implement core features that the version you ask for implements.
If the extension wgl_arb_create_context_profile is defined, then you can also useWGL_CONTEXT_PROFILE_MASK_ARB
To select a Core Profile (WGL_CONTEXT_CORE_PROFILE_BIT_ARB
) Or a compatibility profile (WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB
). Note that these are bits, So you cocould ask for both (but it wowould simply return a compatibility one). The details of what this means merit a longer discussion.
You can also pass a number of flags withWGL_CONTEXT_FLAGS_ARB
. With these, you can ask for a forward compatible context (WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
) And/or a debug context (WGL_CONTEXT_DEBUG_BIT_ARB
). A debug context will often implement arb_debug_output for enhanced error message testing. A forward compatible context must fully remove deprecated features in the version that it returns;You shoshould never actually use this.
ThehshareContext
Is a special field. If you have two GL contexts, and you want them to share objects, then you can use the FunctionwglShareLists
. But you have to do this before you create objects in either context.wglCreateContextAttribsARB
Incorporates this functionality directly into context creation.
See also
- Core and compatibility in contexts
- Tutorial: OpenGL 3.0 context creation (Glx)
- Tutorial: OpenGL 3.1 The first triangle (C ++/WIN)
References
- Wgl_arb_pixel_format Specification
- Wgl_arb_pixel_format_float Specification
- Wgl_arb_framebuffer_srgb Specification
- Wgl_arb_create_context Specification
Category: