Direct3D 实例

24 篇文章 0 订阅
9 篇文章 1 订阅

场景提交概述

场景提交即将在后台缓冲区绘制好的场景提交到前台缓冲区,从而在屏幕上显示出来。提交接口函数是一组控制特定的渲染设备状态的方法,这些设备影响显示器的显示。

(1)前台缓冲区:这是一块由显卡转换来的矩形存储区,这块矩形存储区的内容显示在显示器或其他输出设备上。

(2)后台缓冲区:后台缓冲区是一个表面,其内容可以提交到前台缓冲区。

(3)交换链:一组后台缓冲区集合,它们被顺序地提交到前台缓冲区。一般情况下,一个全屏交换链通过翻转设备驱动接口(DDI)来提交随后的显示内容,窗口交换链通过位块传送DDI提交显示内容。

前台缓冲区不能直接在Direct3D API中使用。所以,应用程序不能对前台缓冲区进行锁定或渲染。DirectX 9.0应用程序中没有主表面的概念,不能创建一个带有主表面的对象。

 

窗口模式下的多视口(视区)

Direct3D设备对象拥有并控制自己的交换链,此外,应用程序可以使用函数IDirect3DDevice9::CreateAdditionalSwapChain()创建附加交换链,用来在同一个设备中提交多个视口。一般地说,应用程序为每个视口创建一个交换链,每个交换链对应一个特定的视口。应用程序在每个视口的后台缓冲区内渲染图形,然后用函数 IDirect3DDevice9::Present()将它们分别提交。注意:对于任何Direct3D设备对象,一次只能有一个交换链用于全屏显示。

 

多显示器操作

当一个设备被成功设置为全屏操作时,创建该设备的Direct3D对象被标识为拥有系统的所有显卡。这种状态称为独占模式(exclusive mode),也就是说,Direct3D对象为独占模式。独占模式是指,这时其他所有的Direct3D对象创建的设备都不能进行全屏操作,也不能申请资源空间。此外,当一个对象是独占模式时,所有未在全屏模式下的设备都将被设为丢失状态。当Direct3D对象的最后一个全屏设备被设置为窗口模式或被销毁时,独占模式被取消。

当一个Direct3D设备是独占模式时,设备将被分为两大类,第一类设备有下列属性:

(1)它们都是由同一个创建全屏设备的Direct3D对象创建的。

(2)因为设备是全屏的,它们具有同一个焦点窗口。

(3)它们代表不同于任何全屏设备的显卡。

对于这种类型的设备,不用关心它们能否被重新设置或创建,因为它们不处于丢失状态。甚至,这种类型的设备都可以被设置为全屏状态。

不属于第一类的设备即由其他Direct3D对象创建的设备,或和当前全屏设备不具有相同的焦点窗口,或和当前全屏设备使用不同的显卡。这一类Direct3D设备不能被重新设置,将一直处于丢失状态,直至当前全屏设备的独占模式取消。这样一来,一个多显示器应用程序可在全屏模式下拥有多个设备,但是,这些设备必须由相同的Direct3D对象创建,对应于不同的物理显卡并且共享同一个焦点窗口。

 

操作深度缓冲区

深度缓冲区与设备相关。当应用程序设置渲染目标时,需要访问深度缓冲区。可以使用函数IDirect3DDevice9::GetDepthStencilSurface()和IDirect3DDevice9::SetDepthStencilSurface()来操作深度缓冲区。

 

访问前台缓冲区

可以通过函数IDirect3DDevice9::GetFrontBufferData()访问前台缓冲区,这是得到一个反锯齿场景屏幕快照的唯一方法。

 

图形反锯齿(antialiasing)

图形像素在颜色缓冲区或屏幕中以一个二维坐标(x, y)表示当前位置。如果实际计算的像素值是浮点数,则将被转换为整数坐标显示,这种光栅化的处理方法可能使图形出现锯齿形外观。图形学中称这种由于采样频率不足而造成的失真为锯齿(alisasing),Direct3D采用图形反锯齿(通过多重采样)来改善图形的锯齿效果,增加图形边缘的平滑度。

 

查询设备是否支持多重采样

使用IDirect3D::CheckDeviceMultiSampleType()函数检查当前设备是否支持图形多重采样:

Determines if a multisampling technique is available on this device.

