当前位置: 首页 > news >正文

WOW小地图生成

参考wowmapview写了一个小地图查看的控件, 可以载入*.wdl文件解析出一张类似于"卫星图"的东西

WDL文件保存的是WOW地图的低精度高度数据, 冒似用来做远处的LOD的

每个地图最大是64*64个tile, 而一个tile它保存了17*17 + 16*16个16位的高度数据.

如果生成一张512*512大小的小地图的话, 每个tile就只有8*8个像素

因此, 我们只取17*17中的偶数点

下面这张是Kalimdor的生成效果

#pragma once using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; using namespace System::Drawing::Imaging; using namespace System::IO; namespace WOWMinimap { typedef unsigned int uint; typedef unsigned char byte; /// <summary> /// Summary for MiniMap /// </summary> public ref class MiniMap : public System::Windows::Forms::UserControl { public: static const int MINIMAP_SIZE = 512; static const int MAX_WIDTH_IN_TILE = 64; static const int MAX_TILE_NUM = MAX_WIDTH_IN_TILE * MAX_WIDTH_IN_TILE; static const int TILE_WIDTH_IN_PIXEL = 8; static const int TILE_WIDTH_IN_VERTEX = 17; static const int TILE_VERTEX_NUM = TILE_WIDTH_IN_VERTEX * TILE_WIDTH_IN_VERTEX; public: MiniMap(void) { InitializeComponent(); // //TODO: Add the constructor code here // this->bitmap = gcnew Bitmap(MINIMAP_SIZE, MINIMAP_SIZE, PixelFormat::Format32bppArgb); } void LoadMapHeight(String^ filename) { FileStream^ fs = gcnew FileStream(filename, FileMode::Open); BinaryReader^ br = gcnew BinaryReader(fs); // abort the version chunk fs->Seek(0x10, SeekOrigin::Begin); // load tile's file offsets array<uint>^ offsets = gcnew array<uint>(MAX_WIDTH_IN_TILE*MAX_WIDTH_IN_TILE); for (int i = 0; i < MAX_TILE_NUM; i++) { offsets[i] = br->ReadUInt32(); } // load tile height for (int i = 0; i < MAX_TILE_NUM; i++) { Console::WriteLine("{0}%", 100.0f * i / float(MAX_TILE_NUM-1)); if (0 == offsets[i]) { // tile is not used continue; } LoadTileHeight(i, offsets[i], fs); } // repaint this->Invalidate(); fs->Close(); } private: void LoadTileHeight(uint index, uint offset, FileStream^ fs) { fs->Seek(offset + 8, SeekOrigin::Begin); BinaryReader^ br = gcnew BinaryReader(fs); // read heights array<short>^ heights = gcnew array<short>(TILE_VERTEX_NUM); for (int i = 0; i < TILE_VERTEX_NUM; i++) { heights[i] = br->ReadUInt16(); } int left = index % MAX_WIDTH_IN_TILE * TILE_WIDTH_IN_PIXEL; int top = index / MAX_WIDTH_IN_TILE * TILE_WIDTH_IN_PIXEL; Rectangle rect(left, top, TILE_WIDTH_IN_PIXEL, TILE_WIDTH_IN_PIXEL); BitmapData^ bmpData = this->bitmap->LockBits(rect, ImageLockMode::WriteOnly, this->bitmap->PixelFormat); int* color = (int*)bmpData->Scan0.ToPointer(); // convert to color for (int z = 0; z < TILE_WIDTH_IN_PIXEL; z++) { for (int x = 0; x < TILE_WIDTH_IN_PIXEL; x++) { short height = heights[(z * 2) * TILE_WIDTH_IN_VERTEX + x * 2]; color[x] = HeightToColor(height).ToArgb(); } color += MINIMAP_SIZE; } this->bitmap->UnlockBits(bmpData); } Color HeightToColor(short height) { byte r1,r2,g1,g2,b1,b2; float t; byte r, g, b; if (height < 0) { // water = blue if (height < -511) height = -511; height /= -2; r = g = 0; b = 255 - height; } else { // green: 20,149,7 0-600 // brown: 137, 84, 21 600-1200 // gray: 96, 96, 96 1200-1600 // white: 255, 255, 255 if (height < 600) { r1 = 20; r2 = 137; g1 = 149; g2 = 84; b1 = 7; b2 = 21; t = height / 600.0f; } else if (height < 1200) { r2 = 96; r1 = 137; g2 = 96; g1 = 84; b2 = 96; b1 = 21; t = (height-600) / 600.0f; } else /*if (height < 1600)*/ { r1 = 96; r2 = 255; g1 = 96; g2 = 255; b1 = 96; b2 = 255; if (height >= 1600) height = 1599; t = (height-1200) / 600.0f; } r = (byte)(r2*t + r1*(1.0f-t)); g = (byte)(g2*t + g1*(1.0f-t)); b = (byte)(b2*t + b1*(1.0f-t)); } return Color::FromArgb(r, g, b); } protected: /// <summary> /// Clean up any resources being used. /// </summary> ~MiniMap() { if (components) { delete components; } } virtual void OnPaint(PaintEventArgs^ e) override { e->Graphics->DrawImage(this->bitmap, 0, 0, this->Width, this->Height); } private: /// <summary> /// Required designer variable. /// </summary> System::ComponentModel::Container ^components; Bitmap^ bitmap; #pragma region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> void InitializeComponent(void) { this->SuspendLayout(); // // MiniMap // this->Name = L"MiniMap"; this->SizeChanged += gcnew System::EventHandler(this, &MiniMap::MiniMap_SizeChanged); this->ResumeLayout(false); } #pragma endregion private: System::Void MiniMap_SizeChanged(System::Object^ sender, System::EventArgs^ e) { this->Invalidate(); } }; }

