Ogre1.7.2 terrain地形构建例子

Ogre 1.7中的地形教程 地形创建的工作步骤:1.创建地形全局配置2.创建地形分组3.创建默认的地形分块属性4.创建地形分块第一步首先,在Ogre1.7中,地形是由一块一块的地形组成的,他们每快地形都有共同的属性,所以在创建地形之前我们必须指定地形块的全局配置。代码:  mTerrainGlobals = new Ogre::TerrainGlobalOptions(); mTerrainGlobals->setMaxPixelError(8); mTerrainGlobals->setCompositeM 阅读详情

Ogre 1.7.2中的地形教程


    ○读者可以对照着Ogre1.7.2中的terrain.h源码进行阅读加深理解,蓝色部分均为源码

○去除了一些具体场景比如添加mesh,设置setAmbientLight等与terrain无关的操作

 

第一步 创建地形全局配置 TerrainGlobalOptions

下面这段代码在setupContent()函数中,使用过Ogre1.6.5的一定对createScene()函数非常熟悉。这里setupContent()相当于createScene()函数。

首先,在Ogre1.7中,地形是由一块一块的地形组成的,他们每快地形都有共同的属性,所以在创建地形之前我们必须指定地形块的全局配置。

mTerrainGlobals = OGRE_NEW TerrainGlobalOptions();

TerrainGlobalOptions是一个类,定义了地形块的一些全局变量和默认值,需要的话我们可以改变他的变量参数,我们后面再做改变。


   第二步  创建地形分组Ogre::TerrainGroup

我们将要创建地形分组对象,该对象用于创建以及管理地形块。

代码:
  mTerrainGroup = OGRE_NEW TerrainGroup(mSceneMgr, Terrain::ALIGN_X_Z, TERRAIN_SIZE, TERRAIN_WORLD_SIZE);
  mTerrainGroup->setFilenameConvention(TERRAIN_FILE_PREFIX, TERRAIN_FILE_SUFFIX);
  mTerrainGroup->setOrigin(mTerrainPos);

这段代码比较简单

首先使用OGRE_NEW (其实也就是new)实例化一个TerrainGroup对象

参数1:为他指定场管理器、

参数2:地形的平铺方向,平铺方向一般采用ALIGN_X_Z,也就是采用Y作为高度

参数3:unit16 TERRAINSIZE=2~n+1,比如512+1=513,不符合公式的可能会导致地图显示异常,表示“The

size of each terrain down one edge in vertices (2^n+1)”楼主只能理解意思,不能完全正确

表达其中的专有名词,实际调试中,这个参数影响地图边缘的锯齿度,越小锯齿越明显,取值太小

的话,运行会错误;

参数4:Real TERRAINWORLDSIZE,地图大小,表示地图正方形的边长)

然后第二句设置了该地形组的起始位置,在以后创建的地形块中均采用此位置作为相对位置


   第三步  配置地图块参数 configureTerrainDefaults

执行configTerrainDefaults(l);

传递了一个参数light,函数定义为:
void configureTerrainDefaults(Light* l)

