在前面数据绑定基本流程,简单说了下,在Axiom中,数据从我们C#的托管环境到下面的OpenGL或是D3D的非托管环境,有个转化过程,相关实现我们可以从BufferBase看起.BufferBase与他的子类集合了相关数据块在托管环境与非托管环境的相关操作.     在BufferBase中,包装了一个重要的类GCHandle,其中托管代码中,因为GC的关系,在运行时所有元素的内存地址也都是变化的,这里在我们需要用到GCHandleType.Pinned,这个会固定我们申请的空间地址,防止GC移动与释放这块内存,当然这块内存的回收也和C++里一样,需要我们手动调用Free方法去释放.GCHandle对象保存了数据块在内存中的位置,而GCHandle里的Ptr(int)保存的是我们在GCHandle内存块里的位置(如申请100字节长度,那么Ptr只能是0-99这100百个数),默认是头0开始,一般用来做偏移地址运算.BufferBase提供一个虚拟方法Pin(),供子类提供数据块固定的指针地址,以便于OpenGL,D3D中非托管环境调用.最后BufferBase里的方法Wrap,用来直接生成一个UnsafeBuffer的对象.

下面针对UnsafeBuffer,我们来先看一段代码:

这段代码里,我们首先用GCHandle.Alloc申请一块buffer大小的空间,在这buffer虽然是object类型,但是因为我们申请的是固定的句柄(GCHandleType.Pinned),这个是不支持引用类型的,就是buffer必需是值类型(值类型也有要求,应该说是准确声明空间长度的值类型),不过在Axiom中,我们一般是传递如int[],float[]这种,所以此处满足.申请后,我们用方法AddrofPinnedObject得到用Pinned方式申请的指针,上面this.Buf是成byte*块,就是字节块,这样主要是为了好做相关地址运算,如下面我传入一个-100.0,-100.0,0.0...的数组,请看下面相关结果.

表达式

内存地址

地址求值

(float*)this.Buf

0x01fdfab4

*((float*)this.Buf): -100.0

(float*)this.Buf + 1

0x01fdfab8

*((float*)this.Buf + 1): -100.0

(float*)this.Buf + 2

0x01fdfabc

*((float*)this.Buf + 2): 0.0

(float*)(this.Buf+4)

0x01fdfab8

*((float*)(this.Buf+4)): -100.0

(float*)(this.Buf+8)

0x01fdfabc

*((float*)(this.Buf+8)): 0.0

我们知道内存中,数据全是0101这样的bit位,我们的数组buffer保存在内存中也是这样,我们平常定义的什么int,float,byte等只是为了让计算机正确解析位来转换成相应数据.这里转换成byte*,float*,int*的区别也是这样,如果转化成byte位,那么他加1就是一个byte,同理,他转化成int,float,他就加4个byte,也就是4个字节长度.我们知道sizeof计算的长度就是字节来算的,这里转化成byte*就是用了容易对地址进行定义,因为字节是我们数据块用到的最小单位,对应属性Length长度指的也是字节.如上,转化成byte*后,我要得到第二个float就用(float*)(this.Buf+4)或是(float*)this.buf+1,效果一样.我们再来看下面一段代码就很清楚了.

我们知道,long是8个字节,而index是指单位为字节的长度,那么转化成对应的long数组里对应的long的索引应该是index*8,例如index是10,那么long数组对应值应该是对应字节块的初地址加上80的偏移量.对应的如ITypePointer<byte>,ITypePointer<short>,ITypePointer<int,float>,ITypePointer<double>分别是index,index*2,index*4,index*8.

而同属BufferBase的子类的ManagedBuffer,不同于UnsafeBuffer管理的byte*,他管理的是byte[],好吧,这二个也是一样,相关的索引器也是在对byte索引的偏移计算,同UnsafeBuffer逻辑一样,不同的是,UnsafeBuffer中的GCHandle.Alloc操作是在初始化的时候.而ManagedBuffer是发生在调用方法Pin时,才会执行GCHandle.Alloc操作.注意,不管是UnsafeBuffer还是ManagedBuffer,Pin方法指向的指针位置是当前内存块的头地址(GCHandle.AddrofPinnedObject())加上偏移地址(BufferBase.Ptr).

