文档章节

Direct3D中的绘制(1)

rise-worlds
 rise-worlds
发布于 2016/06/20 13:40
字数 2224
阅读 0
收藏 0

3.1顶点/索引缓存

       顶点和索引缓存有相似的接口并且共享相似的方法;因此我们把它们合在一起讲解。一个顶点缓存是一块连续的存储了顶点数据的内存。同样的,一个索引缓存是一块连续的存储了索引数据的内存。我们使用顶点和索引缓存保存我们的数据是因为它们能被放置在显存中。渲染显存中的数据要比渲染系统内存中的数据快的多。

       在代码中,一个顶点缓存是通过IDirect3DVertexBuffer9接口来定义的。类似的,一个索引缓存是通过IDirect3DIndexBuffer9接口来定义。

3.1.1创建一个顶点和索引缓存

我们能使用下面两个方法创建一个顶点缓存和索引缓存:

HRESULT IDirect3DDevice9::CreateVertexBuffer(

       UINT Length,

       DWORD Usage,

       DWORD FVF,

       D3DPOOL Pool

       IDirect3DVertexBuffer9** ppVertexBuffer,

       HANDLE* pSharedHandle

);

HRESULT IDirect3DDevice9::CreateIndexBuffer(

       UINT Length,

       DWORD Usage,

       D3DFORMAT Format,

       D3DPOOL Pool,

       IDirect3DIndexBuffer9** ppIndexBuffer,

       HANDLE* pSharedHandle

);

这两个方法大部分参数是相同的,因此我们一起介绍它们。

Length —— 分配给缓存的字节大小。假如想得到一个能存储8个顶点的顶点缓存,那么我们就要在顶点结构中设置这个参数为 8 * sizeof ( Vertex ) 。

Usage —— 指定关于怎样使用缓存的额外信息。这个值可以是0,没有标记,或者是下面标记的一个或多个的组合:

         D3DUSAGE_DYNAMIC——设置这个参数可以使缓存是动态的。

         D3DUSAGE_POINTS——这个参数指定缓存存储原始点。这个参数仅仅用在顶点缓冲中。

         D3DUSAGE_SOFTWAREPROCESSING——使用软件顶点处理

         D3DUSAGE_WRITEONLY——指定应用程序只能写缓存。它允许驱动程序分配最适合的内存地址作为写缓存。注意如果从创建好的这种缓存中读数据,将会返回错误信息。

FVF —— 存储在缓存中的顶点格式

Pool —— 缓存放置在哪一个内存池中

ppVertexBuffer ——返回创建好的顶点缓存的指针。

pSharedHandle ——没有使用;设置为0。

Format ——指定索引的大小;使用D3DFMT_INDEX16设置16位索引,使用D3DFMT_INDEX32设置32位索引。注意并非所有设备都支持32位索引;请检查设备能力。

ppIndexBuffer ——返回创建好的索引缓存的指针。

注意:不使用D3DUSAGE_DYNAMIC参数创建的缓存被叫做静态缓存。静态缓存通常被放置在显存中,在其中的数据能被很有效的处理。然而,对于静态缓存,从中读取和写入数据是很慢的,因为访问显存是很慢的。因为这个原因我们用静态缓存存储静态数据(不需要被经常改变的数据)。地形和建筑物是很好的候选例子,因为在应用程序中他们通常不需要被改变。静态缓存应该在应用程序初始化的时候就被填充好,而不是在运行时才做。

注意:使用D3DUSAGE_DYNAMIC参数创建的缓存被叫做动态缓存。动态缓存通常被放在AGP内存中,这种内存中的数据能被很快的更新。处理动态缓存中的数据不会比处理静态缓存中的数据快,因为这些数据必须在渲染前被转移到显存中,动态缓存的好处是它们能够被稍微快点地被更新(比CPU写快)。因此,假如你需要经常更新缓存中的数据,那么你就应该使用动态缓存。粒子系统是很好的一个应用,因为它们是动态的,并且他们通常每一帧都会被更新。

