在渲染多边形网格对象到场景中的时候,离观察者越远的对象应该越模糊,同时离观察者越近的物体应该越清楚,这就是深度排序(depth sorting)。深度排序有两种常用的方法。

第一种方法称为画家算法(painter's algorithm)。这种方法将对象划分成不同的多边形,由后往前对这些多边形进行排序,再按照排好的顺序绘制出这些多边形。采用这种方法绘制多边形,能够确保前面的多边形总是在其后多边形之前进行绘制。

深度排序的第二种方法称为z缓冲方法(z- buffer),它是图形硬件设备使用最多的方法。这种方法依赖于像素,每个像素都有一个z值(z值是像素距离观察者的距离)。当每个像素被写入时,渲染器首先检查是否已经存在一个z值更小的像素,如果不存在,这个像素就被绘制出来;如果存在,就跳过该像素。

许多 3D图形加速卡都有一个内置的z缓冲,这也是深度排序选择z缓冲方法的原因。在应用程序中使用z缓冲,最容易的方法就是在创建设备对象以及设置显示方式的时候初始化z缓冲,如下所示:

D3DPRESENT_PARAMETERS d3dpp;

ZeroMemory(&d3dpp, sizeof(d3dpp));

d3dpp.Windowed                = TRUE;
  d3dpp.SwapEffect              = D3DSWAPEFFECT_DISCARD;
  d3dpp.BackBufferFormat        = d3ddm.Format;
  d3dpp.EnableAutoDepthStencil  = TRUE;
  d3dpp.AutoDepthStencilFormat  = D3DFMT_D16;

if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd,
                                 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice)))
    return FALSE;

// Set the rendering states
  g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
  g_pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

同时在绘制每帧之前应该用IDirect3DDevice9::Clear来清除z缓存。

// clear device back buffer
    g_d3d_device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(0, 0, 0, 255), 1.0f, 0);

完整代码如下所示:

/***************************************************************************************
PURPOSE:
    ZBuffer Demo

Required libraries:
  WINMM.LIB, D3D9.LIB, D3DX9.LIB.
***************************************************************************************/

#include <windows.h>
#include <stdio.h>
#include "d3d9.h"
#include "d3dx9.h"

#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")

#pragma warning(disable : 4305)

#define WINDOW_WIDTH    400
#define WINDOW_HEIGHT   400

#define Safe_Release(p) if((p)) (p)->Release();

// window handles, class and caption text.
HWND g_hwnd;
HINSTANCE g_inst;
static char g_class_name[] = "ZBufferClass";
static char g_caption[]    = "ZBuffer Demo";

// the Direct3D and device object
IDirect3D9* g_d3d = NULL;
IDirect3DDevice9* g_d3d_device = NULL;

// The 3D vertex format and descriptor
typedef struct
{
    float x, y, z;  // 3D coordinates   
    D3DCOLOR color; // diffuse color
} VERTEX;

#define VERTEX_FVF   (D3DFVF_XYZ | D3DFVF_DIFFUSE)

IDirect3DVertexBuffer9* g_vertex_buffer = NULL;

//--------------------------------------------------------------------------------
// Window procedure.
//--------------------------------------------------------------------------------
long WINAPI Window_Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }

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

//--------------------------------------------------------------------------------
// Initialize d3d, d3d device, vertex buffer; set render state for d3d;
// set perspective matrix and view matrix.
//--------------------------------------------------------------------------------
BOOL Do_Init()
{
    D3DPRESENT_PARAMETERS present_param;
    D3DDISPLAYMODE  display_mode;
    D3DXMATRIX mat_proj, mat_view;
    BYTE* vertex_ptr;

// initialize vertex data
    VERTEX verts[] = {
      { -100.0f, -100.0f, 0.0f, D3DCOLOR_RGBA(255,0,0,255) },
      { -100.0f,  100.0f, 0.0f, D3DCOLOR_RGBA(255,0,0,255) },
      {  100.0f, -100.0f, 0.0f, D3DCOLOR_RGBA(255,0,0,255) },
      {  100.0f,  100.0f, 0.0f, D3DCOLOR_RGBA(255,0,0,255) },
      { -100.0f, -100.0f, 0.0f, D3DCOLOR_RGBA(255,0,0,255) },
      { -100.0f,  100.0f, 0.0f, D3DCOLOR_RGBA(255,0,0,255) },

{ -100.0f, -100.0f, 0.0f, D3DCOLOR_RGBA(0,0,255,255) },
      { -100.0f,  100.0f, 0.0f, D3DCOLOR_RGBA(0,0,255,255) },
      {  100.0f, -100.0f, 0.0f, D3DCOLOR_RGBA(0,0,255,255) },
      {  100.0f,  100.0f, 0.0f, D3DCOLOR_RGBA(0,0,255,255) },
    };

// do a windowed mode initialization of Direct3D
    if((g_d3d = Direct3DCreate9(D3D_SDK_VERSION)) == NULL)
        return FALSE;

// retrieves the current display mode of the adapter
    if(FAILED(g_d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &display_mode)))
        return FALSE;

