Direct-X学习笔记--地形

Direct3D地形绘制基础 思路是:地形中海拔较低的部分上色为沙滩色,中等海拔的部分上色为绿色的丘陵颜色,高海拔的部分上色为雪山的颜色。RAW文件本质上是一个连续的字节存储块,其中将字节型向量复制到一个整型向量中,我们就可对高度值进行比例变换从而突破0~255的限制,该方法的唯一限制是。我们对该类的构造函数还传入了与地形相关的设备指针、一个标识了存储高度图数据的文件的字符串,以及一个用于对高度图中各元素实施比例变换的。,所以,如果您要从一个256×256的RAW文件中读取数据,相应地您只能创建一个至多有256×256个顶点的地形。 阅读详情

地形系统,在游戏中肯定少不了滴。终于要开始学习这个东东啦!地形看起来非常神奇,绵延的山峦,横看成岭侧成峰,远近高低各不同,这么复杂的地形到底我们到底要怎么写呢?说实话不学这个之前我真的完全想不到地形的实现方法。


一.简介

三维地形系统在很多地方都有应用,不论是游戏还是模拟系统中,地形都是必不可少的元素之一。说到地图,我们最容易想到的就是一个二维数组,根据数组元素的不同,绘制出不同的图形,这也是二维游戏常用的方法,例如《炸弹超人》《QQ堂》等游戏的地图就是一个二维数组。那三维地图要怎么生成呢,其实三维地图也是用一个二维数组,数组的下标代表x,z坐标,即平面的坐标,而数组元素的值则为地形的高度。
上面这张图我们可以看出,底面是由若干正方形的网格构成的,而正方形网格又是由两个三角形构成的,这就回到了我们最早练习的顶点及索引缓冲区绘图的情况。

二.高度图

既然我们要制作三维地形,肯定不是希望地形一马平川的,而是希望高低不平的地形,来达到更好的效果。那么要怎么设定这个地形的高度呢?手动赋值?肯定不可能...rand()%高度,不能定制高度...于是伟大的先人们就发明了高度图这个神器。

说到高度图,或者说图片,都是由像素构成的,我们所说的1024*768也是说的像素。而最简单的图片,也是我们最容易想到的就是用一个字节表示一个像素,一共可以表示2^8= 256种颜色。 我们最常使用的就是灰度图,每个点可以用0-255共256种高度值,但是我们可以不仅仅表示0-255,我们可以使用一个缩放系数,乘以高度值,统一缩放整体高度,来达到表示更高或者更矮的高度的目的。


这是一张高度图,越亮的地方表示高度越高,越暗的地方高度越低。我们可以用photoshop来制作高度图,其实把蓝天白云图变成黑白颜色的就是一幅很好的高度图。高度图的后缀名为raw格式,我们存储的时候选择这个格式就好。


三.封装一个地形类

我们通过C++封装一个地形相关的类,这样我们每次创建地形的时候,就只要通过几个参数和一张高度图以及纹理图片就可以创建一个逼真的三维地形啦。

这个类中主要涉及到以下几个方面:
1)读取高度图
2)创建地形顶点设置纹理
3)绘制地形

简单说一下思路:
1)raw文件比较纯粹,里面几乎没有什么冗余,都是我们需要的地形的高度信息,我们只需要将其全部读取即可。此外,我们还需要一张纹理贴图,用于地形的纹理映射。
2)我们可以通过参数设置地形的大小,但是前提是高度图大小要足够,所以我们设置的大小最好跟高度图的大小一致。当然,这里的大小指的是m*n,具体每个格子的宽度我们可以再设置一个参数来控制,最后,我们还可以通过一个参数设置高度的缩放比例。
3)建立地形的退到比较麻烦,我们要根据地形图的大小创建若干顶点,然后根据顶点高度设置索引,使地形突起。还要将纹理一并设置。
4)绘制就比较简单啦,和之前的索引绘图一样,设置数据流,设置灵活顶点格式,设置索引,设置渲染状态,绘制。


下面是该类的具体实现:
头文件:
/************************************************************************/
/*封装三维地形的类                                                                     */
/************************************************************************/
#ifndef __TERRAIN_H_
#define __TERRAIN_H_
#include <vector>
#include <string>
#pragma once
struct TERRAINVERTEX//地形的顶点格式
{
	float _x, _y, _z;
	float _u, _v;
	TERRAINVERTEX(float x, float y, float z, float u, float v) : _x(x), _y(y),_z(z),_u(u),_v(v){}
	static const DWORD FVF = D3DFVF_XYZ | D3DFVF_TEX1;
};

