一、预备知识

1、表面

表面就是Direct3D用于储存2D图像数据的一个像素矩阵。width和height以像素为单位,pitch以字节单位,用接口IDirect3DSurface来描述表面

LockRect:该方法用于获取指向表面存储区的指针,通过通过指针运算,可对每个像素进行读写操作;

UnlockRect:配对使用,调用lock必须unlock,解除对表面存储区的锁定;

GetDesc: 获取表面的描述信息,通过填充D3DSURFACE_DESC;

//Assume _surface is a pointer to an IDirect3DSurface9 interface
//Assume a 32-bit pixel format for each pixel //Get the surface description.
D3DSURFACE_DESC surfaceDesc;
_surface->GetDesc(&surfaceDesc); //Get a pointer to the surface pixel data
D3DLOCKED_RECT lockedRect;
_surface->LockRect(
&lockedRect,
,
); //Iterate through each pixel in the surface and set it to red
DWORD *imageData = (DWORD *)lockedRect.pBits;
for (int i = ; i < surfaceDesc.height; ++i)
{
for (int j = ; j < surfaceDesc.width; ++j)
{
int nIndex = i * lockedRect.pitch / + j;
imageData[nIndex] = 0xffff000;
}
}
_surface->UnlockRect();

2、多重采样

多重采样(multisampling)一项用于平滑块状图像的技术

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

typedef enum D3DMULTISAMPLE_TYPE
{
D3DMULTISAMPLE_NONE = ,
D3DMULTISAMPLE_NONMASKABLE = ,
D3DMULTISAMPLE_2_SAMPLES = ,
D3DMULTISAMPLE_3_SAMPLES = ,
D3DMULTISAMPLE_4_SAMPLES = ,
D3DMULTISAMPLE_5_SAMPLES = ,
D3DMULTISAMPLE_6_SAMPLES = ,
D3DMULTISAMPLE_7_SAMPLES = ,
D3DMULTISAMPLE_8_SAMPLES = ,
D3DMULTISAMPLE_9__SAMPLES = ,
D3DMULTISAMPLE_10_SAMPLES = ,
D3DMULTISAMPLE_11_SAMPLES = ,
D3DMULTISAMPLE_12_SAMPLES = ,
D3DMULTISAMPLE_13_SAMPLES = ,
D3DMULTISAMPLE_14_SAMPLES = ,
D3DMULTISAMPLE_15_SAMPLES = ,
D3DMULTISAMPLE_16_SAMPLES = ,
D3DMULTISAMPLE_FORCE_DWORD = 0xffffffff,
} D3DMULTISAMPLE_TYPE, *LPD3DMULTISAMPLE_TYPE;

3、像素格式D3DFORMAT

创建表面或者纹理(texture)时需要指定像素格式

D3DFMT_R8G8B8 D3DFMT_X8R8G8B8 D3DFMT_A8R8G8B8 D3DFMT_A16B16G16R16F D3DFMT_A32B32G32R32F D3DFMT_DXT5

4、内存池

D3D RUTIME的内存类型,分为3种,VIDEO MEMORY(VM)、AGP MEMORY(AM)和SYSTEM MEMORY(SM)

VIDEO MEMORY(VM):VM就是位于显卡上的显存,CPU只能通过AGP或PCI-E总线访问到,读写速度都是非常慢的,
                               CPU连续写VM稍微快于读,因为CPU写VM时会在CACHE中分配32或64个字节(取决于CACHE LINE长度)
                               的写缓冲,当缓冲满后会一次性写入VM;

SYSTEM MEMORY(SM):SM就是系统内存,CPU读写都非常快,
                                  因为SM是被CACHE到2级缓冲的,但GPU却不能直接访问到系统缓冲,所以创建在SM中的资源,
                                  GPU是不能直接使用的;

AGP MEMORY(AM):AM是最麻烦的一个类型,AM实际也存在于系统内存中,
                            但这部分MEM不会被CPU CACHE,意味着CPU读写AM都会写来个CACHE MISSING然后才通过内存总线访问AM,
                            所以CPU读写AM相比SM会比较慢,但连续的写会稍微快于读,
                            原因就是CPU写AM使用了“write combining”,而且GPU可以直接通过AGP或PCI-E总线访问AM

所有D3D资源都创建在这3种内存之中,在创建资源时,我们可以指定如下存储标志,
D3DPOOL_DEFAULT、D3DPOOL_MANAGED、D3DPOOL_SYSTEMMEM和D3DPOOL_SCRATCH

D3DPOOL_DEFAULT:默认值,该类型的内存池指示Direct3D将资源放入最适合该资源类型极其适用方式的存储区中。该存储区可能是显存,AGP存储区或系统存储区。注意,调用IDirect3DDevice9::Reset之前,必须对默认内存池中的资源销毁或释放。上述函数调用后,还必须对内存池中的资源重新初始化。
D3DPOOL_MANAGE:放入该托管内存池中的资源交由Direct3D管理(即资源将根据需要被设备自动转移到显存或AGP存储区中)。此外,这些资源将在系统存储区中保留一个备份。这样,必要时,Direct3D会将这些资源自动更新到显存中。
D3DPOOL_SYSTEMMEM:指定将资源放入系统存储区中。
D3DPOOL_SCRATCH:指定将资源放入系统存储区中。不同于D3DPOOL_SYSTEMMEM,这些资源不受图形设备的制约。所以,设备无法访问该类型内存池中的资源。但这些资源之间可互相复制。

