转自:http://www.cppblog.com/mybios/archive/2008/03/09/44046.aspx
天龙八部GridInfo文件的格式已经有人公布了,在这里:http://www.mobilegamebase.com/blog/article.asp?id=17
不过,此文中有点笔误的地方,就是那个nFirstLayerOP的位标记的描述有点错误,正确的应该如下:
 // 图片水平翻转,即左右翻转
#define FLIP_HORIZINTAL 1
 // 图片垂直翻转,即上下翻转
#define FLIP_VERTICAL 2
 // 逆时针旋转90度
#define ANTICLOCKWISE_90 4
 // 以三角形的对角线镜像,IndexOrder==0时就把左上的纹理坐标复制到右下,否则把右上的坐标复制到左下
#define FLIP_DIAGONAL 8

具体的读取源码如下,使用的是Ogre的资源管理器来读取,另提供了saveToXML和saveToTGA的功能保存到XML文件和TGA文件:

GridInfos.h

#pragma once
namespace Ogre
{
    struct GridHeader
    {
        DWORD nMagic;
        // 版本号
        DWORD nVersion;
        // 地表宽度(横向格子数)
        int nWidth;
        // 地表高度(纵向格子数)
        int nHeight;
    };

// 图片水平翻转,即左右翻转
#define FLIP_HORIZINTAL 1
    // 图片垂直翻转,即上下翻转
#define FLIP_VERTICAL 2
    // 逆时针旋转90度
#define ANTICLOCKWISE_90 4
    // 以三角形的对角线镜像,IndexOrder==0时就把左上的纹理坐标复制到右下,否则把右上的坐标复制到左下
#define FLIP_DIAGONAL 8

// 单个网格信息
    struct GridInfo
    {
        // 该值即为pixelmap的索引(第几个pixelmap)
        short    nFirstLayer;
        // 对nFirstLayer的操作,取值是上面几个定义的宏,可以互相组合
        BYTE    nFirstLayerOp;
        // 该值为pixelmap的索引
        //天龙八部的地表最多可以两层融合,说白了就是每个点里有两层UV,这里为第二层pixelmap的索引
        short    nSecondLayer;
        // 对nSecondLayer的操作,取值同nFirstLayerOp
        BYTE    nSecondLayerOp;
        // 对格子的三角形的操作,可能取值如下
        //    0正常三角形索引
        //    1不同于正常的三角形索引
        BYTE    IndexOrder;
    };

// 整个地形的网格信息
    class GridInfos
    {
    public:
        GridInfos(void);
        virtual ~GridInfos(void);
        // 打开网格文件
        void open(const String &fileName , const String &groupName);
        // 保存到XML文件中
        void saveToXML(const String &xmlFileName);
        // 保存到TGA文件中
        void saveToTGA(const String &tgaFileName);
        // 完毕并清空网格
        void close();

typedef std::vector<GridInfo> GridData;
        // 网格信息数组
        GridData m_data;
        // 宽高
        size_t m_width , m_height;

};

};

GridInfos.cpp

#include "GridInfos.h"
namespace Ogre
{

GridInfos::GridInfos(void)
        : m_width(0)
        , m_height(0)
    {
    }

GridInfos::~GridInfos(void)
    {
        close();
    }

// 打开网格文件
    void GridInfos::open(const String &fileName , const String &groupName)
    {
        DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource(fileName , groupName);
        if(stream.isNull()) 
        { 
            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
                "打开地形网格文件失败:" + fileName, 
                "GridInfos::open");
            return ; 
        }
        GridHeader header;
        // 读取文件头
        stream->read(&header , sizeof(header));
        m_width = header.nWidth;
        m_height = header.nHeight;

bool largeVersion = false;
        // 看版本号大于这个,就表示后面跟着有个标记用来表示结构体的大小是7字节的版本还是5字节的版本
        if(header.nVersion >= 0x00100001)
        {
            stream->read(&largeVersion , sizeof(largeVersion));
        }

size_t uCount = m_width * m_height;
        m_data.resize(uCount); 
        BYTE byteValue;

for(size_t i = 0 ; i < uCount ; i ++)
        {
            GridInfo &info = m_data[i];
            if(largeVersion)
            {
                stream->read(&info.nFirstLayer , 2);
            }
            else
            {
                stream->read(&byteValue , 1);
                info.nFirstLayer = byteValue;
            }
            info.nFirstLayer--;

stream->read(&info.nFirstLayerOp , 1);
            if(largeVersion)
            {
                stream->read(&info.nSecondLayer , 2);
            }
            else
            {
                stream->read(&byteValue , 1);
                info.nSecondLayer = byteValue;
            }
            info.nSecondLayer--;
            stream->read(&info.nSecondLayerOp , 1);
            stream->read(&info.IndexOrder , 1);
        }

//saveToXML(fileName + ".xml");

}

