windows-nt/Source/XPSP1/NT/multimedia/opengl/toolkits/libmtk/pixelfmt.c
2020-09-26 16:20:57 +08:00

201 lines
6 KiB
C

/******************************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;
}