785 lines
37 KiB
Plaintext
785 lines
37 KiB
Plaintext
|
************************
|
|||
|
*** ***
|
|||
|
*** ***
|
|||
|
*** DirectDraw Notes ***
|
|||
|
*** ***
|
|||
|
*** ***
|
|||
|
************************
|
|||
|
|
|||
|
Last updated September 10, 1996
|
|||
|
|
|||
|
Notes for DirectDraw 3.0
|
|||
|
========================================
|
|||
|
The CoCreateInstance API cannot be used to create an IDirectDraw2 object.
|
|||
|
To work around this problem, create a DirectDraw object and call
|
|||
|
QueryInterface on it to get the IDirectDraw2 interface.
|
|||
|
|
|||
|
IDirectDrawSurface2::Flip may cause your machine to hang. To work around this
|
|||
|
problem, call IDirectDrawSurface::Flip instead.
|
|||
|
|
|||
|
|
|||
|
Notes for DirectDraw 2.0
|
|||
|
========================================
|
|||
|
|
|||
|
In some hardware configurations, stretched transparent blits do not work
|
|||
|
correctly. If at all possible, when writing DirectDraw applications, you
|
|||
|
should avoid using stretched transparent blits. To work around this
|
|||
|
limitation, you can do a stretched blit to an intermediate surface, followed
|
|||
|
by a transparent blit to your original destination surface.
|
|||
|
|
|||
|
On some, relatively rare, older video boards, source color key blitting
|
|||
|
to the primary surface may not work. You can work around this by composing
|
|||
|
your image with transparency to a back buffer, then blitting the result to
|
|||
|
the primary surface.
|
|||
|
|
|||
|
DirectDraw::Initialize() is now called if the DirectDraw object
|
|||
|
is created with standard COM methods.
|
|||
|
|
|||
|
|
|||
|
Notes for DirectDraw 2.0 Beta 3
|
|||
|
========================================
|
|||
|
|
|||
|
|
|||
|
SetDisplayMode now supports setting the monitor refresh rate
|
|||
|
------------------------------------------------------------
|
|||
|
The IDirectDraw2::SetDisplayMode function now takes two additional
|
|||
|
parameters. The dwRefreshRate parameter can be used to specify a
|
|||
|
monitor refresh rate in Hz. Valid refresh rates can now be enumerated
|
|||
|
with the IDirectDraw2::EnumDisplayModes function. The refresh rate is
|
|||
|
returned in the dwRefreshRate field of the DDSURFACEDESC structure.
|
|||
|
|
|||
|
If a refresh rate of 0 is specified in SetDisplayMode, this means to
|
|||
|
revert back to the IDirectDraw behaviour and set the default refresh
|
|||
|
rate for the specified mode. The display driver may or may not enumerate
|
|||
|
specific refresh rates for each mode. If no refresh rate is specified
|
|||
|
by the driver for a particular mode, the dwRefreshRate field in the
|
|||
|
DDSURFACEDESC structure set by EnumDisplayModes will be 0.
|
|||
|
|
|||
|
|
|||
|
Direct Draw modes now respect monitor settings
|
|||
|
----------------------------------------------
|
|||
|
Windows 95 allows a user to specify the type of monitor that is being
|
|||
|
used. DirectDraw now checks the display modes that it knows about against
|
|||
|
the display restrictions of the installed monitor. If it is determined
|
|||
|
that the requested mode is not compatible with the monitor, then SetDisplayMode
|
|||
|
will fail. Only modes which are supported on the installed monitor will be
|
|||
|
enumerated in EnumDisplayModes.
|
|||
|
|
|||
|
|
|||
|
IDirectDrawSurface2::DDGetInterface now supported
|
|||
|
-------------------------------------------------
|
|||
|
A new method has been added to the IDirectDrawSurface2 interface which is
|
|||
|
call DDGetInterface. This function returns a pointer to the DirectDraw
|
|||
|
object that was used to create the specified surface.
|
|||
|
|
|||
|
Direct Draw clipper objects now have a COM class factory
|
|||
|
--------------------------------------------------------
|
|||
|
Direct Draw clipper objects now have full class factory support for COM
|
|||
|
compliance. Clippers can now be created using either CoGetClassObject
|
|||
|
to obtain a class factory and then calling CreateInstance or by calling
|
|||
|
CoCreateInstance directly. The class identifier for the clipper class is
|
|||
|
CLSID_DirectDrawClipper. Please note that it is still possible to create
|
|||
|
clipper objects using either of the two existing API functions;
|
|||
|
DirectDrawCreateClipper or IDirectDraw::CreateClipper. Class factory
|
|||
|
support is provided in addition to these functions rather than in
|
|||
|
replacement of them.
|
|||
|
|
|||
|
Clippers created by the class factory mechanism must be initialized
|
|||
|
with the IDirectDrawClipper::Initialize member before use. Initialize
|
|||
|
takes two parameters; a DirectDraw driver object interface pointer and
|
|||
|
a flags field. Currently the flags field must be 0. If a NULL driver object
|
|||
|
is specified then the clipper is not owned by a Direct Draw driver object
|
|||
|
and behaves identically to clippers created with DirectDrawCreateClipper.
|
|||
|
If a driver object is specified the clipper will be owned by that driver
|
|||
|
object and behaves identically to IDirectDraw::CreateClipper.
|
|||
|
|
|||
|
Flip now flips all levels of a mip-map
|
|||
|
--------------------------------------
|
|||
|
Previously, Flip only flipped the the mip-map level supplied as an
|
|||
|
argument. Now, however, Flip will flip all the levels of a mip-map
|
|||
|
from the level supplied to the lowest level in the map. A destination
|
|||
|
surface can also be provided in which case all levels in the mip-map will
|
|||
|
flip to the back buffer in thier flippable chain which matches the supplied
|
|||
|
override. For example, if the third back buffer in the top level
|
|||
|
flippable chain is supplied all levels in the mip-map will flip to thier
|
|||
|
third back buffer.
|
|||
|
|
|||
|
The number of levels in a mip-map is now stored explicitly
|
|||
|
----------------------------------------------------------
|
|||
|
The number of levels in a mip-map chain is now stored explicitly.
|
|||
|
When the surface description of a mip-map is obtained (via
|
|||
|
IDirectDrawSurface::Lock or IDirectDrawSurface::GetSurfaceDesc) the
|
|||
|
dwMipMapCount field will contain the number of levels in a mip-map
|
|||
|
including the top-level. Note, for levels other than the top-level
|
|||
|
in the map, dwMipMapCount will specify the number of levels from
|
|||
|
that map to the smallest map in the chain.
|
|||
|
|
|||
|
New surface capability bit for Direct3D texture loading
|
|||
|
-------------------------------------------------------
|
|||
|
A new surface capability bit, DDSCAPS_ALLOCONLOAD, has been added
|
|||
|
to support device dependent and compressed texture surfaces. This
|
|||
|
capability bit specifies that a given texture surface does not
|
|||
|
have memory allocated for it when it is created. Instead, sufficient
|
|||
|
memory will be allocated when the texture is loaded using the Direct3D
|
|||
|
texture Load member. Currently the semantics of this bit are not fully
|
|||
|
implemented and the width, height and pixel format of the texture
|
|||
|
surface should be specified when DDSCAPS_ALLOCONLOAD is specified.
|
|||
|
However, for the final release, width, height and pixel format will
|
|||
|
not be specified at create time but will be initialized when the
|
|||
|
texture is loaded. If DDSCAPS_ALLOCONLOAD is specified so must
|
|||
|
DDSCAPS_TEXTURE. For further information see the Direct3D documentation
|
|||
|
on the IDirect3DTexture::Load member function.
|
|||
|
|
|||
|
|
|||
|
Notes for DirectDraw 2.0 Beta 2
|
|||
|
========================================
|
|||
|
|
|||
|
|
|||
|
Support for high resolutions and TrueColor bit depths
|
|||
|
-----------------------------------------------------
|
|||
|
Direct Draw supports all of the screen resolutions and depths supported
|
|||
|
by the Display Driver. Version 1.0 of Direct Draw limited the available
|
|||
|
video modes to 640x480 with pixel depths of 8 bits per pixel and 16 bits
|
|||
|
per pixel. This restriction has been relaxed and Direct Draw now allows
|
|||
|
an application to change the mode into any mode supported by the Display
|
|||
|
Driver. This includes all supported 24 and 32 bits-per-pixel modes.
|
|||
|
|
|||
|
Note that this release of Direct Draw does not check the monitor capabilities
|
|||
|
stored by the system to determine if a particular display resolution is
|
|||
|
compatible with the monitor. This means that an application may use
|
|||
|
EnumerateDisplayModes to determine the available video modes and then switch
|
|||
|
into a mode that is not supported by the monitor. This is a defect which
|
|||
|
will be corrected in the next release.
|
|||
|
|
|||
|
|
|||
|
HEL Blitting Support for 24 and 32 bit Surfaces
|
|||
|
-----------------------------------------------
|
|||
|
Direct Draw now supports HEL blitting of 24 and 32 bits-per-pixel surfaces.
|
|||
|
If the Display Driver supports blitting at these resolutions then the
|
|||
|
hardware blitter will be used for vram to vram blits. Otherwise, the
|
|||
|
Hardware Emulation Layer (HEL) will be used to do the blits.
|
|||
|
|
|||
|
|
|||
|
Multiple Direct Draw Objects per Process
|
|||
|
----------------------------------------
|
|||
|
Direct Draw 1.0 only allowed the creation of one Direct Draw object per
|
|||
|
process. If your process happened to use another system component (such
|
|||
|
as Direct Play) that created a Direct Draw object, the process would be
|
|||
|
unable to create another Direct Draw object for its own use.
|
|||
|
|
|||
|
This restriction has been eliminated in this release. It is now possible
|
|||
|
for a process to call DirectDrawCreate as many times as necessary. A
|
|||
|
unique and independent interface will be returned from each call. Each
|
|||
|
DirectDraw object may be used as desired. There are no dependencies
|
|||
|
between the objects. They behave exactly as they would if they had been
|
|||
|
created by two different processes.
|
|||
|
|
|||
|
Since the Direct Draw objects are independent, surface, palette, and
|
|||
|
clipper objects which are created with a particular Direct Draw object
|
|||
|
should not be used with other Direct Draw objects. This is because these
|
|||
|
objects are automatically released when the Direct Draw object is
|
|||
|
destroyed. If they are used with another Direct Draw object, they
|
|||
|
may go away if the original object is destroyed.
|
|||
|
|
|||
|
Clipper objects which are created with DirectDrawClipperCreate are
|
|||
|
independent of any particular Direct Draw object and may be used with
|
|||
|
one or more Direct Draw objects.
|
|||
|
|
|||
|
|
|||
|
SetCooperativeLevel Doesn't Require an HWND for non-Exclusive Mode
|
|||
|
------------------------------------------------------------------
|
|||
|
Direct Draw 1.0 required an HWND to be specified in the SetCooperativeLevel
|
|||
|
call regardless of whether or not Full-screen Exclusive mode was being
|
|||
|
requested. This function no longer requires an HWND to be specified
|
|||
|
if the application is requesting DDSCL_NORMAL mode. It is now possible
|
|||
|
for an application to use Direct Draw with multiple windows. All of these
|
|||
|
windows may be used simultaneously in normal windowed mode.
|
|||
|
|
|||
|
|
|||
|
New IDirectDraw2 and IDirectDrawSurface2 interfaces
|
|||
|
---------------------------------------------------
|
|||
|
The COM model that Direct Draw uses specifies that additional functionality
|
|||
|
is provided by providing new interfaces. This release of Direct Draw
|
|||
|
implements a new Direct Draw interface and a new Direct Draw Surface
|
|||
|
interface. These new interfaces may be obtained by using QueryInterface
|
|||
|
as shown in the following code fragment:
|
|||
|
|
|||
|
/*
|
|||
|
* create an IDirectDraw2 interface
|
|||
|
*/
|
|||
|
LPDIRECTDRAW lpDD;
|
|||
|
LPDIRECTDRAW2 lpDD2;
|
|||
|
|
|||
|
ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
|
|||
|
if( ddrval != DD_OK )
|
|||
|
return;
|
|||
|
|
|||
|
ddrval = lpDD->SetCooperativeLevel( hwnd, DDSCL_NORMAL );
|
|||
|
if( ddrval != DD_OK )
|
|||
|
return;
|
|||
|
|
|||
|
|
|||
|
ddrval = lpDD->QueryInterface( IID_IDirectDraw2, (LPVOID *)&lpDD2);
|
|||
|
if( ddrval != DD_OK )
|
|||
|
return;
|
|||
|
|
|||
|
|
|||
|
ddscaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
|
|||
|
ddrval = lpDD2->GetAvailableVidMem(&ddscaps, &total, &free);
|
|||
|
if( ddrval != DD_OK )
|
|||
|
return;
|
|||
|
|
|||
|
This code fragment shows C++ syntax for creating an IDirectDraw interface
|
|||
|
and then using QueryInterface to create an IDirectDraw2 interface. It is
|
|||
|
this interface which contains the GetAvailableVidMem function. An attempt
|
|||
|
to use the GetAvailableVidMem function from an IDirectDraw interface will
|
|||
|
result in a compile-time error.
|
|||
|
|
|||
|
The IDirectDraw2 interface contains all of the same member functions as the
|
|||
|
IDirectDraw interface along with one additional member functions called
|
|||
|
GetAvailableVidMem. The SetDisplayMode function in this interface will
|
|||
|
allow refresh rates to be specified. This is not enabled for this beta and
|
|||
|
this function will return DDERR_UNSUPPORTED. The SetDisplayMode function
|
|||
|
in the IDirectDraw interface can be used instead.
|
|||
|
|
|||
|
The IDirectDrawSurface2 interface contains all of the same member functions
|
|||
|
as the IDirectDrawSurface interface with two additional member functions
|
|||
|
called PageLock and PageUnlock. The following code fragment shows how to
|
|||
|
create an IDirectDrawSurface2 interface:
|
|||
|
|
|||
|
LPDIRECTDRAWSURFACE lpSurf;
|
|||
|
LPDIRECTDRAWSURFACE2 lpSurf2;
|
|||
|
|
|||
|
// Create surfaces
|
|||
|
memset( &ddsd, 0, sizeof( ddsd ) );
|
|||
|
ddsd.dwSize = sizeof( ddsd );
|
|||
|
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
|
|||
|
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN |
|
|||
|
DDSCAPS_SYSTEMMEMORY;
|
|||
|
ddsd.dwWidth = 10;
|
|||
|
ddsd.dwHeight = 10;
|
|||
|
|
|||
|
ddrval = lpDD2->CreateSurface( &ddsd, &lpSurf, NULL );
|
|||
|
if( ddrval != DD_OK )
|
|||
|
return;
|
|||
|
|
|||
|
ddrval = lpSurf->QueryInterface( IID_IDirectDrawSurface2, (LPVOID *)&lpSurf2);
|
|||
|
if( ddrval != DD_OK )
|
|||
|
return;
|
|||
|
|
|||
|
ddrval = lpSurf2->PageLock( 0 );
|
|||
|
if( ddrval != DD_OK )
|
|||
|
return;
|
|||
|
|
|||
|
ddrval = lpSurf2->PageUnlock( 0 );
|
|||
|
if( ddrval != DD_OK )
|
|||
|
return;
|
|||
|
|
|||
|
|
|||
|
New PageLock and PageUnlock functions
|
|||
|
-------------------------------------
|
|||
|
A new feature that is supported with this release is the capability for
|
|||
|
DirectDraw to allow a driver to control the blitting to or from a system
|
|||
|
memory surface. A driver may choose to do this blitting by copying the
|
|||
|
bytes one by one or by using DMA transfers. If the driver uses a DMA
|
|||
|
transfer, it is important that the system memory which contains the bits
|
|||
|
for the surface is locked so that it cannot be paged out while the DMA is
|
|||
|
in progress. This can be done using the PageLock and PageUnlock functions
|
|||
|
available in the IDirectDrawSurface2 interface.
|
|||
|
|
|||
|
HRESULT PageLock( LPDIRECTDRAWSURFACE lpddSurf, DWORD dwFlags );
|
|||
|
HRESULT PageUnlock( LPDIRECTDRAWSURFACE lpddSurf, DWORD dwFlags );
|
|||
|
|
|||
|
There are no flags currently defined for these functions so the only valid
|
|||
|
value for dwFlags is 0. This function may be called on a vram surface but
|
|||
|
it will simply return DD_OK without doing anything. If called on a Sytem
|
|||
|
Memory surface (ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY is nonzero) then all
|
|||
|
of the memory pages used by this surface will be locked so that they can<61>t
|
|||
|
be paged out. A Lock count is maintained for each surface and incremented
|
|||
|
each time PageLock is called for that surface. The count is decremented
|
|||
|
when PageUnlock is called. When the count reaches 0, the memory is unlocked
|
|||
|
and may then be paged by the operating system. Note that the performance
|
|||
|
of the operating system may be negatively affected if too much memory is
|
|||
|
locked.
|
|||
|
|
|||
|
The following codes may be returned from these two functions:
|
|||
|
DD_OK
|
|||
|
DDERR_INVALIDOBJECT
|
|||
|
DDERR_INVALIDPARAMS
|
|||
|
DDERR_SURFACE_LOCK
|
|||
|
DDERR_CANTPAGELOCK
|
|||
|
|
|||
|
|
|||
|
Driver can now Blit to and from System Memory surfaces
|
|||
|
------------------------------------------------------
|
|||
|
In DirectDraw 1.0, if a surface was in system memory, the HEL automatically
|
|||
|
performed the blit. Some display cards have DMA hardware which allows them
|
|||
|
to efficiently blit to and from system memory surfaces. The DDCAPS
|
|||
|
structure has been expanded to allow drivers to report this capability.
|
|||
|
The following fields have been added.
|
|||
|
|
|||
|
DWORD dwSVBCaps
|
|||
|
DWORD dwSVBCKeyCaps
|
|||
|
DWORD dwSVBFXCaps
|
|||
|
DWORD dwSVBRops[DD_ROP_SPACE]
|
|||
|
|
|||
|
DWORD dwVSBCaps
|
|||
|
DWORD dwVSBCKeyCaps
|
|||
|
DWORD dwVSBFXCaps
|
|||
|
DWORD dwVSBRops[DD_ROP_SPACE]
|
|||
|
|
|||
|
DWORD dwSSBCaps
|
|||
|
DWORD dwSSBCKeyCaps
|
|||
|
DWORD dwSSBFXCaps
|
|||
|
DWORD dwSSBRops[DD_ROP_SPACE]
|
|||
|
|
|||
|
The SVB prefix indicates capabilities bits that relate to System memory to
|
|||
|
Video memory Blits. The VSB prefix indicates capabilities bits that relate
|
|||
|
to Video memory to System memory Blits. The SSB prefix indicates
|
|||
|
capabilities bits that relate to System memory to System memory Blits.
|
|||
|
|
|||
|
The dwSVBCaps field corresponds to the dwCaps field except that it describes
|
|||
|
the blitting capabilities of the display driver for System Memory to Video
|
|||
|
Memory blits. Likewise, the dwSVBCKeyCaps corresponds to the dwCKeyCaps
|
|||
|
field and dwSVBFXCaps corresponds to dwFXCaps. The dwSVBRops array describes
|
|||
|
the raster ops that the driver supports for this type of blit.
|
|||
|
|
|||
|
These fields are only valid if the DDCAPS_CANBLTSYSMEM bit is set in dwCaps
|
|||
|
indicating that the driver is able to blit to or from system memory.
|
|||
|
|
|||
|
If the system memory surface being used by the hardware blitter is not
|
|||
|
locked, Direct Draw will automatically call PageLock on the surface to insure
|
|||
|
that the memory has been locked.
|
|||
|
|
|||
|
|
|||
|
DirectDraw Palette Objects
|
|||
|
==========================
|
|||
|
|
|||
|
Setting Palettes on Non-Primary surfaces
|
|||
|
----------------------------------------
|
|||
|
In DirectDraw 1.0 palettes could only be attached to the primary surface.
|
|||
|
Palettes can now be attached to any palletized surface (primary, back
|
|||
|
buffer, offscreen plain or texture map). Only those palettes attached
|
|||
|
to primary surfaces will have any effect on the system palette. In it
|
|||
|
important to note that DirectDraw blits never perform color conversion -
|
|||
|
any palettes attached to the source or destination surface of a blit are
|
|||
|
ignored. Furthermore, the DirectDraw surface function GetDC() also ignores
|
|||
|
any DirectDraw palette selected into the surface.
|
|||
|
|
|||
|
Non-primary surface palettes are intended for use by applications or
|
|||
|
Direct3D (or other 3D renderer).
|
|||
|
|
|||
|
Sharing Palettes
|
|||
|
----------------
|
|||
|
Palettes can now be shared between multiple surfaces. The same palette
|
|||
|
can be set on the front and back buffer of a flipping chain or shared
|
|||
|
between multiple texture surfaces. When a palette is attached to a
|
|||
|
surface with SetPalette(), the surface increments the reference count
|
|||
|
of that palette. When the reference count of the surface reaches zero
|
|||
|
it will decrement the reference count of the attached palette. In
|
|||
|
addition, if a palette is detached from a surface by calling SetPalette()
|
|||
|
with a NULL palette interface pointer, the reference count of the
|
|||
|
surface's palette will be decremented. Please note that if SetPalette()
|
|||
|
is called several times consecutively for the same surface with the
|
|||
|
same palette the reference count for the palette will be incremented
|
|||
|
once only. Subsequent calls will not effect the palette<74>s reference count.
|
|||
|
|
|||
|
New Palette Types
|
|||
|
-----------------
|
|||
|
In additional to the 8-bit (256 entry) palettes supported previously,
|
|||
|
DirectDraw 2.0 supports 1-bit (2 entry), 2-bit (4 entry) and 4-bit
|
|||
|
(16 entry) palettes. Such palettes can by created by specifying one of
|
|||
|
the new palette capability flags; DDPCAPS_1BIT, DDPCAPS_2BIT and
|
|||
|
DDPCAPS_4BIT. Matching capability flags have been added for surface
|
|||
|
pixel formats (DDPF_PALETTEINDEXED1, DDPF_PALETTEINDEXED2 and
|
|||
|
DDPF_PALETTEINDEXED4). A palette can only be attached to a surface with
|
|||
|
a matching pixel format. For example, a 2 entry palette created with the
|
|||
|
DDPCAPS_1BIT flag can only be attached to a 1-bit surface created with
|
|||
|
the pixel format flag DDPF_PALETTEINDEXED1 etc. Furthermore, it is now
|
|||
|
possible to create indexed palettes. An indexed palette is one whose
|
|||
|
entries do not hold RGB colors but integer indices into the array of
|
|||
|
PALETTEENTRYs of some target palette. An indexed palette's color table
|
|||
|
is an array of 2, 4, 16 or 256 bytes where each byte is an index into
|
|||
|
some unspecified, destination palette.
|
|||
|
|
|||
|
To create an indexed palette specify the palette capability flag
|
|||
|
DDPCAPS_8BITENTRIES when calling CreatePalette(). For example, to
|
|||
|
create a 4-bit, indexed palette specify DPCAPS_4BIT | DDPCAPS_8BITENTRIES.
|
|||
|
When creating an indexed palette a pointer to an array of BYTEs is passed
|
|||
|
rather than a pointer to an array of PALETTEENTRY structures. The pointer
|
|||
|
to the array of BYTEs must be cast to an LPPALETTEENTRY when calling
|
|||
|
CreatePalette().
|
|||
|
|
|||
|
DirectDraw Clipper Objects
|
|||
|
==========================
|
|||
|
|
|||
|
Sharing Clippers
|
|||
|
----------------
|
|||
|
Clippers can now be shared between multiple surfaces. For example, the
|
|||
|
same clipper can be set on both the front and back buffers of a flipping
|
|||
|
chain. When a clipper is attached to a surface with SetClipper(), the
|
|||
|
surface increments the reference count of that clipper. When the reference
|
|||
|
count of the surface reaches zero it will decrement the reference count
|
|||
|
of the attached clipper. In addition, if a clipper is detached from a
|
|||
|
surface by calling SetClipper() with a NULL clipper interface pointer,
|
|||
|
the reference count of the surface's clipper will be decremented.
|
|||
|
|
|||
|
Please note that if SetClipper() is called several times consecutively
|
|||
|
for the same surface with the same clipper the reference count for the
|
|||
|
clipper will be incremented once only. Subsequent calls will not
|
|||
|
effect the clipper's reference count.
|
|||
|
|
|||
|
Driver Independent Clippers
|
|||
|
---------------------------
|
|||
|
It is now possible to create clipper objects which are not owned by a
|
|||
|
DirectDraw driver object. Such clippers can be shared across multiple
|
|||
|
driver objects. Driver independent clipper objects are created with
|
|||
|
the new DirectDraw API function DirectDrawCreateClipper(). This function
|
|||
|
can be called before any DirectDraw driver objects are created. As these
|
|||
|
clippers are not owned by any DirectDraw driver object, they are not
|
|||
|
automatically released when an application's driver objects are released.
|
|||
|
If not released explicitly by the application such clippers will be
|
|||
|
released by DirectDraw when the application terminates.
|
|||
|
|
|||
|
It is still possible to create clippers with the DirectDraw interface
|
|||
|
member function CreateClipper(). Such clippers behave identically to
|
|||
|
the clippers of DirectDraw 1.0. Specifically they will be automatically
|
|||
|
released when the driver object from which they were created is released.
|
|||
|
|
|||
|
Enhanced Surface Format Support in the Hardware Emulation Layer (HEL)
|
|||
|
=====================================================================
|
|||
|
|
|||
|
In DirectDraw 1.0 the Hardware Emulation Layer (HEL) could only create
|
|||
|
surfaces whose pixel format exactly matched that of the current primary
|
|||
|
surface. This restriction has been relaxed for DirectDraw 2.0.
|
|||
|
|
|||
|
The HEL now supports the following pixel formats for offscreen plain
|
|||
|
surfaces.
|
|||
|
|
|||
|
Pixel Format Flags Bit Depth Red Mask Green Mask Blue Mask Alpha Mask
|
|||
|
DDPF_RGB | DDPF_PALETTEINDEXED1 1 0x00000000 0x00000000 0x00000000 0x00000000
|
|||
|
DDPF_RGB | DDPF_PALETTEINDEXED2 2 0x00000000 0x00000000 0x00000000 0x00000000
|
|||
|
DDPF_RGB | DDPF_PALETTEINDEXED4 4 0x00000000 0x00000000 0x00000000 0x00000000
|
|||
|
DDPF_RGB | DDPF_PALETTEINDEXED8 8 0x00000000 0x00000000 0x00000000 0x00000000
|
|||
|
DDPF_RGB 16 0x0000F800 0x000007E0 0x0000001F 0x00000000
|
|||
|
DDPF_RGB 16 0x00007C00 0x000003E0 0x0000001F 0x00000000
|
|||
|
DDPF_RGB 24 0x00FF0000 0x0000FF00 0x000000FF 0x00000000
|
|||
|
DDPF_RGB 24 0x000000FF 0x0000FF00 0x00FF0000 0x00000000
|
|||
|
DDPF_RGB 32 0x00FF0000 0x0000FF00 0x000000FF 0x00000000
|
|||
|
DDPF_RGB 32 0x000000FF 0x0000FF00 0x00FF0000 0x00000000
|
|||
|
|
|||
|
In addition to supporting a wider range of offscreen surface formats the
|
|||
|
HEL also supports surfaces intended for use by Direct3D (or other 3D
|
|||
|
renders). These surfaces are discussed in the next section.
|
|||
|
|
|||
|
Support for 3D Surfaces
|
|||
|
=======================
|
|||
|
|
|||
|
Support for surfaces specific to 3D rendering has been enhanced in
|
|||
|
DirectDraw 2.0. The 3D specific surface types; texture maps, mipmaps
|
|||
|
and Z-buffers will be discussed below.
|
|||
|
|
|||
|
Texture Maps
|
|||
|
------------
|
|||
|
The surface capability flag used to indicate that a surface is a texture
|
|||
|
is DDSCAPS_TEXTURE. This flag was previously DDSCAPS_TEXTUREMAP but was
|
|||
|
modified for consistency with Direct3D. Texture maps can now be allocated
|
|||
|
in system memory using the HEL. To allocate a texture map surface specify
|
|||
|
the DDSCAPS_TEXTURE flag in the ddsCaps field of the surface description
|
|||
|
passed to CreateSurface(). A wide range of texture pixel formats are
|
|||
|
supported by the HEL. These formats are as follows:
|
|||
|
|
|||
|
Pixel Format Flags Bit Depth Red Mask Green Mask Blue Mask Alpha Mask
|
|||
|
DDPF_RGB | DDPF_PALETTEINDEXED1, 1 0x00000000 0x00000000 0x00000000 0x00000000
|
|||
|
DDPF_RGB | DDPF_PALETTEINDEXED1 |
|
|||
|
DDPF_PALETTEINDEXEDTO8 1 0x00000000 0x00000000 0x00000000 0x00000000
|
|||
|
DDPF_RGB | DDPF_PALETTEINDEXED2 2 0x00000000 0x00000000 0x00000000 0x00000000
|
|||
|
DDPF_RGB | DDPF_PALETTEINDEXED2 |
|
|||
|
DDPF_PALETTEINDEXEDTO8 2 0x00000000 0x00000000 0x00000000 0x00000000
|
|||
|
DDPF_RGB | DDPF_PALETTEINDEXED4 4 0x00000000 0x00000000 0x00000000 0x00000000
|
|||
|
DDPF_RGB | DDPF_PALETTEINDEXED4 |
|
|||
|
DDPF_PALETTEINDEXEDTO8 4 0x00000000 0x00000000 0x00000000 0x00000000
|
|||
|
DDPF_RGB | DDPF_PALETTEINDEXED8 8 0x00000000 0x00000000 0x00000000 0x00000000
|
|||
|
DDPF_RGB, 8 0x000000E0 0x0000001C 0x00000003 0x00000000
|
|||
|
DDPF_RGB | DDPF_ALPHAPIXELS, 16 0x00000F00 0x000000F0 0x0000000F 0x0000F000
|
|||
|
DDPF_RGB, 16 0x0000F800 0x000007E0 0x0000001F 0x00000000
|
|||
|
DDPF_RGB, 16 0x0000001F 0x000007E0 0x0000F800 0x00000000
|
|||
|
DDPF_RGB, 16 0x00007C00 0x000003E0 0x0000001F 0x00000000
|
|||
|
DDPF_RGB | DDPF_ALPHAPIXELS, 16 0x00007C00 0x000003E0 0x0000001F 0x00008000
|
|||
|
DDPF_RGB, 24 0x00FF0000 0x0000FF00 0x000000FF 0x00000000
|
|||
|
DDPF_RGB, 24 0x000000FF 0x0000FF00 0x00FF0000 0x00000000
|
|||
|
DDPF_RGB, 32 0x00FF0000 0x0000FF00 0x000000FF 0x00000000
|
|||
|
DDPF_RGB, 32 0x000000FF 0x0000FF00 0x00FF0000 0x00000000
|
|||
|
DDPF_RGB | DDPF_ALPHAPIXELS, 32 0x00FF0000 0x0000FF00 0x000000FF 0xFF000000
|
|||
|
DDPF_RGB | DDPF_ALPHAPIXELS, 32 0x000000FF 0x0000FF00 0x00FF0000 0xFF000000
|
|||
|
|
|||
|
The above formats are those which can be created by the HEL in system
|
|||
|
memory. The DirectDraw driver for a 3D accelerated video card is free to
|
|||
|
create textures of other formats in video memory. Such a driver should
|
|||
|
export the DDSCAPS_TEXTURE bit to indicate that it can create textures
|
|||
|
and should be prepared to handle the DirectDraw HAL callback,
|
|||
|
CanCreateSurface() to verify that the surface description for a texture
|
|||
|
map is one the driver is prepared to create.
|
|||
|
|
|||
|
Mipmaps
|
|||
|
-------
|
|||
|
DirectDraw 2.0 supports mipmapped texture surfaces. A mipmap is a
|
|||
|
sequence of textures, each of which is a progressively lower resolution,
|
|||
|
pre-filtered representation of the same image. Mipmaps are a
|
|||
|
computationally low cost way of improving the quality of rendered textures.
|
|||
|
Each pre-filtered image (or level) in the mipmap is a power of two
|
|||
|
smaller than the previous level. In DirectDraw 2.0 mipmaps are represented
|
|||
|
as a chain of attached surfaces. The highest resolution texture is at the
|
|||
|
head of the chain and has, as an attachment, the next level of the mipmap
|
|||
|
which has, in turn, an attachment which is the next level in the mipmap
|
|||
|
and so on down to the lowest resolution level of the mipmap.
|
|||
|
|
|||
|
To create a surface representing a single level of a mipmap specify the
|
|||
|
DDSCAPS_MIPMAP surface capability in the surface description passed to
|
|||
|
CreateSurface(). As all mipmaps are also textures the DDSCAPS_TEXTURE
|
|||
|
capability must also be specified. It is possible to create each level
|
|||
|
manually and build the chain with AddAttachedSurface(). However,
|
|||
|
CreateSurface() can be used to build an entire mipmap chain in a single
|
|||
|
operation. The following code fragment demonstrates building a chain
|
|||
|
of five mipmap levels of sizes 256x256, 128x128, 64x64, 32x32 and 16x16.
|
|||
|
|
|||
|
DDSURFACEDESC ddsd;
|
|||
|
LPDIRECTDRAWSURFACE lpDDMipMap;
|
|||
|
ZeroMemory(&ddsd, sizeof(ddsd));
|
|||
|
ddsd.dwSize = sizeof(ddsd);
|
|||
|
ddsd.dwFlags = DDSD_CAPS | DDSD_MIPMAPCOUNT;
|
|||
|
ddsd.dwMipMapCount = 5;
|
|||
|
ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP |
|
|||
|
DDSCAPS_COMPLEX;
|
|||
|
ddsd.dwWidth = 256UL;
|
|||
|
ddsd.dwHeight = 256UL;
|
|||
|
|
|||
|
ddres = lpDD->CreateSurface(&ddsd, &lpDDMipMap);
|
|||
|
if (FAILED(ddres))
|
|||
|
...
|
|||
|
|
|||
|
It is permissible to omit the number of mipmaps levels, in which case
|
|||
|
CreateSurface() will create a chain of surfaces each a power of two
|
|||
|
smaller than the previous one down to the smallest possible size. It is
|
|||
|
also possible to omit the width and height in which case CreateSurface()
|
|||
|
will create the number of levels you specify with a minimum level size of
|
|||
|
1x1.
|
|||
|
|
|||
|
A chain of mipmap surfaces is traversed using GetAttachedSurface()
|
|||
|
specifying the DDSCAPS_MIPMAP and DDSCAPS_TEXTURE capability flags. The
|
|||
|
following code fragment traverses a mipmap chain from highest to lowest
|
|||
|
resolutions.
|
|||
|
|
|||
|
LPDIRECTDRAWSURFACE lpDDLevel, lpDDNextLevel;
|
|||
|
DDSCAPS ddsCaps;
|
|||
|
|
|||
|
lpDDLevel = lpDDMipMap;
|
|||
|
lpDDLevel->AddRef();
|
|||
|
ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
|
|||
|
ddres = DD_OK;
|
|||
|
while (ddres == DD_OK)
|
|||
|
{
|
|||
|
// Process this level
|
|||
|
...
|
|||
|
ddres = lpDDLevel->GetAttachedSurface(&ddsCaps,
|
|||
|
&lpDDNextLevel);
|
|||
|
lpDDLevel->Release();
|
|||
|
lpDDLevel = lpDDNextLevel;
|
|||
|
}
|
|||
|
if ((ddres != DD_OK) && (ddres != DDERR_NOTFOUND))
|
|||
|
...
|
|||
|
|
|||
|
It is also possible to build flippable chains of mipmaps. In this
|
|||
|
scenario each mipmap level has an associated chain of back buffer
|
|||
|
texture surfaces. Each back buffer texture is attached to one level
|
|||
|
of the mipmap. Only the front buffer in the chain has DDSCAPS_MIPMAP
|
|||
|
set, the others are simply texture maps (DDSCAPS_TEXTURE). A mipmap
|
|||
|
level can have two attached texture maps, one with the capability flag
|
|||
|
DDSCAPS_MIPMAP set, which is the next level in the mipmap chain, and one
|
|||
|
with the capability flag DDSCAPS_BACKBUFFER set, which is back buffer
|
|||
|
of the flippable chain. Note that all the surfaces in each flippable
|
|||
|
chain must be of the same size.
|
|||
|
|
|||
|
It is not possible to build such a surface arrangement with a single
|
|||
|
call to CreateSurface(). To construct a flippable mipmap either build
|
|||
|
a complex mipmap chain and manually attach backbuffers with
|
|||
|
AddAttachedSurface() or create a sequence of flippable chains and
|
|||
|
build the mipmap with AddAttachedSurface().
|
|||
|
|
|||
|
It is important to note that blit operations apply to only a single
|
|||
|
level in the mipmap chain. To blit an entire chain of mipmaps each
|
|||
|
level must be blit separately. Also note that Flip()will not currently
|
|||
|
flip an entire mipmap chain but only a single level of the mipmap. This
|
|||
|
is a defect and will be corrected.
|
|||
|
|
|||
|
Z Buffers
|
|||
|
---------
|
|||
|
The DirectDraw HEL can now create Z buffers for use by Direct3D (or
|
|||
|
other 3D rendering software). The HEL supports both 16 and 32-bit
|
|||
|
Z buffers. The DirectDraw driver for a 3D accelerated video card can
|
|||
|
permit the creation of Z buffers in video memory by exporting the surface
|
|||
|
capability bit DDSCAPS_ZBUFFER. It should also specify the Z buffer
|
|||
|
depths it supports using the dwZBufferBitDepth field of the DDCAPS
|
|||
|
structure.
|
|||
|
|
|||
|
Z buffers can be cleared using the DirectDraw surface function Blt().
|
|||
|
A new DDBLT_ flag (DDBLT_DEPTHFILL) has been defined to indicate that
|
|||
|
the blit is a Z buffer clear. If this flag is specified the DDBLTFX
|
|||
|
structure passed to Blt() should have its dwFillDepth field set to
|
|||
|
the required Z depth. If the DirectDraw driver for a 3D accelerated
|
|||
|
video card wishes to provide support for Z buffer clearing in hardware
|
|||
|
it should export the capability flag DDCAPS_BLTDEPTHFILL and should
|
|||
|
have code to handle DDBLT_DEPTHFILL blits. The destination surface
|
|||
|
of a depth fill blit must be a Z buffer. Please note that the actual
|
|||
|
interpretation of depth value is 3D renderer specific.
|
|||
|
|
|||
|
Direct3D Integration
|
|||
|
====================
|
|||
|
|
|||
|
DirectDraw 2.0 is very tightly integrated with Direct3D. The most
|
|||
|
important aspects of this integration are discussed below.
|
|||
|
|
|||
|
The Direct3D Driver Interface
|
|||
|
-----------------------------
|
|||
|
DirectDraw 2.0 presents a single, unified driver object to the
|
|||
|
application programmer. This driver object encapsulates both
|
|||
|
DirectDraw and Direct3D state. The DirectDraw driver COM interfaces
|
|||
|
(IID_IDirectDraw or IID_IDirectDraw2) and the Direct3D driver COM interface
|
|||
|
(IID_IDirect3D) are both interfaces which allow the application programmer
|
|||
|
to communicate with the same underlying driver object. Hence no Direct3D
|
|||
|
driver object is created. Rather a Direct3D interface to the DirectDraw
|
|||
|
driver object is obtained. This is achieved using the standard COM
|
|||
|
QueryInterface() function.
|
|||
|
|
|||
|
The following code fragment demonstrates creating the DirectDraw driver
|
|||
|
object and obtaining a Direct3D interface for communicating with that object.
|
|||
|
|
|||
|
LPDIRECTDRAW lpDD;
|
|||
|
LPDIRECT3D lpD3D;
|
|||
|
ddres = DirectDrawCreate(NULL, &lpDD, NULL);
|
|||
|
if (FAILED(ddres))
|
|||
|
...
|
|||
|
ddres = lpDD->QueryInterface(IID_IDirect3D, &lpD3D);
|
|||
|
if (FAILED(ddres))
|
|||
|
...
|
|||
|
|
|||
|
The above code creates a single object and obtains two interfaces to
|
|||
|
that object. Hence, the reference count of the driver object after the
|
|||
|
QueryInterface() is two. The important implication of this is that the
|
|||
|
lifetime of the Direct3D driver state is the same as that of the DirectDraw
|
|||
|
object. Releasing the Direct3D interface does not destroy the Direct3D
|
|||
|
driver state. That state is not destroyed until all references (both
|
|||
|
DirectDraw and Direct3D) to that driver object have been released.
|
|||
|
Hence, if you release a Direct3D interface, while holding a reference
|
|||
|
to a DirectDraw driver interface, and then re-query the Direct3D
|
|||
|
interface all the Direct3D state will be preserved.
|
|||
|
|
|||
|
The Direct3D Device Interface
|
|||
|
-----------------------------
|
|||
|
As with the driver object, there is no distinct Direct3D device object.
|
|||
|
A Direct3D device is simply an interface for communicating with a
|
|||
|
DirectDraw surface used as a 3D rendering target. For example, the
|
|||
|
following code fragment creates a Direct3D device interface to a
|
|||
|
DirectDraw surface object.
|
|||
|
|
|||
|
LPDIRECTDRAWSURFACE lpDDSurface;
|
|||
|
LPDIRECT3DDEVICE lpD3DDevice;
|
|||
|
|
|||
|
ddres = lpDD->CreateSurface(&ddsd, &lpDDSurface, NULL);
|
|||
|
if (FAILED(ddres))
|
|||
|
...
|
|||
|
ddres = lpDDSurface->QueryInterface(lpGuid, &lpD3DDevice);
|
|||
|
if (FAILED(ddres))
|
|||
|
...
|
|||
|
|
|||
|
The same rules of reference counting and state lifetime discussed for
|
|||
|
driver objects apply to DirectDraw surfaces and Direct3D devices.
|
|||
|
Additionally, multiple, distinct Direct3D device interfaces can be
|
|||
|
obtained for the same DirectDraw surface. Hence, it is possible that
|
|||
|
a single DirectDraw surface be the target for both a ramp based device
|
|||
|
and an RGB based device.
|
|||
|
|
|||
|
The Direct3D Texture Interface
|
|||
|
------------------------------
|
|||
|
Direct3D textures are, once again, not a distinct object type but
|
|||
|
rather another interface of DirectDraw surface objects. The following
|
|||
|
code fragment obtains a Direct3D texture interface from a DirectDraw
|
|||
|
surface object.
|
|||
|
|
|||
|
LPDIRECTDRAWSURFACE lpDDSurface;
|
|||
|
LPDIRECT3DTEXTURE lpD3DTexture;
|
|||
|
|
|||
|
ddres = lpDD->CreateSurface(&ddsd, &lpDDSurface, NULL);
|
|||
|
if (FAILED(ddres))
|
|||
|
...
|
|||
|
ddres = lpDDSurface->QueryInterface(IID_IDirect3DTexture,
|
|||
|
&lpD3DTexture);
|
|||
|
if (FAILED(ddres))
|
|||
|
...
|
|||
|
|
|||
|
The same reference counting and state lifetime rules of driver objects
|
|||
|
and devices apply. It is possible to use a single DirectDraw surface as
|
|||
|
both a rendering target and a texture.
|
|||
|
|
|||
|
The DirectDraw HEL and Direct3D
|
|||
|
-------------------------------
|
|||
|
The DirectDraw HEL has been enhanced to support the creation of texture,
|
|||
|
mipmap and Z buffer surfaces. Furthermore, due to the tight integration
|
|||
|
of DirectDraw and Direct3D, a DirectDraw enabled system will always
|
|||
|
provide Direct3D support (in software emulation at least). Hence, the
|
|||
|
DirectDraw HEL exports the DDCAPS_3D capability flag to indicate the
|
|||
|
availability of Direct3D in software emulation. A DirectDraw driver for
|
|||
|
a hardware accelerated 3D video card should export this capability flag
|
|||
|
to indicate the presence of hardware accelerated 3D.
|
|||
|
|
|||
|
GetAvailableVidMem
|
|||
|
==================
|
|||
|
DirectDraw 2.0 adds a new DirectDraw interface function to query the
|
|||
|
amount of video memory available to a specific type of surface as
|
|||
|
defined by surface capability flags. To ensure COM compliance this
|
|||
|
function is not a member of the DirectDraw 1.0 interface but is part
|
|||
|
of the new DirectDraw 2.0 interface, IID_IDirectDraw2. To invoke this
|
|||
|
function you must first query for the new DirectDraw interface.
|
|||
|
|
|||
|
The following code fragment demonstrates using GetAvailableVidMem()
|
|||
|
to determine both the total and free video memory available for
|
|||
|
texture map surfaces.
|
|||
|
|
|||
|
LPDIRECTDRAW2 lpDD2;
|
|||
|
DDSCAPS ddsCaps;
|
|||
|
DWORD dwTotal;
|
|||
|
DWORD dwFree;
|
|||
|
|
|||
|
ddres = lpDD->QueryInterface(IID_IDirectDraw2, &lpDD2);
|
|||
|
if (FAILED(ddres))
|
|||
|
...
|
|||
|
ddsCaps.dwCaps = DDSCAPS_TEXTURE;
|
|||
|
ddres = lpDD2->GetAvailableVidMem(&ddsCaps, &dwTotal, &dwFree);
|
|||
|
if (FAILED(ddres))
|
|||
|
...
|
|||
|
|
|||
|
It should be noted that this function gives a snapshot of the current
|
|||
|
video memory state only. The amount of free video memory is subject to
|
|||
|
change as surfaces are created and released. Hence, the free memory
|
|||
|
figure should be used as a rough guide only. In addition, a particular
|
|||
|
video card may make no distinction between two different memory types.
|
|||
|
For example, it may use the same portion of video memory to store Z
|
|||
|
buffers and textures. Hence, allocating one type of surface (a Z buffer
|
|||
|
say) may affect the amount of video memory available for another type
|
|||
|
of surface (textures say). Therefore, it is best to first allocate an
|
|||
|
application's fixed resources (such as front, back and Z buffer) before
|
|||
|
determining how much memory is available for dynamic use (for texture
|
|||
|
mapping, for example).
|
|||
|
|
|||
|
Miscellaneous Changes
|
|||
|
=====================
|
|||
|
|
|||
|
New Error Return Codes
|
|||
|
----------------------
|
|||
|
DDERR_NOMIPMAPHW - an attempt was made to create a mipmap in video
|
|||
|
memory but the hardware DirectDraw driver does not support mipmaps.
|
|||
|
|
|||
|
DDERR_INVALIDSURFACETYPE - an attempt was made to perform an operation
|
|||
|
on a surface but the capabilities of that surface do not support the
|
|||
|
operation.
|