我要发帖 回复

管理员

735

主题

2万

积分

30

专家分

忠于职守杰出贡献鼓励

兴趣点(最多三项):

建模技术

私信
发表时间 : 2009-8-17 13:21:52 | 浏览 : 2372    评论 : 0
作者:mybios

天龙八部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;
            
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
= ((ulong)m_data.nFirstLayer <<
16l) | (ulong)m_data.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;
            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();
    }



}
;

最近VR访客

手机版|VR开发网 ( 津ICP备18009691号 ) 统计 网安备12019202000257

GMT+8, 2020-9-23 02:46 PM

返回顶部