DirectX9.0 Direct3D Graphics Pipeline 总结 - 雨霖林

本文详细对比了DirectX9.0中DrawIndexedPrimitive与DrawIndexedPrimitiveUp,DrawPrimitive与DrawPrimitiveUp的区别,包括顶点数据存放位置、渲染流程及顶点定义等内容,并介绍了完整的渲染流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

DirectX9.0 Direct3D Graphics Pipeline 总结 - 雨霖林

写下这个东西,是为了能够留住他,正是写下来是为了能够记得住。

1.DrawIndexedPrimitive 与 DrawIndexedPrimitiveUp ,DrawPrimitive 与 DrawPrimitiveUp 顶点数据存放位置的不同

将顶点数据和索引数据放在主存储器时,使用的是DrawPrimitiveUp和DrawIndexedPrimitiveUp。

这两个函数执行时d3d的驱动程序先用cpu将顶点数据从主存储器复制到显示适配器内存,GPU接下来才有办法读取。每次绘制都会重复复制动作。如果把模型数据直接存储在显存中就可以用DrawIndexedPrimitive和DrawPrimitive来画。

使用DrawIndexedPrimitive和DrawPrimitive要做一些准备工作。首先使用D3DDEVICE的CreateVertexBuffer和CraeteIndexBuffer来获取一块显存,再把数据填进去。D3D9复制数据到显存首先要使用Lock函数获得指针,再自行填入数据。之后的绘制工作时不需要进行数据从内存向显存的拷贝工作。

把数据存放在显示内存中的缺点是,CPU比GPU读写显存速度慢。所以顶点数据不需要常常改变的数据,放在显存中。经常改变的顶点数据放在内存中比较好。一般来说,绝大多数的模型数据会放在显存中。

GUI的显示数据放在内存中,可能是因为顶点的坐标经常变吧。

2.DrawIndexedPrimitive 与 DrawIndexedPrimitiveUp ,DrawPrimitive 与 DrawPrimitiveUp 再谈不同

绘制的流程不同:

DrawPrimitiveUP 的准备工作至少有:SetFVF式 或者 SetVertexDeclaration 来设置顶点格式 设置顶点格式SetVertexDeclaration 更加灵活。

DrawIndexedPrimitiveUp 版本只是带索引。

DrawPrimitive的准备工作: SetFVF式 或者 SetVertexDeclaration , SetStreamSource设置顶点输入流,DrawPrimitive来绘制。

DrawIndexedPrimitive 的版本是要索引的 需要一个额外的设置:用SetIndices来设置索引

3.顶点定义

struct Vertex

{

Vertex(){}

Vertex(float x, float y, float z,

float nx, float ny, float nz, float u, float v)

{

_x = x; _y = y; _z = z;

_nx = nx; _ny = ny; _nz = nz;

_u = u; _v = v;

}

float _x, _y, _z, _nx, _ny, _nz, _u, _v;

static const DWORD FVF;

};

const DWORD Vertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;

顶点数据结构体 顶点格式FVF必须与数据结构体内的数据位置对应

用于SetFVF的顶点格式掩码

#define D3DFVF_RESERVED0 0x001

#define D3DFVF_POSITION_MASK 0x400E

#define D3DFVF_XYZ 0x002

Vertex format includes the position of an untransformed vertex. This flag cannot be used with the D3DFVF_XYZRHW flag.

 

D3DFVF_XYZ包含未转换的顶点数据 数据类型为: float,float,float.

#define D3DFVF_XYZRHW 0x004

Vertex format includes the position of a transformed vertex. This flag cannot be used with the D3DFVF_XYZ or D3DFVF_NORMAL flags.

坐标变换过的顶点(已经转换成屏幕坐标). 不能与D3DFVF_XYZ 或 D3DFVF_NORMAL 同时使用.坐标原点是屏幕左上角。

数据类型为: float,float,float,float

#define D3DFVF_XYZB1 0x006

Vertex format contains position data, and a corresponding number of weighting (beta) values to use for multimatrix vertex blending operations.

D3DFVF_XYZB1 包含未转换顶点数据和一个用于VertexBlend的权重。

数据类型不明:float,float,float,float吗 权重是一个float吗

#define D3DFVF_XYZB2 0x008

#define D3DFVF_XYZB3 0x00a

#define D3DFVF_XYZB4 0x00c

#define D3DFVF_XYZB5 0x00e

