坐标系与基本图元(7)

坐标系与基本图元(7)

场景提交概述

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

(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.

Method Parameters Sub-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;
}

时间: 2024-10-18 21:37:12

坐标系与基本图元(7)的相关文章

坐标系与基本图元~转载天行健 君子当自强而不息

坐标系与基本图元 坐标系与基本图元(8)      摘要: 游戏程序通常都是运行在全屏幕模式下,进行全屏显示的关键是使用全屏显示的渲染设备.创建全屏显示模式渲染设备同窗口模式渲染设备基本相同,区别是将 d3dpp.Windowed设置为FALSE,告诉Direct3D系统,将要创建的是全屏模式渲染设备.此外,还需要明确指定后台缓冲区的大小和格式,这和创建窗口模式渲染设备是不相同的,在创建窗口模式渲染设备时可将后台缓冲区格式设置为D3DFMT_UNKNOWN,后台缓冲区大小也可取默认值,而在创建全

坐标系与基本图元(3)

坐标系与基本图元(3) 渲染顶点缓冲区图形 void render(){ g_device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_X#050505, 1.0f, 0); g_device->BeginScene(); g_device->SetStreamSource(0, g_vertex_buffer, 0, sizeof(sCustomVertex)); g_device->SetFVF(D3DFVF_CUSTOM_VERTEX)

坐标系与基本图元(8)

坐标系与基本图元(8) 全屏幕显示 游戏程序通常都是运行在全屏幕模式下,进行全屏显示的关键是使用全屏显示的渲染设备.创建全屏显示模式渲染设备同窗口模式渲染设备基本相同,区别是将d3dpp.Windowed设置为FALSE,告诉Direct3D系统,将要创建的是全屏模式渲染设备.此外,还需要明确指定后台缓冲区的大小和格式,这和创建窗口模式渲染设备是不相同的,在创建窗口模式渲染设备时可将后台缓冲区格式设置为D3DFMT_UNKNOWN,后台缓冲区大小也可取默认值,而在创建全屏模式渲染设备时这些都需要

坐标系与基本图元(1) ~转载天行健 君子当自强而不息

坐标系与基本图元(1) Direct3D基本图元 图元(primitives)是Direct3D中定义的基本图形表示,它是组成一个单一实体的一组顶点.最简单的图元是三维坐标系中多个点的集合,称为点列表(point list).通常,图元是多边形(polygon),一个多边形是由至少三条边组成的封闭图形.最简单的多边形是三角形,Direct3D使用三角形来构成大多数其他多边形,这是因为三角形的三个顶点肯定是共面的,而渲染不共面的顶点效率比较低.通过组合三角形可以形成更大.更复杂的多边形和网格(me

坐标系与基本图元(5)

坐标系与基本图元(5) 使用索引缓冲区绘制图形 当绘制一个比较复杂的图形时,需要使用许多相互邻接的三角形.如果为每个三角形准备三个顶点数据,显然有许多数据是重复的,这样会浪费大量的内存和系统带宽.为了解决这一问题,可以先创建一个顶点缓冲区,将不重复的顶点数据写入顶点缓冲区,然后创建一个顶点索引缓冲区(index buffer),存放各个三角形的顶点索引信息,最后通过顶点索引和顶点数据共同完成图形绘制. 在Direct3D中一个顶点的索引只需要用一个16位或32位的整数表示,因此当多边形的顶点有较

坐标系与基本图元(4)

坐标系与基本图元(4) 各种基本图元的绘制 上面使用顶点缓冲区绘制的是三角形列表图元,前面介绍过Direct3D支持点列表,线段列表.线段条带.三角形列表.三角形条带.三角扇形6种基本图元.下面通过示例程序BasicPrimitive演示各种基本图元的绘制.该示例程序使用同一个顶点缓冲区绘制不同类型的图元,程序中通过一个全局变量标识当前绘制的图元类型,通过单击键盘上的"1" ~ "6"数字键可以在各图元类型之间进行切换,单击空格键可以在线框模式和实体模式之间切换.

坐标系与基本图元(2)

坐标系与基本图元(2) 创建顶点缓冲区 在创建顶点缓冲区之前,需要先定义一个表示顶点的结构类型,描述顶点保存格式的FVF和一个保存顶点的结构数组. struct sCustomVertex{ float x, y, z, rhw; DWORD color;}; #define D3DFVF_CUSTOM_VERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE) sCustomVertex vertices[] ={ { 100.0f, 400.0f, 1.0f, 1.0f,

坐标系与基本图元(6)

坐标系与基本图元(6) 灵活顶点格式 灵活顶点格式(Flexible Vertex Format, FVF)用来描述在顶点缓冲区中的顶点存储格式中包含了哪些属性.Direct3D应用程序可以用几种不同的方式定义灵活顶点格式.灵活顶点格式使应用程序只使用它需要的顶点数据,排除那些它不需要的组成成分.这样,应用程序可以节省内存空间,减少系统带宽.通过D3DFVF的组合,可以描述图元顶点的格式.灵活顶点格式指定的格式包括点的大小,用D3DFVF_PSIZE指定,该大小在投影机空间用来表示未经变换的顶点

Qt5图形视图框架之概念篇(1)

本章将主要简述Graphics View框架结构的特点.主要包含的元素及坐标系统. 1.Graphics View框架结构的特点: (1)系统可以利用Qt绘图系统的反锯齿.OpenGL工具来改善绘图性能. (2)其支持事件传播结构,可以使图元在场景中的交互能力提高一倍,凸缘可以处理键盘事件和鼠标事件. (3)通过BSP提供快速的图元查找,可以实现实时显示包含数百万图元的大场景. 2.Graphics View的三元素: (1)场景类(QGraphicsScene):本身不可见,是一个放置图元的容