24 hours study DX third-hour - double buffer

xiaoxiao2021-03-06  56

#include "stdafx.h" #define initguid # include

#define safeesease (x) i (x) {x-> release (); x = null;} #define image_count 6 // Picture

?

Char file_names [image_count] [256] = {??? "E: / CJD / material / PIC / World of Warcraft /1.BMP", ?"E:/cjd/ Material / PIC / World of Warcraft /2.BMP", " E: / CJD / Material / PIC / World of Warcraft / 3.BMP",?"e:/cjd/ Material / PIC / World of Warcraft / 4.BMP",? "E:/cjd/ Material / PIC / World of Warcraft / 5.BMP ",?" E: / cjd / material / PIC / World of Warcraft / 6.bmp" }// picture list

// Function declares BOOL INITWINDOW (Hinstance Hinstance, Int ncmdshow); Lresult Callback WinProc (HWND HWND, UINT MESSAGE, WPARAM WPARAM, LPARAM LPARAM); INT CUR_IMAGE = 0; // Current picture number

// Variable Description HWND HWND; // Window Handle

/ * ================================================================================================================================================================ ============================= LPDIRECTDRAW7 and LPDIRECTDRAWSURFACE7 type (7 is the version number) is predefined in ddraw.h header files Point to the long pointer of IDirectDraw7 and iDirectdrawSurface7 (previously added LP represents long point), from the later "->" instead of "." It can also be seen.

DD is the abbreviation of DirectDraw, and DDS is the abbreviation of DirectDrawSurface, so habits we are using the variables from LPDD and LPDDSxxx.

Although VC.NET comes with DirectX SDK is version 8.1, because Microsoft stops from DirectX 8.0 to update DirectDraw, DirectDRAW currently has 7.0. ============================================================================================================================================================================================================= ======================================= * / lpdirectdraw7 lpdd = null; // DirectDRAW object pointer lpdirectdrawsurface7 lpddsprimary = null; // DirectDraw Main page pointer LPDIRECTDRAWSURFACE7 LPDDSBUFFER = NULL; // DirectDraw Background Cache Pointer LPDIRECTDRAWSURFACE7 LPSLIDES [Image_Count]; // Picture Storage Space

RECT;

?

Void MakeRect (int in in =}; reference.top = =} {? reference.top;}