#define D3DFVF_XYZW 0x4002

Vertex format contains transformed and clipped (x, y, z, w) data. ProcessVertices does not invoke the clipper, instead outputting data in clip coordinates. This constant is designed for, and can only be used with, the programmable vertex pipeline.

顶点数据是坐标转换和剪裁了的 这种顶点数据专门给VS shader使用的

数据类型:float, float, float

#define D3DFVF_NORMAL 0x010

Vertex format includes a vertex normal vector. This flag cannot be used with the D3DFVF_XYZRHW flag.

顶点法线数据 数据类型: float, float, float

#define D3DFVF_PSIZE 0x020

#define D3DFVF_DIFFUSE 0x040

Vertex format includes a diffuse color component.

顶点数据包含漫反射分量,这样不用光照,可以直接用来代替光照值。

数据类型: float, float, float

#define D3DFVF_SPECULAR 0x080

Vertex format includes a specular color component.

顶点数据包含镜面高光分量,可以用来在不光照情况下代替光照值

#define D3DFVF_TEXCOUNT_MASK 0xf00

Mask value for texture flag bits.

#define D3DFVF_TEXCOUNT_SHIFT 8

纹理坐标偏移的bit位 出现在第八位上

#define D3DFVF_TEX0 0x000

#define D3DFVF_TEX1 0x100

#define D3DFVF_TEX2 0x200

#define D3DFVF_TEX3 0x300

#define D3DFVF_TEX4 0x400

#define D3DFVF_TEX5 0x500

#define D3DFVF_TEX6 0x600

#define D3DFVF_TEX7 0x700

#define D3DFVF_TEX8 0x800

Number of texture coordinate sets for this vertex. The actual values for these flags are not sequential.

顶点包含多少套纹理坐标。

#define D3DFVF_TEXCOORDSIZEN(coordIndex)

 

Define a texture coordinate data set. n indicates the dimension of the texture coordinates. coordIndex indicates texture coordinate index number.

n表示纹理坐标的维数。coordIndex表示纹理坐标的index数

#define D3DFVF_LASTBETA_UBYTE4 0x1000

#define D3DFVF_LASTBETA_D3DCOLOR 0x8000

#define D3DFVF_RESERVED2 0x6000 // 2 reserved bits

另外一种顶点创建格式

//创建顶点格式

D3DVERTEXELEMENT9 decl[] =

{

// float*3 for position (x,y,z)

{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},

// float*3 for texcoord (x,y,z) 第二个参数是在顶点结构中的偏移量

{0,12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},

D3DDECL_END()

};

//根据顶点格式数组的内容创建顶点格式 第一个是Position 第二个是cubemap的texcoord

Device->CreateVertexDeclaration(decl, &g_pVertexDecl);

非宏形式的顶点格式结构体:

typedef struct _D3DVERTEXELEMENT9

{

WORD Stream; // Stream index 顶点流索引

WORD Offset; // Offset in the stream in bytes 顶点流偏移

BYTE Type; // Data type 数据格式 一个宏定义

BYTE Method; // Processing method 处理方式

BYTE Usage; // Semantics 数据意义

BYTE UsageIndex; // Semantic index

} D3DVERTEXELEMENT9, *LPD3DVERTEXELEMENT9;

#define D3DDECL_END() {0xFF,0,D3DDECLTYPE_UNUSED,0,0,0}

顶点样式的多样性导致了顶点声明很复杂,种类和花样都挺多

4。DrawIndexedPrimitive 与 DrawIndexedPrimitiveUp ,DrawPrimitive 与 DrawPrimitiveUp 三谈不同

完整渲染流程: DrawPrimitiveUp 与 DrawIndexedPrimitiveUp

Device->SetFVF(D3DFVF_XYZ|D3DFVF_TEX1); 设置顶点格式

Device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, g_Quad, sizeof(Vertex_VT));

HRESULT DrawPrimitiveUP(

[in] D3DPRIMITIVETYPE PrimitiveType,

[in] UINT PrimitiveCount,

[in] const void *pVertexStreamZeroData, 顶点内存地址

[in] UINT VertexStreamZeroStride 顶点间隔 一般为顶点结大小

);

//带索引版本

Device->DrawIndexedPrimitiveUP(D3DPT_TRIANGLESTRIP, 0, g_iNumGridVertices,g_iNumGridTriangles,

g_pGridIndices, D3DFMT_INDEX16, g_pGridVerticesDX9, sizeof(Vertex_DX9) );