{
    mTerrainGlobals->setMaxPixelError(8);
    mTerrainGlobals->setCompositeMapDistance(3000);//距离镜头超过3000部分使用地图合成(CompositeMap)模式表现
    mTerrainGlobals->setLightMapDirection(l->getDerivedDirection());//地图光照方向(和实时阴影生成相关)
    mTerrainGlobals->setCompositeMapAmbient(mSceneMgr->getAmbientLight());
    mTerrainGlobals->setCompositeMapDiffuse(l->getDiffuseColour());


  Terrain::ImportData& defaultimp = mTerrainGroup->getDefaultImportSettings();
  defaultimp.terrainSize = TERRAIN_SIZE;//不太了解,调试中,这个值越小,地图边缘锯齿现象越严重,太小的话,运行起来程序会跑死、出错
  defaultimp.worldSize = TERRAIN_WORLD_SIZE;//假设为a,那么地图大小为 a x a
  defaultimp.inputScale = 600;//决定地图最大落差(高度),即位图中白色和黑色部分的高度差
  defaultimp.minBatchSize = 33;
  defaultimp.maxBatchSize = 65;


  defaultimp.layerList.resize(3);//这里设置了3层纹理,DDS为一种高级的纹理模式,DirectDrawSurface,觉得难以理解的话

//可以理解为一种特殊的.jpg图片模式,但是用DDS质材的话可以接收并显示地形阴影,用JPG就显示不出来,而且据我调试观

//察发现,第一个.dds质材是用来显示纹理图形,第二个.dds才是用来接收和显示阴影的
  defaultimp.layerList[0].worldSize = 100;//这个值关系到此贴图的细致程度,太大的话图片被拉伸得很大,看起来模糊
  defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_diffusespecular.dds");
  defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_normalheight.dds");
  defaultimp.layerList[1].worldSize = 30;
  defaultimp.layerList[1].textureNames.push_back("grass_green-01_diffusespecular.dds");
  defaultimp.layerList[1].textureNames.push_back("grass_green-01_normalheight.dds");
  defaultimp.layerList[2].worldSize = 200;
  defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_diffusespecular.dds");
  defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_normalheight.dds");

 }

 


   第四步  创建地形分块

【平坦地形】

以上三步工作做好了之后,我们就可以很方便的创建地形块了,如果想创建平坦的地形(例子中是山地地形,这里只是延伸说明,源码没有下面这4行代码)

for (long x = TERRAIN_PAGE_MIN_X; x <= TERRAIN_PAGE_MAX_X; ++x)
      for (long y = TERRAIN_PAGE_MIN_Y; y <= TERRAIN_PAGE_MAX_Y; ++y)

     mTerrainGroup->defineTerrain(x, y,0.0f);

    mTerrainGroup->loadAllTerrains(true);

你将会在你的场景中看到一块地形了,defineTerrain方法首先要指定该块地形在地形分组中的索引位置,然后第三个参数必须指定高度数据,这里我设置为0.0f,那么将是出现一个平面地形。

【用灰度图创建山地地形】

若是想读取位图来创建地形,而不是平坦的地面,需要进行如下操作

  for (long x = TERRAIN_PAGE_MIN_X; x <= TERRAIN_PAGE_MAX_X; ++x)
       for (long y = TERRAIN_PAGE_MIN_Y; y <= TERRAIN_PAGE_MAX_Y; ++y)
         defineTerrain(x, y, blankTerrain);
         mTerrainGroup->loadAllTerrains(true);

     

defineTerrain(x, y, blankTerrain)定义为:

void defineTerrain(long x, long y, bool flat = false)