注意:在程序中读取显存和AGP内存都是非常慢的。因此,假如你在运行时需要读取你的几何物体,最好的方案是指定一块系统内存,往其中拷贝并且读取数据。

下边是创建一个静态顶点缓存的例子,该缓存能存储8个顶点。

IDirect3DVertexBuffer9* vb;

device->CreateVertexBuffer( 8 * sizeof( Vertex ),    0,    D3DFVF_XYZ,  D3DPOOL_MANAGED, &vb, 0);

3.1.2 访问缓冲内存

为了访问一个顶点/索引缓存,我们需要得到一个指针。我们通过一个指针获得缓存数据必须使用Lock方法。当我们访问完缓存后必须对它解锁。一旦有一个指向内存的指针,我们就能对它进行读写。

HRESULT IDirect3DVertexBuffer9::Lock(

       UINT OffsetToLock,

       UINT SizeToLock,

       BYTE** ppbData,

       DWORD Flags

);

HRESULT IDirect3DIndexBuffer9::Lock(

       UINT OffsetToLock,

       UINT SizeToLock,

       BYTE** ppbData,

       DWORD Flags

);

这两个方法的参数都是完全相同的。

OffsetToLock —— 偏移量,以字节为单位,从缓存开始位置到锁定开始位置的距离。如图3.1。

SizeToLock —— 锁定的字节数。

ppbData —— 一个指向锁定内存开始位置的指针。

Flags —— 标记描述怎样锁定内存。它可能是0或者是下面参数中的1个或多个的组合:

       D3DLOCK_DISCARD——这个参数仅仅会在动态缓存时被使用。它指示硬件丢弃缓存并返回一个指向新分配的缓存的指针。这是很有用,因为当我们存取一个新分配的缓存时它允许硬件继续从丢弃的缓存渲染。这防止了硬件延迟。

       D3DLOCK_NOOVERWRITE——这个参数仅仅会在动态缓存时被使用。它声明你将向缓存中添加数据。即你不能向已经渲染的内存中写数据。这是有好处的因为他允许你在添加新数据到缓存的同时让硬件继续渲染。

       D3DLOCK_READONLY——这个参数声明你锁定的缓存只能从中读取数据而不能写数据。这允许一些内在的优化。

       用参数D3DLOCK_DISCARD和D3DLOCK_NOOVERWRITE表明缓存的一部分被锁定之后能继续被使用。假如硬件配置允许这些标记被使用,则在对缓存进行锁定时,其他的显示操作就不会中断。

       下边的例子展示了通常怎样使用Lock方法。注意当我们使用完以后要调用Unlock方法。

Vertex* vertices;

_vb->Lock(0, 0, (void**)&vertices, 0); // 锁定整个缓存

vertices[0] = Vertex(-1.0f, 0.0f, 2.0f); // 向缓存里写顶点

vertices[1] = Vertex( 0.0f, 1.0f, 2.0f);

vertices[2] = Vertex( 1.0f, 0.0f, 2.0f);

_vb->Unlock(); // 当你访问完缓存时,解锁缓存

3.1.3 找回顶点和索引缓存信息

有时我们需要得到顶点/索引缓存信息。下面的例子示范了用于获得这些信息的方法:

D3DVERTEXBUFFER_DESC vbDescription;

_vertexBuffer->GetDesc(&vbDescription); // 取得顶点缓存信息

D3DINDEXBUFFER_DESC ibDescription;

_indexBuffer->GetDesc(&ibDescription); //取得索引缓存信息

D3DVERTEXBUFFER_DESC和D3DINDEXBUFFER_DESC结构的定义如下:

Describes a vertex buffer.