LPDIRECTDRAWSURFACE7 bitmap_surface (LPCTSTR file_name) {HDC hdc; HBITMAP bit; LPDIRECTDRAWSURFACE7 surf; // load BMP bit = (HBITMAP) LoadImage (NULL, file_name, IMAGE_BITMAP, 0,0, ?? LR_DEFAULTSIZE | LR_LOADFROMFILE)?????; • If (! bit) // load failed, return null ?? return null;? // Get BMP size? Bitmap bitmap;? getObject (bit, sizeof (bitmap), & bitmap);? // Save BMP size? int Surf_width = bitmap.bmwidth;? int surf_height = bitmap.bmheight;

? // Create a page? HRESULT DDRVAL;? DDSURFACEDESC2 DDSD;? // Empty DDSurfaceDesc2 structure? ZeromeMory (& DDSD, SIZEOF (DDSD)); DDSD.dwsize = sizeof (ddsurfaceDesc2);? // Set the padding mark? DDSD.DWFLAGS = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;?????? // offscreen page ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; // specify the width and height ddsd.dwWidth = 1024; ddsd.dwHeight = 768; // create offscreen Page? DDRVAL = LPDD-> CreateSurface (& DDSD, & Surf, null) ;? if (ddrval! = Dd_ok) {?? // failed, release BMP ?? deleteObject (bit); ?? Return NULL;?}? Else // Create a success? {?? // get DC ?? Surf-> getDC (& HDC); ?? // Get consistent with DC ?? HDC bit_dc = createcompatibleDC (HDC); ?? // ?? SELECTOBJECT (Bit_DC, Bit); ?? // Transfer BMP ?? Bitblt (HDC, 0, 0, Surf_Width, Surf_Height, Bit_DC, 0, 0, Srccopy); ?? // Release DC ?? Surf-> ReleaseDC (HDC); ?? DELETEDC (Bit_DC);?}? // Release BMP? DeleteObject (bit);? // Return the off-screen page pointer? Return Surf;}

// ------ Function to Draw A Slide ------ // void Draw_slide () {? // Determine We get pictures? If (! Lpslides [cur_image]) {?? lpslides [cur_image] = Bitmap_surface (file_names [cur_image]); ?? IF (! lpslides [cur_image]) ??? Return;?}? // Start Picture on the screen? // DrawImage () ;? MakeRect (0,0,1024, 768); // Set to transfer the RECT? // Transfer image? / * Bltfast () is OK. Its prototype is:? HRESULT BltFast (DWORD dwX, DWORD dwY, // image will be transferred to the destination page where LPDIRECTDRAWSURFACE lpDDSrcSurface, // LPDIRECTDRAWSURFACE lpDDSrcSurface, // LPRECT lpSrcRect, // a RECT (Rectangle??.?? , Ie the address of the rectangular structure, indicating the area that will be transmitted on the source page. ????????????????????? // If the parameter is NULL, the entire source page will Use.? DWORD DWTRANS ??? // Specify the type of transfer. There are several following: ?????????????????? // ddbltfast_nocolorKey ????? // Specify once Ordinary replication, without transparent ingredients. ????? // ddbltfast_srccolorKey ????? // Specify a transparent color image transfer, use the transparent color of the source page. ????? // DDBLTFast_Wait ? ????? // If the image transmitter is busy, keep trying until the image transmitter is ready and transferred. ?????? // Using this parameter.?);? * / • LPDDSBuffer-> Bltfast (0, 0, lpslides [cur_image], & recehead);? / * ?? Note? In this example, we will have three pages, which is the main page, used to change the background cache page and the off-screen page used to store pictures ?? Create a complex page and the background cache page, the dual cache is very It is easy to implement, the main difference is that the image is to be transmitted to the background cache page instead of at the main page, when the completion is completed, the home page is called the flip command. ????? The flip command causes the home page to exchange the background cache page, but this action is not going on immediately, but it is waiting until the blank period of the next refresh cycle happens :) ?? Flip function prototype as follows: ?? HRESULT FLIP (?? LPDIRECTDRAWSURFACE LPDDSURFACE, ???????? // The address of the IDirectdrawSurface7 interface of another page in the page chain, ???????? // represents the target page of the page. This page Must be a member of the page chain. ???????? // This parameter default is null, in this case, ???????? // DirectDraw slave Change the page in turn according to the front and rear membership.

?? DWORD DWFLAGS / / Distribution flag option, often use ddflip_wait, similar to DDBLTFast_Wait in BLTFAS. ??); ????? General us to change the page: ?? lpddsprimary-> flip (null, ddflip_wait);? * /? Lpddsprimary-> flip (null, ddflip_wait); // change page? // Change the picture, ready to draw the next, and determine the image index, form a loop? Int next_slide = (cur_image> = image_count-1)? 0: cur_image 1;? If (! Lpslides [next_slide] ?? lpslides [next_slide] ?? lpslides [next_slide] = bitmap_surface (file_names [next_slide]) ;? int prev_slide = (cur_image <1) IMAGE_COUNT-1:??; (! lpSlides [prev_slide]) cur_image-1 if ?? lpSlides [prev_slide] = bitmap_surface (file_names [prev_slide]) } // ************************************************************* ************* / / Function: initddraw () // Function: DX initialization function // ******************** ******************************************************************************** BOOL INITDDRAW () {? DDSurfaceDesc2 DDSD; / / DirectDraw's page description? / * ??? Before all work, remember to join the two lib files ??? In the Object / Library modules column of the LINK page under menu Project-setting? "DDRAW.LIB" And "DXGUID.LIB", the latter can not join, and use #define initguid instead ??? ps: It is best to choose Setting for all configurations ??? This will be effective under debug and release? * /? / *? ?? If you want to use DirectDraw, you must create a DirectDraw object that is the core of the DirectDraw interface. ??? Use the DirectDrawCreateex () function to create a DirectDraw object, which is defined in DDRAW.H, which is as follows:

