DirectX5.0 Latest Game Programming Guide DirectDraw articles 4, DirectDraw advanced features

zhaozj2021-02-11  206

Fourth, DirectDRAW Advanced Features 1, Direct Memory Access DMA Some Display Devices can support bit block transfer operations (or other operations) in the system memory surface, which is direct memory access DMA (Direct Memory Access). You can use DMA support to accelerate a certain action. For example, in this device you can transfer from the system memory block to the video memory, and the processor is also ready to process the next frame. Before using the DMA operation, it is necessary to detect whether the device supports DMA and support. The step is to get the ability to get the device with the iDirectdraw2 :: getCaps method, then view the DWCAPS member in the DDCAPS structure contains the DDCaps_canbltsysmem flag, if it indicates that the device supports DMA. If the device supports DMA, you need to know how the driver is supported. This needs to view the relevant structural members, which contain information about the system memory - video memory, video memory - system memory and system memory - system memory. Several members DDCAPS structure provides the information, as shown below: System-to-videoVideo-to-systemSystem-to-system dwSVBCaps dwVSBCaps dwSSBCaps dwSVBCKeyCaps dwVSBCKeyCaps dwSSBCKeyCaps dwSVBFXCaps dwVSBFXCaps dwSSBFXCaps dwSVBRops dwVSBRops dwSSBRops

For example, the performance flag of bit block transmission of the system memory to video memory is provided by DWSVBCAPS, DWSVBCKEYCAPS, DWSVBFXCAPS, and DWSVBROPS. The bit block transmission performance flag of the video memory to the system memory is included in a member starting with the "DWVSB", and the bit block transfer performance flag between the system memory is included in a member starting with the "DWSSB". The most critical characteristics of these members are support for transmission operations for asynchronous DMA bit blocks. If the driver supports the asynchronous DMA bit block transfer operation between the surface, the DDCaps_bltqueue flag will be located in DWSVBCAPS, DWVSBCAPS, and DWSSBCAPS members. If the flag does not exist, it indicates that the driver does not support asynchronous DMA bit block transfer operations. SRCPY transmission between the system memory to video memory is the most common bit block transmission operation supported by hardware. Therefore, the most typical application of this operation is to move many textures to video memory from the system surface memory. The DMA transfer of the system memory to video memory is approximately as fast as the processor control, but has a greater advantage because these operations can run parallel with the host processor. Hardware transfer uses physical memory addresses instead of virtual memory addresses, some device drivers require physical memory. This mechanism is done by calling the idirectdrawsurface3 :: panel method. If the device driver does not require a page lock, the DDCAPS2_nopageLockRequired flag will be set when the hardware is obtained with the iDirectdraw2 :: getCaps method. Page locking a surface prevents the system from doing the physical memory of the surface and keeps the physical memory of the surface unchanged until the IDirectdrawSurface3 :: PageUnlock method is called. If the device driver request page is locked, DirectDraw only allows the DMA to operate on the system memory surface that is already locked. If you don't call IDirectdrawSurface3 :: PageLock, DirectDraw will perform transfer work with software simulation. It should be noted that the locking surface will greatly reduce the efficiency of Windows operation. Therefore, it is preferable to handle more quantity of system memory only in full-screen exclusive mode, and can unlock these surfaces when the application minimizes. Of course, after the application is restored, the system memory surface page should be re-locked.

2. When using the DirectDraw palette in window mode, the iDirectdrawpalette interface method is directly written to the hardware. When the window mode is displayed, the iDirectdrawpalette interface method will call the GDI palette processing function to make it harmonically with other Windows applications. 2.1, window mode The type of palette entity is different from full-screen exclusive applications, and the window mode of the window must share the desktop palette with other applications. The PaletteEntry structure used to work with DirectDrawPalette objects and GDI contains a PEFLAGS member that contains information about how the system explains the PaletteEntry structure. Members of Peflags describe three types of palette entities. 2.1.1 Windows Static entity In standard mode, Windows reserves palette entities 0 ~ 9 and entities 246 ~ 255 for system color, display menu strips, menu text, and window boundaries. In order to keep the application consistent appearance, avoid damage to other applications, you need to protect these entities that are set to the palette of the main surface. Typically, the programmer can call the Win32 function getSystemPaletteEntries to get the system palette, and then explicitly set the same palette in the custom palette to match the system palette in front of the main table. Although the system palette entity is copied to the custom palette in the custom palette, it can work in the first place, but when the user changes the color of the desktop color, the custom palette will become invalid. In order to avoid the user's ability to change the color color color, you can provide an index of a system palette to replace the specified color value to protect the appropriate entity. With this method, the palette will always match whether the system is used, and the palette will always match and do not need to do any updates. The PC_EXPLICIT logo for PEFLAGS members allows you to directly index to a system palette entity. After using this flag, the system will no longer think that other members of the structure contain color information. You can set the value of the PERED member to the required system palette index to set all the colors to 0. For example, if you want to guarantee the appropriate entity in your palette, you can always match the system palette color matching, you can use the following code: // set the first and last 10 Entries to match the system palette.paletteentry PE [256 ]; ZeromeMory (PE, SIZEOF (PE)); for (int i = 0; i <10; i ) {PE [i] .peflags = pe [i 246] .peflags = pc_explicit; pe [i] .pled = I; PE [i 246] .pled = i 246;} You can call Win32 function setsystempaletteuse to force Windows only use the first and last palette entities 0 and 255. In this case, only entities 0 and 255 should be set to PC_ExPlicit in the PaletteEntry structure. 2.1.2, ANIMATED Entries You can use the PC_RESERVED flag in the PaletteEntry structure to specify that the motion is a palette entity. Windows does not allow other applications to map its own logical palette entities to your specified physical palette entity, avoiding other applications to change their color when moving palettes in your application. 2.1.3 Non-sports entities You can use the PC_nocollapse flag in the PaletteEntry structure to specify a non-motion palette entity. The PC_NOCOLLAPSE flag notifies that Windows does not have to replace the non-sports entity without the assigned palette entity.

2.2, create a palette under window mode is an example of creating a DirectDraw palette in non-exclusive window mode. In order to make the palette work normally, 256 entities are set in the PaletteEntry structure submitted to the IDiretDraw2 :: CreatePalette method.

LPDIRECTDRAW lpDD; // Assumed to be initialized previously PALETTEENTRY pPaletteEntry [256]; int index; HRESULT ddrval; LPDIRECTDRAWPALETTE lpDDPal; // First set up the Windows static entries for (index = 0; index <10; index ). {// The first 10 static entries: pPaletteEntry [index] .peFlags = PC_EXPLICIT; pPaletteEntry [index] .peRed = index; pPaletteEntry [index] .peGreen = 0; pPaletteEntry [index] .peBlue = 0; // The last 10 static entries: pPaletteEntry [index 246] .peFlags = PC_EXPLICIT; pPaletteEntry [index 246] .peRed = index 246; pPaletteEntry [index 246] .peGreen = 0; pPaletteEntry [index 246] .peBlue = 0;} // Now . set up private entries In this example, the first 16 // available entries are animated for (index = 10; index <26; index ) {pPaletteEntry [index] .peFlags = PC_NOCOLLAPSE | PC_RESERVED;. pPaletteEntry [index]. Pred = 255; pPaletteentry [index] .pegreen = 64; ppaletteentry [index] .peb Lue = 32;} // NOW SET UP THE REST, THE NONANIMATED Entries. for (Index <246; Index ) // Index IS set up by previous for loop {ppaletteentry [index] .peflags = pc_nocollapse; ppaletteentry index] .peRed = 25; pPaletteEntry [index] .peGreen = 6; pPaletteEntry [index] .peBlue = 63;..} // All 256 entries are filled Create the palette ddrval = lpDD-> CreatePalette (DDPCAPS_8BIT, pPaletteEntry, & lpDDPal , NULL); 2.3, window mode Setting the palette entity for the IdirectDraw2 :: CREATEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTEENTTEENTTEENTTEENTTEENTTTE :: STENTRIES method. Therefore, you can maintain the PaletteEntry group without reconstructing it.

When needed, change the structure group and call the IDirectDrawPalette :: setNtries method. In most environments, when you are in window mode, don't try to set any window static entities, otherwise you will appear unpredictable results. The window still entity is allowed only when resetting the entity. For the palette animation, you only need to change very little part of the entity in the PaletteEntry group, submit these entities to the IDirectDrawpalette :: setEntries method. If you want to perform a reset operation, you can only reset the entities that are marked with the PC_NOCOLLLAPSE flag and the PC_RESERVED logo. Attempting to move other entities will bring unpredictable errors. Examples of the palette animation in the following non-exclusive mode: LPDIRECTDRAW lpDD; // Already initialized PALETTEENTRY pPaletteEntry [256]; // Already initialized LPDIRECTDRAWPALETTE lpDDPal; // Already initialized int index; HRESULT ddrval; PALETTEENTRY temp; // Animate . some entries Cycle the first 16 available entries // They were already animated temp = pPaletteEntry [10];.. for (index = 10; index <25; index ) {pPaletteEntry [index] = pPaletteEntry [index 1] PPALETTEENTRY [25] = Temp; // set the values. do not pass a pointer to the entire patrie entry /// structrue, but only to the change Entries. DDRVAL = LPDDPAL-> setEntries (0, // Flags Must BE Zero 10, // First Entry 16, // Number of Entries & (PPALETTEENTRY [10])); // Where to get the data 3, Multi-Display System Windows 98 (Memphis) and Windows NT support multiple systems Display devices and displays. Multi-display system (commonly referred to as "multimon" enables operating systems to use two or more display devices and displays to create a single logical desktop. For example, in a Multimon system with two displays, users can display applications on one of the displays, and can also drag and drop the window from one display to another display. DirectDraw supports this architecture. A DirectDRAW application is capable of listing hardware devices, selecting a device, then using the GUID of the device to create a DirectDRAW object for the device. This technology ensures that the best performance performance can be achieved regardless of the Multimon system or in a single display system. The current active display device is considered "default device", or "null device" (null device "because the currently active display device is null as its GUID as it is listed.

Many applications can create a DirectDraw object for "empty devices", assuming that the device is hardware acceleration. However, in the Multimon system, "empty equipment" does not always accelerate hardware, depending on the collaboration level used at the time. In full-screen exclusive mode, "empty equipment" is hardware acceleration, but the system does not know other installed devices. This means that the full-screen exclusive mode is running as fast as the speed of the Multimon system is as fast as running on other systems, but cannot use the embedded support for image operations that span image operations across the display device. An application that requires full-screen exclusive mode of multiple devices can create a DirectDRAW object for each device to use. Note that the DirectDraw object is created for the specified device, and you must provide the GUID of the object. When you call the DirectDrawenumeRate method, you can list the GUID of each device. When the standard collaboration level is set, the "empty device" does not have hardware acceleration capabilities. In fact, it simulates the resources of the two physical devices to simulate a logical device. On the other hand, the "empty device" automatically has graphical operational capabilities across the display. Therefore, when the logical position of the second display is in the left side of the main display, the negative coordinate value is legal. If the application requires the hardware acceleration function after setting the standard collaboration level, it must create a single DirectDraw object using the GUID of the specified device. If you don't use "empty devices", you cannot get image operation capabilities across the display device. That is, the bit block transmission operation across the main surface boundary will be cut (if a shear plate) or failure (returns Dderr_INVALIDRECT). Regardless of which system, the collaboration level should be set immediately after obtaining the DirectDRAW object before being queried by other interfaces, and avoid setting a collaboration level multiple times in the Multimon system. If you need to switch from full screen mode to standard mode, you'd better create new DirectDraw objects, not to use old DirectDraw objects.

