热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Axiom:数据绑定基本流程

在前面我们学习OpenGL时,不管绘制如球,立方体,平面,地面,动画模型中最常用的几个操作有创建缓冲区,写入缓冲区.在Axiom中,相关的操作被整合与组织到VertexData,I

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


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

bubuko.com,布布扣

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

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


bubuko.com,布布扣id="code_img_closed_8dc51de8-c5f2-4166-91e6-1e12b3563011" class="code_img_closed"
src="/img/jia.gif">bubuko.com,布布扣 id="code_img_opened_8dc51de8-c5f2-4166-91e6-1e12b3563011"
class="code_img_opened" Onclick="cnblogs_code_hide(‘8dc51de8-c5f2-4166-91e6-1e12b3563011‘,event)"
src="/img/jian.gif">

1 var decl = mesh.SharedVertexData.vertexDeclaration;
2 var binding = mesh.SharedVertexData.vertexBufferBinding;
3
4 var offset = 0;
5 decl.AddElement( 0, offset, VertexElementType.Float3, VertexElementSemantic.Position );
6 offset += VertexElement.GetTypeSize( VertexElementType.Float3 );
7 decl.AddElement( 0, offset, VertexElementType.Float3, VertexElementSemantic.Normal );
8 offset += VertexElement.GetTypeSize( VertexElementType.Float3 );
9 decl.AddElement( 0, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0 );
10 offset += VertexElement.GetTypeSize( VertexElementType.Float2 );

VertexElement

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




VertexBufferBinding主要成员包含一个Dictionary Times New Roman"; font-size: large;‘><Times New Roman"; font-size: large;‘>shortTimes New Roman"; font-size: large;‘>, Times New Roman"; font-size: large;‘>HardwareVertexBuffer Times New Roman"; font-size: large;‘>> Times New Roman"; font-size: large;‘>Bindings的数据结构,其中Times New Roman"; font-size: large;‘>HardwareVertexBuffer这个比较重要,可以看下一般如何创建HardwareVertexBuffer,如下:

 


bubuko.com,布布扣id="code_img_closed_ddd27dd9-ce3e-497d-97bd-fa4dbfc2a6f0" class="code_img_closed"
src="/img/jia.gif">bubuko.com,布布扣 id="code_img_opened_ddd27dd9-ce3e-497d-97bd-fa4dbfc2a6f0"
class="code_img_opened" Onclick="cnblogs_code_hide(‘ddd27dd9-ce3e-497d-97bd-fa4dbfc2a6f0‘,event)"
src="/img/jian.gif">

1 var vertices = new float[32]
2 {
3 -100, -100, 0, // pos
4 0, 0, 1, // normal
5 0, 1, // texcoord
6 100, -100, 0, 0, 0, 1, 1, 1, 100, 100, 0, 0, 0, 1, 1, 0, -100, 100, 0, 0, 0, 1, 0, 0
7 };
8 var vbuf = HardwareBufferManager.Instance.CreateVertexBuffer( decl, 4, BufferUsage.StaticWriteOnly );
9 binding.SetBinding( 0, vbuf );
10 vbuf.WriteData( 0, 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操作如下:


bubuko.com,布布扣id="code_img_closed_887471f7-a897-4f4d-82a7-20ff97daf068" class="code_img_closed"
src="/img/jia.gif">bubuko.com,布布扣 id="code_img_opened_887471f7-a897-4f4d-82a7-20ff97daf068"
class="code_img_opened" Onclick="cnblogs_code_hide(‘887471f7-a897-4f4d-82a7-20ff97daf068‘,event)"
src="/img/jian.gif">

1 this.vboID = glGenBuffers(1)
2 glBindBuffer(GL_ARRAY_BUFFER,this.vboID)
3 glBufferData (GL_ARRAY_BUFFER, len(vdata)*4, vdata, GL_STATIC_DRAW)
4 this.eboID = glGenBuffers(1)
5 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,this.eboID)
6 glBufferData (GL_ELEMENT_ARRAY_BUFFER, len(vIndex)*4, vIndex,GL_STATIC_DRAW)

