A translation for DX multi-window programming (thank you happy

xiaoxiao2021-03-06  14

Introduction

In DirectX 8, support for rendering to multiple windows is provided through the creation of additional swap chains. However, there are currently no examples of this in the SDK, and the documentation is a bit vague. This article is provided to fill the gaps, And Will Explain The Steps You Need To Take To Write An Application That Will Render Multiple Views in Separate Windows.

In DX8, support for multi-window is provided by creating more SWAP CHAINs. There is no related example in the SDK and the document is just a general discussion. This article is to solve this problem, which will show you how to render multiple views in multiple separation windows step by step.

Step 1 - Setting Up The Parent Frame

Step 1: Set the parent frame window

In an application with multiple views, we start with a top level frame that will contain child windows in its client area to display various views. Once the parent frame parent frame has been created, we create our Direct3D device interface, specifying windowed mode and setting The Top Level Window Handle As The Focus Window:

In a multi-view application, we need from the highest level of frame - this framework will contain all the subviews window within his users - Start our journey. When the parent framework is created, we need to create a Direct3D Device interface to specify the window mode, and set this highest level of window handle as the "Focus window" handle:

g_pd3d = direct3dcreate8 (d3d_sdk_version);

IF (! g_pd3d) return -1;

D3DPresent_Parameters D3DPP;

ZeromeMory (& D3DPP, SIZEOF (D3DPP));

D3DPP.Windowed = true;

D3dpp.swapeffect = D3DSWAPEFFECT_COPY;

// use the current display mode. Using the current display mode

D3DDISPLAYMODE MODE;

IF (failed (g_pd3d-> getadapterdisplaymode (d3dadapter_default, & mode)))) {

SAFE_RELEASE (G_PD3D);

Return -1;

}

D3DPP.BACKBUFFERFORMAT = Mode.Format;

D3DPP.BACKBUFFERWIDTH = Mode.width;

D3DPP.BACKBUFFERHEIGHT = mode.height;

D3dpp.enableautodepthstencil = true;

D3DPP.AUTODEPTHSTENCILFORMAT = D3DFMT_D16;

// m_hwnd is handle to top level window m_hwnd is the handle of the highest layer window

IF (Failed (g_pd3d-> createDevice (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, M_HWND, D3DCREATE_SOFTWARE_VERTEXPROCESSING,

& D3DPP, & g_pd3ddevice)))))

SAFE_RELEASE (G_PD3D);

Return -1;

}

.

Note The above code is simply considered to test the format of the depth cache (? Depth Format), but only selects a determined format (D3DFMT_D16). Your program should select an acceptable depth cache format for Render Targets that need to be rendered.

The device has a frame buffer, which the child views will be rendered into, as well as a depth buffer which will be shared among the views. The frame buffer and depth buffer are sized to the full screen resolution, to allow for the fact that . ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

DEVICE requires a frame cache, which can be rendered, and the depth buffer should also be shared by different views. Frame caches and depth caches are set to full screen size to consider the case where possible windows will change. If not, when the window changes the size, it is necessary to reset Device and recreate Swap Chain.

Step 2 - Setting Up View Windows

Step 2: Set the subview window

Now we are ready to create our view windows, and associate them with swap chains that can be rendered to the device Once the windows have been created, the following code generates a swap chain for the child window.:

Now we can prepare to create our sub-window is also the view window and associate them with the exchange chain so that they can be rendered to Device. When the window is created, the following code will create a switched chain for the child window:

D3DPresent_Parameters D3DPP;

ZeromeMory (& D3DPP, SIZEOF (D3DPP));

D3DPP.Windowed = true;

D3dpp.swapeffect = D3DSWAPEFFECT_COPY;

// use the current display mode. Using the current display mode

D3DDISPLAYMODE MODE;

G_PD3D-> GetAdapterDisplayMode (D3DADAPTER_DEFAULT, & MODE);

D3DPP.BACKBUFFERFORMAT = Mode.Format;

// m_hwnd Contains Child WINDOW Handle M_HWND Subsence Handle

D3DPP.HDEVICEWINDOW = m_hwnd;

// m_pswapchain is idirect3dswapchain * m_pswapchain is an iDirect3dswapchain * object

g_pd3ddevice-> createadditionalswapchain (& D3DP, & m_pswapchain);

After executing this code, the m_pSwapChain variable will contain a pointer to an IDirect3DSwapChain interface, which contains a frame buffer corresponding to the client area of ​​the child window. This process is performed for each view window, so that that there is a swap chain for Each view window.

After these codes, the m_pswapchain variable stores a pointer to the IDirect3dswapchain interface. This interface will store the frame buffer corresponding to the sub-window view area.

Step 3 - Rendering a View

Step 3: Rendering view

Prior to rendering each view, we must direct the device to render to the appropriate frame buffer, using the SetRenderTarget () method We pass the back buffer from the window's swap chain, while using the depth buffer that was originally created with the device.:

Before rendering each view window, we must make DEVICE to render the corresponding frame buffer, which we need to use the SetrenderTarget method. We pass the backup buffer BACKBuffer in which the Sub-window swapchain switched chain, and the depth buffer that is created with the device starts with Device.

LPDIRECT3DSURFACE8 PBACK = NULL, PSTENCIL = NULL;

m_pswapchain-> getBackBuffer (0, D3DBACKBUFFER_TYPE_MONO, & PBACK);

g_pd3ddevice-> getDepthstencilsurface (& pstencil);

g_pd3ddevice-> setrendertarget (PBack, Pstencil);

PBACK-> Release ();

Pstencil-> release ();

Note that we release the stencil and backbuffer pointers after we use them, because the GetBackBuffer () and GetDepthStencilSurface () functions call AddRef () on these interfaces to increment their reference counters. Failing to release them would lead to a memory leak.

Note We must release the pointers of Stencil and BackBuffer because both functions of getBackBuffer and getDepthstencilSurface call COM's AddRef methods, so if they do not delete them, the memory leak will cause memory. We are now ready to render the view. Rendering is performs: Except this Normal Manner, Except That We call present () on the display

We have now prepared to rendering the window. The rendering method looks similar to our usual way, just one thing: we now need to call the Swap chain interface, not the device interface.

g_pd3ddevice-> clear (0, null, d3dclear_target | D3DCLEAR_ZBuffer, 0x00000000, 1.0, 0);

IF (succeeded (g_pd3ddevice-> beginscene ())) {

// Rendering Code Goes Here Rendering Code Write here

g_pd3ddevice-> endscene ();

}

M_Pswapchain-> Present (NULL, NULL, NULL, NULL);

Step 4 - Handling Resize of Child Views

The fourth step, the resize problem of the child window

DirectX will automatically deal with changes in the child view by using a stretch blit to present the swap chain if the dimensions have client area is not the same size as the swap chain's frame buffer. However, this may not be desirable, as it will cause AliaSing if the client is increased in size.

If the view area size of the window is different, the size of Swapchain is different, then DirectX will pass the stretch change of the image via the Stretch Blit. Although this may not be expected, because this will cause the image to blur the image.

To Prevent this, you can write a handler for the wm_size message of the child window. The handler shouth limited the existing swap chain Using The code from Step 2.

If you want to solve this problem, you need to write a process code for the Skay's WM_SIZE message, this code release the SWAP Chain exchange chain, and uses the code in the second step to create a brand new SWAP Chain exchange chain.

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

New Post(0)