4, Video Ports DirectDraw video port extension is a low-level programming interface, which is not used for current system multimedia programming. The object of the video port interface is a video software company, such as a company developing DirectShow. Programmers who want to use video technology in their own software can also use video port extensions. However, the advanced programming interfaces provided in many software are sufficient to meet the needs. The DirectDrawVideoPort object is characterized by the video port hardware installed in some computer systems. In general, the video port object controls how video port hardware applies directly to the video signal from the video decoder to the frame buffer. You can create multiple DirectDrawVideoPort objects to control multiple video channels as needed. Because each channel can be listed and configured, video hardware does not need to be completely identical to each channel. Video port hardware can access the surface directly in the frame buffer, and bypass the CPU and PCI bus. Direct access to the frame buffer allows you to effectively play active video and recording a video without loading in the CPU. Once there is a surface existing, the image can be displayed on the screen, which can be used for Direct3D texture, intercept access and other processing of the CPU. In a computer equipped with a video port device, the data in the video stream can directly flow from the video decoder and the video port to the frame buffer. These components typically connect together with the display adapter, or as separate hardware interconnects. The following figure gives the process of data stream: What is the video source? In the video port technology, strict, the video source is a Video INPUT device, such as Zoom video port, MPEG encoder, etc. These hardware sources will be sent to the physical connection of the video decoder by connecting the signal in different formats (including NTSC, PAL, and SECAM). Video decoder (Viceo decoder) is another hardware component. It works is to translate the information provided by the video source and send it to the video port with the connection format followed. The decoder keeps the physical connection with the video port, which is also responsible for sending video data, hourglass information, and synchronization information to the video port. Video port is also a set of hardware. It exists on the VGA chip that displays the adapter, with the ability to directly access the frame buffer. It handles information from the decoder and placed in the frame buffer for display. During the processing of data, the video port can operate image data to provide proportional changes, stretch compression, color control, and shear. Frame Buffer Accepts video data provided by the video port, and then processes these image data with programmed methods, transfer their bit blocks to other locations or use overrides to display them on the screen. The virtual DirectDraw video port extension is a DirectDrawVideoPort object that provides video services using video port technology via IDDVIDEOPORTCONTAINER and IDIRECTDRAWVIDEOPORT interface. The DirectDrawVideoPort object does not control the video decoder and can only provide your own service. DirectDraw also cannot control video sources because the video source has exceeded the range of video ports. The DirectDrawVideoPort object is just characterized by the video port itself. It uses the parameters set by the interface method to send the input signal and the image data to the frame buffer to perform flip or other processing. The IDDVIDEOPORTCONTAINER interface (obtained with iDirectdraw2 :: queryinterface) provides the ability to query hardware to create a video port object. You can create a video port object with the IDDVIDEOPORTCONTAINER :: CreateVideoPort method, which shows its feature via the iDirectDrawVideoPort interface.

With these interfaces, you can check the ability of the video port, allocate override surfaces to receive image data, start and stop video playback, set hardware parameters to process image data to generate cut, color conversion, scale zoom, and stretching compression. The DirectDraw video port extension supports multiple video ports on the same computer, allowing you to create multiple video port objects.

5. Get flipping and bit block transmission status We already know that after calling the IDirectdrawSurface3 :: Flip method, the main surface and the background buffer will exchange each other. But the action of the exchange is not immediately happening immediately. For example, if the previous flip task is not completed, the method returns DDERR_WASSTILLDRAWING, and DirectDraw continues to call iDirectdrawsurface3 :: flip until DD_OK. If the application is in a waiting state before calling the idirectdrawsurface3 :: flip method, the efficiency of the program will be very low. Instead, you can create a function to call the idirectdrawsurface3 :: getFlipStatus method in the background buffer to detect if the previous flip work is completed. If not completed, return or DDERR_WASSTILLDRAWING, the application can perform other tasks within a period of time between the state. Here is an example of this idea:. While (lpDDSBack-> GetFlipStatus (DDGFS_ISFLIPDONE) == DDERR_WASSTILLDRAWING); // Waiting for the previous flip to finish The application can // perform another task here ddrval = lpDDSPrimary-> Flip (NULL. , 0); You can also call IDirectDrawsurface3 :: getBltstatus with the same method to detect whether the primary block transfer is completed. Because IdirectdrawSurface3 :: getflipstatus and idirectdrawsurface3 :: getBltstatus can return to the current status currently in the application, so you can use them in the program without too much influence running speed. The work that performs color fill needs to call the idirectdrawsurface3 :: blt method. For example, if the most often displayed color is blue, you can call the idirectdrawsurface3 :: bLT method in a blue, use the DDBLT_COLORFILL flag first filled the surface, and then write other objects to the top. This method allows you to fill the most common colors very quickly, then just write a small number of colors to the surface. The following is an example of performing color fill: DDBLTFX ddbltfx; ddbltfx.dwSize = sizeof (ddbltfx); ddbltfx.dwFillColor = 0; ddrval = lpDDSPrimary-> Blt (NULL, // Destination NULL, NULL, // Source rectangle DDBLT_COLORFILL, & ddbltfx) Switch (DDRVAL) {CASE DDERR_WASSTILLDRAWING:.................................................... .. . In order to improve the execution speed of the DirectDRAW application, the ability to display the hardware should be detected immediately after creating the DirectDraw object, and then use the feature component program provided by the hardware as much as possible. You can detect hardware performance using the idirectdraw2 :: getcaps method.

