Should I initialize OpenGL before initializing GLEW?

Hi
Should I initialize OpenGL before initializing GLEW?
If It’s correct, how can I check the WGL_ARB_pixel_format( with WGLEW_ARB_pixel_format ) to use the wglChoosePixelFormatARB()? It means I should initialize GLEW before initializing the OpenGL.
-Ehsan-

Yes, you need to first initialize OpenGL, then GLEW.

That is a common problem. Therefore you usually create a dummy window, initialize OpenGL, initialize GLEW, check for the available pixel-formats, destroy the dummy window and create the real window with the now known pixel-format.

It’s a bit complicated, but that’s AFAIK the only way to do it.

Jan.

I wrote the following code at the beginning of my game:
if( !raster.Init( hWnd ) )
return false;
GLenum err = glewInit();
if( err != GLEW_OK )
MessageBox( NULL, “Couldn’t initialize GLEW”, “Persian Engine Error”, MB_OK | MB_ICONINFORMATION );
raster.Release(hWnd);
if( !raster.Init( hWnd, 24, 32, 0, true ) ) //request multisampling( true == multisampling )
return false;

if( raster.multiSample )
glEnable( GL_MULTISAMPLE );

I’m wandering why I see a black screen when I request multisampling.

Raster class initializes OpenGL. Here’s RASTER::Init()
bool RASTER::Init(HWND hWnd, unsigned char color_bits, unsigned char depth_bits,
unsigned char stencil_bits, bool multiSampling )
{
if( multiSampling )
{
if( WGLEW_ARB_pixel_format )
{
int pixelFormat;
UINT numFormats;
hDC = GetDC( hWnd );
int attributes[] = {
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
WGL_SAMPLE_BUFFERS_ARB, 1,
WGL_COLOR_BITS_ARB, 16,
WGL_DEPTH_BITS_ARB, 16,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_STENCIL_BITS_ARB, stencil_bits,
WGL_SAMPLES_ARB, 4,
0, 0
};
wglChoosePixelFormatARB( hDC, attributes, NULL, 1, &pixelFormat, &numFormats );
if( numFormats == 0 )
{
MessageBox( NULL, “Couldn’t support multisampling”, “Persian Engine Error”, MB_OK | MB_ICONERROR );
multiSampling = false;
multiSample = false;
}

}
else
{
MessageBox( NULL, “Couldn’t support multisampling”, “Persian Engine Error”, MB_OK | MB_ICONERROR );
multiSampling = false;
multiSample = false;
}
multiSample = true; //Succesfully installed multisampling
}//if( multisampling )
if( !multiSampling )
{
PIXELFORMATDESCRIPTOR pfd;
int PixelFormat;

hDC = GetDC(hWnd);
if (hDC == NULL)
{
MessageBox(hWnd, “Couldn’t find the device context.”, “Persian Engine Error”, MB_OK | MB_ICONERROR);
return (false); }
memset (&pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.cColorBits = color_bits;
pfd.cDepthBits = depth_bits;
pfd.cStencilBits = stencil_bits;
PixelFormat = ChoosePixelFormat(hDC, &pfd);
if (PixelFormat == 0)
{
MessageBox(hWnd, “Couldn’t choose the pixel format.”, “Persian Engine Error”, MB_OK | MB_ICONERROR);
ReleaseDC (hWnd, hDC);
hDC = NULL;
return (false);
}

if (SetPixelFormat(hDC, PixelFormat, &pfd) == 0)
{
MessageBox(hWnd, “Couldn’t set the pixel format.”, “Persian Engine Error”, MB_OK | MB_ICONERROR);
ReleaseDC (hWnd, hDC);
hDC = NULL;
return (false);
}
glrc = wglCreateContext(hDC);
if (glrc == NULL)
{
MessageBox(hWnd, “Couldn’t create the OpenGL context.”, “Persian Engine Error”, MB_OK | MB_ICONERROR);
ReleaseDC (hWnd, hDC);
hDC = NULL;
return (false);
}

if (!wglMakeCurrent(hDC, glrc)) {
MessageBox(hWnd, “Couldn’t make a stream between HDC and HRC.”, “Persian Engine Error”, MB_OK | MB_ICONERROR);
wglDeleteContext(glrc);
ReleaseDC (hWnd, hDC);
glrc = NULL;
hDC = NULL;
return (false); }
}// else
return (true);
}

-Ehsan-


I’m wandering why I see a black screen when I request multisampling.

Because you are not doing anything when wglChoosePixelFormatARB selects some pixel format. In that case you code skips call to SetPixelFormat and entire OGL context creation.

You need something like:

int selected_format = 0 ;

// Try multisampled selection first.

if ( multiSampling ) {
   ... use the wglChoosePixelFormatARB and if it succeeds, store format it selected within the selected_format variable ...

}

// If nothing was selected yet, use ordinary selection.

if ( selected_format == 0 ) {
   ... use the ChoosePixelFormat and store its result to selected_format ...
}

// If no format was selected previously, we have problem.

if ( selected_format == 0 ) {
    return false ;
}

// Do the initialization

SetPixelFormat( selected_format )
wglCreateContext
wglMakeCurrent

BTW: The

multiSample = true; //Succesfully installed multisampling

line is called even if selection of multisampled format failed.

Should I set the third variable of the SetPixelFormat() function to NULL when I use multisamling?
-Ehsan-

Doesn’t NULL cause a crash?

I fill it with the “usual” stuff.
I don’t know why SetPixelFormat takes that parameter but we have no choice.

As far as I know the parameter is used during recording of WMF and EMF metafile formats and is probably used to select appropriate pixel format on target context when the metafile is played back.

If the call is not recorded into metafile, the parameter is likely entirely ignored or only basically checked. Probably the most clean way to get it filled with some values might be to use the DescribePixelFormat function.

I don’t know why SetPixelFormat() fails when I use the returned pixel format of wglChoosePixelFormat() – I corrected the above code. What do you mean from the usual stuff?
My graphic card is Geforce FX 5500.
-Ehsan-

What error code is set by the failing SetPixelFormat?

I read the following stuff in the net:

SetPixelFormat() can only be called once on any dc. After that, you have to create a new window and get the dc. You cannot call SetPixelFormat() twice on any dc. For example, to change antialias modes, you have to destroy the viewport panel, create a new one, and set the pixel format with the new antialias mode.
But i have not destroyed the window in the second call of SetPixelFormat(). Should i destroy and then create the window every time I want to set a new pixel format?
-Ehsan-

Originally posted by Ehsan Kamrani:
Should i destroy and then create the window every time I want to set a new pixel format?

Yes.

Originally posted by Ehsan Kamrani:
I don’t know why SetPixelFormat() fails when I use the returned pixel format of wglChoosePixelFormat() – I corrected the above code. What do you mean from the usual stuff?
My graphic card is Geforce FX 5500.
-Ehsan-

The usual stuff would be the values set by DescribePixelFormat. I feel safer then leaving all zeroes or some random values.

I have another question:
If I initialize, then release and again initialize my raster class without requesting multisapling and without destroying the window, I don’t receive any errors.Does it mean that in this case SetPixelFormat() can set the new pixel format?

Originally posted by Ehsan Kamrani:
If I initialize, then release and again initialize my raster class without requesting multisapling and without destroying the window, I don’t receive any errors.Does it mean that in this case SetPixelFormat() can set the new pixel format?
It is possible that the SetPixelFormat() silently does nothing if the format is the same as the format set previously.

Thank you. Multisampling really improved the quality of our game :slight_smile: