找回密码
 register

QQ登录

只需一步,快速开始

查看: 391|回复: 0

[游戏教程] 天龙八部GridInfo读取源码

[复制链接]

[游戏教程] 天龙八部GridInfo读取源码

[复制链接]
  • 打卡等级:热心大叔
  • 打卡总天数:95
  • 打卡月天数:18
  • 打卡总奖励:95
  • 最近打卡:2025-01-20 23:11:04
Waylee

主题

0

回帖

1万

积分

仙帝

积分
12398
Waylee 2024-2-4 02:16 | 显示全部楼层 |阅读模式

马上注册,查看网站隐藏内容!!

您需要 登录 才可以下载或查看,没有账号?register

×
天龙八部GridInfo文件的格式已经有人公布了
不过,此文中有点笔误的地方,就是那个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:pen(const String &fileName , const String &groupName)
    {
        DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource(fileName , groupName);
        if(stream.isNull()) 
        { 
            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
                "打开地形网格文件失败:" + fileName, 
                "GridInfos:pen");
            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 << 16) | (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:fstream 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();
    }
 
 
};



您需要登录后才可以回帖 登录 | register

本版积分规则

雪舞知识库 | 浙ICP备15015590号-1 | 萌ICP备20232229号|浙公网安备33048102000118号 |天天打卡

GMT+8, 2025-1-21 01:58 , Processed in 0.100295 second(s), 7 queries , Redis On.

Powered by XueWu Licensed

Copyright © Tencent Cloud.

快速回复 返回顶部 返回列表