在前面我们学习OpenGL时,不管绘制如球,立方体,平面,地面,动画模型中最常用的几个操作有创建缓冲区,写入缓冲区.在Axiom中,相关的操作被整合与组织到VertexData,IndexData中,所以在后面,我们会看到Axiom里元素如果要绘画在屏幕上的元素,几乎都会包含这二个类的实体.

     在看相关介绍前,我们先看下如下关系图:

   VertexData主要包含二个类的实体,一个是VertexDeclaration,另一个是VertexBufferBinding.

VertexDeclaration是用来指定数据的组成结构,比如在前面我们使用OpenGL的混合顶点数组时,会用T2F_N3F_V3F指定对应数组每八个浮点数据一组,前二个指定纹理坐标,中间三个数据指定法线,最后三个数据指定顶点.VertexDeclaration类似这个T2F_N3F_V3F,他包含一系列VertexElement,每个VertexElement指定上面的T2F,N3F,V3F这种类型,请看下面一段代码:

 var decl = mesh.SharedVertexData.vertexDeclaration;
var binding = mesh.SharedVertexData.vertexBufferBinding; var offset = ;
decl.AddElement( , offset, VertexElementType.Float3, VertexElementSemantic.Position );
offset += VertexElement.GetTypeSize( VertexElementType.Float3 );
decl.AddElement( , offset, VertexElementType.Float3, VertexElementSemantic.Normal );
offset += VertexElement.GetTypeSize( VertexElementType.Float3 );
decl.AddElement( , offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, );
offset += VertexElement.GetTypeSize( VertexElementType.Float2 );

VertexElement

  在中间有AddElement就是增加一个VertexElement,其中Float3,Float2就是指如上的3F,2F.而Position,Normal,TexCoords分别对应上面的P,N,T.说到底,这个decl就是指定了如P3F_N3F_T2F这种结构.

  

  VertexBufferBinding主要成员包含一个Dictionary <short, HardwareVertexBuffer > Bindings的数据结构,其中HardwareVertexBuffer这个比较重要,可以看下一般如何创建HardwareVertexBuffer,如下:
 
 var vertices = new float[]
{
-, -, , // pos
, , , // normal
, , // texcoord
, -, , , , , , , , , , , , , , , -, , , , , , ,
};
var vbuf = HardwareBufferManager.Instance.CreateVertexBuffer( decl, , BufferUsage.StaticWriteOnly );
binding.SetBinding( , vbuf );
vbuf.WriteData( , vbuf.Size, vertices, true );

VertexBuffer

  看过OpenGL绑定过程的,一定看起来很熟悉是不是,实际差不多,在CreateVertexBuffer里,首先会在HardwareVertexBuffer结合decl与顶点个数4.这里为什么是4,其实大家可以算一下,decl里声明的是P3F_N3F_T2F,意思是每个顶点有八个数据来指明相关属性,而vertices的长度是32,就是指明这个数据只包含了4个顶点.然后我们可以计算我们需要申请的显存长度,sizeInBytes=4*8*sizeof(float)=128.然后如果我们使用OpenGL渲染,就会调用GLHardwareVertexBuffer,这个类的初始化里就使用了glGenBuffers.最后vbuf.WriteData操作就会调用glBufferData把相关数据写入到显存里.

很明显,对比原来我们常用的OpenGL操作如下:

         this.vboID = glGenBuffers()
glBindBuffer(GL_ARRAY_BUFFER,this.vboID)
glBufferData (GL_ARRAY_BUFFER, len(vdata)*, vdata, GL_STATIC_DRAW)
this.eboID = glGenBuffers()
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,this.eboID)
glBufferData (GL_ELEMENT_ARRAY_BUFFER, len(vIndex)*, vIndex,GL_STATIC_DRAW)

glBindBuffer

  可以发现少了点什么,是的,我们只是写入了顶点数据,对应顶点索引没有,看看在Axiom里如何使用.

 var ibuf = HardwareBufferManager.Instance.CreateIndexBuffer( IndexType.Size16, , BufferUsage.StaticWriteOnly );

 var faces = new short[]
{
, , , , ,
};
sub.IndexData.indexBuffer = ibuf;
sub.IndexData.indexCount = ;
sub.IndexData.indexStart = ;
ibuf.WriteData( , ibuf.Size, faces, true );

