• DirectX的Vertex Buffer顶点缓冲的理解和应用 Shader必知必会


    故名思义Vertex Buffer就是存放顶点的缓冲。相当于一个内存区,指明了这些几何图形的顶点的位置。

    一般简单的几何图形,如正方形,手动地可以定义这些顶点,定义好顶点之后,就需要如下这样来设置好,才能开始画图,而这正是DirectX里面最难理解的问题之一,和OpenGL也一样,同样需要这样设置的,OpenGL SuperBibl 第五版中居然把这个问题放到了差不多最后一个章节去介绍,可想而知,这个理解起来是有难度的。当然作者这样安排的合理性是有人怀疑的。

    1. gd3dDevice->SetVertexDeclaration(Decl);  
    2. gd3dDevice->SetStreamSource(0, mGridVB, 0, sizeof(VertexPNT));  
    3. gd3dDevice->SetIndices(mGridIB));  

    为什么要如上这样设置DirectX的数据呢?

    第一句:是告诉DirectX设备我们将要使用的顶点所包含的属性,什么是顶点的属性呢?顶点位置,顶点的单位向量,顶点的颜色,纹理坐标等都是气属性。

    这里的Decl就是IDirect3DVertexDeclaration9 接口,用微软的话对这个接口的解析就是:

    Applications use the methods of the IDirect3DVertexDeclaration9 interface to encapsulate the vertex shader declaration.

    那么什么是the vertex shader declaration呢?

    A vertex shader declaration is made up of an array of vertex elements.

    然后又什么是vertex elements呢?

    它的数据结构是:D3DVERTEXELEMENT9

    Defines the vertex data layout. Each vertex can contain one or more data types, and each data type is described by a vertex element.

    每个vertex element描述了vertex的其中一个属性,这些属性就是组成了所谓的the vertex data layout(顶点数据层)。

    通过这样,DirectX就知道了如何去描绘这些几何图形了。

    归纳:

    A vertex is composed of n streams. (一般是用一个流,但是一些高级的应用就需要用到多个流。)

    A stream is composed of m elements.

    An element is [position, color, normal, texture coordinate].

    第二句:IDirect3DDevice9::SetStreamSource绑定了顶点缓冲和设备的数据流,构造顶点数据和其中一个数据流接口的联系,顶点数据将通过数据流传入几何函数进行处理。画图函数是IDirect3DDevice9::DrawPrimitive,引用改数据流然后进行画图。

    输入的顶点元素(the input vertex elements)映射到寄存器是由可编程shader声明的。由shader指令进行解析。顶点shader函数是由一个数组指令定义,应用到每一个顶点,然后写出到顶点输出寄存器。

    使用流的一个主要好处就是可以DIY顶点数据,只带需要的数据就可以了,不用处理多余的数据,像以前不用流的多层渲染那样。节省了数据流量带宽,就加快了渲染速度。

    第三句:就是设置其索引缓冲。

    语法:

    typedef struct D3DVERTEXELEMENT9 {
      WORD Stream;
      WORD Offset;
      BYTE Type;
      BYTE Method;
      BYTE Usage;
      BYTE UsageIndex;
    } D3DVERTEXELEMENT9, *LPD3DVERTEXELEMENT9;
    1. 如下定义了一个数组,包括了顶点位置,单位向量和纹理坐标。然后顶一个了一个IDirect3DVertexDeclaration9接口Decl  
    1. D3DVERTEXELEMENT9 VertexPNTElements[] =   
    2.     {  
    3.         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},  
    4.         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},  
    5.         {0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},  
    6.         D3DDECL_END()  
    7.     };    
    8.     HR(gd3dDevice->CreateVertexDeclaration(VertexPNTElements, &Decl));  


    总的来说,这个是非常难理解的概念,但是要用shader的话,又是必须要过的第一关。这也是shader入门难的缘故之一吧。

  • 相关阅读:
    MySQL关于check约束无效的解决办法
    关于constraint的用法
    MySQL关于Duplicate entry '1' for key 'PRIMARY'错误
    iOS实现高斯模糊效果(Swift版本)
    iOS获取视频中的指定帧的两种方法
    Java关于e.printStackTrace()介绍
    iOS关于JSONKit解析Unicode字符内容出错,问题出在u0000
    Java转型(向上转型和向下转型)
    添加删除Windows组件里没有IIS(Internet信息服务)项的解决方法
    Windows2003:“无法加载安装程序库wbemupgd.dll
  • 原文地址:https://www.cnblogs.com/ainima/p/6331178.html
Copyright © 2020-2023  润新知