typedef struct D3DVERTEXBUFFER_DESC {
D3DFORMAT Format;
D3DRESOURCETYPE Type;
DWORD Usage;
D3DPOOL Pool;
UINT Size;
DWORD FVF;
} D3DVERTEXBUFFER_DESC, *LPD3DVERTEXBUFFER_DESC;
Members
Format
Member of the D3DFORMAT enumerated type, describing the surface format of the vertex buffer data.
Type
Member of the D3DRESOURCETYPE enumerated type, identifying this resource as a vertex buffer.
Usage
Combination of one or more D3DUSAGE flags.
Pool
Member of the D3DPOOL enumerated type, specifying the class of memory allocated for this vertex buffer.
Size
Size of the vertex buffer, in bytes.
FVF
Combination of D3DFVF that describes the vertex format of the vertices in this buffer.

Defines resource types.

typedef enum D3DRESOURCETYPE
{
D3DRTYPE_SURFACE = 1,
D3DRTYPE_VOLUME = 2,
D3DRTYPE_TEXTURE = 3,
D3DRTYPE_VOLUMETEXTURE = 4,
D3DRTYPE_CubeTexture = 5,
D3DRTYPE_VERTEXBUFFER = 6,
D3DRTYPE_INDEXBUFFER = 7,
D3DRTYPE_FORCE_DWORD = 0x7fffffff,
} D3DRESOURCETYPE, *LPD3DRESOURCETYPE;
Constants
D3DRTYPE_SURFACE
Surface resource.
D3DRTYPE_VOLUME
Volume resource.
D3DRTYPE_TEXTURE
Texture resource.
D3DRTYPE_VOLUMETEXTURE
Volume texture resource.
D3DRTYPE_CubeTexture
Cube texture resource.
D3DRTYPE_VERTEXBUFFER
Vertex buffer resource.
D3DRTYPE_INDEXBUFFER
Index buffer resource.
D3DRTYPE_FORCE_DWORD
Forces this enumeration to compile to 32 bits in size. Without this value, some compilers would allow this enumeration to compile to a size other than 32 bits. This value is not used.

Describes an index buffer.

typedef struct D3DINDEXBUFFER_DESC {
D3DFORMAT Format;
D3DRESOURCETYPE Type;
DWORD Usage;
D3DPOOL Pool;
UINT Size;
} D3DINDEXBUFFER_DESC, *LPD3DINDEXBUFFER_DESC;
Members
Format
Member of the D3DFORMAT enumerated type, describing the surface format of the index buffer data.
Type
Member of the D3DRESOURCETYPE enumerated type, identifying this resource as an index buffer.
Usage
Combination of one or more of the following flags, specifying the usage for this resource.
D3DUSAGE_DONOTCLIP
Set to indicate that the index buffer content will never require clipping.
D3DUSAGE_DYNAMIC
Set to indicate that the index buffer requires dynamic memory use. This is useful for drivers because it enables them to decide where to place the buffer. In general, static index buffers are placed in video memory and dynamic index buffers are placed in AGP memory. Note that there is no separate static usage; if you do not specify D3DUSAGE_DYNAMIC the index buffer is made static. D3DUSAGE_DYNAMIC is strictly enforced through the D3DLOCK_DISCARD and D3DLOCK_NOOVERWRITE locking flags. As a result, D3DLOCK_DISCARD and D3DLOCK_NOOVERWRITE are only valid on index buffers created with D3DUSAGE_DYNAMIC; they are not valid flags on static vertex buffers.

For more information about using dynamic index buffers, see Using Dynamic Vertex and Index Buffers.

Note that D3DUSAGE_DYNAMIC cannot be specified on managed index buffers. For more information, see Managing Resources (Direct3D 9).

D3DUSAGE_RTPATCHES
Set to indicate when the index buffer is to be used for drawing high-order primitives.
D3DUSAGE_NPATCHES
Set to indicate when the index buffer is to be used for drawing N patches.
D3DUSAGE_POINTS
Set to indicate when the index buffer is to be used for drawing point sprites or indexed point lists.
D3DUSAGE_SOFTWAREPROCESSING
Set to indicate that the buffer is to be used with software processing.
D3DUSAGE_WRITEONLY
Informs the system that the application writes only to the index buffer. Using this flag enables the driver to choose the best memory location for efficient write operations and rendering. Attempts to read from an index buffer that is created with this capability can result in degraded performance.
Pool
Member of the D3DPOOL enumerated type, specifying the class of memory allocated for this index buffer.
Size
Size of the index buffer, in bytes.