IndexBuffer

  会发现不一样的是,顶点数据用的是HardwareVertexBuffer,而顶点索引用的HardwareIndexBuffer,基本用法一样,不同的调用的CreateIndexBuffer,结合前面与调试在相关位置,发现还是和前面一样,一样会调用glGenBuffers,glBindBuffer,glBufferData.不同前面是GL_ARRAY_BUFFER,这里是GL_ELEMENT_ARRAY_BUFFER.

我们知道,在底层不管是OpenGL或是D3D,他们都是C,C++及的语言,针对底层的指针操作,在C#中都由上面的BufferBase的派生类包装GCHandle提供相关的非托管内存访问托管对象的方法,能创建防GC回收托管对象.详细请看GCHandle 结构.在HardwareBuffer里的相关和内存,显存有关的操作全是用BufferBase来完成.具体请看Axiom3D:Buffer漫谈整个代码是创建一个四个点的面,分别创建顶点与顶点索引缓冲区,相对整个部分代码如下:

         /// <summary>
/// Creates a plane as a submesh of the given mesh
/// </summary>
[OgreVersion( , , )]
private static void _createPlane( Mesh mesh )
{
var sub = mesh.CreateSubMesh();
var vertices = new float[]
{
-, -, , // pos
, , , // normal
, , // texcoord
, -, , , , , , , , , , , , , , , -, , , , , , ,
}; mesh.SharedVertexData = new VertexData();
mesh.SharedVertexData.vertexCount = ;
var decl = mesh.SharedVertexData.vertexDeclaration;
var binding = mesh.SharedVertexData.vertexBufferBinding; var offset = ;
decl.AddElement( , offset, VertexElementType.Float3, VertexElementSemantic.Position );
offset += VertexElement.GetTypeSize( VertexElementType.Float3 );
decl.AddElement( , offset, VertexElementType.Float3, VertexElementSemantic.Normal );
offset += VertexElement.GetTypeSize( VertexElementType.Float3 );
decl.AddElement( , offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, );
offset += VertexElement.GetTypeSize( VertexElementType.Float2 ); var vbuf = HardwareBufferManager.Instance.CreateVertexBuffer( decl, , BufferUsage.StaticWriteOnly );
binding.SetBinding( , vbuf ); vbuf.WriteData( , vbuf.Size, vertices, true ); sub.useSharedVertices = true;
var ibuf = HardwareBufferManager.Instance.CreateIndexBuffer( IndexType.Size16, , BufferUsage.StaticWriteOnly ); var faces = new short[]
{
, , , , ,
};
sub.IndexData.indexBuffer = ibuf;
sub.IndexData.indexCount = ;
sub.IndexData.indexStart = ;
ibuf.WriteData( , ibuf.Size, faces, true ); mesh.BoundingBox = new AxisAlignedBox( new Vector3( -, -, ), new Vector3( , , ) );
mesh.BoundingSphereRadius = Utility.Sqrt( * + * );
}

createPlane