?????? HRESULT WINAPI DirectDrawCreateex (?????? Guid Far * lpguid, // Pointer to the GUID of the DirectDRAW interface, NULL indicates the default (current) ?????? lpvoid * LPLPDD, ?? // Used to accept the address of the initial DirectDraw object? ?????? REFIID IID, ?????? // IID_IDIRECTDRAW7, current version ?????? IUNKNOWN FAR * PUNKOUTER? // Null ? Retain ???); ?????? All DirectDRAW functions are the HRESULT type, which is a 32-bit value. ??? function call successfully expressed "DD_OK", all the error value flags are "DDERR", such as: ??? DDERR_DIRECTDRAWALREADYCREATED ??? DDERR_OUTOFMEMORY? * /? // Use IF here (XXX! = DD_OK) Method for error detection, this is the most common method ???? IF (DirectDrawCreateex (NULL, (LPVOID *) & LPDD, IID_IDIRECTDRAW7, NULL)! = DD_OK) ?? Return false; // Create a DirectDRAW object? After the DirectDrawCreate function calls successfully, the LPDD has point to a DirectDraw object. It is the highest level leader of the entire DirectDRAW interface, and the following steps are under its control. • We use idirectdraw7 :: setCooperativeEvel () to set the DirectDraw program to the system's control level. The prototype is as follows:? HRESULT SETCOOPERATIVELEVEL (HWND HWND, DWORD DWFLAGS)? The first parameter is a window handle, we give it hwnd, allow the DirectDRAW object to contact the main window. ???? The second parameter is the control level flag. Here is DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN, indicating that we expect DirectDraw to work in exclusive and full-screen. ????? The control level describes how DirectDRAW is working with the display device and system. • DirectDraw control level is generally used to determine that the application is running in full screen mode (must be used simultaneously with exclusive mode), or runs in window mode. However, the control level of DirectDraw can also set the following two: ???? (1) allows Press Ctrl Alt DEL to restart (only for exclusive mode, DDSCL_AllowReboot). ??? (2) Does not allow minimization or restore of the DirectDraw application (DDSCL_NOWIDOWCHANGES). ????? Ordinary control level (DDSCL_NORMAL) indicates that our DirectDraw application will run in the form of a window. Under this control level, we will not change the display resolution, or make a change operation (this is an important operation). Other than this, we cannot call functions that will have a fierce reaction to the memory, such as LOCK (). ???? When the application is a full screen and the exclusive control level, we can fully utilize hardware resources. • At this point, other applications can still create a page, using DirectDraw or GDI functions, just unable to change the display mode.

? * / ???? if (! LpDD-> SetCooperativeLevel (hWnd, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | ?? DDSCL_ALLOWREBOOT) = DD_OK) ??????? return FALSE; // set the control level DirectDraw / * Next?? We use iDirectdraw7 :: setDisplayMode () to set the display mode, its original shape is:? HRESULT SETDISPLAYMODE (? DWORD DWPIDTH, DWORD DWHEIGHT, / / ​​DWWIDTH AND DWHEIGHT to set the width and height of the display mode.? DWORD DWBPP, // DWBPP is used to set the number of color bits of the display mode. • DWORD dwrefreshrate, // dwrefreshrate Set the refresh rate of the screen, 0 is the use of the default value.? DWORD dwflags // dwflags Now the only valid value is DDSDM_Standardvgamode, ?????? ?????????? // This value is used for VGA Mode 13 in 320 × 240 × 8 mode, ?????? // We usually set it to 0??? ??); ps: EnumdisplayModes () function with the IDirectDraw7 interface can get the currently available mode list. Please check the help of DX? * / ???? if (LPDD-> SetDisplayMode (1024, 768, 32, 85, 0)! = DD_OK) ??????? Return False; // Setting the display mode ??? / * ?? Before creating a page, first you need to fill a DDSurfaceDesc2 structure, which is the abbreviation of DirectDraw Surface Description, meaning the page description of DirectDraw. ?? It is very large, it can only make a simplest introduction. What should you pay attention to, you must empty it before filling this structure! ? * /

? // Start creating the home page, first empty the page description? ZeromeMory (& DDSD, SIZEOF (DDSD));

? // Plip page description ??? DDSD.DWSIZE = SIZEOF (DDSD); // Give the size of the DWSIZE page? DDSD.DWFLAGS = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; // Have a background cache ??? DDSD.DDSCAPS.DWCAPS = DDSCAPS_PRIMARFACE | DDSCAPS_FLIP | ?? DDSCAPS_COMPLEX; // Main page, there is a background cache, change the page chain? DDSD.DWBACKBUFFERCOUNT = 1; // The number of times the back built cache is 1 ??? / *? Createsurface () The first parameter is the first parameter of the function is The address of the DDSurfaceDesc2 structure of the page information is filled. This is & DDSD ;? The second parameter is the address of the receiving the home page pointer, here is & lpddsprimary; the third parameter must now be null, preserved for the function . ??? If the function call is successful, LPDDSPrimary will become a legitimate homepage object. • Since the working mode of the program has been set in front, it is the entire display screen, which is actually our entire display screen. • The graphic drawn on the main page will immediately reflect on our display screen. ? * / ???? IF (LPDD-> CreateSurface (& DDSD, & LPDDSPRIMARY, NULL)! = DD_OK) ?????? Return False; // Create the main page

??? DDSD.DDSCAPS.DWCAPS = DDSCAPS_BACKBuffer; // Background Cache page ??? / *? When you create the main page, the additional page (here is the background cache page) also created at the same time, but they are not called by you CreateSurface () returned? You have to get this interface through the getattachedSurface () function,? * / ??? if (LPDDSPRIMARY-> GetAttachedSurface (& DDSD.DDSCAPS, & LPDDSBUFFER)! = DD_OK) ?? Return False; // Created Backstage Cache page? Lpslides [0] = bitmap_surface (file_names [0]) ;? if (! Lpslides [0]) ?? Return false;? // Draw? Draw_slide () ;? return true;} void cleanup (void) {? // Release interface? For (int i = 0; i

?? SafeRelease (LPSLIDES [I]);

Safelelease (LPDDSBuffer);? SafeRelease (LPDDSPRIMARY); / / Delete Main page? SafeRelease (LPDD); // Delete DDRAW object? // PS: The order is just opposite to the order of creation}

// ******************************************************** ************ // Function: WinMain () // Function: Windows program portfolio function. Create a main window, process message loop // ************************************************* ****************** INT PASCAL WINMAIN (Hinstance Hinstance, Hinstance HPREVINSTANCE, LPSTR LPCMDLINE, INT NCMDSHOW) {? if (! initwindow (hinstance, ncmdshow) Return False; // Create a main window? // Return False while creating unsuccessful, return the program? MSG msg ;? // Enter the message loop:? For (;;)? {? I (peekmessage (& msg, null, 0, 0 , PM_REMOVE))? {?? if (msg.Message == wm_quit) Break; ?? TranslateMessage (& msg); ?? DISPATCHMESSAGE (& MSG) ;?}?} ?? Return msg.wpaham;

// ******************************************************** *********** // Function: initwindow () // Function: Create window // ********************** **********************************************

Static Bool INITWINDOW (Hinstance Hinstance, INT NCMDSHOW) {? // Define Window Style:? WNDCLASS WC;? wc.style = NULL; / / Form Class Style? wc.lpfnWndProc = (WinProc) WinProc; // Window Message Processing function pointer? Wc.cbclsextra = 0; // Assign an additional byte number after the window structure? Wc.cbWndextra = 0; // All-byte number after assigning the window instance? Wc.hinstance = Hinstance; // The handle of the application corresponding to the window? Wc.hicon = null; // window icon? Wc.hcursor = loadcursor (null, idc_arrow); // Window mouse? Wc.hbrbackground = Createsolidbrush (RGB (0, 0, 0)); // Black background? Wc.lpszMenuname = null; // makeintResource (iDR_Menu); // window menu resource name? Wc.lpszclassname = "my_test"; // window class name? RegisterClass & wc); // Register the window ??? // Create a window according to the parameters ???? hWnd = createWindow ("my_test", // Create the name of the window class used by the window? "24 hours learning DX_ 2nd Hours ", // window title ?? WS_POPUP | WS_MAXIMIZE, / / ​​window style, defined as the X, Y coordinate of the normal type 0, 0, // window position, and the width of the width, Height ?? null, // parent window handle ?? null, // menu handle ?? hinstance, // application handle ?? NULL); IF (! Hwnd) Return False;? Showwindow (hwnd, ncmdshow); / / Display window? UpdateWindow (hwnd); // Refresh window? INITDDRAW (); // Initialization DX? Return True;}

// ******************************************************** *********** // Function: WinProc () // Function: Process Window Message // ********************** ***********************************************

Lresult Callback WinProc (HWND HWND, UINT MESSAGE, WPARAM WPARAM, LPARAM LPARAM) {? Switch (message)? {? Case wm_command: ?? Break;? Case wm_keydown: // keystroke message ?? switch (wparam) ?? { ?? Case vk_escape: ??? Postmessage (hwnd, wm_close, 0, 0); // Send a WM_CLOSE message to the window ??? Break; ?? // is pressed, change the picture, redraw ?? case vk_left : ??? Cur_Image -; ??? f (cur_image <0) ???? cur_image = image_count-1; ??? Draw_slide (); ??? Break; ?? case vk_right: ??? CUR_IMAGE ;? ?? IF (cur_image> image_count-1) ???? cur_image = 0; ??? Draw_slide (); ??? Break; ??} ?? Break;? Case WM_DESTROY: // If the window is released ...? Cleanup (); ???? postquitmessage (0); // Send a wm_quit message to the window ?? Break; ??? default: // Call the default message processing process ?? Return DefWindowProc (Hwnd, Message, WPARAM, LPARAM ) ;??} ?? Return 0;}?

?

转载请注明原文地址:https://www.9cbs.com/read-116994.html

New Post(0)