DX笔记之一---Direct3D基础

一、预备知识

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,
    0,
    0);

//Iterate through each pixel in the surface and set it to red
DWORD *imageData = (DWORD *)lockedRect.pBits;
for (int i = 0; i < surfaceDesc.height; ++i)
{
    for (int j = 0; j < surfaceDesc.width; ++j)
    {
        int nIndex = i * lockedRect.pitch / 4 + 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 = 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;

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 = 0;
    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;                            //需要时用的后台缓存个数,通常为1
    d3dpp.MultiSampleType                = D3DMULTISAMPLE_NONE;            //后台缓存使用的多重采样类型
    d3dpp.MultiSampleQuality            = 0;                            //多重采样质量水平
    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;                            //附加特性 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(0, "CreateDevice() - FAILED", 0, 0);
            return false;
        }
    }

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

DX笔记之一---Direct3D基础

时间: 2024-10-17 11:07:02

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

加壳学习笔记(二)-汇编基础

7.简单的汇编语法:   堆栈平衡  PUSH,POP功能: 把操作数压入或取出堆栈语法: PUSH 操作数 POP 操作数格式: PUSH r PUSH M PUSH data POP r POP mPUSHF,POPF,PUSHA,POPA功能: 堆栈指令群格式: PUSHF POPF PUSHA POPAADD,ADC功能: 加法指令语法: ADD OP1,OP2 ADC OP1,OP2格式: ADD r1,r2 ADD r,m ADD m,r ADD r,data影响标志: C,P,A,

深入理解计算机系统读书笔记一 ---&gt; 计算机基础漫游

一.程序编译的不同阶段. 通常我们是以高级程序开发易于阅读的代码,我们通过语法规则推断代码的具体含义.但是计算机执行代码的时候就需要把代码解析成既定的可执行问题,计算机是如何处理的呢?这里以C语言hello.c文件为例来说明中间过程. #include <stdio.h> int main() { printf("hello world!\n"); } 先上张图. C语言源程序----预处理解析头文件和函数  --- 编译器解析成汇编语言 ---   翻译机器语言指令,打包

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

卷积神经网络(CNN)学习笔记1:基础入门 Posted on 2016-03-01   |   In Machine Learning  |   9 Comments  |   14935  Views 概述 卷积神经网络(Convolutional Neural Network, CNN)是深度学习技术中极具代表的网络结构之一,在图像处理领域取得了很大的成功,在国际标准的ImageNet数据集上,许多成功的模型都是基于CNN的.CNN相较于传统的图像处理算法的优点之一在于,避免了对图像复杂的

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

Linux及Arm-Linux程序开发笔记(零基础入门篇)  作者:一点一滴的Beer http://beer.cnblogs.com/ 本文地址:http://www.cnblogs.com/beer/archive/2011/05/05/2037449.html 目录 一.Arm-Linux程序开发平台简要介绍... 3 1.1程序开发所需系统及开发语言... 3 1.2系统平台搭建方式... 4 二.Linux开发平台搭建... 5 2.1安装虚拟工作站... 5 2.2安装Linux虚拟

机器学习实战笔记1(机器学习基础)

1:如何选择合适的算法 2:python简介 (1)   python的优势:相对于matlab,matlab单个软件授权就要花费数千美元,也没有一个有影响力的大型开源项目.相对于c++/c/java,完成简单的操作就需要编写大量的代码:而如今我们应该花费更多的时间去处理数据内在的含义,而无需花费太多精力解决计算机如何得到数据结果(python简洁) (2)   python具有numpy科学函数库,它是一个使运算更容易.执行更迅速的库:另外还有matplotlib绘图工具. 3:python语

马哥Linux课程随堂笔记(操作系统基础01)

Linux课程笔记(操作系统基础)-20160822 第四层:应用程序(1.通过内核调用运行,2.调用库运行) 第三层:library:API(应用编程接口)库 只能被其他程序调用的时候才能执行,执行环境就是被调用 第二层:Kernerl:内核管理硬件资源 第一层:硬件 内核的功能: 1.进程管理 2.内存管理 3.文件系统 4.网络功能 5.硬件驱动 6.安全机制 GNU计划,又称革奴计划,是由RichardStallman在1983年9月27日公开发起的.它的目标是创建一套完全自由的操作系统

APUE 学习笔记(一) Unix基础知识

1. Unix 体系结构 内核的接口被称为系统调用 公用函数库构建在系统调用接口之上 应用软件既可以调用公用函数库,也可以直接进行系统调用 2. 文件和目录 目录操作函数:opendir---> readdir---> closedir struct dirent 结构体 stat 系统调用 3.程序.进程.线程 程序:存放在磁盘上.并处于某个目录中的一个可执行文件.使用exec系列函数将程序从磁盘读入存储器,并使其执行 进程:程序的执行实体.进程控制的3个函数:fork.exec.waitp

(赵小明RHCE笔记)linux基础之一

默认情况下,linux有一个图形界面,五个文本虚拟终端[email protected]# tty  用来查看当前是在哪个tty下ctrl+alt+F1-F7用来切换不同终端startx命令用来启动图形化界面一.图形界面从图形界面切换到文字界面需要ctrl+alt+F1-F7从文字界面切换到其他文字界面仅需alt+F1-F7ctrl+shift+t创建多个命令终端shift+Pgup/Pgdn在有很多输出的时候翻页查看ctrl+shift+c复制选中文字ctrl+shift+v粘贴ctrl+Pg

(赵小明RHCE笔记)linux基础之二 vim的使用

一.introducing vim 1.vim是vi的新版本,是unix的标准文本编辑器  默认情况下执行vi运行的是vim 2.优点  速度:  简便化:  高可用性3.缺点  比一般的编辑器稍难二.VIM的使用1.VIM有多种模式2.三种主要模式  a.命令模式(默认):移动光标.剪切/粘帖文本,更改模式  b.插入编辑模式:修改文本内容  c.扩展模式:保存.退出等等3.按多次Esc会返回至命令模式4.进入文件 vim /tmp/passwd  q!:不保存退出  e!:重新读取该文件,之