class CTerrain
{
private:
	LPDIRECT3DDEVICE9	m_pDevice;		//设备指针
	LPDIRECT3DTEXTURE9  m_pTexture;			//纹理坐标
	LPDIRECT3DINDEXBUFFER9 m_pIndexBuffer;		//索引缓存
	LPDIRECT3DVERTEXBUFFER9 m_pVertexBuffer;	//顶点缓存

	std::vector<float> m_vHeightInfo;		//存放高度信息
			
	int m_nCellsPerRow;				//每行的单元数				
	int m_nCellsPerCol;				//每列的单元数
	int m_nVertsPerRow;				//每行的顶点数
	int m_nVertesPerCol;				//每列的顶点数
	int m_nNumVertices;				//总共顶点数
	float m_fTerrainWidth;				//地形的宽度
	float m_fTerrainDepth;				//地形的深度
	float m_fCellSpacing;				//单元格的间距
	float m_fHeightScale;				//高度缩放系数

public:
	CTerrain(IDirect3DDevice9 *pDv);
	virtual ~CTerrain(void);

	//从文件中加载高度图以及纹理
	bool LoadTerrainFromFile(std::string RawFilename, std::string TextureFilename);
	//地形初始化函数(行数,列数,间距,高度比例)
	bool InitTerrain(int nRows, int nCols, float fSpace, float fScale);
	//绘制地形函数
	bool RenderTerrain(D3DXMATRIX* pMatWorld, bool bDrawFrame = false);
};
#endif


.cpp文件:
#include "stdafx.h"
#include "Terrain.h"
#include <fstream>


CTerrain::CTerrain(IDirect3DDevice9 *pDv)
{
	//各种初始化
	m_pDevice = pDv;
	m_pTexture = NULL;
	m_pIndexBuffer = NULL;
	m_pVertexBuffer = NULL;
	m_nCellsPerRow = 0;
	m_nCellsPerCol = 0;
	m_nVertsPerRow = 0;
	m_nVertesPerCol = 0;
	m_nNumVertices = 0;
	m_fTerrainWidth = 0.0f;
	m_fTerrainDepth = 0.0f;
	m_fCellSpacing = 0.0f;
	m_fHeightScale = 0.0f;
}

CTerrain::~CTerrain(void)
{
}