5、交换链和页面置换

Direct3D维护着一个表面集合,该集合通常由两到三个表面组成,称为交换链。该集合用接口IDirect3DSwapChain9来表示。

交换链和页面置换技术主要用于生成更加平滑的动画。

6、深度缓存

深度缓存是一个只含有特定像素的深度信息而不含图像数据的表面。深度缓存为最终绘制的图像中的每一个像素都保留了一个深度项。所以,当绘制的图像的分辨率为640X800,深度缓存中有640X800个深度项。

前面物体部分遮挡位于其后的物体,Direct3D为了判定某一个物体的哪些像素位于另一个物体之前。使用了一项称为深度缓存或z-缓存的技术。

深度缓存用于计算每个像素的深度值,并进行深度测试。深度测试的基本内容是依据深度值让处于同一位置的不同像素进行竞争。以选出应写入该位置的像素。距离摄像机最近的像素获胜,并被写入深度缓存的相应位置。

深度缓存的格式决定了深度测试的精度。24位的深度缓存要比16位的深度缓存精确得多。

D3DFMT_D32:32位深度缓存。
     D3DFMT_D24S8:24位深度缓存,其中8位保留供模板缓存使用。
     D3DFMT_D24X8:仅指定24位深度缓冲。
     D3DFMT_X4S4:指定24位深度缓存,其中4位保留供模板缓存使用。
     D3DFMT_D16:仅指定16位深度缓存。

二、Direct3D的初始化

1、获取接口IDirect3D9的指针

IDirect3D9* Direct3DCreate9(
UINT SDKVersion
);
Create an IDirect3D9 object and return an interface to it.

SDKVersion:The value of this parameter should be D3D_SDK_VERSION

//step 1: Create the IDirect3D9 object
IDirect3D9 d3d9;
d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
 

2、校验硬件顶点运算

//step 2: Check for hardware vp
// HRESULT GetDeviceCaps(
// [in] UINT Adapter,
// [in] D3DDEVTYPE DeviceType,
// [out] D3DCAPS9 *pCaps
// );
// Adapter [in]
// Type: UINT
// Ordinal number that denotes the display adapter. D3DADAPTER_DEFAULT is always the primary display adapter.
// DeviceType [in]
// Type: D3DDEVTYPE
// Member of the D3DDEVTYPE enumerated type. Denotes the device type.
// pCaps [out]
// Type: D3DCAPS9*
// Pointer to a D3DCAPS9 structure to be filled with information describing the capabilities of the device.
D3DCAPS9 caps;
d3d9.GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps); int vp = ;
if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

3、填充D3DPRESENT_PARAMETER结构

//step 3: Fill out the D3DPRESENT_PARAMETERS structure.

    D3DPRESENT_PARAMETERS d3dpp;
d3dpp.BackBufferWidth = nWidth; //后台缓冲中表面的宽度,单位为像素
d3dpp.BackBufferHeight = nHeight; //后台缓冲中表面的高度,单位为像素
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; //后台缓冲的像素格式
d3dpp.BackBufferCount = ; //需要时用的后台缓存个数,通常为1
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; //后台缓存使用的多重采样类型
d3dpp.MultiSampleQuality = ; //多重采样质量水平
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; //D3DSWAPEFFECT枚举类型的一个成员,该类型指定了交换链中的缓冲的页面置换方式,D3DSWAPEFFECT_DISCARD时效果最高
d3dpp.hDeviceWindow = hWnd; //指定所以进行绘制的应用程序窗口
d3dpp.Windowed = bWindowed; //true:窗口模式 false:全屏模式
d3dpp.EnableAutoDepthStencil = true; //true:Dierct3D自动创建并维护深度缓存或者模板缓存
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; //深度缓存或者模板缓存的像素格式(D3DFMT_D24S8 24位深度,8位模板)
d3dpp.Flags = ; //附加特性 0无标记或D3DPRESENTFLAG集合中的一个成员 常用的2个
//D3DPRESENTFLAG_LOCKABLE_DEPTHBUFFER 指定可锁定后台缓存,可能会减低性能
//D3DPRESENTFLAG_DISCARD_DEPTHBUFFER 指定当下一个后台缓存提交时,哪个深度或者模板缓存将被丢弃。这样可以提升性能;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; //刷新频率
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;//D3DPRESENT集合中的一个成员,
//D3DPRESENT_INTERVAL_IMMEDIATE 立即提交

4、创建IDirect3DDevice9接口