相关文章:

  • 水平滚动_精密滚动直线导轨副行业周期特征及前景分析(附报告目录)
  • 当年明月 Vs. 阎崇年
  • 文件设置索引_elasticsearch 索引存储深入详解(Elasticsearch教程03)|MVP讲堂
  • SQL 2005的SSIS与Oracle的迁移性能
  • 字体 用_做海报设计,不知道用什么字体?
  • 你的简历合适且有意义吗?
  • 数据库 自带_Kepware实现向数据库实时写入数据
  • 国际商务英语学习[十八]
  • opencv矩阵转eigen_numpy opencv matlab eigen SVD结果对比
  • 及cp含义_电气设计图纸中AL、AW、HAL等各种符号分别代表什么含义?
  • 对当前虚拟货币问题的思考(下)
  • 光照系统可以工作了。
  • 组播vlan_单播地址、组播地址、广播地址的优缺点
  • 打印表单_重磅更新 | 表单提交校验逻辑、轮播图纷纷上线
  • 期待能好好好好好好的睡一觉。
  • php的引用
  • 【译】JS基础算法脚本:字符串结尾
  • [iOS]Core Data浅析一 -- 启用Core Data
  • 【Linux系统编程】快速查找errno错误码信息
  • 【从零开始安装kubernetes-1.7.3】2.flannel、docker以及Harbor的配置以及作用
  • Android 初级面试者拾遗(前台界面篇)之 Activity 和 Fragment
  • Android 控件背景颜色处理
  • AWS实战 - 利用IAM对S3做访问控制
  • canvas实际项目操作,包含:线条,圆形,扇形,图片绘制,图片圆角遮罩,矩形,弧形文字...
  • echarts的各种常用效果展示
  • js递归,无限分级树形折叠菜单
  • Python_OOP
  • Spring声明式事务管理之一:五大属性分析
  • 笨办法学C 练习34:动态数组
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 对JS继承的一点思考
  • 关于Java中分层中遇到的一些问题
  • 利用DataURL技术在网页上显示图片
  • 聊聊redis的数据结构的应用
  • 前端 CSS : 5# 纯 CSS 实现24小时超市
  • 入手阿里云新服务器的部署NODE
  • 一道面试题引发的“血案”
  • 一些css基础学习笔记
  • C# - 为值类型重定义相等性
  • ​软考-高级-系统架构设计师教程(清华第2版)【第15章 面向服务架构设计理论与实践(P527~554)-思维导图】​
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • #HarmonyOS:基础语法
  • (23)Linux的软硬连接
  • (70min)字节暑假实习二面(已挂)
  • (AngularJS)Angular 控制器之间通信初探
  • (bean配置类的注解开发)学习Spring的第十三天
  • (二)windows配置JDK环境
  • (二)构建dubbo分布式平台-平台功能导图
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (十二)python网络爬虫(理论+实战)——实战:使用BeautfulSoup解析baidu热搜新闻数据
  • (一)C语言之入门:使用Visual Studio Community 2022运行hello world
  • (转)重识new
  • .Net6使用WebSocket与前端进行通信