HRESULT DrawIndexedPrimitiveUP(

[in] D3DPRIMITIVETYPE PrimitiveType,

[in] UINT MinVertexIndex, //索引开始位

[in] UINT NumVertices, //顶点数

[in] UINT PrimitiveCount,

[in] const void *pIndexData,//索引数据内存地址

[in] D3DFORMAT IndexDataFormat,//索引的bit数 格式

[in] const void *pVertexStreamZeroData, 顶点数据

[in] UINT VertexStreamZeroStride 顶点间隔 顶点结构大小

);

完整渲染流程: DrawPrimitive 与 DrawIndexedPrimitive

准备工作:

① 用IDirect3DDevice9::CreateVerTexBuffer创建顶点缓冲区

HRESULT CreateVertexBuffer(

UINT Length,

DWORD Usage,

DWORD FVF,

D3DPOOL Pool,

IDirect3DVertexBuffer9** ppVertexBuffer,

HANDLE* pSharedHandle

);

Length:用字节表示顶点缓冲的大小。FVF:灵活顶点格式

Usage:高级应用。设0 

Pool:告诉D3D将顶点缓冲存储在内存中的哪个位置。

typedef enum _D3DPOOL {

D3DPOOL_DEFAULT = 0, // AGP, graphics card memory

D3DPOOL_MANAGED = 1, // AGP, graphics card memory && copy in sys memory

D3DPOOL_SYSTEMMEM = 2, // system memory, re-creatable

D3DPOOL_SCRATCH = 3, // system memory, not re-creatable

D3DPOOL_FORCE_DWORD = 0x7fffffff

} D3DPOOL;

ppVertexBuffer:返回来的指向IDirect3DVertexBuffer9的指针。之后对顶点缓冲进行的操作就是通过这个指针啦。到这里还要再提醒一下,对于这些接口指针,在使用完毕后,一定要使用Release来释放它。

pSharedHandle:设为NULL就行了。

得到一个指向IDirect3DVertexBuffer9的指针后,顶点缓冲也就创建完毕了。现在要做的就是把之前保存在数组中的顶点信息放在顶点缓冲区里面。首先,使用IDirect3DVertexBuffer9::Lock来锁定顶点缓冲区:

② 用IDirect3DVertexBuffer9:: Lock锁定缓冲区

锁定一个资源意味着允许CPU访问其存储内容。除了允许处理器访问外,其它任何涉及资源的操作都会在锁定期间被串行化。对一个资源同一时刻只能锁定一次,那怕第二次锁定是一个非常重叠的区域也不行。并且当表面未解锁前,禁止在此表面进行任何加速器操作。

HRESULT Lock(

UINT OffsetToLock,

UINT SizeToLock,

void **pPBData,

DWORD Flags

);

OffsetToLock:指定要开始锁定的缓冲区的位置。通常在起始位置0开始锁定。

SizeToLock:指定在锁定的缓冲区的大小。设为0的话就是表示要锁定整个缓冲区。

ppbData:用来保存返回的指向顶点缓冲区的指针。通过这个指针来向顶点缓冲区填充数据。

Flags: 如何使用顶点缓冲器,即锁定方式:

D3DLOCK_DISCARD:应用程序将覆盖顶点缓冲器中的所有位置;

D3DLOCK_NO_DIRTY_UPDATE :对锁定的顶点缓冲器不添加dirty区域。

D3DLOCK_NOSYSLOCK :允许在Lock()期间改变显示模式。

D3DLOCK_READONLY :应用程序不会写入顶点缓冲器(只读)

D3DLOCK_NOOVERWRITE:顶点缓冲器的数据不会被覆盖。

填充为顶点缓冲区后,使用IDirect3DVertexBuffer9:: Lock:来解锁。

③ 将定义的三角形数据用内存拷贝的方法(memcpy)拷贝到顶点缓冲区

这个过程是一个内存向显存拷贝的过程

④用IDirect3DVertexBuffer9:: UnLock解锁缓冲区

如果不Lock/Unlock 就直接使用会造成使用未定义指针;之所以这样做,而不是事先分配vertex数组是因为这不是在主存中分配空间,而是在显存中分配空间。

Deivce->SetFVF()

Device->SetStreamSource()