hResult = d3d9->CreateDevice(
D3DADAPTER_DEFAULT, // primary adapter
deviceType, // device type
hWnd, // window associated with device
vp, // vertex processing
&d3dpp, // present parameters
device); // return created device if(FAILED(hResult))
{
// try again using a 16-bit depth buffer
d3dpp.AutoDepthStencilFormat = D3DFMT_D16; hResult = d3d9->CreateDevice(
D3DADAPTER_DEFAULT,
deviceType,
hWnd,
vp,
&d3dpp,
device); if(FAILED(hResult))
{
d3d9->Release(); // done with d3d9 object
::MessageBox(, "CreateDevice() - FAILED", , );
return false;
}
}

最后贴一下自己的成果,虽然基本是从龙书上copy下来 o(╯□╰)o

DX笔记之一---Direct3D基础的更多相关文章

  1. 【转载】Direct3D基础知识

    原文:Direct3D基础知识 重新从头开始学习DX,以前太急于求成了,很多基础知识都没掌握就开始写程序了,结果出了问题很难解决.   1.       D3D体系结构 D3D与GDI处与同一层次,区 ...

  2. DirectX11笔记(五)--Direct3D渲染1--VERTICES AND INPUT LAYOUTS

    原文:DirectX11笔记(五)--Direct3D渲染1--VERTICES AND INPUT LAYOUTS 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.c ...

  3. DirectX11笔记(三)--Direct3D初始化2

    原文:DirectX11笔记(三)--Direct3D初始化2 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010333737/article/ ...

  4. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  5. [Java入门笔记] 面向对象编程基础(二):方法详解

    什么是方法? 简介 在上一篇的blog中,我们知道了方法是类中的一个组成部分,是类或对象的行为特征的抽象. 无论是从语法和功能上来看,方法都有点类似与函数.但是,方法与传统的函数还是有着不同之处: 在 ...

  6. 8.python笔记之面向对象基础

    title: 8.Python笔记之面向对象基础 date: 2016-02-21 15:10:35 tags: Python categories: Python --- 面向对象思维导图 (来自1 ...

  7. Java学习笔记:语言基础

    Java学习笔记:语言基础 2014-1-31   最近开始学习Java,目的倒不在于想深入的掌握Java开发,而是想了解Java的基本语法,可以阅读Java源代码,从而拓展一些知识面.同时为学习An ...

  8. 卷积神经网络(CNN)学习笔记1:基础入门

    卷积神经网络(CNN)学习笔记1:基础入门 Posted on 2016-03-01   |   In Machine Learning  |   9 Comments  |   14935  Vie ...

  9. Linux及Arm-Linux程序开发笔记(零基础入门篇)

    Linux及Arm-Linux程序开发笔记(零基础入门篇)  作者:一点一滴的Beer http://beer.cnblogs.com/ 本文地址:http://www.cnblogs.com/bee ...

随机推荐

  1. ServiceStack.Redis常用操作 - 事务、并发锁

    一.事务 使用IRedisClient执行事务示例: using (IRedisClient RClient = prcm.GetClient()) { RClient.Add("key&q ...

  2. Go语言的学习

    1.配置环境变量 2.本地阅读报的说明和文档 不用FQ window+R  出现黑窗口   执行    godoc -http :8080 在本地浏览器 localhost:8080 回车 3多行注释 ...

  3. A configuration error occurred during startup. Please verify the preference field with the prompt: Cannot connect to vm

    1.报错图 解决方法: Window->Preferences->MyEclipse Enterprice Workbench->Servers->Tomcat->选择你 ...

  4. python中文乱码例子

    #coding=utf-8 #---中文乱码--- #直接打印中文 print '千里之外取人首级,瞬息之间爆人菊花.' #中文前面加u,变成Unicode编码 print u'千里之外取人首级' # ...

  5. Codevs 3304 水果姐逛水果街Ⅰ 线段树

    题目: http://codevs.cn/problem/3304/   时间限制: 2 s   空间限制: 256000 KB   题目等级 : 钻石 Diamond 题解       题目描述 D ...

  6. Google网页搜索

    本博文的主要内容有 .Google网页搜索的介绍 .Google网页搜索的使用偏好设置 .Google网页搜索的普通搜索 .Google网页搜索的高级搜索 .Google高级搜索之一:布尔逻辑搜索   ...

  7. redis基本用法

    java连接redis基本用法 package Redis;    import java.util.HashMap;  import java.util.List;  import java.uti ...

  8. UVa1151 Buy or Build

    填坑(p.358) 以前天真的以为用prim把n-1条边求出来就可以 现在看来是我想多了 #include<cstdio> #include<cstring> #include ...

  9. Java 多线程并发 Future+callable 实例

    需求:一个业务实现 查询, 因为 要查询十几次, 所以每个平均0.6秒, 之前只有主线程一步步查 ,结果用了10秒,效率十分低下 , 于是改用线程池并发: 以下是代码设计: 1.线程池工具类: pac ...

  10. html5 文件拖拽上传

    本文首先发表在  码蜂笔记 : http://coderbee.net/index.php/web/20130703/266 html5 文件拖拽上传是个老话题了,网上有很多例子,我一开始的代码也是网 ...