Very strange bug with wglGetProcAddress

Hi !

I have a very very strange behaviour with wglGetProcAddress (under VC++):

In my prog (kind of renderer), I have a rendering class I create each time I switch to openGL window for rendering. In the constructor, I call wglGetProcAddress() to get pointers on OGL functions. Everything goes well. BUT, sometimes, after more or less reproductible actions within Dialog boxes before launching rendering, wglGetProcAddress returns NULL ! Is there sth special I should care about with wglGetProcAddress ? I’ve never had such pb before…

thx,
g0b

Don’t know what might be happening.Maybe your calling it while no context is current.

'guess it’s a context-related pb, yes… I’ve move the wglGetProcAddress somewhere else in the code and it seems to work… strange…

thx,
g0b

Well… if you put wglGetProcAddress into the constructor of a class, and that class is being instantiated BEFORE your Choose/Describe/SetPixelFormat stuff, the wglGetProcAddress is going to fail.

Originally posted by Deiussum:
Well… if you put wglGetProcAddress into the constructor of a class, and that class is being instantiated BEFORE your Choose/Describe/SetPixelFormat stuff, the wglGetProcAddress is going to fail.

That was the case, but what surprise me, is that it does NOT always fail. Behaviour seems quite random in fact…

g0b

Hi I have the same problem. In my case, I am drawing the result on a bitmap using PFD_DRAW_TO_BITMAP. The drawing works fine but I cannot do blending because wglGetProcAddress returns always NULL. The error message says it cannot find the procedure but it works if I draw the result in a window. What is the problem? Why it works in a code but not does not in another code?

// DrawOnBitmap.cpp : Defines the entry point for the application.
//

#include <windows.h> // Header File For Windows
#include <gl\gl.h> // Header File For The OpenGL32 Library
#include <gl\glu.h> // Header File For The GLu32 Library
#include <gl\glaux.h> // Header File For The Glaux Library

#include “MIPLib.h”

HDC hDC=NULL; // Private GDI Device Context
HGLRC hRC=NULL; // Permanent Rendering Context
HINSTANCE hInstance; // Holds The Instance Of The Application

bool keys[256]; // Array Used For The Keyboard Routine
bool active=TRUE; // Window Active Flag Set To TRUE By Default
bool fullscreen=TRUE; // Fullscreen Flag Set To Fullscreen Mode By Default

int WINAPI WinMain( HINSTANCE hInstance, // Instance
HINSTANCE hPrevInstance, // Previous Instance
LPSTR lpCmdLine, // Command Line Parameters
int nCmdShow) // Window Show State
{
CreateAWindow();

int width=512;
int height=512;
int bits=24;

BITMAPINFO g_BitmapInfo;
HDC hDc = GetDC( NULL );
memset( &g_BitmapInfo, 0, sizeof(BITMAPINFO) );
g_BitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
g_BitmapInfo.bmiHeader.biWidth = width;
g_BitmapInfo.bmiHeader.biHeight = height;
g_BitmapInfo.bmiHeader.biPlanes = 1;
g_BitmapInfo.bmiHeader.biBitCount = 24;
g_BitmapInfo.bmiHeader.biCompression = BI_RGB;
BYTE **g_pBitmapBits;
HBITMAP g_hBitmapImage = CreateDIBSection( hDc, &g_BitmapInfo, DIB_RGB_COLORS,
(void **)(&g_pBitmapBits), NULL, 0 );
ReleaseDC( NULL, hDc );

PIXELFORMATDESCRIPTOR pfd ;
memset(&pfd,0,sizeof(PIXELFORMATDESCRIPTOR)) ;
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR) ;
pfd.nVersion = 1 ;
pfd.dwFlags = PFD_DRAW_TO_BITMAP | // replaces PFD_DRAW_TO_WINDOW
			  PFD_SUPPORT_OPENGL |
			  PFD_SUPPORT_GDI|PFD_STEREO_DONTCARE ;
