写入纹理数据:

  主要分为五种写入方式:新建纹理、编辑已有纹理、编辑ExtHeader中的指定项、写入元数据和写入指定面的纹理数据。写入过程中数据存在一个临时文件中,在close时才会把临时文件的内容拷贝到指定写入的文件中并删除临时文件。

  1. 新建纹理。调用对应的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时不会有纹理信息的复制。
  2. 编辑已有纹理。校验格式后需检查是否已有该文件,如果文件存在,编辑方式根据是否为incremental决定用incremental writer(继承自base writer)或main writer,如果文件存在,则关闭已打开文件后再用reader打开并校验header,否则和新建一样直接用main writer。incremental writer写入的数据不压缩(main writer要压缩,在base writer初始化时设置),从而避免每次保存都要压缩编辑又要解压缩,只在最终保存时压缩一次,提高保存效率。校验header和extended header(不需要用reader打开),通过后移到文件末位准备写入。
  3. 写入元数据。根据参数的不同,分为添加和复制,复制实际是对添加的一层封装,先校验key的长度和value的大小,如果当前key已存在,则覆盖value,不存在则新建。
  4. 写入指定面的纹理数据。分写入普通数据和常量数据,main writer和incremental writer写入方式不同:
    1. main writer
      1. 写入普通数据时,需校验faceinfo,记录当前面在文件中的位置后,写入面数据,如果有alpha通道,先将数据复制到临时buffer中,然后乘上alpha通道,然后再用临时buffer的数据覆盖原数据,最后,如果需要生成mipmap则生成第一级reduction,默认分辨率大于2x2才能生成,否则所有数据除以uv分辨率的乘积后保存到面的常量区,如果有alpha通道还要再除以alpha值。所有操作完成后释放临时buffer并标记有新数据写入。
      2. 写入常量数据时,校验faceinfo后,直接复制数据到面的常量区。
    2. incremental writer
      1. 写入普通数据时,与main writer大部分过程相似,但是因为要更新header信息,所以多了header写入,但是header的信息要在面数据写入后才能获得,所以先留出header的空间并记录位置,写完面信息后再倒回去写header,最后再把fp移到末尾。
      2. 写入常量数据时,同样需要写入header,不过因为是常量数据,所以header信息预先知道,所以可以写入header后再写入面数据就完成了。
  5.   关闭文件。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的更多相关文章

  1. Ptex源码学习笔记-1

    Ptex是Walt Disney Animation Studios开发的纹理映射工具.在看一个叫appleseed的渲染器时看到他支持这种纹理,所以就查看一下,发现比较轻量,所以就想趁此机会学习下. ...

  2. Underscore.js 源码学习笔记(下)

    上接 Underscore.js 源码学习笔记(上) === 756 行开始 函数部分. var executeBound = function(sourceFunc, boundFunc, cont ...

  3. Underscore.js 源码学习笔记(上)

    版本 Underscore.js 1.9.1 一共 1693 行.注释我就删了,太长了… 整体是一个 (function() {...}());  这样的东西,我们应该知道这是一个 IIFE(立即执行 ...

  4. AXI_LITE源码学习笔记

    AXI_LITE源码学习笔记 1. axi_awready信号的产生 准备接收写地址信号 // Implement axi_awready generation // axi_awready is a ...

  5. Hadoop源码学习笔记(6)——从ls命令一路解剖

    Hadoop源码学习笔记(6) ——从ls命令一路解剖 Hadoop几个模块的程序我们大致有了点了解,现在我们得细看一下这个程序是如何处理命令的. 我们就从原头开始,然后一步步追查. 我们先选中ls命 ...

  6. Hadoop源码学习笔记(5) ——回顾DataNode和NameNode的类结构

    Hadoop源码学习笔记(5) ——回顾DataNode和NameNode的类结构 之前我们简要的看过了DataNode的main函数以及整个类的大至,现在结合前面我们研究的线程和RPC,则可以进一步 ...

  7. Hadoop源码学习笔记(4) ——Socket到RPC调用

    Hadoop源码学习笔记(4) ——Socket到RPC调用 Hadoop是一个分布式程序,分布在多台机器上运行,事必会涉及到网络编程.那这里如何让网络编程变得简单.透明的呢? 网络编程中,首先我们要 ...

  8. Hadoop源码学习笔记(3) ——初览DataNode及学习线程

    Hadoop源码学习笔记(3) ——初览DataNode及学习线程 进入了main函数,我们走出了第一步,接下来看看再怎么走: public class DataNode extends Config ...

  9. Hadoop源码学习笔记(2) ——进入main函数打印包信息

    Hadoop源码学习笔记(2) ——进入main函数打印包信息 找到了main函数,也建立了快速启动的方法,然后我们就进去看一看. 进入NameNode和DataNode的主函数后,发现形式差不多: ...

随机推荐

  1. Python基础篇【第5篇】: Python内置模块(二)

    内置模块 1. OS os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录:相当于shell ...

  2. block使用小结、在arc中使用block、如何防止循环引用

    引言 使用block已经有一段时间了,感觉自己了解的还行,但是几天前看到CocoaChina上一个关于block的小测试主题: [小测试]你真的知道blocks在Objective-C中是怎么工作的吗 ...

  3. php使用file函数、fseek函数读取大文件效率分析

    php读取大文件可以使用file函数和fseek函数,但是二者之间效率可能存在差异,本文章向大家介绍php file函数与fseek函数实现大文件读取效率对比分析,需要的朋友可以参考一下. 1. 直接 ...

  4. oracle 实现ID自增

    CREATE TABLE testTable1 ( ID INT NOT NULL, NAME ) NOT NULL, PRIMARY KEY(ID) ) TABLESPACE MYDB; --创建自 ...

  5. Java多线程Thread

    转自:http://www.cnblogs.com/lwbqqyumidi/p/3804883.html Java总结篇系列:Java多线程(一)   多线程作为Java中很重要的一个知识点,在此还是 ...

  6. PgSQL dump 工具

    #!/bin/bash #Auther Sun Ying ##Copy left ##Version: Demo Version ##Basic Compare the datebase change ...

  7. nginx相关的一些记录

    http redirect to https: if ($http_cf_visitor ~ '"scheme":"http"'){ rewrite ^/(.* ...

  8. Android IOS WebRTC 音视频开发总结(二五)-- webrtc优秀资源汇总

    本文主要整理一些webrtc相关资料供学习(会持续更新),转载请说明出处,文章来自博客园RTC.Blacker,欢迎关注微信公众号:blackerteam ---------------------- ...

  9. Oracle重新装机后如何快速还原以前表和用户

    本人使用的oracle10g 首先拷贝以前的oradata 文件夹 一:重新创建oracle数据库后手动关闭oracle所有服务 二:将oradata中新创建的数据库目录改名,d:\app\user\ ...

  10. PS Web切图界面设置

    界面为移动工具时(快捷键V),选中左上角的图层. 点击视图,选中显示→智能参考线,与标尺. 点击窗口,把"库" "颜色"去掉,把屏幕右上角的"通道&q ...