// 完毕并清空网格
    void GridInfos::close()
    {
        m_width = m_height = 0;
        m_data.clear();
    }
    // 保存到TGA文件中
    void GridInfos::saveToTGA(const String &tgaFileName)
    {
        size_t uCount = m_width * m_height;
        RGBA *rgb = new RGBA[uCount];
        for(size_t i = 0 ; i < uCount ; i ++)
        {
            rgb[i] = ((ulong)m_data[i].nFirstLayer << 16l) | (ulong)m_data[i].nSecondLayer;
        }
        Image image;
        image.loadDynamicImage((uchar*)rgb , m_width , m_height , 1 , PF_A8R8G8B8);
        image.save(tgaFileName);
    }
    // 保存到XML文件中
    void GridInfos::saveToXML(const String &xmlFileName)
    {
        std::ofstream stream;
        stream.open(xmlFileName.c_str());

stream << "<Grids>" << std::endl;
        for(size_t i = 0 ; i < m_data.size() ; i ++)
        {
            GridInfo &info = m_data[i];
            stream << "<Grid x=" << i % m_width
                << " z=" << i / m_width
                << " FirstLayer=" << (int)info.nFirstLayer
                << " FirstLayerOp=" << (int)info.nFirstLayerOp
                << " SecondLayer=" << (int)info.nSecondLayer
                << " SecondLayerOp=" << (int)info.nSecondLayerOp
                << " IndexOrder=" << (int)info.IndexOrder
                << "/>"
                << std::endl
                ;
        }
        stream << "</Grids>" << std::endl;
        stream.close();
    }

};

天龙八部GridInfo读取源码相关推荐

  1. 文件源码读取 php伪协议,include(文件包含漏洞,php伪协议)

    点击tips 查看元素,也并没有有用的信息,联想到题目,include 想起了文件包含漏洞. 构造payload ?file=/../../../../../../flag.php 没有返回东西.看完 ...

  2. vs code vue 语法提示不全_Vue造轮子必备*.vue文件源码读取并高亮展示

    相关依赖版本: node v10.15.0 npm v6.4.1 yarn v1.22.10 vue-cli v4.5.9 @vue/compiler v3.0.4 GitHub:  vue-sour ...

  3. php读取图片文件流,详解php文件包含原理(读取文件源码、图片马、各种协议、远程getshell等)...

    详解php文件包含原理(读取文件源码.图片马.各种协议.远程getshell等) 作者是namezz (看完图相当于做了一轮实验系列) 现有文件代码如下 1.png (21.16 KB, 下载次数: ...

  4. include详解 shell_详解php文件包含原理(读取文件源码、图片马、各种协议、远程getshell等) ......

    详解php文件包含原理(读取文件源码.图片马.各种协议.远程getshell等) 作者是namezz (看完图相当于做了一轮实验系列) 现有文件代码如下 include和include_once.re ...

  5. android悬浮窗、收款二维码、相机处理、事件通知库、NFC读取等源码

    Android精选源码 一个漂亮而强大的自定义view SeekBar 适用于Android的简单NFC读取源码 安卓任意界面悬浮窗实现源码 android实现收款二维码保存代码 RxBus 一个简易 ...

  6. Android10.0 日志系统分析(三)-logd、logcat读写日志源码分析-[Android取经之路]

    摘要:本节主要来讲解Android10.0 logd.logcat读写日志源码内容 阅读本文大约需要花费20分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Andro ...

  7. japidocs怎么设置参数必填_JApiDocs 动态生成接口文档,并解析java 源码中的注释...

    1.介绍 JApiDocs 是一个符合 Java 编程习惯的 Api 文档生成工具.最大程度地利用 Java 的语法特性,你只管用心设计好接口,添加必要的注释,JApiDocs 会帮你导出一份漂亮的 ...

  8. flink的dataset/stream/sql三套API的选择以及是否应该阅读源码

    我常常在钉钉群群里面请教,群里也有阿里P7/P8的专家. 但是每当我请教dataset/datastream相关问题的时候,即使是专家也没有响应. 钉钉群里面P7的是云邪,擅长使用的也是flink s ...

  9. Android四级缓存,RecyclerView 源码四级缓存原理

    入口 我们从使用功能上去读取源码,通常的用法是这个样子 -> 我们设置layoutmanager,GridLayouManager 继承LinearLayoutManager,所以我们就Line ...

最新文章

  1. stylelint初体验
  2. CentOS7重新生成 /boot/grub2/grub.cfg
  3. SpringBoot 项目war包部署 配置外置tomcat方法
  4. Kotlin实战指南六:可空类型、非可空类型
  5. jquery代码小片段
  6. m1芯片Mac安装Apple版TensorFlow(conda-forge)+编译安装sklearn
  7. EOS cleos --skip-transaction-signatures 跳过签名
  8. Socket I/O模型全接触
  9. aix Oracle 限制访问,改变AIX上使用oracle的一些限制
  10. 操作系统编写之代码解释
  11. 常用设计模式Python实现
  12. 流程图绘制和符号含义
  13. 解决fortify扫描出的Path Manipulation问题(java语言)
  14. 办公小技巧:excel纸张大小设置
  15. 基于stm32的两轮自平衡小车4(软件调试篇)
  16. “秒杀系统“设计原理
  17. 为CentOS 6、7升级gcc至4.8、4.9、5.2、6.3、7.3等高版本
  18. python 踩坑之解决django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.Did you insta
  19. 在VC 6.0里Win32 Application和Win32 console Application的区别
  20. 真正超简单解决App启动时白屏问题

热门文章

  1. 前端 - 面试题总汇
  2. 索尼电视linux系统版本,索尼X9500H智能液晶4K电视加入最新安卓9.0操作系统
  3. macbook上好用的解压软件_苹果电脑有什么好用的解压软件?推荐 Mac OSX 下最方便实用的六款解压缩软件...
  4. 3dmark压力测试 linux,3DMark新增压力测试 你的电脑可靠?得先过这关
  5. 快速把照片做成MV,用什么软件好?抖音火爆效果制作
  6. 添加 “Microsoft Word 97 - 2003 文档” 右键功能菜单
  7. 腾讯2020年第三季度财报在哪看
  8. 关于电商秒杀系统中防超卖处理方案简述,统统给你解决!
  9. 百度和谷歌对骂对方是SB!!!!
  10. 网站域名注册信息怎么查询?