本文转载自:http://www.cnblogs.com/flying_bat/archive/2008/03/20/1115377.html

共有 人打赏支持
rise-worlds

rise-worlds

粉丝 2
博文 1755
码字总数 0
作品 0
深圳
程序员
私信 提问
【 Visual C++】游戏开发笔记之三——绘制图元

使用Direct3D绘制图元 我们接下来的部分将介绍使用Direct3D在屏幕上绘图的图元。计算机图形学中的图元是可以渲染到屏幕上的基本形状。将图元组合在一起可以构成不同的形状和物体,诸如人物模...

长平狐
2012/11/12
160
0
【 Visual C++】游戏开发笔记之二——最简单的DirectX,vc窗口的编写

笔记一中我们介绍了如何用代码创建空的win32窗口,然而创建空的win32窗口只完成了一半的工作,接下来要做的工作是设置Direct3D,从而可以在屏幕上渲染图形。 Direct3D要调用很多函数才能成功...

长平狐
2012/11/12
158
0
使用 Direct2D 绘制分层窗口

这是我关于Direct2D的第三篇介绍了,今天主要讲下其无可比拟的互操作性。为了避免繁缛末节的讲述,我们从一个实例入手:层级窗口。相对于windows的其它众多功能。层级窗口并未做相应的更新,...

Dy_
2014/01/16
8.2K
10
图形处理 Graphic (Drawing & Animation)

在XAML中添加如下代码创建椭圆,只需要指定Width、Height和用于Fill的Brush即可。 在Windows8和Windows Phone8应用中可以使用C#代码绘制图形图像以及动画,也可以使用XAML代码来实现。 可扩展...

失足处男的倒霉孩子
2013/12/27
1K
1
【Visual C++】游戏开发笔记二十七 Direct3D 11入门级知识介绍

本系列文章由zhmxy555(毛星云)编写,转载请注明出处。 http://blog.csdn.net/zhmxy555/article/details/7707628 作者:毛星云 邮箱: happylifemxy@163.com 期待着与志同道合的朋友们相互交...

长平狐
2012/11/12
441
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring Boot 2.x基础教程:快速入门

简介 在您第1次接触和学习Spring框架的时候,是否因为其繁杂的配置而退却了?在你第n次使用Spring框架的时候,是否觉得一堆反复黏贴的配置有一些厌烦?那么您就不妨来试试使用Spring Boot来让...

程序猿DD
昨天
0
0
SpringSecurity认证流程源码级详解

SpringSecurity认证流程源码级详解 认证流程说明 认证结果如何在多个请求之间共享 获取认证用户信息

chendom
昨天
0
0
C语言中的volatile——让我保持原样

volatile译为:易变的。这不是和题目的让我保持原样矛盾了吗?其实不然,在变量前加上该关键字修饰,确实是告诉编译器,这个变量是一个容易改变的变量,不要对它进行优化,每次都要到变量的地...

天王盖地虎626
昨天
0
0
五、RabbitMQ的消息属性(读书笔记)

简介 当使用RabbitMQ发布消息时,消息又AMQP规范中的三个低层帧类型组成: Basic.publish方法帧; 内容头帧; 消息体帧; 这三种帧类型按顺序一起工作,以便消息传递时完好无损。 其中,内容...

XuePeng77
昨天
0
0
JavaEE开发的颠覆者SpringBoot实战摘要笔记

一、注解理解 1.spring注解 1)@Configuration/@ComponentScan/@Bean注解实现java方式的配置。 @Configuration代替xml文件 @ComponentScan指定扫描范围 @Bean代替bean标签 2)@Bean、@Componen...

啃不动地大坚果
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部