// Ron Fosner's code for weighting pixel formats and forcing software. /*=================================================================== This is your weighting function. Customize it to suit your needs. You write it so that it examines the PFD passed in and returns a weighting factor. You then select the largest weight (which is supposedly the best pixel format). The optional bForceSoftwareFlag will eliminate any hardware accelerated format from consideration (i.e. it'll force software rendering) The currentColorDepth param is the current desktop color depth. Formats that are in this color depth are preferred over others. If the color depth isn't better that 256 color mode, we don't select and pixel format. ===================================================================*/ unsigned WeightPixelFormats( PIXELFORMATDESCRIPTOR& pfd, unsigned currentColorDepth, bool bForceSoftware ) { unsigned weight = 0; // if it's not the same color depth, double buffered in a Window, and in RGBA mode // with a z buffer we don't want it if ( currentColorDepth != pfd.cColorBits || !(pfd.dwFlags & PFD_SUPPORT_OPENGL) || !(pfd.dwFlags & PFD_DRAW_TO_WINDOW) || ( pfd.cDepthBits <= 8 ) || !(pfd.iPixelType == PFD_TYPE_RGBA) ) return(0); weight = 1; // it's usable if ( pfd.dwFlags & PFD_DOUBLEBUFFER ) { weight *= 2; // we like double buffered } // we like smaller (but nonzero depth buffers) // so weight smaller better - assume smallest is 16 bits, else ignore it if ( 16 <= pfd.cDepthBits ) { weight += 128 - pfd.cDepthBits; // assume that the depth buffer will never >= 128 bits // assert( pfd.cDepthBits <= 128 ); } // only good for ICD's or generic, don't worry about mini-client drivers if ( pfd.dwFlags & PFD_GENERIC_FORMAT ) { // software implementation } else { // hardware implementation if ( true == bForceSoftware ) { weight = 0; // kill it } else { weight += 1024; } } return( weight ); } /*=================================================================== Use this function instead of ChoosePixelFormat, You pass in the Window DC, the current desktop color depth, and a flag that's true if you only want software rendering only. It will return the pixel format that will be best suited (as selected by the WeightPixelFormats function). You then use the returned value for CreatePixelFormat. Sugggestions/bugs report to Ron Fosner - ron@directx.com ===================================================================*/ int EnumPixelFormats( HDC hdc, unsigned colorDepth, bool bSoftware ) { int iPixelFormat; int iCount; unsigned weight = 0; PIXELFORMATDESCRIPTOR pfd2; PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR),// size of this pfd 1, // version number PFD_DRAW_TO_WINDOW | // support window PFD_SUPPORT_OPENGL | // support OpenGL PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, // RGBA type 32, 0, 0, 0, 0, 0, 0, // color bits ignored 0, // no alpha buffer 0, // shift bit ignored 0, // no accumulation buffer 0, 0, 0, 0, // accum bits ignored 16, // 16-bit z-buffer 0, // no stencil buffer 0, // no auxiliary buffer PFD_MAIN_PLANE, // main layer 0, // reserved 0, 0, 0 // layer masks ignored }; // assert( NULL != hdc ); iPixelFormat = 1; pfd2 = pfd; // obtain detailed information about // the device context's first pixel format iCount = 1 + ::DescribePixelFormat( hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd2); // use stupid OS function to select one by default in case we // can't come up with something better iPixelFormat = ::ChoosePixelFormat( hdc, &pfd ); if ( 0 == iPixelFormat ) { // TRACE( "No OpenGL pixel formats found\n"); return 0; } // TRACE("%d OpenGL pixel formats found\n", iCount-1); // pfd counts are 1 based (not 0) while ( --iCount ) { ::DescribePixelFormat( hdc, iCount, sizeof(PIXELFORMATDESCRIPTOR), &pfd ); unsigned w = WeightPixelFormats( pfd, colorDepth, bSoftware ); if ( w > weight ) // do we like this one better? { weight = w; iPixelFormat = iCount; } } #if defined (_DEBUG) // ::DescribePixelFormat( hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd ); // TRACE("Pixel format %d selected\n",iPixelFormat); // TRACE("Pixel format has %d color & %d depth bits\n",(int)pfd.cColorBits, (int)pfd.cDepthBits ); #endif return iPixelFormat; }