Depending on the GLEW assembly used, the waterproof method is to call glewInit after changing each context!
With function pointers, X11 / GLX are invariant.
But in OpenGL function pointers, Windows is specific to each context. Some GLEW assemblies are context-sensitive, while others are not. Therefore, to cover this case, technically you have to call it, every time the context has really changed.
(EDIT: due to request for clarification)
for each window (i.e. each OpenGL rendering context)?
First of all: OpenGL contexts are not window bound. It is great to have one window, but several rendering contexts. In Microsoft Windows, what is important for OpenGL is the device context (DC) associated with the window. But it also works the other way around: you can have one OpenGL context, but you can use several windows with it (provided that the pixelformat window is compatible with the OpenGL context).
So this is legal:
HWND wnd = create_a window() HDC dc = GetDC(wnd) PIXELFORMATDESCRIPTOR pf = select_pixelformat(); SetPixelFormat(dc, pf); HGLRC rc0 = create_opengl_context(dc); HGLRC rc1 = create_opengl_context(dc); wglMakeCurrent(dc, rc0); draw_stuff();
And this one
HWND wnd0 = create_a window() HDC dc0 = GetDC(wnd) HWND wnd1 = create_a window() HDC dc1 = GetDC(wnd) PIXELFORMATDESCRIPTOR pf = select_pixelformat(); SetPixelFormat(dc0, pf); SetPixelFormat(dc1, pf); HGLRC rc = create_opengl_context(dc0);
Here is where the extensions enter the image. A function of type glActiveTexture not part of the OpenGL specification that was bound to the Windows binary application interface (ABI). Therefore, you should get a pointer to it at runtime. This is what GLEW does. Internally, it looks like this:
First, it defines the types of function pointers, declares them as external variables, and uses a little preprocessing magic to avoid namespace conflicts.
typedef void (*PFNGLACTIVETEXTURE)(GLenum); extern PFNGLACTIVETEXTURE glew_ActiveTexture; #define glActiveTexture glew_ActiveTexture;
In glewInit function pointer variables are set to the values obtained using wglGetProcAddress (I omit the casting type for readability).
int glewInit(void) { if( openglsupport >= gl1_2 ) { glew_ActiveTexture = wglGetProcAddress("glActiveTexture"); } }
Now the important part: wglGetProcAddress works with the OpenGL rendering context that is current at the time of the call. So, whatever it was until the last wglMakeCurrent call made before it. As already explained, extension function pointers are tied to their OpenGL context, and different OpenGL contexts can give different function pointers for the same function.
So if you do it
wglMakeCurrent(…, rc0); glewInit(); wglMakeCurrent(…, rc1); glActiveTexture(…);
he may fail. Thus, in the general case with GLEW, every wglMakeCurrent call should immediately follow glewInit . Some GLEW assemblies are multi-competitive and do this internally. No others. However, it is completely safe to call glewInit several times, so a safe way is to call it to be sure.