|
|
/******************************Module*Header*******************************\
* Module Name: pixelfmt.c * * Pixel format selection * * Copyright (c) 1994 Microsoft Corporation * \**************************************************************************/
#include "mtk.h"
/******************************Public*Routine******************************\
* SSU_ChoosePixelFormat * * Local implementation of ChoosePixelFormat * * Choose pixel format based on flags. * This allows us a little a more control than just calling ChoosePixelFormat \**************************************************************************/
static int SSU_ChoosePixelFormat( HDC hdc, int flags ) { int MaxPFDs; int iBest = 0; int i; PIXELFORMATDESCRIPTOR pfd;
//mf: this don't handle alpha yet...
// Always choose native pixel depth
int cColorBits = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
BOOL bDoubleBuf = flags & SS_DOUBLEBUF_BIT;
int cDepthBits = 0; if( SS_HAS_DEPTH16(flags) ) cDepthBits = 16; else if( SS_HAS_DEPTH32(flags) ) cDepthBits = 32;
i = 1; do { MaxPFDs = DescribePixelFormat(hdc, i, sizeof(pfd), &pfd); if ( MaxPFDs <= 0 ) return 0;
if( ! (pfd.dwFlags & PFD_SUPPORT_OPENGL) ) continue;
if( flags & SS_BITMAP_BIT ) { // need bitmap pixel format
if( ! (pfd.dwFlags & PFD_DRAW_TO_BITMAP) ) continue; } else { // need window pixel format
if( ! (pfd.dwFlags & PFD_DRAW_TO_WINDOW) ) continue; // a window can be double buffered...
if( ( bDoubleBuf && !(pfd.dwFlags & PFD_DOUBLEBUFFER) ) || ( !bDoubleBuf && (pfd.dwFlags & PFD_DOUBLEBUFFER) ) ) continue; }
if ( pfd.iPixelType != PFD_TYPE_RGBA ) continue; if( pfd.cColorBits != cColorBits ) continue;
if( (flags & SS_GENERIC_UNACCELERATED_BIT) && ((pfd.dwFlags & (PFD_GENERIC_FORMAT|PFD_GENERIC_ACCELERATED)) != PFD_GENERIC_FORMAT) ) continue;
if( (flags & SS_NO_SYSTEM_PALETTE_BIT) && (pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE) ) continue;
if( cDepthBits ) { if( pfd.cDepthBits < cDepthBits ) continue; } else { // No depth buffer required, but use it if nothing better
if( pfd.cDepthBits ) { if( pfd.dwFlags & PFD_GENERIC_ACCELERATED ) // Accelerated pixel format - we may as well use this, even
// though we don't need depth. Otherwise if we keep going
// to find a better match, we run the risk of overstepping
// all the accelerated formats and picking a slower format.
return i; iBest = i; continue; } }
// We have found something useful
return i;
} while (++i <= MaxPFDs); if( iBest ) // not an exact match, but good enough
return iBest;
// If we reach here, we have failed to find a suitable pixel format.
// See if the system can find us one.
memset( &pfd, 0, sizeof( PIXELFORMATDESCRIPTOR ) ); pfd.nSize = sizeof( PIXELFORMATDESCRIPTOR ); pfd.cColorBits = cColorBits; pfd.cDepthBits = cDepthBits; pfd.iPixelType = PFD_TYPE_RGBA; pfd.dwFlags = PFD_SUPPORT_OPENGL; if( bDoubleBuf ) pfd.dwFlags |= PFD_DOUBLEBUFFER; if( flags & SS_BITMAP_BIT ) pfd.dwFlags |= PFD_DRAW_TO_BITMAP; else pfd.dwFlags |= PFD_DRAW_TO_WINDOW;
if( (flags & SS_GENERIC_UNACCELERATED_BIT) || (flags & SS_NO_SYSTEM_PALETTE_BIT) ) // If either of these flags are set, we should be safe specifying a
// 'slow' pixel format that supports bitmap drawing
//mf: DRAW_TO_WINDOW seems to override this...
pfd.dwFlags |= PFD_DRAW_TO_BITMAP; SS_WARNING( "SSU_ChoosePixelFormat failed, calling ChoosePIxelFormat\n" );
return ChoosePixelFormat( hdc, &pfd ); }
/******************************Public*Routine******************************\
* SSU_SetupPixelFormat * * Choose pixel format according to supplied flags. If ppfd is non-NULL, * call DescribePixelFormat with it. * \**************************************************************************/
BOOL SSU_SetupPixelFormat(HDC hdc, int flags, PIXELFORMATDESCRIPTOR *ppfd ) { int pixelFormat; int nTryAgain = 4;
do{ if( (pixelFormat = SSU_ChoosePixelFormat(hdc, flags)) && SetPixelFormat(hdc, pixelFormat, NULL) ) { SS_DBGLEVEL1( SS_LEVEL_INFO, "SSU_SetupPixelFormat: Setting pixel format %d\n", pixelFormat ); if( ppfd ) DescribePixelFormat(hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), ppfd); return TRUE; // Success
} // Failed to set pixel format. Try again after waiting a bit (win95
// bug with full screen dos box)
Sleep( 1000 ); // Wait a second between attempts
} while( nTryAgain-- );
return FALSE; }
/******************************Public*Routine******************************\
* SSU_bNeedPalette * \**************************************************************************/
BOOL SSU_bNeedPalette( PIXELFORMATDESCRIPTOR *ppfd ) { if (ppfd->dwFlags & PFD_NEED_PALETTE) return TRUE; else return FALSE; }
/******************************Public*Routine******************************\
* SSU_PixelFormatDescriptorFromDc * \**************************************************************************/
int SSU_PixelFormatDescriptorFromDc( HDC hdc, PIXELFORMATDESCRIPTOR *Pfd ) { int PfdIndex;
if ( 0 < (PfdIndex = GetPixelFormat( hdc )) ) { if ( 0 < DescribePixelFormat( hdc, PfdIndex, sizeof(*Pfd), Pfd ) ) { return(PfdIndex); } } return 0; }
|