李锦俊(mybios)的blog

游戏开发 C++ Cocos2d-x OpenGL DirectX 数学 计算机图形学 SQL Server

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  86 Posts :: 0 Stories :: 370 Comments :: 0 Trackbacks

公告

QQ:30743734
EMain:mybios@qq.com

常用链接

留言簿(16)

我参与的团队

最新随笔

搜索

  •  

积分与排名

  • 积分 - 361885
  • 排名 - 66

最新评论

阅读排行榜

评论排行榜

天龙八部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();
    }



}
;

如果本文对你的开发有所帮助,并且你手头恰好有零钱。

不如打赏我一杯咖啡,鼓励我继续分享优秀的文章。




posted on 2009-07-26 20:36 李锦俊(mybios) 阅读(5103) 评论(5)  编辑 收藏 引用 所属分类: 3D引擎开发

Feedback

# re: 发布一个前段时间写的天龙八部GridInfo读取源码 2009-07-27 00:57 lyo
哈哈,终于有更正贴出现了
我也是测试了半天才解决。。。
http://lyodev.appspot.com/2009/07/analysis-of-the-amendment-gridinfo-dragon  回复  更多评论
  

# re: 发布一个前段时间写的天龙八部GridInfo读取源码 2009-07-27 08:04 李锦俊
@lyo
呵呵,同学所见略同啊  回复  更多评论
  

# re: 发布一个前段时间写的天龙八部GridInfo读取源码 2009-08-06 11:55 开源人
不知道你为什么要把每个地块的pixmapid都减1。info.nFirstLayer--;
希望你把地形那块也开源啊。。我们可以学下。。中国程序员太保守。  回复  更多评论
  

# re: 发布一个前段时间写的天龙八部GridInfo读取源码 2009-08-07 13:52 heha
SecondLayer=-1 SecondLayerOp=255
SecondLayer=-1 SecondLayerOp=255
SecondLayer=-1 SecondLayerOp=255
请问下,-1,255这些参数怎么理解。  回复  更多评论
  

# re: 发布一个前段时间写的天龙八部GridInfo读取源码 2009-08-10 20:49 mybios
@heha
SecondLayer=-1说明这层不使用,那后面的SecondLayerOp=255就更没意义了。

@开源人
这里减一是因为天龙里的这个id是从1开始的,0就代表这层不使用。
而c程序的数组索引是从0开始的,所以在载入时一次性减一,以便在使用的时候不需要再减一,而判断这层是否使用就改成用-1来判断,而不是原来的0。  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理