Not all hardware features can be simulated with software. If you want to use a feature that is only supported by some hardware, it is best to do a system that you may not support this hardware, that is, if the hardware does not support this hardware solution. 7. In display memory, the bitmap is typically, from the display memory to the bit block transmission between the display memory is high, the bit block transmitted between the display memory is high. Therefore, it is preferred to store the wizard bitmap that will be used as much as possible in the display memory. Most display adapters contain sufficient additional memory to store more than one main surface and background buffer. You can use DWVIDMEMTAAL and DWVIDMEMFree members in the DDCAPS structure to detect how much memory can be used to store bitmaps in memory. The DirectX Viewer sample program included in the DirectX SDK gives this process.

8, Triple Buffering In some cases, display the adapter may have more display memory, which may use three cushions to increase the display speed. Three buffers use a master surface and two back buffers. The following is an example of initializing a three buffer: // The LPDDSPRIMARY, LPDDSMIDDLE, AND LPDDSBACK Are Globally // Declared, Uninitialized LPDirectdrawSurface Variables.

DDSurfaceDesc Ddsd; ZeromeMory (& DDSD, SIZEOF (DDSD));

// Create the primary surface with two back buffers ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;. Ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; ddsd.dwBackBufferCount = 2; ddrval = lpDD- > CreateSurface (& DDSD, & LPDDSPRIMARY, NULL);

// If we successfully created the flipping chain, // retrieve pointers to the surfaces we need for // flipping and blitting.if (ddrval == DD_OK) {// Get the surface directly attached to the primary (the back buffer). ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; ddrval = lpDDSPrimary-> GetAttachedSurface (& ddsd.ddsCaps, & lpDDSMiddle); if (! ddrval = DD_OK);. // Display an error message here} you need to keep all three buffer flip chain surface The trajectory only needs to keep the main surface and the pointer of the background buffer surface. The main surface pointer is used to flip the main surface in the flip chain, and the background buffer pointer is used for bit block transmission. The three buffer allows the application continuation bit block to be transferred to the background buffer, as long as the last bit block transmission of the background buffer has been completed, even if the flip is not completed. Execution flip is not a synchronous event, and once the flip may be longer than the other flip. Therefore, if only one background buffer is used, the program may consume a waiting state before the iDirectdrawsurface3 :: flip method returns DD_OK.

9. DirectDRAW Applications and Window Style If the application uses DirectDraw in window mode, you can use any style to create a window. The appearance of full screen exclusation cannot be created with a WS_EX_TOOLWINDOW style, which should be used with the WS_EX_TOPMOST extension window style and WS_Visible window style to ensure that the image is correctly displayed. These two styles can keep the application at the front end of the window z direction, avoiding GDI to the main surface. The following example shows how to make exclusive full-screen mode applications: // register the window, and init all directx and graphic objects.bool winApi initApp (int nwinmode) {Wcex.cbsize = sizeof (WNDCLASSEX); wcex.hInstance = g_hinst; wcex.lpszClassName = g_szWinName; wcex.lpfnWndProc = WndProc; wcex.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS; wcex.hIcon = LoadIcon (NULL, IDI_APPLICATION); wcex.hIconSm = LoadIcon ( NULL, IDI_WINLOGO); wcex.hCursor = LoadCursor (NULL, IDC_ARROW); wcex.lpszMenuName = MAKEINTRESOURCE (IDR_APPMENU); wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hbrBackground = GetStockObject (NULL_BRUSH);

RegisterClassex (& WCEX);

G_hWndmain = CREATEWINDOWEX (WS_EX_TOPMOST, G_SZWINNAME, G_SZWINCAPTION, WS_Visible | WS_POPUP, 0, 0, CX_SCREEN, CY_SCREEN, NULL, NULL, G_HINST, NULL);

IF (! g_hwndmain) return (false);

Setfocus (g_hwndmain); showwindow (g_hwndmain, nwinmode); UpdateWindow (g_hwndmain);

Return True;}

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

New Post(0)