bool CTerrain::LoadTerrainFromFile(std::string RawFilename, std::string TextureFilename)
{
	//打开文件
	using namespace std;
	ifstream inFile;
	inFile.open(Raw
Direct-X学习笔记--深度缓存 今天来学习一下深度测试,不过这个东东貌似暂时就是了解一下原理啦,因为DX默认是打开深度测试的,即我们不需要额外进行设置就可以使用深度测试的功能,不过这个还是有必要了解一下,一是对DX的流程更加了解,二是我们可以手动设置深度测试的参数以及函数,达到一些自己想要实现的效果。 一.简介 三维的世界中,有各种物体,而这些物体难免会有遮挡,而且同一个物体不同部分也会有遮挡的关系,要想表现出来更加 阅读详情

相关推荐

Direct-X学习笔记--天空盒

学习了三维的地形系统之后,该抬头看看天空啦。下面学习一下传说中的三维天空系统。其实三维天空的实现比地形系统简单得多,我们只需要用一点点小伎俩,就可以蒙混大多数人。 一.简介 我们在玩游戏的时候,尤其是野外的大场景中,要想更逼真离不开三维天空系统。要用程序来模拟无边无际的天空是不可能的,而聪明的前辈们自然也想到了用“天圆地方”这种古代人们对于天空的认识来作为三维天空设计思想。即用一个足够

puppet_master的专栏 3831

DirectX学习笔记(十四):三维地形系统的实现

本系列文章由zhmxy555(毛星云)编写,转载请注明出处。   文章链接: http://blog.youkuaiyun.com/zhmxy555/article/details/8685546 作者:毛星云(浅墨)    邮箱: happylifemxy@163.com      上个星期浅墨写的介绍三维摄像机的文章和示例程序放出以后,大家似乎都表现出了很高涨的热情,

lishuzhai的专栏 5525

IsaacLab地形生成实战:从基础构造到自定义地形开发

本文深入探讨了IsaacLab中地形生成的核心技术与实战开发。从理解高度场与三角网格两种基础表示原理出发,详细解析了构建凸起平台、阶梯、斜坡等基础地形的代码实现,并系统阐述了从配置、生成到渲染的完整工作流程。重点分享了创建自定义地形(如波浪地形)的完整步骤与高级技巧,旨在帮助开发者高效构建多样化仿真环境,以提升机器人强化学习与运动控制算法的训练效率与泛化能力。

dapp9builder的博客 478

DirectX游戏设计之创建三维地形讲解

DirectX游戏设计之创建三维地形讲解

基于高度图地形生成器

提供一个基于高度图的地形生成软件,可以直观的展示地图生成的效果,可以实现多纹理混合。

vs2010中c#调用directx 9.0 direct3d画二维图形的方法

vs2010中c#调用directx 9.0 direct3d画二维图形的方法,文档中包括详细的配置,以及初始化等操作。需要自己下载directx 9.0的sdk并安装。 在c#工程中,我添加了两个panel,按下对应的button会画出两个对称的三角形

uniapp开发AndroidAPP集成支付宝支付及问题处理(商家订单参数异常等),集成微信小程序支付及问题处理(运行真机调试白屏)

2、选择支付宝支付,调用支付接口唤起支付宝支付。

qq_16785561的博客 3486

unity打包流程整理-Windows/Mac/Linux平台

1.Platform(平台)功能: 选择目标构建的目标平台选项PC, Mac & Linux Standalone: 适用于 Windows、Mac 和 Linux 平台2.Target Platform(目标平台)功能: 选择具体的操作系统版本选项Windows: 针对 Windows 操作系统Mac: 针对 macOS 操作系统Linux: 针对 Linux 操作系统3.Architecture(架构)功能: 选择应用程序的目标处理器架构选项x86: 针对 32 位系统。

weixin_42333247的博客 5135

暗黑破坏神2重制版 mod制作教程(一)

暗黑2重制版mod修改教程

hhhh2312的博客 7449

光伏系统选型指南:5种主流MPPT算法优缺点对比(附选型流程图)

本文深入剖析了光伏系统中五种主流MPPT算法的核心原理与性能差异。通过对比扰动观察法、电导增量法、恒定电压法、模糊逻辑控制及人工智能算法在追踪精度、响应速度、实现成本与稳定性等方面的表现,为不同应用场景(如户用、工商业及大型电站)提供了清晰的选型决策流程图和实战指南,帮助工程师优化系统效率与投资回报。

weixin_29294597的博客 106

arcgis导出自身相交数据

今天接到一个客户需求,一份面文件,里面有好多元素是两两相交甚至是三个相交的,现在要把这些重叠部分提取出来,并且把相交部分的原始要素的名称也保留在字段中,也就是说名称这个会有好多个名称字段,如果两个要素相交那就是前两个名称字段有值,后面的为空,如果是三个要素相交,那么输出的这个要素就是前三个名称字段有值,后面的为空,嗯,这里也不太确定会出现多少个名称字段,这个需要依照数据来定。 这是原始数据,...

miaowumi92的博客 6787

21天学会基于 Linux 的 NPU 固件开发--12.3 如何参与 Linux 内核 NPU 子系统开发

从修复一个简单的文档拼写错误开始,或者为现有的开源 NPU 驱动(如 Sophgo, StarFive, Etinix 等厂商已上游化的驱动)添加一个缺失的 IOCTL 支持或优化一个算子,都是伟大的第一步。在 2026 年的 Linux Kernel (v6.12+) 中,NPU 驱动不再是孤立的字符设备,而是深度集成在 DRM 和 DMA-BUF 生态中,实现了与 GPU 类似的资源管理和调度能力。内核驱动必须提供清晰的 UAPI (User API),通常定义在。Step 4: 合并 (Merge)

amy_mhd的博客 66

智能车图像处理11-进阶篇3--中线累积差值的统计

中线累积差值的统计在后面判断小S,以及长直道的时候都有用到,关键点在于中线的跳变 第12 - 13 行:comulants1 和comlants2代表的是两种不同的累差,取的行数不同 第14-17 行:comulants2取6到25行,其实就是My_Abs(LCenter[i], LCenter[i - 1])的累加 第18-21 行:comulants1去第1到40行 第27- 行: 计算了一下右线的开始于最终结束行,这里判断R_black是否为0,是和中线的提取中g

taiyuezyh的博客 3824

2026滑块验证码终极实战:缺口检测算法+人机轨迹模拟,识别率从60%飙升至95%全方案

**摘要:2026年AIGC技术发展导致传统验证码失效,滑块验证码成为主流防护手段。本文深入分析了传统方案识别率低的原因,并提出多级检测融合和行为拟合优化方案。通过图像预处理优化、三级缺口检测引擎(差分图像法、Hu矩轮廓匹配、YOLOv8n模型兜底)将识别率提升至99.2%。同时针对轨迹模拟环节,设计了包含抖动特征、时间随机性和个体差异的行为模型,使通过率从12%提升至87%。该方案解决了传统方法在缺口定位精度和轨迹真实性方面的核心痛点,为应对新一代验证码风控提供了完整的技术框架。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1898

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

上一篇: Direct-X学习笔记--封装一个网格模型类
下一篇: Direct-X学习笔记--天空盒
puppet_master
puppet_master 领域专家: C/C++技术领域 领域专家: C/C++技术领域
博客等级 码龄12年 2695粉丝 161原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值