同样如ManagedBufferCol3b等,都是在原来类的基础上增加一个对应的索引器.

在前面Axiom3D:数据绑定基本流程可以看到顶点数据(VertexData),索引数据(IndexData),他们都有HardwareBuffer对象,这个对象用来与BufferBase互动.HardwareBuffer与BufferBase的关系有些类似AnimationTrack与KeyFrame,他们的具体实现交给子类,抽象互动都由本身来实现.前面我们说了BufferBase,主要是提供一个数据块空间,这个空间的位置,对这个空间的索引,相关子类对应托管环境与非托管环境的实现.而HardwareBuffer如下方法WriteData,ReadData,Copy分别提供对BufferBase的写入,读取,复制数据一些操作的包装.针对GL的环境,我们来看下HardwareBuffer的子类GLHardwareVertexBuffer,其WriteData,ReadData就是调用glBufferData,glGetBufferData分别把BufferBase里的数据块写入到显存,或从显存中读取出来.不用显存,DefaultHardwareVertexBuffer提供针对内存中BufferBase的相关操作,不像GLHardwareVertexBuffer需要把数据从CPU到GPU的过程,DefaultHardwareVertexBuffer里的读取,写入,复制操作就是把BufferBase的数据块从一个地方复制到另一个地方,直接用的就是对应的BufferBase的Copy操作.

还有一个地方,数据也是一块一块的包装在一个位置的,就是纹理,我们知道纹理图片里的每个像素点都是各个类型的RGBA元素组合而成,那么在我们内存或显存中,图片就是一个数据块区域,知道了这个数据块区域的格式,如RGBA8B,那么我们就能正确的解析成相应的像素点集合,然后就能正确的在显示器上显示成对应图像了.通过纹理我们能利用GPU强大的并行功能,因为纹理就是数据块,就是数组.具体可以参看GPGPU基本运算与乒乓技术.

如同顶点对应HardwareVertexBuffer,顶点索引对应HardwareIndexBuffer,图片也有自己的HardwareBuffer对应类HardwarePixelBuffer.在介绍这个类时,先看下类BasicBox与PixelBox,其中PixelBox是BasicBox的子类,BasicBox差不多就是针对一个描述一个立方体,有6面,分别是前后左右上下6面(一般情况下,默认宽度Width指左右距离,高度Height指上下距离,深度Depth指前后距离).而PixelBox描述的是图片(包含一维至三维,一维用宽度Width,二维增加高度Height,三维增加深度Depth).在BasicBox的上面增加一个BufferBase用来表示像素数据,其中PixelBox有个比较重要的属性PixelFormat,其实这个类就相当于VertexDeclaration,一个是指明像素是如何组成的,如SHORT_RBG.而VertexDeclaration指明顶点是如何组成,如T2fN3fV3f.有了PixelFormat,我们才能正确序列化PixelBox里的数据块BufferBase里的信息.在PixelConverter这个类中提供了二个PixelBox互相操作的方法,例如从一张图片中提取他的R通道数据,调用PixelConverter的BulkPixeConversion方法就可.有兴趣可以看一下具体实现,本质还是对BufferBase根据PixelFormat与索引得到偏移赋值操作.

  而HardwarePixelBuffer提供二个抽象方法,一个是BlitFormMemory,把PixelBox中的像素数据取出放到新的内存或显存.另一个是BlitToMemory,把显存和内存里的数据取出.这二个函数分别在GL的环境中的子类GLHardwareBuffer与他的子类GLTextureBuffer中的实现如下,BlitFormMemory就是调用GL的API如glTexImage2D这类把数据,而BlitToMemory就是调用glGetTexImage,这样就很容易理解了.

  下图是上面类的关系,突出像素HardwarePixelBuffer与BufferBase的关系。

