Ptex源码学习笔记-2
写入纹理数据:
主要分为五种写入方式:新建纹理、编辑已有纹理、编辑ExtHeader中的指定项、写入元数据和写入指定面的纹理数据。写入过程中数据存在一个临时文件中,在close时才会把临时文件的内容拷贝到指定写入的文件中并删除临时文件。
- 新建纹理。调用对应的open函数,首先应该校验新建的纹理参数是否符合要求,然后用main writer(继承自base writer)写入,基本就是初始化header和ruduce函数的绑定,同时设置压缩方式并新建临时tile文件以供写入。新纹理写入到.new文件,保存时再写入到最终位置。初始化时用到了std::vector.reserve和resize,以前没注意,现在知道,增大时,reserve改变vector的容量(分配空间)并使所有迭代器无效,resize增加元素,减小时,reserve没有减小的功能(可用shrink_to_fit),resize会减小元素数,但不会改变容量,二者对应的大小用capacity和size获取。由于是新建,所以tex参数为空指针,在初始化PtexMainWriter时不会有纹理信息的复制。
- 编辑已有纹理。校验格式后需检查是否已有该文件,如果文件存在,编辑方式根据是否为incremental决定用incremental writer(继承自base writer)或main writer,如果文件存在,则关闭已打开文件后再用reader打开并校验header,否则和新建一样直接用main writer。incremental writer写入的数据不压缩(main writer要压缩,在base writer初始化时设置),从而避免每次保存都要压缩编辑又要解压缩,只在最终保存时压缩一次,提高保存效率。校验header和extended header(不需要用reader打开),通过后移到文件末位准备写入。
- 写入元数据。根据参数的不同,分为添加和复制,复制实际是对添加的一层封装,先校验key的长度和value的大小,如果当前key已存在,则覆盖value,不存在则新建。
- 写入指定面的纹理数据。分写入普通数据和常量数据,main writer和incremental writer写入方式不同:
- main writer
- 写入普通数据时,需校验faceinfo,记录当前面在文件中的位置后,写入面数据,如果有alpha通道,先将数据复制到临时buffer中,然后乘上alpha通道,然后再用临时buffer的数据覆盖原数据,最后,如果需要生成mipmap则生成第一级reduction,默认分辨率大于2x2才能生成,否则所有数据除以uv分辨率的乘积后保存到面的常量区,如果有alpha通道还要再除以alpha值。所有操作完成后释放临时buffer并标记有新数据写入。
- 写入常量数据时,校验faceinfo后,直接复制数据到面的常量区。
- incremental writer
- 写入普通数据时,与main writer大部分过程相似,但是因为要更新header信息,所以多了header写入,但是header的信息要在面数据写入后才能获得,所以先留出header的空间并记录位置,写完面信息后再倒回去写header,最后再把fp移到末尾。
- 写入常量数据时,同样需要写入header,不过因为是常量数据,所以header信息预先知道,所以可以写入header后再写入面数据就完成了。
- main writer
- 关闭文件。main writer和incremental writer的close函数都需要先调用base writer的close函数间接调用各自的finish函数写入新数据,main writer较为复杂,如果已有reader(在编辑的时候会将用reader打开纹理,reader存在说明新添加了纹理),则需要从reader中获取facedata,然后根据是否为常量写入数据(从reader里复制),如果没有reader(说明没有添加新纹理),则直接将缺失纹理的面标记为常量。然后根据需要生存mipmap,标记有常量相邻面的面,更新header的level和face数目信息。然后新建文件,根据ptex规定的存储顺序依次写入数据,注意header、extended header和level的部分信息(header大小和levelinfo)在数据写入完成前是不知道的,所以要预先留空,之后再填上。faceinfo和constdata直接写入新建文件,facedata需要按level写入,每一个level先写leveldataheader,然后再从之前写入的临时文件复制该level的各个面的纹理数据到新文件。所有都完成后关闭新文件(即保存的文件),如果之前是按tile写入的,base writer会在完成后删除tile文件,main writer需要释放reader和删除临时文件(如果有),最后删除原文件,将新文件的文件名(原文件名后面加了.new)改成原文件的文件名(去掉.new)。incremental writer在base writer关闭后关闭fp就可以了。
Ptex源码学习笔记-2的更多相关文章
- Ptex源码学习笔记-1
Ptex是Walt Disney Animation Studios开发的纹理映射工具.在看一个叫appleseed的渲染器时看到他支持这种纹理,所以就查看一下,发现比较轻量,所以就想趁此机会学习下. ...
- Underscore.js 源码学习笔记(下)
上接 Underscore.js 源码学习笔记(上) === 756 行开始 函数部分. var executeBound = function(sourceFunc, boundFunc, cont ...
- Underscore.js 源码学习笔记(上)
版本 Underscore.js 1.9.1 一共 1693 行.注释我就删了,太长了… 整体是一个 (function() {...}()); 这样的东西,我们应该知道这是一个 IIFE(立即执行 ...
- AXI_LITE源码学习笔记
AXI_LITE源码学习笔记 1. axi_awready信号的产生 准备接收写地址信号 // Implement axi_awready generation // axi_awready is a ...
- Hadoop源码学习笔记(6)——从ls命令一路解剖
Hadoop源码学习笔记(6) ——从ls命令一路解剖 Hadoop几个模块的程序我们大致有了点了解,现在我们得细看一下这个程序是如何处理命令的. 我们就从原头开始,然后一步步追查. 我们先选中ls命 ...
- Hadoop源码学习笔记(5) ——回顾DataNode和NameNode的类结构
Hadoop源码学习笔记(5) ——回顾DataNode和NameNode的类结构 之前我们简要的看过了DataNode的main函数以及整个类的大至,现在结合前面我们研究的线程和RPC,则可以进一步 ...
- Hadoop源码学习笔记(4) ——Socket到RPC调用
Hadoop源码学习笔记(4) ——Socket到RPC调用 Hadoop是一个分布式程序,分布在多台机器上运行,事必会涉及到网络编程.那这里如何让网络编程变得简单.透明的呢? 网络编程中,首先我们要 ...
- Hadoop源码学习笔记(3) ——初览DataNode及学习线程
Hadoop源码学习笔记(3) ——初览DataNode及学习线程 进入了main函数,我们走出了第一步,接下来看看再怎么走: public class DataNode extends Config ...
- Hadoop源码学习笔记(2) ——进入main函数打印包信息
Hadoop源码学习笔记(2) ——进入main函数打印包信息 找到了main函数,也建立了快速启动的方法,然后我们就进去看一看. 进入NameNode和DataNode的主函数后,发现形式差不多: ...
随机推荐
- gradle修改AndroidManifest.xml中的版本号
def VersionCode = "19" ant.replaceregexp(file:"../Assets/Plugins/Android/AndroidManif ...
- ActiveMQ与WebSocket的结合应用
前段时间无意之中看到了WebSocket这样东西,发现自己真的是火星了.早在11年就有的东西,一直都不知道. 研究了一番之后感觉还是比较好用的. 我很少做Socket开发,但是曾经由于项目的原因,用过 ...
- PHP类型转换
php代码 <?php$foo = "0"; // $foo 是字符串 (ASCII 48)var_dump($foo) ; echo '<br/>'; $foo ...
- ADC测试matlab代码
前面有做过ADC性能测试,测试方式是先使用ADC采集一个单频信号,然后利用matlab进行性能分析. 下面把matlab分析的代码记录下来: %The following program code p ...
- reverse engineering in ax
install Visio2010 Premium(UML model template). not work in Visio 2013 and other version.
- 【整理】动态加载Web Services
WebClient client = new WebClient(); String url = "http://localhost/MESAPIWebService/MESAPI.asmx ...
- 【练习】oracel获取当前session的id方法
1. :: SYS; SID ---------- 2. :: SYS@ORA11GR2>SELECT USERENV('SID') FROM DUAL; USERENV('SID') ---- ...
- 2、C#面向对象:封装、继承、多态、String、集合、文件(上)
面向对象封装 一.面向对象概念 面向过程:面向的是完成一件事情的过程,强调的是完成这件事情的动作. 面向对象:找个对象帮你完成这件事情. 二.面向对象封装 把方法进行封装,隐藏实现细节,外部直接调用. ...
- MATLAB处理信号得到频谱、相谱、功率谱
(此帖引至网络资源,仅供参考学习)第一:频谱 一.调用方法 X=FFT(x):X=FFT(x,N):x=IFFT(X);x=IFFT(X,N) 用MATLAB进行谱分析时注意: (1)函数FFT返回值 ...
- 监听JVM的几个命令(可用于linux 本机)
1. jstat 这个命令对于查看Jvm的堆栈信息很有用.能够查看eden,survivor,old,perm等heap的capacity,utility信息 对于查看系统是不是有能存泄漏以及参数设置 ...