DIRCETDRAW C / C instructions
310CDT translation, I translated, I took it up and I took it.
This is a series of DirectDraw guides, teach you to build a simple DirectDraw application step by step. This guide uses a lot of DirectDraw provided by the SDK package. These examples show how to set up DirectDraw, how to use the DirectDraw method to implement a general task :
Note: The examples in these guidelines are written with C . If you are using the C compiler, make the appropriate changes to successfully compile. You need to add the VTABLE and this pointer to the interface method.
1.Directdraw basic usage
To use DirectDraw, you must first create a DirectDraw instance representing your computer's display interface. Then you can manipulate this object through the way. You may need to create one or more DirectDraw Object (DirectDraw Surface Object) Examples to display your app on the graphics device.
To demonstrate this, Ddex1 Sample (SDK root / Samples / MultiMedia / DDRAW / SRC / DDEX1) demonstrates the following steps:
STEP 1: Create a DirectDraw object to create an instance of a DirectDraw object, your application must use the DirectDrawCreateEx function in the initApp function, just like the routine DDEX1. DirectDrawCreateEx function includes 4 parameters. The first is: display device Global Unique Identification (GUID). In most cases, it is set to NULL, select the system default display device. The second parameter is: The address containing the pointer to the DirectDRAW object is established. The third parameter is the IDirectDraw7 interface Reference sign. Must be set to IID_IDirectDraw 7. The fourth parameter is set to null, which is prepared for future extensions. The following example shows how to create a DirectDraw object and determine whether it is successful .hret = DirectDrawCreateex (Null, (Void **) & g_pdd, IID_IDirectDraw7, null; if (hret == dd_ok) {// g_pdd is a valid DirectDraw object.} Else {// The DirectDraw Object Could NOT BE CREATED.}
Step2: Decision program behavior Before you change the display method, you must specify a DWFlags parameter (DDSCL_EXCLUSIVE and DDSCL_FULLSCREEN) at least in the iDirectdraw7 :: setCoopeRarativeEvel function. This way, your application has received all controls for display devices, others The program cannot share .DDSCL_FULLSCREEN Let your application run in full screen mode. Your program covers the desktop, and only your program can output on the screen. However, the desktop is still valid. (Switch by Alt Tab) desktop)
The following example demonstrates the usage of the SetCoopeLevel function. HRESULT HRET; LPDIRECTDRAW7 g_pdd; // already create by DirectDrawCreateex
hRet = g_pDD-> SetCooperativeLevel (hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); if (hRet = DD_OK!) {// Exclusive mode was successful.} else {// Exclusive mode was not successful // The application can still run, however.. }
If SetCoopeRATIVELEVEL does not return DD_OK, you can specify that DDSCL_NORMAL continues to run your program. However, your program is no longer exclusive mode, and you may not be able to complete some of your requirements. In this case, you'd better display one The dialog allows the user to decide whether to continue. If you set the full screen exclusive partnership, you must pass the program's window handle to SetCoopeRATIVELEVEL, so that Windows has the ability to determine if your program is extremely terminated. Step3: change the display mode Next, you can use the IDirectDraw7 :: setDisplayMode function to change the display mode. The following example will demonstrate how to set the display mode to 640 × 480 × 8 bits per pixel (bpp) .hResult hret; lpdirectdraw7 g_pdd; // already created by DirectDrawCreateex
Hret = g_pdd-> setDisplaymode (640, 480, 8, 0, 0); if (hret! = dd_ok) {// The display mode change successfully.} else {// the display mode cannot be change. // the mode ModeD. // THE MODE IS Either NOT Supported OR // Another Application Has Exclusive Mode.}
When you set up the display mode, you should determine if the user's hardware supports this mode. You can set a pattern that can be supported by most display adapters. For example: your program can be used as 640 × 480 × 8 Mode mode, design can be run on all systems. Note: iDirectdraw7 :: setDisplayMode Returns a Dderr InvalidMode error value, if the display adapter can't switch to the desired mode. You can use iDirectdraw7 :: EnumdisplayModes function Look at the user's ability to display the adapter.
Step4: Flipping Surface After setting up the display mode, you should create a plane. Routing: DDEX1 is set to exclusive mode with iDireAtiveEvelAVel. So, you can create a swap page (Flipping Surfaces). If you set up The DDSCL_NORMAL mode, you can create a flat moving (blit) plane. Creating a switching page requires the following steps: (4.1) Defining the plane of the demand: The first step is to define a demand in the DDSurfaceDesc2 structure. The following example demonstrates the definition and sign of the structure: // Create The Primary Surface With One 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;
In this example, DWSIZE members are the size of the DDSurfaceDesc2 structure. This is to prevent the DirectDraw method you use to return an incorrect member. (DWSIZE is preparing to extend the extension of the future DDSurfaceDesc2 structure) DDSurfaceDesc2 structure in DwFlags members Members will be fill effective information. For example, in DDEX1, DWFlags is set to you want to use DDSCAPS structures (DDSD_CAPS) and you want to create a background buffer (DDSD_BACKBUFFERCOUNT) DWCAPS member in an example to be marked in DDSCAPS Structure used in the structure. In this case, he specifies a main plane (Primary Surface DDSCAPS_PRIMARYSURFACE), a swap page (FLIPPING SURFACE DDSCAPS_FLIP), a synthetic surface (Complex Surface DDSCAPS_COMPLEX). Finally, the example specifies a background buffer . The background buffer is the actual drawing operation first there, then, then quickly flipped to the primary surface. In DDEX1, the number of buffers in the background is 1. In fact, you want your memory allows You want to build a few. You want to know more about creating more than 1 buffer information, you can go to "Triple Buffering". Created "Plane" occupied storage, can be system memory It is a memory. If the space used by the application exceeds the memory, DireCTDRAW uses system memory. (For example, you specify multiple caches to only 1MB of memory is on the device. You can also set the DDSCAPS structure of DWCAPS, set to DDSCAPS_VIDEOMEMEORY or DDCAPS_SYSTEMMEMORY to achieve only memory or a memory only. (as specified by memory, and memory is not enough, IDirectDraw7 :: CreateSurface returns an error DDERR_OUTOFVIDEOMEMORY) (4.2) create a flat finish after filling DDSURFACEDESC2 structure, you can use He and G_PDD pointer (pointer to DirectDrawCreateex functions) Call iDirectdraw7 :: createSurface method, just like: hret = g_pdd-> createsssurface (& DDSD, & g_pddsprimary, null); if (hret! = DD_OK) {// g_pddsprimary point {// the new surface.} The g_pddsprimary parameter will point to the address of the primary Surface, which is returned by the CreateSurface function, if the call is successful. after pointing to the main plane (primary surface) of the pointer is valid, IDirectDrawSurface7 :: GetAttachedSurface can call a method to get a pointer to the buffer pointer follows:. ZeroMemory (& ddscaps, sizeof (ddscaps)); ddscaps.dwCaps = DDSCAPS_BACKBUFFER; hRet = g_pDDSPrimary- > GetAttachedSurface (& ddscaps, & g_pDDSBack); {. // g_pDDSBack points to the back buffer} if (! hRet = DD_OK) else {return FALSE;} IDirectDrawSurface7 :: GetAttachedSurface if the call is successful, g_pDDSBack point parameter buffer.
STEP5: After the output of the primary surface and the background buffer are created, the example DDEX1 outputs some text to buffer with the Windows standard GDI function. As follows: if (g_pddsback-> getdc (& hdc) == DD_OK) {setbkcolor (HDC, RGB (0, 0, 255)); setTextColor (HDC, RGB (255, 255, 0)); if (Phase) {getClientRect (HWND, & RC); GetTextExtentPoint (HDC, SZMSG , LSTRLEN (SZMSG), & size); Textout (HDC, (rc.right - size.cx) / 2, (rc.bottom - size.cy) / 2, SZMSG, SIZEOF (SZMSG) - 1); Textout (HDC , 0, 0, SZFRONTMSG, PHASE = 0;} else {textout (HDC, 0, 0, SzBackMSG, Lstrlen (szBackMSG)); Phase = 1;} g_pddsback-> releasedc (hdc);} This example uses the iDirectdrawsurface7 :: getDC method to get the handle of the device context, and, in order to be written, the buffer is buffered. If you are not ready to use the Windows function you need to device context, you can use iDirectdrawsurface7 :: Lock IDirectDrawsurface7 :: UNLOCK method plus unlock. Next, the PHASE variable determines whether the primary buffer message or the background cache message. If Phase = 1, output the main cache message, and set PHASE = 0. If Phase = 0, outputting the background Save the message and set PHASE = 1. After the message is output to the cache area, unlock the cache area with the idirectdrawsurface7 :: releasedc method. Lock to the memory of the creating a plane is to ensure that your program and system cannot save this memory at the same time. Take it. This prevents you from writing an error in the "flat" memory. In addition, the "flat" memory is unlocked, your program will not flush the plane. After the plane is locked, the standard WindowsGDI function is used in the example: setBkcolor Set the background color SetTextColor Set the color of the word displayed on the background, output text and background color with Textout on "Surface". After the text is output to the cache, the example application IDirectDrawsurface7 :: releasedc method unlocks "surface" and releases the handle. No matter When your program completes writes to the cache, you must call IDirectDrawsurface7 :: releasedc or iDirectdrawsurface7 :: unlock, which is specifically used by your program. Don't unlock, your program will not flush the plane. Note: After the "plane" is unlocked with iDirectdrawsurface7 :: unique, the pointer to "Plane" will be invalid. You must use iDirectdrawsurface7 :: Lock to get a valid pointer.
Step: 6 In DDEX1, the WM_TIMER message triggers the flip from the cache to the main level. When the "Plane" memory is unlocked, you can use the idirectdrawsurface7 :: flip method to flip to the main plane. As follows: Case WM_Timer : // update and flip surfaces if (g_bactive && timer_id == wparam) {UpdateFrame (hwnd); while (true) {hret = g_pddsprimary-> flip (null, 0); if (hret == DD_OK) Break; IF hret == DDERR_SURFACELOST) {hret = g_pddsprimary-> restore (); if (hret! = DD_OK) Break;} f (hret! = DDERR_WASSTILLDRAW) BREAK;}} Break; In the example, the g_pddsprimary parameter indicates the main plane and with him. Connecting cache. When iDirectdrawsurface7 :: flip is called, the front and rear plane will exchange (just exchange pointer, no actual data exchange). If the flip is successful, return DD_OK, jump out of the loop. IDirectdrawSurface7 :: restore method Save the plane. If saved, the program loops to call idirectdrawsurface7 :: flip, try again. The program jumps out, returns an error. Note: When you call IDirectdrawsurface7 :: flip, flip The action cannot be done immediately. If, the previous flipping action has not yet finished Cheng, IDirectdrawSurface7 :: FLIP will return DDERR_WASSTILLDRAWING. In this example, idirectdrawsurface7 :: flip will be called until returns DD_OK.