glBindBuffer

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


bubuko.com,布布扣id="code_img_closed_cf4d3db3-4ebc-4306-b001-2ac3fb0d30c0" class="code_img_closed"
src="/img/jia.gif">bubuko.com,布布扣 id="code_img_opened_cf4d3db3-4ebc-4306-b001-2ac3fb0d30c0"
class="code_img_opened" Onclick="cnblogs_code_hide(‘cf4d3db3-4ebc-4306-b001-2ac3fb0d30c0‘,event)"
src="/img/jian.gif">

1 var ibuf = HardwareBufferManager.Instance.CreateIndexBuffer( IndexType.Size16, 6, BufferUsage.StaticWriteOnly );
2
3 var faces = new short[6]
4 {
5 0, 1, 2, 0, 2, 3
6 };
7 sub.IndexData.indexBuffer = ibuf;
8 sub.IndexData.indexCount = 6;
9 sub.IndexData.indexStart = 0;
10 ibuf.WriteData( 0, ibuf.Size, faces, true );

IndexBuffer





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

   
 我们知道,在底层不管是OpenGL或是D3D,他们都是C,C++及的语言,针对底层的指针操作,在C#中都由上面的BufferBase的派生类包装
GCHandle提供相关的非托管内存访问托管对象的方法,能创建防GC回收托管对象.详细请看GCHandle 结构.在HardwareBuffer里的相关和内存,显存有关的操作全是用BufferBase来完成.

  整个代码是创建一个四个点的面,分别创建顶点与顶点索引缓冲区,相对整个部分代码如下:


bubuko.com,布布扣id="code_img_closed_846a2545-d7a9-43b3-bce5-623296fdc441" class="code_img_closed"
src="/img/jia.gif">bubuko.com,布布扣 id="code_img_opened_846a2545-d7a9-43b3-bce5-623296fdc441"
class="code_img_opened" Onclick="cnblogs_code_hide(‘846a2545-d7a9-43b3-bce5-623296fdc441‘,event)"
src="/img/jian.gif">

1 ///


2 /// Creates a plane as a submesh of the given mesh
3 ///

4 [OgreVersion( 1, 7, 2 )]
5 private static void _createPlane( Mesh mesh )
6 {
7 var sub = mesh.CreateSubMesh();
8 var vertices = new float[32]
9 {
10 -100, -100, 0, // pos
11 0, 0, 1, // normal
12 0, 1, // texcoord
13 100, -100, 0, 0, 0, 1, 1, 1, 100, 100, 0, 0, 0, 1, 1, 0, -100, 100, 0, 0, 0, 1, 0, 0
14 };
15
16 mesh.SharedVertexData = new VertexData();
17 mesh.SharedVertexData.vertexCount = 4;
18 var decl = mesh.SharedVertexData.vertexDeclaration;
19 var binding = mesh.SharedVertexData.vertexBufferBinding;
20
21 var offset = 0;
22 decl.AddElement( 0, offset, VertexElementType.Float3, VertexElementSemantic.Position );
23 offset += VertexElement.GetTypeSize( VertexElementType.Float3 );
24 decl.AddElement( 0, offset, VertexElementType.Float3, VertexElementSemantic.Normal );
25 offset += VertexElement.GetTypeSize( VertexElementType.Float3 );
26 decl.AddElement( 0, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0 );
27 offset += VertexElement.GetTypeSize( VertexElementType.Float2 );
28
29 var vbuf = HardwareBufferManager.Instance.CreateVertexBuffer( decl, 4, BufferUsage.StaticWriteOnly );
30 binding.SetBinding( 0, vbuf );
31
32 vbuf.WriteData( 0, vbuf.Size, vertices, true );
33
34 sub.useSharedVertices = true;
35 var ibuf = HardwareBufferManager.Instance.CreateIndexBuffer( IndexType.Size16, 6, BufferUsage.StaticWriteOnly );
36
37 var faces = new short[6]
38 {
39 0, 1, 2, 0, 2, 3
40 };
41 sub.IndexData.indexBuffer = ibuf;
42 sub.IndexData.indexCount = 6;
43 sub.IndexData.indexStart = 0;
44 ibuf.WriteData( 0, ibuf.Size, faces, true );
45
46 mesh.BoundingBox = new AxisAlignedBox( new Vector3( -100, -100, 0 ), new Vector3( 100, 100, 0 ) );
47 mesh.BoundingSphereRadius = Utility.Sqrt( 100*100 + 100*100 );
48 }
createPlane

 

