Primary programming application by DirectDraw6 by Gamster H. S
Directory: 1. Environmental settings for VC. 2. Talking about COM. 3. DirectDraw is briefly described. 4. Primary programming application of DirectDraw.
The first article: VC environment setting. You have to set the environment variable value of the VC before making any DirectX programming. It is mainly convenient for future project design. I am using VC5 and DirectX6, this is my setting:
1. Select Options. 2. Select Directories Tab. 3. Select Include Files4 in the Show Directories FOR box. Select a new item in the Directories box, type C: / MSSDK / INCLUDE, this directory will contain all the relevant headers, such as: DDRAW.H, DSOUND.H, ... 5. Select Library Files6 in the Show Directories FOR box. Select a new item in the Directories box, type C: / MSSDK / LIB, this directory will contain all related library files, such as: ddraw.lib, dsound .lib, dxguid.lib, ... 7. Select OK
When you build a Microsoft program, the following is the basic steps:
1. The entire DDEX1 (C: / MSSDK / MultiMedia / DDRAW / DDRAW / SRC / DDEX1) directory COPY Copy to you is in your right directory (such as D: / MyDD /, a full name D: / MyDD / DDEX1). 2. Select New.3 in the VC5 menu item files. Select Win32 Application.4. Type the appropriate location (such as d: / mydd /). 5. Type suitable Project Name (here Ddex1) .6. Select menu item Project-> add to project-> files, add * .cpp file, *. RC file. In the DDEX1 project, you have to join Ddex1.cpp and DDEX1.RC files. 7. Select menu item Project-> Settings, add DDRaw.LibDxGuid.lib to Object / Library Modules in Link. 8. Build and run.9. Any prblems? You know where to find me!
Chapter II: Talking about COM. I am not clear, but not a few people are mixed. They either know the fur, or they are still in the OOP phase. Others ask, just say that DirectX3, 5, 6 uses many COM technology.
Third article: DirectDraw brief description. DirectX greatly enhances the use of hardware in the WIN environment. DirectDRAW improves the work of various display hardware.
Article 4: DirectDraw's primary programming application. This article will briefly describe the use of various DirectDraw APIs in DDEX1 to DDEX5, as for higher design purposes, I hope yourself slowly learn from others.
1. Global variables in the DirectDraw example.
File: // ---------------------------------------------- ------------------------------- // Global DataFile: // ------------ -------------------------------------------------- --------------- LPDIRECTDRAW4 g_pDD = NULL; // DirectDraw objectLPDIRECTDRAWSURFACE4 g_pDDSPrimary = NULL; // DirectDraw primary surfaceLPDIRECTDRAWSURFACE4 g_pDDSBack = NULL; // DirectDraw back surfaceLPDIRECTDRAWSURFACE4 g_pDDSOne = NULL; // Offscreen surface 1LPDIRECTDRAWPALETTE G_PDIRECTDRAWPALETTE G_PDDPAL = NULL; // The primary Surface PaletteBool g_bactive = false; // is Application Active? The above global variables are: 1) Object pointers for IDirectDraw4, respectively. Use it to establish several other global variables. 2) The object pointer of IDirectdrawSurfce4, here is 3: g_pddsprimary is a display buffer block for display; g_pddsback is behind the scenes display buffer block, from the rear screen buffer screenshot, fight this buffer On the block, then turn into a display buffer block, the original display buffer is turned into a backfinder display buffer block; g_pddsone is the rear screen buffer for storing different graphics materials. 3) The object pointer for iDirectdrawpalette is used to store a palette of a specific Bitmap. Use another variable and DirectDraw without any relationship. Just confirm that the program is in the operation. The above encoding has an explanation, so it is easy to understand anyone. Any problems? You know where to find me!
2. Initialize all full variables These original code I copled from the Static HRESULT INITAPP (Hinstance Hinstance, Int ncmdshow) function in Ddex5.cpp:
1) define a few local variables: DDSURFACEDESC2 ddsd; // the structure contain information about a particluar DirectDrawSurface DDSCAPS2 ddscaps; // this is important for further step HRESULT hRet; // error output LPDIRECTDRAW pDD; // IDirectDraw Object..
2) Set various objects:
/// // Create the main DirectDraw object /// hRet = DirectDrawCreate (NULL, & pDD, NULL); if (hRet = DD_OK!) Return InitFail (hWnd, hRet, "DirectDrawCreate FAILED"); to establish a IDirectDraw Object, HRET is equipped with a return value of DirectDrawCreate (). This trick is very useful. All DirectX functions returns a certain value, and the DirectDraw's function returns DD_OK to indicate that the function call is successful. The return value of DDERR _ *** indicates that the function call failed (or other reasons). Check the function return value to prepare the cloth will not be wrong. I will postpone the explanation of the initfail () function.
// fetch directdraw4 interface hret = pdd-> queryinterface (iid_idirectddraw4, (lpvoid *) & g_pdd); if (hret! = Dd_ok) Return Initfail (HWND, HRET, "Queryinterface Failed");
We applied for an iDirectdraw4 object with QueryInterface in COM, which is different from DirectX5, DirectDraw adds the IDirectDraw4 interface, which has added several more useful functions. You can find it from DirectX's help file. Although it is English, it is still harvested.
// Get exclusive mode hRet = g_pDD-> SetCooperativeLevel (hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); if (hRet = DD_OK!) Return InitFail (hWnd, hRet, "SetCooperativeLevel FAILED");
We will then set up the display method, you can set the full screen, or window type, or modex, the display mode used from DDEX1 to DDEX5 is DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN, full screen! You can find out the annotations about SetCoopeLevel () from the DirectX's help file. Although it is English, it is still harvested.
// set the video mode to 640x480x8 hret = g_pdd-> setDisplaymode (640, 480, 8, 0, 0); if (hret! = Dd_ok) Return INITFAIL (HWND, HRET, "SETDISPLAYMODE FAILED");
We will then set the screen size, pigment and refresh speed. You can find out the annotations for SetDisplayMode () from the DirectX's help file. Although it is English, it is still harvested. The display you set under full screen can be 320x200, 640x480, 800x600, 1024x768, 1280x1024, 1600x1280, etc. Pigment from 8, 16, 24, 32bits.
// Create the primary surface with 1 back buffer ZeroMemory (& ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; ddsd .dwBackBufferCount = 1; hRet = g_pDD-> CreateSurface (& ddsd, & g_pDDSPrimary, NULL); if (hRet = DD_OK!) return InitFail (hWnd, hRet, "CreateSurface FAILED"); // Get a pointer to the back buffer ddscaps. DWCAPS = DDSCAPS_BACKBUFFER; hret = g_pddsprimary-> getattachedsurface (& DDSCAPS, & g_pddsback; if (hret! = dd_ok) Return INITFAIL (HWND, HRET, "GetattachedSurface Failed");
Create a display buffer block with a piece of the screen display buffer block. First, you initialize the object of ddsurfacedesc2. as follows:
ZeromeMory (& DDSD, SIZEOF (DDSD); ddsd.dwsize = sizeof (ddsd); // you will fail without this !!
I have viewed the phenomenon that each DirectDraw structure contains DWSIZE members, must initialize this member as follows: ddstructobj.dwsize = sizeof (ddstructure); // you will fail without this !!
The following group is encoded
DDSD.DWFLAGS = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; DDSD.DDSCAPS.DWCAPS = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
Indicates that the DirectDrawSurface built is Primary Surface, FLIPABLE (back and forth), with the Back Buffer (behind the scenes) Connect to Primary Surface (Attached to).
DDSD.DWBACKBUFFERCOUNT = 1;
Represents only one after the Back Buffer (behind the scenes).
Hret = g_pdd-> createsssurface (& DDSD, & g_pddsprimary, null); if (hret! = dd_ok) Return Initfail (HWND, HRET, "CREATESURFACE FAILED");
// Get a pointer to the back buffer ddscaps.dwCaps = DDSCAPS_BACKBUFFER; hRet = g_pDDSPrimary-> GetAttachedSurface (& ddscaps, & g_pDDSBack); if (! HRet = DD_OK) return InitFail (hWnd, hRet, "GetAttachedSurface FAILED"); this coding section Establish a Primary Surface and establish the Back Buffer. At this time, our initial project is basically over!
3. Error handling. The process of incorrect in the initialization process is now introduced. Return INITFAIL (HWND, HRET, "... FAILED"); this means of use is that when a step initialization process error, the entire program exits and displays a dialog. It is defined as follows:
File: // ---------------------------------------------- ------------------------------- // name: initfail () // Desc: this function is called if an initialization function Failsfile: // ---------------------------------------------- ------------------------------ HRESULT INITFAIL (HWND HWND, HRESULT HRET, LPCTSTST SZERROR, ...) {Char SzBuff [128]; VA_LIST VL;
VA_Start (VL, Szerror); VSPrintf (SZBuff, Szerror, VL); ReleaseAllObjects (); MessageBox (hwnd, szbuff, title, mb_ok); DestroyWindow (hwnd); VA_END (VL); Return Hret;}
You have to write a RELAESEALLOBJECT () function that will release all DDRAW objects. One thing is worth this. If the object has already been released, the program is unknown, trying to release the object that does not exist will have serious consequences, be careful! ! ! !
File: // ---------------------------------------------- ------------------------------- // name: ReleaseAllObjects () // Desc: finished with all objects we use; release; THEMFILE: / / ---------------------------------------------- ------------------------------- Static void ReleaseAllObjects (void) {if (g_pdd! = null) {if (g_pddsprimary! = NULL) {g_pddsprimary-> release (); g_pddsprimary = null;} if (g_pddsone! = Null) {g_pddsone-> release (); g_pddsone = null;} if (g_pddpal! = Null) {g_pddpal-> release () G_pddpal = null;} g_pdd-> release (); g_pdd = null;}} Here, the program first releases the object of the idirectDraw4, and then releases IDirectDraw4 objects. Before released, the program first confirms if the object exists, such as the object retina in the village, release the object, and assigns the value of the object pointer Null.
4. How to recover temporary lost object values. After you press the Alt Tab button, the application switches each other. When you convert it from other applications to DirectDraw about applications, the original object buffer will be released by the I / O system during the handover process. Lost. To re-establish. Only the iDirectdrawsuface4 object under the iDirectdraw4 object is missing, so IDirectDrawSurface4 provides a restore () program. The way of use is as follows:
File: // ---------------------------------------------- ------------------------------- // name: restoreall () // desc: restore Lost ObjectsFile: // - -------------------------------------------------- -------------------------- HRESULT RESTOREALL (VOID) {HRESULT HRET
hret = g_pddsprimary-> restore (); if (hret == DD_OK) {hret = g_pddsone-> restore (); if (hret == dd_ok) {// Re-read Bitmap into memory. DDRELOADBITMAP ()}}
Return hret;
Generally, the loss of the DirectDrawsuface4 object will be the Bitmap contained in the object. Therefore, you want to use the DDRELOADBITMAP () function to read the memory from the Bitmap file. This function is stored in the ddutil.cpp file. Not part of DirectX. Let's take me how to use the functions in ddutil.cpp. 5. With DirectDraw Utilities !! In order to facilitate developers, beginners' confusion on DirectX, MS DirectX design group specially wrote a DDUTIL.CPP file to help everyone. It provides a convenient function to read Bitmap and assign the IDirectdrawSurface4 object, read the tone panel information from Bitmap, set transparencies. Defined as follows:
/ * ================================================================================================================================================================ ========================== * file: Ddutil.cpp * Content: Routines for Loading Bitmap and Palettes from resources ****** *********************************************************** ****************** /
#ifdef __cplusplusextern "c" {/ * Assume C Declarations for C * / # ENDIF / * __CPLUSPLUS * /
extern IDirectDrawPalette * DDLoadPalette (IDirectDraw4 * pdd, LPCSTR szBitmap); extern IDirectDrawSurface4 * DDLoadBitmap (IDirectDraw4 * pdd, LPCSTR szBitmap, int dx, int dy); extern HRESULT DDReLoadBitmap (IDirectDrawSurface4 * pdds, LPCSTR szBitmap); extern HRESULT DDCopyBitmap (IDirectDrawSurface4 * pdds, HBITMAP hbm, int x, int y, int dx, int dy); extern DWORD DDColorMatch (IDirectDrawSurface4 * pdds, COLORREF rgb); extern HRESULT DDSetColorKey (IDirectDrawSurface4 * pdds, COLORREF rgb);
#ifdef __cplusplus} #ENDIF / * __CPLUSPLUS * /
-> DDLoadPalette (iDirectDraw4 * PDD, LPCSTR SZBITMAP): Read the tuning board information from the Bitmap file and delivers this information to IDirectDraw4. 1) Parameter iDirectdraw4 * is the object pointer of iDirectDraw4. 2) Parameter LPCSTR is a full name of the Bitmap file. 3) Use example: g_pddpal = ddloadpalette (g_pdd, "c: ///HAN/Mybitmap1.bmp"); if (g_pddpal) g_pddsprimary-> setPalette (g_pddpal); 4) For details, please refer to DDEX3-5.cpp-> DDLoadBitmap (IDirectdraw4 * PDD, LPCSTR SZBITMAP, INT DX, INT DY): Create a IDirectdrawSurface4 object containing the specified Bitmap, first create an IDirectdrawsurface4 object sufficient to accommodate the specified Bitmap. Then read Bitmap into memory. 1) Parameter iDirectDraw4 * is an object pointer. 2) Parameter LPCSTR is a full name of the Bitmap file. 3) DX, DY represents the Bitmap size. 4) Use example: g_pddsone = ddloadbitmap (g_pdd, "c: ///HAN/Mybitmap.bmp", 640, 490); if (g_pddsone == null) {// Abort the program} 5) No example, more Try.
-> DDRELOADBITMAP (iDirectdrawSurface4 * PDDS, LPCSTR SZBITMAP): Read a bitmap into a specified IDirectdrawSurface4 object pointer. 1) Parameter iDirectdrawsurface4 * is an object pointer and will receive Bitmap. 2) Parameter LPCSTR is a full name of the Bitmap file. 3) Use example: hret = ddreloadbitmap (g_pddsone, "c: /////mybitmap.bmp"); if (failed (hret)) {// Abort the program.} 4) For details, please refer to Ddex3-5.cpp5 I use this function.
-> ddcopybitmap (iDirectdrawsurface4 * pdds, hbitmap hbm, int x, int y, int dx, int dy): you don't need to know.
-> DDColormatch (iDirectdrawsurface4 * pdds, colorref rgb): you don't need to know.
-> DDSetColorKey (IDirectDrawSurface4 * pdds, COLORREF rgb): Set a transparent Colorkey.1) parameters specified in the parameter object pointers IDirectDrawSurface4 IDirectDrawSurface4 * is the object pointer, the receiver, the value Colorkey ColorKey.2) COLORREF. 3) Use example: hret = ddreloadbitmap (g_pddsone, "c: /////mybitmap.bmp"); if (failed (hret)) {// Abort the program.} 4) For details, please refer to Ddex3-5.cpp5 I have a lot of functions. For more information about those functions, you better observe the examples Microsoft provided (DDEX1 - DDEX5) fordetails.It is the easy way All the implementations about those functions is in DDUTIL.CPP file..
6. BLIT, FLIP, & Color Fill. These three applications are the main application of DirectDraw. It functions for painting the Bitmap tile on the backbuffer, or fills in a certain color, turn it back to the screen. The function used is: 1>. BLT and BLTFast painted on the Bitmap tablet on Backbuffer.
File: // BLTFast Example; Rect RcRect;
RcRect.Left = 0; rcRect.top = 0; rcRect.right = 640; rcRect.bottom = 480;
while (1) {ddrval = g_pDDSBack-> BltFast (0, 0, g_pDDSOne, & rcRect, DDBLTFAST_WAIT); if (ddrval == DD_OK) {break;} else if (ddrval == DDERR_SURFACELOST) {// use the restore all function RESTOREAll ();}}
I usually use BLT function:
File: // BLT Example; Rect SrcRect = {0, 0, 640, 480}; Rect DSTRECT = {0, 0, 640, 480};
DDBLTFX Tempfx; // you will fail you don't have this! Tempfx.dwsize = sizeof (ddbltfx); // you will fail your don't have this!
while (1) {ddrval = g_pDDSBack-> Blt (dstRect, g_pDDSOne, srcRect, DDBLT_WAIT, & tempFX); if (ddrval == DD_OK) {break;} else if (ddrval == DDERR_SURFACELOST) {// use the restore all function ! RestoreAll ();} else if (! ddrval = DDERR_WASSTILLDRAWING) {break;}} to use a transparent color (COLORKEY), modified DDBLTFAST_WAIT (last parameter BltFast) was DDBLTFAST_WAIT | DDBLTFAST_SRCCOLORKEY reciprocal change DDBLT_WAIT (Blt second. Parameters) for DDBLT_WAIT | DDBLT_COLORSRC.
2. > Use BLT to fill the color on the backbuffer, (I have never succeeded).
Rect DSTRECT = {0, 0, 640, 480}; DDBLTFX Tempfx; // You will fail you don't have this! Tempfx.dwsize = sizeof (ddbltfx); // you will fail your don't have this ! Tempfx.dwfillcolor = RGB (0, 255, 0); // Green.
while (1) {ddrval = g_pDDSBack-> Blt (dstRect, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, & tempFX); if (ddrval == DD_OK) {break;} else if (ddrval == DDERR_SURFACELOST) {// use the restore All function! rest ();} else if (ddrval! = DDERR_WASSTILLDRAWING) {Break;}}
This example will be filled in the rectangular of DSTRECT (0, 0, 640, 480). The rectangular size and position are determined by the Rect object you define. Several weaknesses with BLT and BLTFAS are: 1) When DSTRECT is not consistent with SrcRect, BLT and BLTFAST will be very slow. 2) When the DSTRect part exceeds the screen, such as the screen size 640x480, you want to display the tile in the long square {500, 500, 800, 600}, this tile is not displayed, because the tile you define is outside the screen! The solution will be proposed in the Advanced Section.
3. > Using FLIP: Turn on the screen to the screen, the original Primar Surface becomes backbuffer. While (1) {ddrval = g_pddsprimary-> flip (null, ddflip_wait); if (ddrval == dd_ok) {Break;} Else if (DDRVAL == DDERR_SURFACELOST) {// Use the restore all function! rest ();} else if (ddrval! = DDERR_WASSTILLDRAWING) {Break;}} 4. Summary: 1) Establish a temporary iDirectDraw object. 2) Use QueryInterface in COM to establish IDirectDraw4 objects. 3) SetCooperativeElevel (Window or full screen). 4) SetDisplayMode (Screen size, chroma, refresh speed). 5) Establish Primary Surface, Back Buffer (behind the scene), and Off-Screen Sufaces (Alternate Display Memory, for Storage Chart). 6) Use the functions in the ddutil file to read Bitmap, set colorKey (when you do BLT operation, this color will not be displayed) .7) Use BLT and BLTFast to entert the tile into your back buffer, use flip to prepare Good Back buffer turns into primary surface. The original Primary Surface turned into back buffer, waiting for the next round of BLT and BLTFAST calls.
These are the basic operations in DirectDraw version 6! I will write a renewal (Advanced Section). Enjoy programming! Please ask questions, write let me or leave a message! Thank Doug Klopfenstein! His Basic DirectDraw Programming (Tan Weng compiled this article!) Give me a great help.