pfd.iPixelType = PFD_TYPE_RGBA ; 
pfd.cColorBits = 24 ;
pfd.cAlphaBits = 0;
pfd.cDepthBits = 8;
pfd.iLayerType = PFD_MAIN_PLANE ; 


// create memory dc
HDC dcMem=CreateCompatibleDC(NULL);
if(dcMem==NULL)
{
	MessageBox(NULL,"Fail to create memory DC!","ERROR",MB_OK|MB_ICONEXCLAMATION);
	return -1;;								// return -1;
}

// select bitmap to the memory dc
SelectObject(dcMem,g_hBitmapImage);

GLuint		pxFormat;			// Holds The Results After Searching For A Match
if (!(pxFormat=ChoosePixelFormat(dcMem,&pfd)))	// Did Windows Find A Matching Pixel Format?
{
	MessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
	DeleteDC(dcMem);
	DeleteObject(g_hBitmapImage);
	return -1;;								// return -1;
}

if(!SetPixelFormat(dcMem,pxFormat,&pfd))		// Are We Able To Set The Pixel Format?
{
	MessageBox(NULL,"Can't set the given PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
	DeleteDC(dcMem);
	DeleteObject(g_hBitmapImage);
	return -1;;								// return -1;
}

if (!(hRC=wglCreateContext(dcMem)))				// Are We Able To Get A Rendering Context?
{
	MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
	DeleteDC(dcMem);
	DeleteObject(g_hBitmapImage);
	return -1;;								// return -1;
}

if(!wglMakeCurrent(dcMem,hRC))					// Try To Activate The Rendering Context
{
	DeleteDC(dcMem);
	DeleteObject(g_hBitmapImage);
	wglDeleteContext(hRC);
	MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
	return -1;;								// return -1;
}

// set view port
glViewport(0,0,width,height);						// Reset The Current Viewport

// set the view port
glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
glLoadIdentity();									// Reset The Projection Matrix
glFrustum(-1.0,1.0,-1.0,1.0,1.0,5.0);
glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix
glLoadIdentity();	

////////////
// init gl
glShadeModel(GL_SMOOTH);							// Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);				// Black Background
glClearDepth(1.0f);									// Depth Buffer Setup
glEnable(GL_DEPTH_TEST);							// Enables Depth Testing
glDepthFunc(GL_LEQUAL);								// The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// Really Nice Perspective Calculations

////////////////////
// draw a triangle
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear Screen And Depth Buffer

glLoadIdentity();									// Reset The Current Modelview Matrix
glTranslatef(0.0f,0.0f,-2.0f);						// Move Left 1.5 Units And Into The Screen 6.0
glBegin(GL_TRIANGLES);								// Drawing Using Triangles
	glVertex3f( 0.0f, 1.0f, 0.0f);					// Top
	glVertex3f(-1.0f,-1.0f, 0.0f);					// Bottom Left
	glVertex3f( 1.0f,-1.0f, 0.0f);					// Bottom Right
glEnd();

///////////////////////////
// save the result to a file
CRGBByteImage img(width,height);
glReadPixels(0,0,width,height,GL_RGB,GL_UNSIGNED_BYTE,img.GetPtrOfData());
img.FlipV();
img.SaveAsBmp("screen.bmp");

/////////// this line always returns NULL !!! Why????
PFNGLBLENDCOLORPROC glBlendColor=(PFNGLBLENDCOLORPROC)wglGetProcAddress("glBlendColor");

///////////////////////////
// close
MessageBox(NULL,"Done!","OK",MB_OK);

DeleteDC(dcMem);
DeleteObject(g_hBitmapImage);
if (hRC)											// Do We Have A Rendering Context?
{
	if (!wglMakeCurrent(NULL,NULL))					// Are We Able To Release The DC And RC Contexts?
	{
		MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
	}

	if (!wglDeleteContext(hRC))						// Are We Able To Delete The RC?
	{
		MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
	}
	hRC=NULL;										// Set RC To NULL
}

return 1;

}