Axiom3D:数据绑定基本流程
在前面我们学习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这种结构.
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:数据绑定基本流程的更多相关文章
- Axiom3D:Buffer漫谈
在前面数据绑定基本流程,简单说了下,在Axiom中,数据从我们C#的托管环境到下面的OpenGL或是D3D的非托管环境,有个转化过程,相关实现我们可以从BufferBase看起.BufferBase与 ...
- SpringMvc的数据绑定流程
在SpringMvc中会将来自web页面的请求和响应数据与controller中对应的处理方法的入参进行绑定,即数据绑定.流程如下: -1.SpringMvc主框架将ServletRequest对象及 ...
- Axiom3D:Ogre中Mesh文件格式分析(一)
在Axiom3D,或者说是Ogre的mesh的文件格式我们可能通过代码反推出相关格式,相关过程本来我是直接写的,后面发现相关流程写完后,我自己都看晕了,然后我就把一些过程用Execl整理出来,发现过程 ...
- SpringMVC 接收表单数据、数据绑定、解决请求参数中文乱码
接收表单数据有3种方式. 1.使用简单类型接收表单数据(绑定简单数据类型) 表单: <form action="${pageContext.request.contextPath}/u ...
- AngularJS 脏检查深入分析
写在开头 关于Angular脏检查,之前没有仔细学习,只是旁听道说,Angular 会定时的进行周期性数据检查,将前台和后台数据进行比较,所以非常损耗性能. 这是大错而特错的.我甚至在新浪前端面试的时 ...
- AngularJS介绍
AngularJS介绍–AngularJS的前世今生 AngularJS是什么 在Web开发领域,我们一般使用HTML作为前端页面元素的声明式语言,使用CSS技术作为展示样式的描述语言,JavaScr ...
- AngularJS基础知识1
一.angularJS简介 1.什么是 AngularJS? AngularJS 是一个 JavaScript 框架.它是一个以 JavaScript 编写的库.AngularJS是协助搭建单页面工程 ...
- WPF DataGrid常用属性记录
WPF DataGrid常用属性记录 组件常用方法: BeginEdit:使DataGrid进入编辑状态. CancelEdit:取消DataGrid的编辑状态. CollapseRowGroup:闭 ...
- 7、SpringMVC源码分析(2):分析HandlerAdapter.handle方法,了解handler方法的调用细节以及@ModelAttribute注解
从上一篇 SpringMVC源码分析(1) 中我们了解到在DispatcherServlet.doDispatch方法中会通过 mv = ha.handle(processedRequest, res ...
随机推荐
- 解决failed to get the required adt version from sdk version
在网上看了很多,选择其中的一个解决方法试了下, 还行. AS 2.3之后不能和Eclipse共用一个SDK,给Eclispe重新配置一个SDK路径
- 【Java】Java日志框架Logback的简单例子
常用的日志框架 SLF4J,全称Simple Logging Facade for Java,即Java简单日志外观框架,顾名思义,它并非具体的日志实现,而是日志外观框架 java.util.logg ...
- 【工具】Windows7搭建FTP服务器
有时候需要将文件在各台电脑间拷贝,所以想建一个ftp服务器方便些,这里的设置仅为家用设置的记录日志,严谨的生产环境请参考其他文章. 创建一个专用于ftp的用户 开始 > 控制面板 > 用户 ...
- 【Bootloader】探究bootloader,分析u-boot源码
Preface 之前也发表过关于<Bootloader启动过程分析>的文章,但是内容表达得比较抽象,大多是文字叙述,所以这里从系统和代码的角度来深入分析bootloader的启动过程. 工 ...
- Asp.Net计算程序执行速度
long t1 = DateTime.Now.Ticks; //执行程序,例如处理100个文件 long t2 = DateTime.Now.Ticks; Response.Write("执 ...
- 第一个驱动之字符设备驱动(二)mdev
mdev是busybox提供的一个工具,用在嵌入式系统中,相当于简化版的udev,作用是在系统启动和热插拔或动态加载驱动程序时, 自动创建设备节点.文件系统中的/dev目录下的设备节点都是由mdev创 ...
- 使用WPF Application Framework (WAF)框架
Visual Studio新建WAF项目的模板:https://marketplace.visualstudio.com/items?itemName=jbe2277.WAFProjectTempla ...
- js读取本地txt文件中的json数据
list.txt内容 [ {"optionKey":"1", "optionValue":"Canon in D"}, ...
- Java输出字符串格式问题 .UnknownFormatConversionException
今天遇到一个问题,使用JSoup挖掘出的数据一直出错 Exception in thread "main" java.util.UnknownFormatConversionExc ...
- putty配色备份
[HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions\Solarized%20Dark] "Colour0"="1 ...