Multisampling Chicken/Egg

Started by
2 comments, last by _the_phantom_ 18 years, 8 months ago
Hello, I am having trouble setting up multisampling in my application due to the fact that I am always destroying my rendering context when destroying the original window for the second pass. I am trying to follow NeHe's Multisampling tutorial but I am having trouble understanding how the second pass works since the needed information is still destroyed and ot yet attainable until too late. This is my Opengl Window Release routine

void KillGLWindow()
{
	if(Option.FullScreen)
	{
		ChangeDisplaySettings(NULL,0);
	}
    KillFont(IDF_ZEROTHREE);
    KillFont(IDF_DIGTALH);
	if(hRC)
	{
		if(!wglMakeCurrent(NULL, NULL))
		{
			MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
		}

		if(!wglDeleteContext(hRC))
		{
			MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
		}
		hRC=NULL;
	}
	if(hDC && !ReleaseDC(hwnd, hDC))
	{
		MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
		hDC=NULL;
	}
	if(hwnd && !DestroyWindow(hwnd))
	{
		MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
		hwnd=NULL;
	}
	if(!UnregisterClass(classname, hInstance))
	{
		MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
		hInstance=NULL;
	}
}

This is the multisampling initiation routine:

bool InitMultisample(HINSTANCE hInstance, HWND hWnd, PIXELFORMATDESCRIPTOR pfd, int samples)
{
    System.arbMultisampleFormat = 0;
	 // See If The String Exists In WGL!
	if (!WGLisExtensionSupported("WGL_ARB_multisample"))
	{
		arbMultisampleSupported=false;
		return false;
	}

	// Get Our Pixel Format
	PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
	if (!wglChoosePixelFormatARB) 
	{
		arbMultisampleSupported=false;
		return false;
	}

	// Get Our Current Device Context
	HDC hDC = GetDC(hWnd);

	int		pixelFormat;
	int		valid;
	UINT	numFormats;
	float	fAttributes[] = {0,0};

	// These Attributes Are The Bits We Want To Test For In Our Sample
	// Everything Is Pretty Standard, The Only One We Want To 
	// Really Focus On Is The SAMPLE BUFFERS ARB And WGL SAMPLES
	// These Two Are Going To Do The Main Testing For Whether Or Not
	// We Support Multisampling On This Hardware.
	int iAttributes[] =
	{
		WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
		WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
		WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
		WGL_COLOR_BITS_ARB,24,
		WGL_ALPHA_BITS_ARB,8,
		WGL_DEPTH_BITS_ARB,16,
		WGL_STENCIL_BITS_ARB,0,
		WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
		WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
		WGL_SAMPLES_ARB,samples,
		0,0
	};

	// First We Check To See If We Can Get A Pixel Format For 4 Samples
	valid = wglChoosePixelFormatARB(hDC,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
 
	// If We Returned True, And Our Format Count Is Greater Than 1
	if (valid && numFormats >= 1)
	{
		arbMultisampleSupported = true;
		System.arbMultisampleFormat = pixelFormat;	
		return arbMultisampleSupported;
	}
	  
	// Return The Valid Format
	return  arbMultisampleSupported;
}

As you can see, wglChoosePixelFormatARB needs the rendering context that is destroyed when the opengl window is destroyed. The context will not be created till after the call to this function and a new pixel format is selected. Can anyone explain more lucidly how to carry out the second pass? Thank you.
Advertisement
Why in the world would you remake your window to do another pass? to have a blank matrix slate and clear framebuffer do

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

To save the contents of the framebuffer, use glCopyTexSubImage2D into an empty texture in video memory. Destroying and remaking the rendering context twice a frame is a horrid idea (I would imagine)
I am making the original pass to obtain the pixel format and then test if it is supported. For multisampling to occur, I have to then assign my pixel format to what is returned from the supportive sampling extension. The problem with this is that the pixel format is already obtained so I will have to destroy the window and then, on its second pass, assign it for my multisampling.
The process is pretty simple;

- create dummy window with a simple OpenGL context (hardware accel, 16bit, no zbuffer, no stencil should do it)
- initalise extensions
- query for pixel formats with FSAA support
- destory dummy window
- create a new window
- the use 'setpixelformat' with the format number returned from step 3 and a dummy pfd
- create teh content on your new final window.

My advice, dont base your code off NeHe's, while the site if a good learning resource for OpenGL it is dire when it comes to Win32 programming, infact if you can i'd find a windowing library which will do it for you which you can just use (*koff*like my OpenGL window Framework*koff*) [grin]

This topic is closed to new replies.

Advertisement