Axiom:数据绑定基本流程,布布扣,bubuko.com


推荐阅读
  • 线段树,注 ... [详细]
  • JavaSE For循环入门示例
    本文将介绍Java中For循环的基本概念和使用方法,通过几个简单的示例帮助初学者更好地理解和掌握For循环。 ... [详细]
  • packagecom.panchan.tsmese.utils;importjava.lang.reflect.ParameterizedType;importjava.lang. ... [详细]
  • Java EE 平台集成了多种服务、API 和协议,旨在支持基于 Web 的多层应用程序开发。本文将详细介绍 Java EE 中的 13 种关键技术规范,帮助开发者更好地理解和应用这些技术。 ... [详细]
  • 2017年5月9日学习总结
    本文记录了2017年5月9日的学习内容,包括技术分享和相关知识点的深入探讨。 ... [详细]
  • 本文章提供了适用于 Cacti 的多核 CPU 监控模板,支持 2、4、8、12、16、24 和 32 核配置。请注意,0.87g 版本的 Cacti 需要手动修改哈希值为 0021 才能使用,而 0.88 及以上版本则可直接导入。 ... [详细]
  • Gty的二逼妹子序列 - 分块与莫队算法的应用
    Autumn 和 Bakser 正在研究 Gty 的妹子序列,但遇到了一个难题。他们希望计算某个区间内美丽度属于 [a, b] 的妹子的美丽度种类数。本文将详细介绍如何利用分块和莫队算法解决这一问题。 ... [详细]
  • 年前,我发表了一篇文章,分享了自己通过在线教育平台学习IT技能的经历。文中详细探讨了在线教育与传统线下教育在技能培训方面的优缺点。许多网友在讨论在线教育时,常常提到“在线教育是否缺乏学习氛围”的问题。本文将对此进行深入分析。 ... [详细]
  • 从零开始编译Linux系统:第16章 全新起点
    本章将详细介绍如何从零开始编译一套完整的Linux系统,涵盖关键组件如glibc库的介绍及其重要性。通过本文,读者将了解从源代码构建Linux系统的全过程。 ... [详细]
  • iOS snow animation
    CTSnowAnimationView.hCTMyCtripCreatedbyalexon1614.Copyright©2016年ctrip.Allrightsreserved.# ... [详细]
  • 使用 Git Rebase -i 合并多个提交
    在开发过程中,频繁的小改动往往会生成多个提交记录。为了保持代码仓库的整洁,我们可以使用 git rebase -i 命令将多个提交合并成一个。 ... [详细]
  • Manacher算法详解:寻找最长回文子串
    本文将详细介绍Manacher算法,该算法用于高效地找到字符串中的最长回文子串。通过在字符间插入特殊符号,Manacher算法能够同时处理奇数和偶数长度的回文子串问题。 ... [详细]
  • malloc 是 C 语言中的一个标准库函数,全称为 memory allocation,即动态内存分配。它用于在程序运行时申请一块指定大小的连续内存区域,并返回该区域的起始地址。当无法预先确定内存的具体位置时,可以通过 malloc 动态分配内存。 ... [详细]
  • 本文介绍了多种开源数据库及其核心数据结构和算法,包括MySQL的B+树、MVCC和WAL,MongoDB的tokuDB和cola,boltDB的追加仅树和mmap,levelDB的LSM树,以及内存缓存中的一致性哈希。 ... [详细]
  • Python多线程详解与示例
    本文介绍了Python中的多线程编程,包括僵尸进程和孤儿进程的概念,并提供了具体的代码示例。同时,详细解释了0号进程和1号进程在系统中的作用。 ... [详细]
author-avatar
gerardlong
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有