{
if (flat) //表示平坦地图,高度为0
 {
   mTerrainGroup->defineTerrain(x, y, 0.0f);
 }
else
 {
   String filename = mTerrainGroup->generateFilename(x, y);

//如果有存档的,或者说以前运行过这个例子,直接加载.dat文件
   if (ResourceGroupManager::getSingleton().resourceExists(mTerrainGroup->getResourceGroup(),
filename))
   {
    mTerrainGroup->defineTerrain(x, y);
    }

//否则读取位图,创建加载地形
  else
   {
     Image img;
     getTerrainImage(x % 2 != 0, y % 2 != 0, img);//从PNG格式的灰度图图片读取灰度值,作为高度的换算基值
     mTerrainGroup->defineTerrain(x, y, &img); //调用重载函数defineTerrain创建地形
     mTerrainsImported = true; //作为下文地形纹理渲染标志,失败则表示没有创建好地形
   }

}

 

getTerrainImage()定义为:

void getTerrainImage(bool flipX, bool flipY, Image& img)
{
 img.load("terrain.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
 if (flipX)
  img.flipAroundY(); //这些函数封装在.dll里了,没能看个究竟~
 if (flipY)
  img.flipAroundX(); //这些函数封装在.dll里了,没能看个究竟~

}


纹理混合


Ogre1.7的地形纹理默认支持8层纹理混合,如果想更改,可通过地形的全局配置设置,混合越多越慢。刚才我们定义了三层纹理。默认情况下,引擎只显示第一层纹理纹理,所以我们得为每一层指定混合系数,0表示不显示,1表示显示,0~1表示混合混合显示。混合包括两大步骤:

void Sample_bumper::initBlendMaps(Terrain* terrain)
{
  TerrainLayerBlendMap* blendMap0 = terrain->getLayerBlendMap(1); //取得第2层纹理(绿色地皮grass_green)
  TerrainLayerBlendMap* blendMap1 = terrain->getLayerBlendMap(2); //取得第3层纹理(长了植物growth_weirdfungus)
  Real minHeight0 = 70;
  Real fadeDist0 = 40;
  Real minHeight1 = 70;
  Real fadeDist1 = 15;
  float* pBlend1 = blendMap1->getBlendPointer(); //取得纹理地图起始位置
  for (Ogre::uint16 y = 0; y < terrain->getLayerBlendMapSize(); ++y)
  {
   for (Ogre::uint16 x = 0; x < terrain->getLayerBlendMapSize(); ++x)
   {
    Real tx, ty;

    blendMap0->convertImageToTerrainSpace(x, y, &tx, &ty);//将纹理坐标转换为地形坐标(类似蒙皮)
    Real height = terrain->getHeightAtTerrainPosition(tx, ty);//取得在(x,y)点坐标的高度(2D坐标系的xy)

//在不同的高度使用不同的纹理,

//当高度<70,Val=0不显示纹理1,高度>110,val=1,只显示纹理2 ,70~110之间混合显示(这里不执行)

//当高度<70,Val=0不显示纹理1,高度>85,val=1,只显示纹理3 ,70~85之间混合显示

    Real val = (height - minHeight0) / fadeDist0; 

    val = Math::Clamp(val, (Real)0, (Real)1);
    //*pBlend0++ = val; //注释掉了,不执行

    val = (height - minHeight1) / fadeDist1;
    val = Math::Clamp(val, (Real)0, (Real)1);
    *pBlend1++ = val; //执行混合设置,0的话不显示,1只显示它,0~1混合显示,值设置完毕之后,指针++指向下一个
   }
  }
  blendMap0->dirty();
  blendMap1->dirty();
  //blendMap0->loadImage("blendmap1.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
  blendMap0->update();
  blendMap1->update();
}

如下图:

第三层指 blend2:growth_weirdfungus-03_diffusespecular.dds

第二层没执行,混合度为0:grass_green-01_diffusespecular.dds

第一层是默认的:dirt_grayrocky_diffusespecular.dds

 

使用DDS质材,可以投射出阴影


或者也可以看我的例子:

 defaultimp.layerList.resize(3);  
 defaultimp.layerList[0].worldSize = 100; //这个值关系到贴图的细致程度,太大的话图片被拉伸得很大,看起来模糊
 defaultimp.layerList[0].textureNames.push_back("BeachStones.jpg");
 defaultimp.layerList[0].textureNames.push_back("");
 defaultimp.layerList[1].worldSize = 30;
 defaultimp.layerList[1].textureNames.push_back("grass_1025.jpg");
 defaultimp.layerList[1].textureNames.push_back("");
 defaultimp.layerList[2].worldSize = 200;
 defaultimp.layerList[2].textureNames.push_back("rock.jpg");
 defaultimp.layerList[2].textureNames.push_back("");

 

因为用的JPG质材,所以不能投射出阴影,要是真想投射阴影的话,将PHOTOSHOP装个DDS插件,读入图片,导出DDS格式的图片,添加第二行代码中为空的质材defaultimp.layerList[0].textureNames.push_back("");




这个例子应该分得很明朗了,设置成高度低于5的使用鹅卵石纹理,高于6的用板岩纹理。没有使用.dds质材

OGRE根据高度图创建Terrain地形流程分析 OGRE可以通过两个接口来生成地形,分别是void TerrainSceneManager::setWorldGeometry( const String& filename )以及void TerrainSceneManager::setWorldGeometry(DataStreamPtr& stream, const String& typeName ),两者的根本区别就是一个是传递地形信息 阅读详情

相关推荐

VMD分子可视化实战:5个隐藏技巧让你的科研图像秒变顶刊级别

本文深入探讨了VMD分子可视化软件在科研图像美化中的5个高阶技巧,旨在帮助研究者将分子结构图提升至顶刊级别。内容涵盖原子色彩与材质的艺术化定制、沉浸式分子环境构建、专业构图与视角控制、数据驱动的动态可视化以及自动化工作流建立,通过精细的色彩映射、光照调整、周期性边界展示和脚本自动化,显著增强图像的科学叙事性与视觉冲击力。

weixin_29240343的博客 420

Ogre 1.7.2中的地形教程

http://blog.sina.com.cn/s/blog_8380edd00100yli4.html    ○读者可以对照着Ogre1.7.2中的terrain.h源码进行阅读加深理解,蓝色部分均为源码 ○去除了一些具体场景比如添加mesh,设置setAmbientLight等与terrain无关的操作   第一步 创建地形全局配置TerrainGlobalOptions 下

linking530的专栏 1457

Java 大视界 -- Java+Spark MLlib 构建智能推荐系统:协同过滤算法实战与优化(441)

Java+Spark MLlib构建智能推荐系统实战 本文详细介绍了基于Java和Spark MLlib构建协同过滤推荐系统的全流程实践方案。主要内容包括: 架构设计:采用离线批处理为主、近实时更新为辅的架构,包含数据采集层、处理层、模型层、推荐生成层、存储层和应用层六大模块,可支撑千万级用户推荐需求。 技术实现: 使用Spark MLlib的ALS算法进行协同过滤模型训练 提供数据清洗、模型训练、推荐生成等核心代码实现 采用MySQL存储推荐结果,支持批量插入和事务保障 生产级优化: 版本化模型存储规避覆

【青云交】华为云云享专家 | 阿里云开发者社区专家博主 技术圈个人影响力前 9 | 博客之星 TOP12 优快云 首位四榜(原力榜 / 作者周榜 / 领军人物 / 综合热榜)榜首,破平台纪录! 苏州地区全榜霸榜,感恩全网十多万粉丝同行! 2524

Ogre1.7的地形、天空与雾

  地形 ogre过去在地形的支持上很少,过去只是让你导入一个高度图,然后在上面放一层基本纹理和一细节纹理,在1.7版本的Ogre后,里面单独加入了terrain的模块,在地形的支持上已经非常强大,关于新版Ogre的地形的资料少之又少,我花了好几天经过反复试验根系摸了一下,总结一下新版Ogre的地形使用 1.设置摄像机的远剪裁面为无限远 if (root->getRenderSystem()->getCapabilities()->hasCapability(Ogre::RSC_INFINITE_F

leon 4057

大疆OcuSync vs 传统2.4GHz:深度拆解无人机图传射频模块的硬件差异

本文深度对比了大疆OcuSync与传统2.4GHz无人机图传射频模块的硬件差异,涵盖芯片组、天线系统、PCB设计、散热方案及生产测试等核心环节。重点解析OcuSync的全定制SoC芯片、智能MIMO天线阵列及精密PCB布局如何实现革命性性能提升,为无人机图传技术发展提供专业参考。

u5v6w7的博客 806

PEMFC电化学入门:从电流密度到Tafel公式的实战计算指南

本文详细介绍了PEMFC电化学的基础知识,从电流密度计算到Tafel公式的应用,提供了实战计算指南。通过代码示例和常见问题排查,帮助工程师快速掌握燃料电池性能优化的关键参数,如交换电流密度和活化损失计算,适用于汽车动力和分布式发电等领域。

weixin_29229055的博客 551

stk软件支持Linux,STK组件基础篇:开发入门

本文及后续系列文章主要采用STK组件的.Net版本作为开发包。1. 获取开发包正常的获取途径是访问AGI官网,注册并登录后,从官网下载开发包:https://support.agi.com/downloads/,如果是首次下载,AGI会向你注册的邮箱地址发送有效期半年的使用授权许可文件(lic文件)。但是由于某种原因国内的IP无法访问该网站,也无法注册成功。2. 开发包组成下载后的开发包是一个压缩...

weixin_39929961的博客 2994

基于Simulink的防空导弹六自由度弹道建模与仿真实战

本文详细介绍了基于Simulink的防空导弹六自由度弹道建模与仿真方法。通过分析导弹动力学原理、Simulink环境配置、气动力建模、推进与控制系统设计等关键环节,提供了一套完整的实战指南。文章特别强调了六自由度模型在防空导弹仿真中的重要性,并分享了常见问题排查与优化建议,为相关领域工程师提供实用参考。

apple5的专栏 865

Ogre实现天龙地形

转帖自http://www.cnblogs.com/syqking/archive/2009/10/20/1586993.html言归正传,先简单地说一下载入一个天龙八部场景的大致过程: 读取.Scene文件 根据读取.Terrain文件 读取地砖大小() 地形大小(xsize, ysize),缩放值(),地图中心坐标()。 读取所有要用的地形贴图(中各项)。 读取.g

流星 1147

绕过Google Play:获取Expo Go安卓APK的实用指南

本文为国内安卓开发者提供了绕过Google Play商店获取Expo Go APK的实用指南。针对无法访问Google Play的痛点,详细介绍了通过官方GitHub Releases、可信第三方网站(如APKMirror)及APK下载器等多种安全获取途径,并重点讲解了APK安装、安全验证(核对签名)及常见连接问题的排查方法,帮助开发者顺利开启React Native开发之旅。

weixin_29006701的博客 577

Vulkan入门系列0- Vulkan与OpenGL的区别

虽然Vulkan和OpenGL都是对GPU的抽象,都能达到相同的功能,但它们的设计理念不同,可以说设计差异是非常之大,由于OpenGL从1992年到现在,已经有30多年的历史,GPU功能日新月异,与当年不可同日而语,在OpenGL保持向下兼容情况下,还要在OpenGL基础上设计一套编程接口显然是不可能的,所以推出了新编程规范Vulkan。另外在一些无窗口的应用中,Vulkan可以有选择的不创建帧缓冲区,比如在数学运算,物理模拟,处理视频流的应用中并不需要窗口,所以Vulkan支持更灵活的应用场景。

GPU全栈博主 4068

【二次开发】CityMaker常见分析——地形挖洞

** 地形挖洞 ** 一:技术原理: 地形挖洞是地形编辑的一部分,主要作用是切除部分地形,显示出地形以下遮挡的部分模型。 地形挖洞主要分为两步:绘制挖洞面,进行地形挖洞。 二:实现地形挖洞: 1. .Net代码 private void terrainholeanalysis() { AxRenderControl rendercontrol=getRenderControl()...

CITYMAKER二次开发学习者之家 1079

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

OGRE地形笔记

<br /><br />开发环境<br />OGRE 1.72<br /> <br />教程<br />Basic Tutorial 3         Terrain, Sky, and Fog<br /> <br /> <br />浅谈<br />在1.71之前版本中使用Terrain Scene Manager进行地形管理,之后使用Ogre Terrain System.<br />Terrain和Paging有必不可分的关系,需要都理解。<br /> <br />管理步骤<br />1、首先需要创建

深蓝的世界 1004

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

OGRE渲染引擎之地形、天空和雾

本教程将重点介绍场景中的渲染地形。我们将介绍需要完成的基本设置,并将介绍使用带地形的照明。我们还将简要介绍使用Skyboxes,Skydomes和Skyplanes模拟天空。最后,我们将解释如何向场景添加雾效果。 可以在样本目录Samples / Terrain / include / Terrain.h中找到本教程的完整源代码 Note 有关如何设置Ogre项目并成功编译的说明,请参阅设置...

Estelle 884

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Ogre天龙八部地形mesh部分的C++源码

Ogre的地形部分历来受人诟病,基本没什么用.听说将来的的Ogre1.7版本会重写地形.期待中...在没有合适的地形可用的情况下,自己手动生成mesh来当地形是一个不错的选择.由于很多人问我天龙八部地形方面的问题,我索性放出自己terrain类的源码.先前我的部分源码有一些问题,这次是最新版本的.其他场景的源码,等我找到工作后可陆续放出,我只是一个待就业的穷学生而已,请见谅

LuoyinanRoy的专栏 9836

OGRE菜鸟笔记-地形学习

首先认识terrain.cfg中的几个参数,它们是理解ogre地形的基础。 # The main world texture (if you wish theterrain manager to create a material for you) WorldTexture=terrain_texture.jpg # The detail texture (if you wish ...

aohuying6065的博客 233

Ogre中的Terrain的Lod细节

Ogre中的Terrain的Lod细节 在OGRE中,Terrain是地形组中的一个区块。 Terrain的一些规则定义, 一个Terrain必须是个正方形的且边的长度必须是 mSize=2^n+1 maxBatch =2^n+1且maxBatch minBatch =2^n+1且minBatch 名称解释:        mSize就是地形矩形的边的顶点数。        m

xuantao的专栏 2430

Ogre1.8地形和天空盒的建立过程详解(一块地形)

编译环境 WIN7 32  VS2008   Ogre的版本 1.8 Ogre的地形算法是采用Geometry MIPMap的算法,当然贴图也是采用MIPMap的算法,这里有Ogre LOD算法的论文解释:http://www.flipcode.com/articles/article_geomipmaps.pdf 看到Ogre的Terrain,突然也想自己实现一个地形的打算,不过估计要过一段

Wait的专栏 1643

OGRE地形初步

感谢“Code Kinght”和痞子龙大神的地形相关博客                                               转载请注明出处http://blog.sina.com.cn/lucyloveayu          在OGRE的使用中,我们经常会涉及到地形(Terarain)的问题,其中涉及到了很多以前自己没有接触过的内容,其文件组织较其他资源来说比较特殊

胖大星的博客 333

ogre1.8自己写的建立地形源码(注释,可直接使用)

为了便于直接使用,所有代码都放在一个cpp文件中了,如下:

Wait的专栏 3201

(转)OGRE根据高度图创建Terrain地形流程分析

    OGRE可以通过两个接口来生成地形,分别是void TerrainSceneManager::setWorldGeometry( const String& filename )以及void TerrainSceneManager::setWorldGeometry(DataStreamPtr& stream, const String& typeName ),两者的根本区别就是一个是传递地形信息文件名一个是传递地形信息数据流,设计两个接口的目的是可以让用户使用自己的地形信息配置文件,而不必局限于

cml1980的专栏 475

【Ogre编程入门与进阶】第八章 地形、天空与雾化效果

在一款完整的3D游戏或是三维动画中,大地和天空都是构建场景时不可缺少的元素,另外,伴随着游戏中的角色形象上变得越来越饱满,越来越细节化,游戏中的地形系统也随着时间的推移变得越来越真实,越来越复杂,我们可以想象一副具有真实感的地形会给玩家带来多大的震撼效果,因此,在游戏引擎中地形系统的重要性就不言而喻了。         目前,游戏中有很多种方法来制作地形系统,当然,每一种方法都有它的优势和弱项。

Everything is possible 5700

(转)Ogre中地形的创建(Terrain)——基于TutorialFramework

With the Ogre wiki tutorial #3 : Terrain, Sky, and Fog we will have a nice looking terrain but it is not ours. So let's change the code a little bit. First we need to understand what is done. In Og...

weixin_30457065的博客 303
上一篇: Ogre1.7地形浅析
下一篇: 运行shell:windows命令,及显示桌面.scf的问题
凭谁问
博客等级 码龄15年 178粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值