HRESULT SetStreamSource(

[in] UINT StreamNumber, //数据流号

[in] IDirect3DVertexBuffer9 *pStreamData, //顶点数据 vertexbuffer

[in] UINT OffsetInBytes, //顶点数据中的偏移

[in] UINT Stride //顶点间隔 顶点结构大小

);

//可以设置多个数据流

Device-> DrawPrimitive

HRESULT DrawPrimitive(

[in] D3DPRIMITIVETYPE PrimitiveType,

[in] UINT StartVertex, //开始的顶点

[in] UINT PrimitiveCount

);

创建CreateIndexBuffer

HRESULT CreateIndexBuffer(

UINT Length,

DWORD Usage,

D3DFORMAT Format,

D3DPOOL Pool,

IDirect3DIndexBuffer9** ppIndexBuffer

);

Length:索引缓冲区的长度。通常使用索引数目乘以sizeof(WORD)或sizeof(DWORD)来设置,因为索引号的数据类型是字节(WORD)或双字节(DWORD),嗯,一个WORD只有两个字节,DWORD也就只有四个字节,比顶点的大小小多了吧。

Usage:和CreateVertexBuffer中的Usage设置一样。一般设为0。

Format:设置索引格式。不是D3DFMT_INDEX16就是D3DFMT_INDEX32的啦。

Pool:又是和CreateVertexBuffer中的一样。一般设为D3DPOOL_DEFAULT。

ppIndexBuffer:指向IDirect3DIndexBuffer9的指针。操作索引缓冲区就靠它的啦。记得使用完后要Release

使用索引:   IDirect3DDevice9::SetIndices

最后使用IDirect3DDevice9::SetIndices来告诉设备要使用哪个索引。

HRESULT Setindices(

IDirect3DindexBuffer9* pIndexData,

UINT BaseVertexIndex

);

pIndexData:设置使用哪个索引缓冲。

BaseVertexIndex:设置以顶点缓冲区中的哪个顶点为索引0。