ZeroMemory(&present_param, sizeof(present_param));

// initialize d3d presentation parameter
    present_param.Windowed               = TRUE;
    present_param.SwapEffect             = D3DSWAPEFFECT_DISCARD;
    present_param.BackBufferFormat       = display_mode.Format;
    present_param.EnableAutoDepthStencil = TRUE;
    present_param.AutoDepthStencilFormat = D3DFMT_D16;

// creates a device to represent the display adapter
    if(FAILED(g_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hwnd,
                                  D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_param, &g_d3d_device)))
        return FALSE;

// set render state

// disable d3d lighting
    g_d3d_device->SetRenderState(D3DRS_LIGHTING, FALSE);
    // enable z-buffer
    g_d3d_device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

// create and set the projection matrix

// builds a left-handed perspective projection matrix based on a field of view
    D3DXMatrixPerspectiveFovLH(&mat_proj, D3DX_PI/4.0, 1.33333, 1.0, 1000.0);

// sets a single device transformation-related state
    g_d3d_device->SetTransform(D3DTS_PROJECTION, &mat_proj);

// create and set the view matrix
    D3DXMatrixLookAtLH(&mat_view,
                       &D3DXVECTOR3(0.0, 0.0, -500.0),
                       &D3DXVECTOR3(0.0f, 0.0f, 0.0f),
                       &D3DXVECTOR3(0.0f, 1.0f, 0.0f));

g_d3d_device->SetTransform(D3DTS_VIEW, &mat_view);

// create the vertex buffer and set data
    g_d3d_device->CreateVertexBuffer(sizeof(verts), 0, VERTEX_FVF, D3DPOOL_DEFAULT, &g_vertex_buffer, NULL);

// locks a range of vertex data and obtains a pointer to the vertex buffer memory
    g_vertex_buffer->Lock(0, 0, (void**)&vertex_ptr, 0);

memcpy(vertex_ptr, verts, sizeof(verts));

// unlocks vertex data
    g_vertex_buffer->Unlock();

return TRUE;
}

//--------------------------------------------------------------------------------
// Release all d3d resource.
//--------------------------------------------------------------------------------
BOOL Do_Shutdown()
{
    Safe_Release(g_vertex_buffer);
    Safe_Release(g_d3d_device);
    Safe_Release(g_d3d);

return TRUE;
}

//--------------------------------------------------------------------------------
// Render a frame.
//--------------------------------------------------------------------------------
BOOL Do_Frame()
{
    D3DXMATRIX mat_world;

// clear device back buffer
    g_d3d_device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(0, 0, 0, 255), 1.0f, 0);

// Begin scene
    if(SUCCEEDED(g_d3d_device->BeginScene()))
    {
        // set the vertex stream, shader.

// binds a vertex buffer to a device data stream
        g_d3d_device->SetStreamSource(0, g_vertex_buffer, 0, sizeof(VERTEX));

// set the current vertex stream declation
        g_d3d_device->SetFVF(VERTEX_FVF);

// create and set the world transformation matrix
        // rotate object along y-axis
        D3DXMatrixRotationY(&mat_world, (float) (timeGetTime() / 1000.0));
       
        g_d3d_device->SetTransform(D3DTS_WORLD, &mat_world);

// renders a sequence of noindexed, geometric primitives of the specified type from the current set
        // of data input stream.
        g_d3d_device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 4);

// draw next four polygons, but rotate on z-axis.
        D3DXMatrixRotationZ(&mat_world, -(float)(timeGetTime() / 1000.0));
        g_d3d_device->SetTransform(D3DTS_WORLD, &mat_world);
        g_d3d_device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 6, 2);

// end the scene
        g_d3d_device->EndScene();
    }

// present the contents of the next buffer in the sequence of back buffers owned by the device
    g_d3d_device->Present(NULL, NULL, NULL, NULL);

return TRUE;
}

//--------------------------------------------------------------------------------
// Main function, routine entry.
//--------------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE inst, HINSTANCE, LPSTR cmd_line, int cmd_show)
{
    WNDCLASSEX  win_class;
    MSG         msg;

g_inst = inst;

// create window class and register it
    win_class.cbSize        = sizeof(win_class);
    win_class.style         = CS_CLASSDC;
    win_class.lpfnWndProc   = Window_Proc;
    win_class.cbClsExtra    = 0;
    win_class.cbWndExtra    = 0;
    win_class.hInstance     = inst;
    win_class.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    win_class.hCursor       = LoadCursor(NULL, IDC_ARROW);
    win_class.hbrBackground = NULL;
    win_class.lpszMenuName  = NULL;
    win_class.lpszClassName = g_class_name;
    win_class.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

if(! RegisterClassEx(&win_class))
        return FALSE;

// create the main window
    g_hwnd = CreateWindow(g_class_name, g_caption, WS_CAPTION | WS_SYSMENU, 0, 0,
                          WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, inst, NULL);

if(g_hwnd == NULL)
        return FALSE;

ShowWindow(g_hwnd, SW_NORMAL);
    UpdateWindow(g_hwnd);

// initialize game
    if(Do_Init() == FALSE)
        return FALSE;

// start message pump, waiting for signal to quit.
    ZeroMemory(&msg, sizeof(MSG));

while(msg.message != WM_QUIT)
    {
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
       
        // draw a frame
        if(Do_Frame() == FALSE)
            break;
    }

// run shutdown function
    Do_Shutdown();

UnregisterClass(g_class_name, inst);
   
    return (int) msg.wParam;
}