Axiom3D:数据绑定基本流程的更多相关文章

  1. Axiom3D:Buffer漫谈

    在前面数据绑定基本流程,简单说了下,在Axiom中,数据从我们C#的托管环境到下面的OpenGL或是D3D的非托管环境,有个转化过程,相关实现我们可以从BufferBase看起.BufferBase与 ...

  2. SpringMvc的数据绑定流程

    在SpringMvc中会将来自web页面的请求和响应数据与controller中对应的处理方法的入参进行绑定,即数据绑定.流程如下: -1.SpringMvc主框架将ServletRequest对象及 ...

  3. Axiom3D:Ogre中Mesh文件格式分析(一)

    在Axiom3D,或者说是Ogre的mesh的文件格式我们可能通过代码反推出相关格式,相关过程本来我是直接写的,后面发现相关流程写完后,我自己都看晕了,然后我就把一些过程用Execl整理出来,发现过程 ...

  4. SpringMVC 接收表单数据、数据绑定、解决请求参数中文乱码

    接收表单数据有3种方式. 1.使用简单类型接收表单数据(绑定简单数据类型) 表单: <form action="${pageContext.request.contextPath}/u ...

  5. AngularJS 脏检查深入分析

    写在开头 关于Angular脏检查,之前没有仔细学习,只是旁听道说,Angular 会定时的进行周期性数据检查,将前台和后台数据进行比较,所以非常损耗性能. 这是大错而特错的.我甚至在新浪前端面试的时 ...

  6. AngularJS介绍

    AngularJS介绍–AngularJS的前世今生 AngularJS是什么 在Web开发领域,我们一般使用HTML作为前端页面元素的声明式语言,使用CSS技术作为展示样式的描述语言,JavaScr ...

  7. AngularJS基础知识1

    一.angularJS简介 1.什么是 AngularJS? AngularJS 是一个 JavaScript 框架.它是一个以 JavaScript 编写的库.AngularJS是协助搭建单页面工程 ...

  8. WPF DataGrid常用属性记录

    WPF DataGrid常用属性记录 组件常用方法: BeginEdit:使DataGrid进入编辑状态. CancelEdit:取消DataGrid的编辑状态. CollapseRowGroup:闭 ...

  9. 7、SpringMVC源码分析(2):分析HandlerAdapter.handle方法,了解handler方法的调用细节以及@ModelAttribute注解

    从上一篇 SpringMVC源码分析(1) 中我们了解到在DispatcherServlet.doDispatch方法中会通过 mv = ha.handle(processedRequest, res ...

随机推荐

  1. 【Unity】11.4 车轮碰撞体(Wheel Collider)

    分类:Unity.C#.VS2015 创建日期:2016-05-02 一.简介 车轮碰撞体 (Wheel Collider)专门用于创建汽车或其他移动交通工具. 车轮碰撞体是一种针对地面车辆的特殊碰撞 ...

  2. 菜鸟学SSH(五)——Struts2上传文件

    上传文件在一个系统当中是一个很常用的功能,也是一个比较重要的功能.今天我们就一起来学习一下Struts2如何上传文件. 今天讲的上传文件的方式有三种: 1,以字节为单位传输文件: 2,Struts2封 ...

  3. .NET MVC5+ Dapper+扩展+微软Unity依赖注入实例

    1.dapper和dapper扩展需要在线安装或者引用DLL即可 使用nuget为项目增加Unity相关的包 2.model类 public class UserInfo { public int I ...

  4. Replace 在动态sql中的实现

    set @stsqlReplace=' update ChgCfm set cfmdate=replace(cfmdate,'''''''',''''), cfmstatu=replace(cfmst ...

  5. (原创)c++11中 function/lamda的链式调用

    关于链式调用,比较典型的例子是c#中的linq,不过c#中的linq还只是一些特定函数的链式调用.c++中的链式调用更少见因为实现起来比较复杂.c++11支持了lamda和function,在一些延迟 ...

  6. docker使用示例

    本文使用docker容器运行wordpress博客,采用了三种方法来演示,docker的使用 自建wordpress容器 采用官方的wordpress容器 采用docker compose容器管理工具 ...

  7. 每日英语:Three Shows That Changed The Way Networks Think About Viewership

    As we continue examining this season’s DVR success stories in The Blacklist and Sleepy Hollow it mak ...

  8. 腾讯云提示invalid pos, pos is bigger than filesize! pos: 0, file_size: 0错误

    腾讯云提示invalid pos, pos is bigger than filesize! pos: 0, file_size: 0错误 起因 使用hdfs dfs -text xxx命令提示下面错 ...

  9. js实现手机摇一摇

    //手机摇一摇 ---------------------------------------------------------- init();var SHAKE_THRESHOLD = 3000 ...

  10. LeetCode:Sqrt(x) 解题报告

    Sqrt(x) Implement int sqrt(int x). Compute and return the square root of x. SOLUTION 1: 参见:二分法总结,以及模 ...