D3D中的Z缓存使用示例
在渲染多边形网格对象到场景中的时候,离观察者越远的对象应该越模糊,同时离观察者越近的物体应该越清楚,这就是深度排序(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缓存使用示例相关推荐
- [ZZ] D3D中的模板缓存(3)
http://www.cppblog.com/lovedday/archive/2008/03/25/45334.html http://www.cppblog.com/lovedday/ D3D中的 ...
- 【Visual C++】游戏开发笔记四十五 浅墨DirectX教程十三 深度测试和Z缓存专场
本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8607864 作者:毛星云(浅墨 ...
- 深度测试和Z缓存专场
本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8607864 作者:毛星云(浅墨 ...
- python pytorch fft_PyTorch 中的傅里叶卷积实现示例
卷积 卷积在数据分析中无处不在.几十年来,它们一直被用于信号和图像处理.最近,它们成为现代神经网络的重要组成部分.如果你处理数据的话,你可能会遇到错综复杂的问题. 数学上,卷积表示为: 尽管离散卷积在 ...
- 在ASP.NET Core应用程序中使用分布式缓存
本文要点 ASP.NET Core内置了分布式缓存接口. 分布式缓存的主要好处有性能.数据共享和稳定性. Couchbase服务器是一个内存优先的数据库,非常适合作为分布式缓存. NuGet程序包使得 ...
- Ocelot中文文档-缓存
Ocelot中文文档-缓存 原文:Ocelot中文文档-缓存 目前Ocelot使用CacheManager项目提供了一些非常基本的缓存.这是一个了不起的项目,它解决了很多缓存问题. 我会推荐这个软件包 ...
- python中case的用法_python中Switch/Case实现的示例代码
python 的 python中Switch/Case实现的示例代码 学习Python过程中,发现没有switch-case,过去写C习惯用Switch/Case语句,官方文档说通过if-elif实现 ...
- ASP.NET Core中的内存缓存
ASP.NET Core中的内存中缓存 让我们看看如何通过缓存优化ASP.NET Core应用程序性能 我相信,在我们的工作中,每个人都收到来自客户的请求或来自我们应用程序用户的反馈,以提高响应速度. ...
- ASP.NET Core中的Http缓存
ASP.NET Core中的Http缓存 Http响应缓存可减少客户端或代理对 web服务器发出的请求数.响应缓存还减少了 web服务器生成响应所需的工作量.响应缓存由 Http请求中的 header ...
最新文章
- 江苏开放大学计算机应用基础第四次作业,江苏开放大学-计算机应用基础第四次.doc...
- 廉价的悼念让死者生气,用区块链营造一个像样的纪念
- UIAutomation识别UI元素
- windows下python视频加速调节_Windows下python+ffmpeg实现批量提取、切割视频中的音频...
- Mongodb 与sql 语句对照
- mysql为何不支持开窗函数?
- ModuleNotFoundError: No module named 'sklearn.grid_search'报错
- 2.5. 标准路由器:Zend_Controller_Router_Rewrite
- [CareerCup] 18.4 Count Number of Two 统计数字2的个数
- 【优化预测】基于matlab飞蛾扑火算法优化LSSVM预测【含Matlab源码 142期】
- refprop用matlab,Matlab 调用 REFPROP(64位)下载即可用
- Path.Combine 合并两个路径字符串,会出现的问题
- 软考|高级信息系统项目管理师
- java soap_Java使用SOAP协议访问webservice接口
- 安装和卸载office以及激活电脑系统血淋淋的教训
- 无为而无不为——论老子哲学的深度悖论(转载)
- 智慧公安大数据人工智能
- Centos8.0: 环境搭建,看这里就够了。
- 漫画 |《帝都程序猿十二时辰》
- 2019年上半年 DDOS流量攻击分析以及解决方案
热门文章
- AS百度地图Didn't find class vi.com.gdi.bgl.android.java.EnvDrawText
- springboot毕设项目基于的大学生创新创业项目的管理系统kri27(java+VUE+Mybatis+Maven+Mysql)
- 炫酷的鼠标特效JS 原生代码
- design-patter(js设计模式)
- Typora主题修改、VScode主题
- VScode 主题字体颜色 必备插件
- 专访天数智芯核心硬件团队:从芯片到应用打造完整生态
- 【专题4:直流无刷电机控制】 之 【4.驱动器设计 - 电源软启动设计】
- 全球月活用户4年破10亿,TikTok的3大底层逻辑
- CAD界面为啥会出现马赛克,又该如何解决