HRESULT CheckDeviceMultiSampleType(
  UINT Adapter,
  D3DDEVTYPE DeviceType,
  D3DFORMAT SurfaceFormat,
  BOOL Windowed,
  D3DMULTISAMPLE_TYPE MultiSampleType,
  DWORD* pQualityLevels
);
Parameters
Adapter
[in] Ordinal number denoting the display adapter to query. D3DADAPTER_DEFAULT is always the primary display adapter. This method returns FALSE when this value equals or exceeds the number of display adapters in the system. See Remarks.
DeviceType
[in] Member of the D3DDEVTYPE enumerated type, identifying the device type.
SurfaceFormat
[in] Member of the D3DFORMAT enumerated type that specifies the format of the surface to be multisampled. For more information, see Remarks.
Windowed
[in] bool value. Specify TRUE to inquire about windowed multisampling, and specify FALSE to inquire about full-screen multisampling.
MultiSampleType
[in] Member of the D3DMULTISAMPLE_TYPE enumerated type, identifying the multisampling technique to test.
pQualityLevels
[out] The number of quality stops available for a given multisample type. This can be NULL if it is not necessary to return the values.
Return Values

If the device can perform the specified multisampling method, this method returns D3D_OK. D3DERR_INVALIDCALL is returned if the Adapter or MultiSampleType parameters are invalid. This method returns D3DERR_NOTAVAILABLE if the queried multisampling technique is not supported by this device. D3DERR_INVALIDDEVICE is returned if DeviceType does not apply to this adapter.

Remarks

This method is intended for use with both render-target and depth-stencil surfaces because you must create both surfaces multisampled if you want to use them together.

The following code fragment shows how you could use IDirect3D9::CheckDeviceMultiSampleType to test for devices that support a specific multisampling method.

if( SUCCEEDED(pD3D->CheckDeviceMultiSampleType( pCaps->AdapterOrdinal, 
                                pCaps->DeviceType, BackBufferFormat, 
                                FALSE, D3DMULTISAMPLE_3_SAMPLES, NULL ) ) &&
         SUCCEEDED(pD3D->CheckDeviceMultiSampleType( pCaps->AdapterOrdinal, 
                                pCaps->DeviceType, DepthBufferFormat, 
                                FALSE, D3DMULTISAMPLE_3_SAMPLES, NULL ) ) )
    return S_OK;

The preceding code will return S_OK if the device supports the full-screen D3DMULTISAMPLE_3_SAMPLES multisampling method with the surface format.

Defines the levels of full-scene multisampling that the device can apply.

typedef enum D3DMULTISAMPLE_TYPE
{
    D3DMULTISAMPLE_NONE = 0,
    D3DMULTISAMPLE_NONMASKABLE  = 1,
    D3DMULTISAMPLE_2_SAMPLES = 2,
    D3DMULTISAMPLE_3_SAMPLES = 3,
    D3DMULTISAMPLE_4_SAMPLES = 4,
    D3DMULTISAMPLE_5_SAMPLES = 5,
    D3DMULTISAMPLE_6_SAMPLES = 6,
    D3DMULTISAMPLE_7_SAMPLES = 7,
    D3DMULTISAMPLE_8_SAMPLES = 8,
    D3DMULTISAMPLE_9__SAMPLES = 9,
    D3DMULTISAMPLE_10_SAMPLES = 10,
    D3DMULTISAMPLE_11_SAMPLES = 11,
    D3DMULTISAMPLE_12_SAMPLES = 12,
    D3DMULTISAMPLE_13_SAMPLES = 13,
    D3DMULTISAMPLE_14_SAMPLES = 14,
    D3DMULTISAMPLE_15_SAMPLES = 15,
    D3DMULTISAMPLE_16_SAMPLES = 16,
    D3DMULTISAMPLE_FORCE_DWORD = 0xffffffff,
} D3DMULTISAMPLE_TYPE, *LPD3DMULTISAMPLE_TYPE;
Constants
D3DMULTISAMPLE_NONE
No level of full-scene multisampling is available.
D3DMULTISAMPLE_NONMASKABLE
Enables the multisample quality value. See Remarks.
D3DMULTISAMPLE_2_SAMPLES
Level of full-scene multisampling available.
D3DMULTISAMPLE_3_SAMPLES
Level of full-scene multisampling available.
D3DMULTISAMPLE_4_SAMPLES
Level of full-scene multisampling available.
D3DMULTISAMPLE_5_SAMPLES
Level of full-scene multisampling available.
D3DMULTISAMPLE_6_SAMPLES
Level of full-scene multisampling available.
D3DMULTISAMPLE_7_SAMPLES
Level of full-scene multisampling available.
D3DMULTISAMPLE_8_SAMPLES
Level of full-scene multisampling available.
D3DMULTISAMPLE_9__SAMPLES
Level of full-scene multisampling available.
D3DMULTISAMPLE_10_SAMPLES
Level of full-scene multisampling available.
D3DMULTISAMPLE_11_SAMPLES
Level of full-scene multisampling available.
D3DMULTISAMPLE_12_SAMPLES
Level of full-scene multisampling available.
D3DMULTISAMPLE_13_SAMPLES
Level of full-scene multisampling available.
D3DMULTISAMPLE_14_SAMPLES
Level of full-scene multisampling available.
D3DMULTISAMPLE_15_SAMPLES
Level of full-scene multisampling available.
D3DMULTISAMPLE_16_SAMPLES
Level of full-scene multisampling available.
D3DMULTISAMPLE_FORCE_DWORD
Forces this enumeration to compile to 32 bits in size. Without this value, some compilers would allow this enumeration to compile to a size other than 32 bits. This value is not used.
Remarks