This book describes the Direct3D graphics pipeline, from presentation of scene data to pixels appearing on the screen. The book is organized sequentially following the data °ow through the pipeline from the application to the image displayed on the monitor. Each major section of the pipeline is treated by a part of the book, with chapters and subsections detailing each discrete stage of the pipeline. This section summarizes the contents of the book. Part I begins with a review of basic concepts used in 3D computer graphics and their representations in Direct3D. The IDirect3D9 interface is introduced and device selection is described. The IDirect3DDevice9 interface is introduced and an overview of device methods and internal state is given. Finally, a basic framework is given for a 2D application. Chapter 1 begins with an overview of the entire book. A review is given of display technology and the important concept of gamma correction. The representation of color in Direct3D and the macros for manipulating color values are described. The relevant mathematics of vectors, geometry and matrices are reviewed and summarized. A summary of COM and the IUnknown interface is COM: Component Object Model given. Finally, the coding style conventions followed in this book are presented along with some useful C++ coding techniques. Chapter 2 describes the Direct3D object. Every application instantiates this object to select a device from those available. Available devices advertise their location in the Win32 virtual desktop and their capabilities to applications 34 CHAPTER 1. INTRODUCTION through the Direct3D object. Selecting a device from those available and exam- ining a device's capabilities are described. Multiple monitor considerations are also discussed. Chapter 3 describes the Direct3D device object which provides access to the rendering pipeline. The device is the interface an application will use most often and it has a large amount of internal state that controls every stage of the rendering pipeline. This chapter provides a high-level overview of the device and its associated internal state. Detailed discussion of the device state appears throughout the rest of the book. Chapter 4 describes the basic architecture of a typical Direct3D application. Every 3D application can use 2D operations for manipulating frame bu®er con- tents directly. An application can run in full-screen or windowed modes and the di®erences are presented here. The handling of Windows messages and a ba- sic display processing loop are presented. At times it may be convenient to use GDI in a Direct3D application window and a method for mixing these two Win- dows subsystems is presented. Almost every full-screen application will want to use the cursor management provided by the device. Device color palettes and methods for gamma correction are presented. Part II describes the geometry processing portion of the graphics pipeline. The application delivers scene data to the pipeline in the form of geometric primitives. The pipeline processes the geometric primitives through a series of stages that results in pixels displayed on the monitor. This part describes the start of the pipeline where the processing of geometry takes place. Chapter 5 describes how to construct a scene representing the digital world that is imaged by the imaginary camera of the device. A scene consists of a collection of models drawn in sequence. Models are composed of a collection of graphic primitives. Graphic primitives are composed from streams of vertex and index data de¯ning the shape and appearance of objects in the scene. Vertices and indices are stored in resources created through the device. Chapter 6 covers vertex transformations, vertex blending and user-de¯ned clipping planes. With transformations, primitives can be positioned relative to each other in space. Vertex blending, also called \skinning", allows for smooth mesh interpolation. User-de¯ned clipping planes can be used to provide cut away views of primitives. Chapter 7 covers viewing with a virtual camera and projection onto the viewing plane which is displayed as pixels on the monitor. After modeling, objects are positioned relative to a camera. Objects are then projected from 3D camera space into the viewing plane for conversion into 2D screen pixels. Chapter 8 describes the lighting of geometric primitives. The lighting model is introduced and the supported shading algorithms and light types are de- scribed. Chapter 9 covers programmable vertex shading. Programmable vertex shaders can process the vertex data streams with custom code, producing a single ver- tex that is used for rasterization. The vertex shading machine architecture and instruction set are presented. Part III covers the rasterization portion of the pipeline where geometry is1.1. OVERVIEW 5 converted to a series of pixels for display on the monitor. Geometric primitives are lit based on the lighting of their environment and their material properties. After light has been applied to a primitive, it is scan converted into pixels for processing into the frame bu®er. Textures can be used to provide detailed surface appearance without extensive geometric modeling. Pixel shaders can be used to provide custom per-pixel appearance processing instead of the ¯xed- function pixel processing provided by the stock pipeline. Finally, the pixels generated from the scan conversion process are incorporated into the render target surface by the frame bu®er. Chapter 10 describes the scanline conversion of primitives into pixel frag- ments. Lighting and shading are used to process vertex positions and their associated data into a series of pixel fragments to be processed by the frame bu®er. Chapter 11 describes textures and volumes. Textures provide many e±cient per-pixel e®ects and can be used in a variety of manners. Volumes extend texture images to three dimensions and can be used for a volumetric per-pixel rendering e®ects. Chapter 13 describes programmable pixel shaders. Programmable pixel shaders combine texture map information and interpolated vertex information to produce a source pixel fragment. The pixel shading machine architecture and instruction set are presented. Chapter 14 describes how fragments are processed into the frame bu®er. After pixel shading, fragments are processed by the fog, alpha test, depth test, stencil test, alpha blending, dither, and color channel mask stages of the pipeline before being incorporated into the render target. A render target is presented for display on the monitor and video scan out. Part IV covers the D3DX utility library. D3DX provides an implementation of common operations used by Direct3D client programs. The code in D3DX consists entirely of client code and no system components. An application is free to reimplement the operations provided by D3DX, if necessary. Chapter 15 introduces D3DX and summarizes features not described else- where. Chapter 16 describes the abstract data types provided by D3DX. D3DX provides support for RGBA color, point, vector, plane, quaternion, and matrix data types. Chapter 17 describes the helper COM objects provided by D3DX. D3DX provides a matrix stack object to assist in rendering frame hierarchies, a font object to assist in the rendering of text, a sprite object to assist in the rendering of 2D images, an object to assist in rendering to a surface or an environment map and objects for the rendering of special e®ects. Chapter 19 describes the mesh objects provided by D3DX. The mesh objects provided by D3DX encompass rendering of indexed triangle lists as well as progressive meshes, mesh simpli¯cation and skinned meshes. Chapter 21 describes the X ¯le format with the ¯le extension .x. The X ¯le format provides for extensible hierarchical storage of data objects with object instancing.6 CHAPTER 1. INTRODUCTION Part V covers application level considerations. This part of the book de- scribes issues that are important to applications but aren't strictly part of the graphics pipeline. Debugging strategies for applications are presented. Almost all Direct3D applications will be concerned with performance; API related per- formance issues are discussed here. Finally, installation and deployment issues for Direct3D applications are discussed. Chapter 22 describes debugging strategies for Direct3D applications. This includes using the debug run-time for DirectX 9.0c, techniques for debugging full-screen applications and remote debugging. Chapter 23 covers application performance considerations. All real devices have limitations that a®ect performance. A general consideration of how the pipeline state a®ects performance is given. Chapter 24 covers application installation and setup. Appendix A provides a guided tour of the DirectX SDK materials.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值