Axiom3D:Buffer漫谈的更多相关文章

  1. Axiom3D:Ogre地形组件代码解析

    大致流程. 这里简单介绍下,Axiom中采用的Ogre的地形组件的一些概念与如何生成地形. 先说下大致流程,然后大家再往下看.(只说如何生成地形与LOD,除高度纹理图外别的纹理暂时不管.) 1.生成T ...

  2. Axiom3D:数据绑定基本流程

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

  3. MySQL · 性能优化· InnoDB buffer pool flush策略漫谈

    MySQL · 性能优化· InnoDB buffer pool flush策略漫谈 背景 我们知道InnoDB使用buffer pool来缓存从磁盘读取到内存的数据页.buffer pool通常由数 ...

  4. 【转载】MySQL · 性能优化· InnoDB buffer pool flush策略漫谈

    背景 我们知道InnoDB使用buffer pool来缓存从磁盘读取到内存的数据页.buffer pool通常由数个内存块加上一组控制结构体对象组成.内存块的个数取决于buffer pool inst ...

  5. 【转】漫谈linux文件IO--io流程讲的很清楚

    [转]漫谈linux文件IO--io流程讲的很清楚 这篇文章写的比较全面,也浅显易懂,备份下.转载自:http://blog.chinaunix.net/uid-27105712-id-3270102 ...

  6. Axiom3D写游戏:用Overlay实现Mesh浏览.

    从网上找了些资源,大多搜Ogre,Mesh资源,然后为了方便查看各个Mesh,以及对应骨骼动画.为了实用性,考虑放在原游戏窗口里实现.最开始打算窗口新建viewport来实现,后发现这种方式的局限性, ...

  7. (转)漫谈JVM

    漫谈JVM 原文:https://liuzhengyang.github.io/2016/10/05/gossip-jvm/ 背景介绍 JVM已经是Java开发的必备技能了,JVM相当于Java的操作 ...

  8. 分布式系统漫谈一 —— Google三驾马车: GFS,mapreduce,Bigtable

    分布式系统学习必读文章!!!! 原文:http://blog.sina.com.cn/s/blog_4ed630e801000bi3.html 分布式系统漫谈一 —— Google三驾马车: GFS, ...

  9. [Alink漫谈之三] AllReduce通信模型

    [Alink漫谈之三] AllReduce通信模型 目录 [Alink漫谈之三] AllReduce通信模型 0x00 摘要 0x01 MPI是什么 0x02 Alink 实现MPI的思想 0x03 ...

随机推荐

  1. Requests: 让 HTTP 服务人类

    requests 2.18.1文档 requests流式post文件 Calling SOAP Web service using requests module of

  2. 斯坦福CS231n深度学习计算机视觉

    http://study.163.com/course/introduction/1003223001.htm

  3. angular学习笔记(三十)-指令(10)-require和controller

    本篇介绍指令的最后两个属性,require和controller 当一个指令需要和父元素指令进行通信的时候,它们就会用到这两个属性,什么意思还是要看栗子: html: <outer‐direct ...

  4. Ctex中WinEdt经常弹出注册小窗口 解决办法

    使用WinEdt 7避免跳出“注册对话框” 在options菜单下点options…,在advanced configuration  =>  Event Handlers  下点Exit, 在 ...

  5. python--笨方法学python 习题52

    笨方法学python是一本不错的python入门书籍.书的最后一节是一个web版的游戏程序,以下是程序代码: 1.项目的目录结构如下所示:skeleton\ app.py map.py templat ...

  6. python类里面使用装饰器

    参考:http://m.blog.csdn.net/blog/wklken/8118942 def on(name, *args_of_on, **kwargs_of_on): def handle_ ...

  7. [MyBean说明书]-如何进行最简单的DEMO

    MyBean是轻量级的.绿色的框架,不需要安装任何的组件和携带任何的其他文件,前 期步骤已经相当精简了,仔细阅读完下面简单的五个步骤,就可以编写基于MyBean的插件: 1.加入Delphi的搜索路径 ...

  8. Vue2键盘事件

    这两天学习了Vue.js 感觉组件这个地方知识点挺多的,而且很重要,所以,今天添加一点小笔记,学习一下Vue键盘事件 键盘事件 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 ...

  9. Windows下断言的类型及实现

    一.内容综述 本文主要介绍Windows下断言assert的实现,并总结断言的不同应用准则.最后给出一个windows自定义断言的方法. 本文行文参考<Debugging Windows Pro ...

  10. hdu3938(最小生成树,推荐)

    题意描述:简单的讲就是,给你一张无向图,求有多少条路径使得路径上的花费小于L,这里路径上的花费是这样规定的,a.b两点之间的多条路径中的最长的边最小值! 思路:这题目有多个询问,肯定要用离线输出.思路 ...