效果图:

D3D中的Z缓存使用示例相关推荐

  1. [ZZ] D3D中的模板缓存(3)

    http://www.cppblog.com/lovedday/archive/2008/03/25/45334.html http://www.cppblog.com/lovedday/ D3D中的 ...

  2. 【Visual C++】游戏开发笔记四十五 浅墨DirectX教程十三 深度测试和Z缓存专场

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8607864 作者:毛星云(浅墨 ...

  3. 深度测试和Z缓存专场

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8607864 作者:毛星云(浅墨 ...

  4. python pytorch fft_PyTorch 中的傅里叶卷积实现示例

    卷积 卷积在数据分析中无处不在.几十年来,它们一直被用于信号和图像处理.最近,它们成为现代神经网络的重要组成部分.如果你处理数据的话,你可能会遇到错综复杂的问题. 数学上,卷积表示为: 尽管离散卷积在 ...

  5. 在ASP.NET Core应用程序中使用分布式缓存

    本文要点 ASP.NET Core内置了分布式缓存接口. 分布式缓存的主要好处有性能.数据共享和稳定性. Couchbase服务器是一个内存优先的数据库,非常适合作为分布式缓存. NuGet程序包使得 ...

  6. Ocelot中文文档-缓存

    Ocelot中文文档-缓存 原文:Ocelot中文文档-缓存 目前Ocelot使用CacheManager项目提供了一些非常基本的缓存.这是一个了不起的项目,它解决了很多缓存问题. 我会推荐这个软件包 ...

  7. python中case的用法_python中Switch/Case实现的示例代码

    python 的 python中Switch/Case实现的示例代码 学习Python过程中,发现没有switch-case,过去写C习惯用Switch/Case语句,官方文档说通过if-elif实现 ...

  8. ASP.NET Core中的内存缓存

    ASP.NET Core中的内存中缓存 让我们看看如何通过缓存优化ASP.NET Core应用程序性能 我相信,在我们的工作中,每个人都收到来自客户的请求或来自我们应用程序用户的反馈,以提高响应速度. ...

  9. ASP.NET Core中的Http缓存

    ASP.NET Core中的Http缓存 Http响应缓存可减少客户端或代理对 web服务器发出的请求数.响应缓存还减少了 web服务器生成响应所需的工作量.响应缓存由 Http请求中的 header ...

最新文章

  1. 江苏开放大学计算机应用基础第四次作业,江苏开放大学-计算机应用基础第四次.doc...
  2. 廉价的悼念让死者生气,用区块链营造一个像样的纪念
  3. UIAutomation识别UI元素
  4. windows下python视频加速调节_Windows下python+ffmpeg实现批量提取、切割视频中的音频...
  5. Mongodb 与sql 语句对照
  6. mysql为何不支持开窗函数?
  7. ModuleNotFoundError: No module named 'sklearn.grid_search'报错
  8. 2.5. 标准路由器:Zend_Controller_Router_Rewrite
  9. [CareerCup] 18.4 Count Number of Two 统计数字2的个数
  10. 【优化预测】基于matlab飞蛾扑火算法优化LSSVM预测【含Matlab源码 142期】
  11. refprop用matlab,Matlab 调用 REFPROP(64位)下载即可用
  12. Path.Combine 合并两个路径字符串,会出现的问题
  13. 软考|高级信息系统项目管理师
  14. java soap_Java使用SOAP协议访问webservice接口
  15. 安装和卸载office以及激活电脑系统血淋淋的教训
  16. 无为而无不为——论老子哲学的深度悖论(转载)
  17. 智慧公安大数据人工智能
  18. Centos8.0: 环境搭建,看这里就够了。
  19. 漫画 |《帝都程序猿十二时辰》
  20. 2019年上半年 DDOS流量攻击分析以及解决方案

热门文章

  1. AS百度地图Didn't find class vi.com.gdi.bgl.android.java.EnvDrawText
  2. springboot毕设项目基于的大学生创新创业项目的管理系统kri27(java+VUE+Mybatis+Maven+Mysql)
  3. 炫酷的鼠标特效JS 原生代码
  4. design-patter(js设计模式)
  5. Typora主题修改、VScode主题
  6. VScode 主题字体颜色 必备插件
  7. 专访天数智芯核心硬件团队:从芯片到应用打造完整生态
  8. 【专题4:直流无刷电机控制】 之 【4.驱动器设计 - 电源软启动设计】
  9. 全球月活用户4年破10亿,TikTok的3大底层逻辑
  10. CAD界面为啥会出现马赛克,又该如何解决