In addition to enabling full-scene multisampling at IDirect3DDevice9::Reset time, there will be render states that turn various aspects on and off at fine-grained levels.

Multisampling is valid only on a swap chain that is being created or reset with the D3DSWAPEFFECT_DISCARD swap effect.

The multisample antialiasing value can be set with the parameters (or sub-parameters) in the following methods.

MethodParametersSub-parameters
IDirect3D9::CheckDeviceMultiSampleType MultiSampleType and pQualityLevels  
IDirect3D9::CreateDevice pPresentationParameters MultiSampleType and pQualityLevels
IDirect3DDevice9::CreateAdditionalSwapChain pPresentationParameters MultiSampleType and pQualityLevels
IDirect3DDevice9::CreateDepthStencilSurface MultiSampleType and pQualityLevels  
IDirect3DDevice9::CreateRenderTarget MultiSampleType and pQualityLevels  
IDirect3DDevice9::Reset pPresentationParameters MultiSampleType and pQualityLevels

It is not good practice to switch from one multisample type to another to raise the quality of the antialiasing.

D3DMULTISAMPLE_NONE enables swap effects other than discarding, locking, and so on.

Whether the display device supports maskable multisampling (more than one sample for a multiple-sample render-target format plus antialias support) or just non-maskable multisampling (only antialias support), the driver for the device provides the number of quality levels for the D3DMULTISAMPLE_NONMASKABLE multiple-sample type. Applications that just use multisampling for antialiasing purposes only need to query for the number of non-maskable multiple-sample quality levels that the driver supports.

The quality levels supported by the device can be obtained with the pQualityLevels parameter of IDirect3D9::CheckDeviceMultiSampleType. Quality levels used by the application are set with the MultiSampleQuality parameter of IDirect3DDevice9::CreateDepthStencilSurface and IDirect3DDevice9::CreateRenderTarget.

See D3DRS_MULTISAMPLEMASK for discussion of maskable multisampling.

 

创建使用多重采样的Direct3D设备

创建使用多重采样的Direct3D设备,需要将函数CreateDevice()的第5个参数D3DPRESENT_PARAMETERS结构体的MultiSampleType成员设为将要设置的多重采样类型,SwapEffect成员设为D3DSWAPEFFECT_DISCARD。

D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));

d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; 
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.MultiSampleType = D3DMULTISAMPLE_4_SAMPLES;

 

启用多重采样的全景图形反锯齿

调用渲染状态设置函数IDirect3DDevice9::SetRenderState(),将第一个参数设置为D3DRS_MULTISAMPLEANTIALIAS,将第二个参数设为TRUE将激活多重采样,设置FALSE将禁用多重采样。

 

图形反锯齿示例程序

示例程序AntiAlisa演示了图形反锯齿效果。目前很多显示硬件可能不支持图形反锯齿,所以在创建渲染设备前应进行设备检查,如果当前显示硬件不支持,可以创建参考设备来测试图形反锯齿效果。在示例程序AntiAlisa运行时通过单击鼠标左键,可以切换是否启用图形反锯齿操作。

启用反锯齿

 

禁用反锯齿

 

完整源代码:

#include  < d3d9.h >

#define  CLASS_NAME    "GameApp"

#define  release_com(p)    do { if(p) { (p)->Release(); (p) = NULL; } } while(0)

IDirect3D9
*                 g_d3d;
IDirect3DDevice9
*         g_device;
IDirect3DVertexBuffer9
*  g_vertex_buffer;
BOOL                    g_support_anti_aliasing 
=  TRUE;

struct  sCustomVertex
{
    
float  x, y, z, rhw;
    DWORD color;
};

#define  D3DFVF_CUSTOM_VERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE) 

void  init_vertices()
{
    sCustomVertex vertices[] 
=
    {
        {  
50.0f 250.0f 0.5f 1.0f 0xffff0000 , },
        { 
150.0f ,   50.0f 0.5f 1.0f 0xff00ff00 , }, 
        { 
250.0f 250.0f 0.5f 1.0f 0xff0000ff , },        
    };

    
//  push vertex data into vertex buffer

    g_device
-> CreateVertexBuffer( sizeof (vertices),  0 , D3DFVF_CUSTOM_VERTEX, D3DPOOL_DEFAULT,  & g_vertex_buffer, NULL);

    
void *  ptr;

    g_vertex_buffer
-> Lock( 0 sizeof (vertices), ( void ** ) & ptr,  0 );
    memcpy(ptr, vertices, 
sizeof (vertices));
    g_vertex_buffer
-> Unlock();
}

bool  init_d3d(HWND hwnd)
{
    g_d3d 
=  Direct3DCreate9(D3D_SDK_VERSION);

    
if (g_d3d  ==  NULL)
        
return   false ;

    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory(
& d3dpp,  sizeof (d3dpp));

    d3dpp.Windowed            
=  TRUE;
    d3dpp.SwapEffect        
=  D3DSWAPEFFECT_DISCARD;    
    d3dpp.BackBufferFormat    
=  D3DFMT_UNKNOWN;
    d3dpp.MultiSampleType    
=  D3DMULTISAMPLE_4_SAMPLES;

    
if (FAILED(g_d3d -> CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, FALSE,
                                                D3DMULTISAMPLE_4_SAMPLES, NULL)))
    {
        MessageBox(hwnd, 
" Hardware do not support antialiasing, use ref device! " " ERROR " , MB_OK);

        
if (FAILED(g_d3d -> CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      
& d3dpp,  & g_device)))
        {
            
return   false ;
        }
    }
    
else
    {
        
if (FAILED(g_d3d -> CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      
& d3dpp,  & g_device)))
        {
            
return   false ;
        }        
    }


    init_vertices();

    
return   true ;
}

void  cleanup()
{    
    release_com(g_vertex_buffer);
    release_com(g_device);
    release_com(g_d3d);
}

void  render()
{    
    g_device
-> SetRenderState(D3DRS_MULTISAMPLEANTIALIAS,  g_support_anti_aliasing);

    g_device
-> Clear( 0 , NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 5 5 5 ),  1.0f 0 );    

    g_device
-> BeginScene();

    g_device
-> SetStreamSource( 0 , g_vertex_buffer,  0 sizeof (sCustomVertex));
    g_device
-> SetFVF(D3DFVF_CUSTOM_VERTEX);    
    g_device
-> DrawPrimitive(D3DPT_TRIANGLELIST,  0 1 );

    g_device
-> EndScene();

    g_device
-> Present(NULL, NULL, NULL, NULL);
}

LRESULT WINAPI WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    
switch (msg)
    {
    
case  WM_LBUTTONDOWN:
        g_support_anti_aliasing 
=   ! g_support_anti_aliasing;
        
break ;

    
case  WM_KEYDOWN:
        
switch (wParam)
        {    
        
case  VK_ESCAPE:
            DestroyWindow(hwnd);
            
break ;
        }    
        
break ;

    
case  WM_DESTROY:        
        PostQuitMessage(
0 );
        
return   0 ;
    }

    
return  DefWindowProc(hwnd, msg, wParam, lParam);
}

int  WINAPI WinMain(HINSTANCE inst, HINSTANCE, LPSTR, INT)
{
    WNDCLASSEX wc;

    wc.cbSize            
=   sizeof (WNDCLASSEX);
    wc.style            
=  CS_CLASSDC;
    wc.lpfnWndProc        
=  WinProc;
    wc.cbClsExtra        
=   0 ;
    wc.cbWndExtra        
=   0 ;
    wc.hInstance        
=  inst;
    wc.hIcon            
=  NULL;
    wc.hCursor            
=  NULL;
    wc.hbrBackground    
=  NULL;
    wc.lpszMenuName        
=  NULL;
    wc.lpszClassName    
=  CLASS_NAME;
    wc.hIconSm            
=  NULL;

    
if ( !  RegisterClassEx( & wc))
        
return   - 1 ;

    HWND hwnd 
=  CreateWindow(CLASS_NAME,  " Direct3D App " , WS_OVERLAPPEDWINDOW,  200 100 300 300 ,
                             NULL, NULL, wc.hInstance, NULL);

    
if (hwnd  ==  NULL)
        
return   - 1 ;

    
if (init_d3d(hwnd))
    {
        ShowWindow(hwnd, SW_SHOWMAXIMIZED);
        UpdateWindow(hwnd);

        MSG msg;
        ZeroMemory(
& msg,  sizeof (msg));

        
while (msg.message  !=  WM_QUIT)
        {
            
if (PeekMessage( & msg, NULL,  0 0 , PM_REMOVE))
            {
                TranslateMessage(
& msg);
                DispatchMessage(
& msg);
            }
                
            render();
        }
    }

    cleanup();

    UnregisterClass(CLASS_NAME, wc.hInstance);    

    
return   0 ;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值