2014年12月4日星期四(DEMO10-2地形生成函数)

2023-11-06


转眼间,2014年快过去了,数了数代码,封装后的代码也有17000行了,但是,还有很多工作量,继续进行最为敬畏的地形生成。

这个DEMO的意思是说,加载256色位图,以位图颜色索引乘以一个缩放因子为高程,将每个单元格分割为三角形,并插入到物体的顶点列表中;当然,还要有一个彩色纹理映射到高程场上。

 

生成地形模式:

#define POLY4DV2_ATTR_8BITCOLOR                 0x0004                    8位

#define POLY4DV2_ATTR_RGB16                              0x0008       16位

 

创建网格后,用两个函数分别计算两种法线:

1,计算多边形法线,(供背面消除和多边形光照计算使用)

Compute_OBJECT4DV2_Poly_Normals( ddraw_mathmath, OBJECT4DV2_PTRobj );

2,计算顶点法线(供Gouraud着色使用)

Compute_OBJECT4DV2_Vertex_Normals( ddraw_mathmath, OBJECT4DV2_PTRobj );

 

要设置着色模式,可以用下述常量之一。

 

#define POLY4DV2_ATTR_SHADE_MODE_EMISSIVE   0x0020

#define POLY4DV2_ATTR_SHADE_MODE_FLAT       0x0040

#define POLY4DV2_ATTR_SHADE_MODE_GOURAUD 0x0080

 

如果要使纹理映射到地形表面,则用POLY4DV2_ATTR_SHADE_MODE_TEXTURE,此时,只能用固定和恒定着色,不能采用Gouraud着色。

 

采用的方法是:计算输入纹理图的纹理坐标,然后将纹理映射到地形图上。

加载函数类似于加载PLG文件

 

 

int DDRAW_LIUSHUIXIAN_TEXTURE::Generate_Terrain_OBJECT4DV2ddraw_math                math,

                                                                  OBJECT4DV2_PTR            obj,              //指向物体的指针

                                                                  float                     twidth,               //世界坐标系中的长度(X轴)

                                                                  float                     theight,          //世界坐标系中的高度(Z轴)

                                                                  float                     vscale,               //最大可能高度值

                                                                  char     *            height_map_file//256色高程图的文件名

                                                                  char     *            texture_map_file, //纹理图的文件名

                                                                  int                       rgbcolor,             //没有纹理时地形的颜色

                                                                  VECTOR4D_PTR          pos,              //初始位置

                                                                  VECTOR4D_PTR          rot,              //初始旋转角度

                                                                  int                       poly_attr)       //着色属性

{

    char                  buffer[256];                   //工作缓冲区

 

    float                     col_tstep,row_tstep;

    float                     col_vstep,row_vstep;

    int                       columns,rows;

    int                       rgbwhite;

 

    BITMAP_FILE               height_bitmap;                     //存储高程图

    BITMAP_FILE               bitmap16bit;

 

 

    //第一步清空和初始化OBJ

    memset(obj, 0, sizeof(OBJECT4DV2) );

    //将物体状态设置为可见和活动的

    obj->state                                      =OBJECT4DV2_STATE_ACTIVE | OBJECT4DV2_STATE_VISIBLE;

 

    //设置物体的位置

    obj->world_pos.x                            = pos->x;

    obj->world_pos.y                            = pos->y;

    obj->world_pos.z                            = pos->z;

    obj->world_pos.w                            = pos->w;

 

    //以后只用色的模式

    rgbwhite                                    = _RGB16BIT565( 255, 255, 255 );

 

    //设置物体包含的帧数

    obj->num_frames                                 =1;

    obj->curr_frame                                 =0;

    obj->attr                                        = OBJECT4DV2_ATTR_SINGLE_FRAME;

 

    //清空位图

    memset(& height_bitmap, 0, sizeof( BITMAP_FILE) );

    //第步,加载高程图

    ddraw_bitmap  bm;

    bm.Load_Bitmap_File( & height_bitmap,height_map_file );

 

    //计算基本信息

    columns                                         = height_bitmap.bitmapinfoheader.biWidth;

    rows                                        = height_bitmap.bitmapinfoheader.biHeight;

 

    col_vstep                                       = twidth / ( float )( columns - 1 );

    row_vstep                                       = theight / ( float) ( rows - 1 );

 

    sprintf(obj->name,"Terrains:%s%s", height_map_file, texture_map_file);

    obj->num_vertices                           =columns * rows;

    obj->num_polys                                  =( ( columns - 1 ) * ( rows - 1 ) ) * 2;

 

    //存储一些结果,供地形追踪算法使用

    obj->ivar1                                      =columns;

    obj->ivar2                                      =rows;

    obj->fvar1                                      =col_vstep;

    obj->fvar2                                      =row_vstep;

 

 

    //为存储顶点数和多边形数的变量分配内存

    Init_OBJECT4DV2(obj, obj->num_vertices, obj->num_polys, obj->num_frames );

 

    //加载纹理图(如果有的话)

    if(( poly_attr & POLY4DV2_ATTR_SHADE_MODE_TEXTURE) && texture_map_file )

    {

         //从磁盘里加载纹理图

         bm.Load_Bitmap_File( & bitmap16bit,texture_map_file );

 

         //创建一个大小和位深合适的位图

         obj->texture                       =( BITMAP_IMAGE_PTR ) malloc( sizeof( BITMAP_IMAGE ) );

         bm.Create_Bitmap( obj->texture, 0, 0, bitmap16bit.bitmapinfoheader.biWidth,bitmap16bit.bitmapinfoheader.biHeight,

             bitmap16bit.bitmapinfoheader.biBitCount);

 

         //加载位图图像

         bm.Load_Image_Bitmap16( obj->texture, & bitmap16bit,0, 0, BITMAP_EXTRACT_MODE_ABS );

 

         //计算纹理图的步进因子

         col_tstep                              = ( float ) ( bitmap16bit.bitmapinfoheader.biWidth- 1 ) / ( float ) ( columns- 1 );

         row_tstep                              = ( float ) ( bitmap16bit.bitmapinfoheader.biHeight- 1 ) / ( float ) ( rows- 1 );

 

         //指出物体带纹理

         SET_BIT(obj->attr,OBJECT4DV2_ATTR_TEXTURES );

 

         //卸载位图

         bm.Unload_Bitmap_File( & bitmap16bit);

    }

 

 

    //第步:按先行后列的顺序加载顶点列表和纹理坐标列表

 

    for(int curr_row= 0; curr_row < rows;curr_row ++ )

    {

         for(int curr_col= 0; curr_col < columns;curr_col ++ )

         {

             int               vertex                    = ( curr_row* columns ) + curr_col;

             //计算顶点坐标

             obj->vlist_local[vertex].x             =curr_col * col_vstep- ( twidth / 2 );

             obj->vlist_local[vertex].y             =vscale * ( ( float) height_bitmap.buffer[curr_col + ( curr_row* columns )] )/ 255;

             obj->vlist_local[vertex].z             =curr_row * row_vstep- ( theight / 2 );

             obj->vlist_local[vertex].w             =1;

 

             //设置顶点的D

             SET_BIT(obj->vlist_local[vertex].attr, VERTEX4DTV1_ATTR_POINT );

 

             //需要纹理坐标

             if(( poly_attr & POLY4DV2_ATTR_SHADE_MODE_TEXTURE) && texture_map_file )

             {

                  //计算纹理坐标

                  obj->tlist[vertex].x               = curr_col* col_tstep;

                  obj->tlist[vertex].y               = curr_row* row_tstep;

             }

         }

    }

 

    //计算平均半径和最大半径

    Compute_OBJECT4DV2_Radius(obj);

 

    //第步:加载多边形列表

    for(int poly =0; poly < obj->num_polys / 2; poly++)

    {

         //每个单元格有两个三角形,单元格顶点按先行后列的顺序排列

         //如果顶点数组大小为m*n,则多边形列表大小为*(m-1)*(n-1)

         int          base_poly_index                    = ( poly% ( columns - 1 ) )  + ( columns* ( poly / ( columns- 1 ) ) );

 

         //当前单元格的左下多边形

         obj->plist[poly*2].vert[0]                  =base_poly_index;

         obj->plist[poly*2].vert[1]                  =base_poly_index + columns;

         obj->plist[poly*2].vert[2]                  =base_poly_index + columns+ 1;

 

         //当前单元格的右上多边形

         obj->plist[poly*2+1].vert[0]                =base_poly_index;

         obj->plist[poly*2+1].vert[1]                =base_poly_index + columns+ 1;

         obj->plist[poly*2+1].vert[2]                =base_poly_index + 1;

 

         //将多边形顶点列表指向物体的顶点列表

         obj->plist[poly*2].vlist                    =obj->vlist_local;

         obj->plist[poly*2+1].vlist                  =obj->vlist_local;

 

         //设置多边形的颜色

         obj->plist[poly*2].color                    =rgbcolor;

         obj->plist[poly*2+1].color                  =rgbcolor;

 

         //检查着色方法是否是Gouraud或phong,如果是,则需要顶点法线

         if(( obj->plist[poly*2].attr& POLY4DV2_ATTR_SHADE_MODE_GOURAUD ) ||( obj->plist[poly * 2].attr& POLY4DV2_ATTR_SHADE_MODE_PHONG ) )

         {

             //设置顶点的属性,指出它包含法线

             SET_BIT(obj->vlist_local[obj->plist[poly * 2].vert[0]].attr, VERTEX4DTV1_ATTR_NORMAL);

             SET_BIT(obj->vlist_local[obj->plist[poly * 2].vert[1]].attr, VERTEX4DTV1_ATTR_NORMAL);

             SET_BIT(obj->vlist_local[obj->plist[poly * 2].vert[2]].attr, VERTEX4DTV1_ATTR_NORMAL);

 

             SET_BIT(obj->vlist_local[obj->plist[poly * 2 + 1].vert[0]].attr, VERTEX4DTV1_ATTR_NORMAL);

             SET_BIT(obj->vlist_local[obj->plist[poly * 2 + 1].vert[1]].attr, VERTEX4DTV1_ATTR_NORMAL);

             SET_BIT(obj->vlist_local[obj->plist[poly * 2 + 1].vert[2]].attr, VERTEX4DTV1_ATTR_NORMAL);

         }

 

         //如果启用了纹理映射,则计算纹理坐标

         if(poly_attr & POLY4DV2_ATTR_SHADE_MODE_TEXTURE)

         {

             //指定多边形使用的纹理

             obj->plist[poly *2].texture           =obj->texture;

             obj->plist[poly * 2+ 1].texture       =obj->texture;

 

             //设置纹理坐标

             //左下三角形

 

             obj->plist[poly*2].text[0]                  =base_poly_index;

             obj->plist[poly*2].text[1]                  =base_poly_index + columns;

             obj->plist[poly*2].text[2]                  =base_poly_index + columns+ 1;

 

             //当前单元格的右上多边形

             obj->plist[poly*2+1].text[0]                =base_poly_index;

             obj->plist[poly*2+1].text[1]                =base_poly_index + columns+ 1;

             obj->plist[poly*2+1].text[2]                =base_poly_index + 1;   

 

             //重新设置多边形颜色,使其反射率更高

             obj->plist[poly*2].color                    =rgbwhite;

             obj->plist[poly*2+1].color                  =rgbwhite;

 

             //设置纹理坐标属性

             SET_BIT(obj->vlist_local[obj->plist[poly * 2].vert[0]].attr, VERTEX4DTV1_ATTR_TEXTURE);

             SET_BIT(obj->vlist_local[obj->plist[poly * 2].vert[1]].attr, VERTEX4DTV1_ATTR_TEXTURE);

             SET_BIT(obj->vlist_local[obj->plist[poly * 2].vert[2]].attr, VERTEX4DTV1_ATTR_TEXTURE);

 

             SET_BIT(obj->vlist_local[obj->plist[poly * 2 + 1].vert[0]].attr, VERTEX4DTV1_ATTR_TEXTURE);

             SET_BIT(obj->vlist_local[obj->plist[poly * 2 + 1].vert[1]].attr, VERTEX4DTV1_ATTR_TEXTURE);

             SET_BIT(obj->vlist_local[obj->plist[poly * 2 + 1].vert[2]].attr, VERTEX4DTV1_ATTR_TEXTURE);

         }

 

         //将材质模式设置为不使用材质

         SET_BIT(obj->plist[poly * 2].attr,POLY4DV2_ATTR_DISABLE_MATERIAL );

         SET_BIT(obj->plist[poly * 2 + 1].attr,POLY4DV2_ATTR_DISABLE_MATERIAL );

 

         //将三角形的状态设置为活动的

         obj->plist[poly *2].state                      =POLY4DV2_STATE_ACTIVE;

         obj->plist[poly * 2+ 1].state                  =POLY4DV2_STATE_ACTIVE;

 

         //将多边形顶点列表指向物体的顶点列表

         obj->plist[poly *2].vlist                      =obj->vlist_local;

         obj->plist[poly * 2+ 1].vlist                  =obj->vlist_local;

 

         //设置纹理坐标列表

         obj->plist[poly *2].tlist                      =obj->tlist;

         obj->plist[poly * 2+ 1].tlist                  =obj->tlist;

    }

 

 

 

    //计算多边形法线的长度

    Compute_OBJECT4DV2_Poly_Normals(math, obj);

    //计算使用GOURAUD着色的多边形,计算其顶点法线

    Compute_OBJECT4DV2_Vertex_Normals(math, obj);

   

 

    return( 1 );

 

 

 

}

 

演示程序是个沙地汽车,但是我不想去做这个,我只想看看引擎的运用,而不是逻辑,

 

在初始化时加载地形

 

 

    VECTOR4D     terrain_pos           = { 0, 0, 0, 0 };

 

 

         liushuixian_texture.Generate_Terrain_OBJECT4DV2( * math, & obj_work,4000, 3000, 700, "earthheightmap01.bmp","earthcolormap01.bmp",

                                                _RGB16BIT565( 255, 255, 255), & terrain_pos, NULL,POLY4DV2_ATTR_RGB16 | POLY4DV2_ATTR_SHADE_MODE_FLAT | POLY4DV2_ATTR_SHADE_MODE_TEXTURE );

摄像机位置改变

POINT4D  cam_pos    ={0,500,-200,1};

截图如下:



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2014年12月4日星期四(DEMO10-2地形生成函数) 的相关文章

  • 【学习填坑之路】FBX-SDK环境搭建及测试

    工作原因记录一下环境搭建 下载并安装FBX SDK 首先下载并安装FBX SDK 点击AutoDesk官网下载 下载后安装运行程序即可 根据自己的Visual Studio版本选择Windows的FBX SDK版本下载安装文件 运行安装程序
  • FastDFS安装与配置

    FastDFS安装与配置 简介 FastDFS是一个开源的轻量级分布式文件系统 它对文件进行管理 功能包括 文件存储 文件同步 文件访问 文件上传 文件下载 等 解决了大容量存储和负载均衡的问题 特别适合以文件为载体的在线服务 如相册网站
  • pandas基本的增删改查用法梳理

    说明 以下为之前在pandas使用过程中的所用的到对数据的基本增删改查处理方法进行梳理 文章目录 1 数据读取 resd csv 2 数据保存 3 pandas常用数据格式处理函数 4 增 5 删 6 改 元素赋值 列赋值 行赋值 7 查
  • Flink(九)CEP

    Flink 八 CEP 1 概述 2 快速入门 3 模式API 3 1 个体模式 3 2 组合模式 3 3 匹配后跳过策略 4 模式的检测处理 4 1 模式应用到数据流 4 2 处理匹配事件 4 3 处理超时事件 1 概述 所谓 CEP 其

随机推荐

  • 1.软件测试-Linux搭建测试环境

    1 数据库 yum y install mysql mysql server mysql devel MySQL 客户端 MySQL server 服务端 mysql devel 库 启动MySQL service mysql start
  • 无界面浏览器访问网页,python

    from selenium import webdriver from selenium webdriver chrome options import Options chrome options Options chrome optio
  • 列存储与行存储的区别

    写入 行存储的写入是一次完成 数据的完整性因此可以确定 列存储需要把一行记录拆分成单列保存 写入次数明显比行存储多 行存储在写入上占有很大的优势 数据修改 行存储是在指定位置写入一次 列存储是将磁盘定位到多个列上分别写入 行存储在数据修改也
  • 从Java到Go:实现多语言翻译服务的高性能解决方案

    本文将深入探讨如何使用Go语言 Golang 开发多语言翻译服务 我们将重点介绍从Java到Go的过渡 并提供详细的代码示例以帮助您快速上手 目录 1 为什么选择Go 2 Go语言基础 2 1 语法结构 2 2 变量 常量和类型
  • java 类增强机制

    前言 对类的增强有多少种方式 我们首先想一下一个类的生命周期 从编码到程序运行结束 对类的增强 目的是为了在使用的时候能够在类原有的行为上进行增强 所以编码一直到使用中的几乎每个环节都可以对类进行增强 主要有以下几种方式 静态代理 编译期织
  • 遇到文件误删情况,使用EasyRecovery快速恢复

    当我们不小心将文件误删了 还有办法恢复吗 可能很多朋友认为这是不可能的 一个连在电脑中都无法找到痕迹的文件 我们要怎么找到它呢 其实也不是不可能 借助专业的数据恢复软件EasyRecovery就可以帮你恢复彻底删除的文件 下面就一起来学习具
  • 【Netty】NIO基础(三大组件、文件编程)

    文章目录 三大组件 Channel Buffer Selector ByteBuffer ByteBuffer 正确使用姿势 ByteBuffer 内部结构 ByteBuffer 常见方法 分配空间 向 buffer 写入数据 从 buff
  • k-近邻算法的Python实现

    k 近邻算法的Python实现 一 概述 k 近邻算法 k Nearest Neighbour algorithm 又称为KNN算法 是数据挖掘技术中原理最简单的算法 KNN的工作原理 给定一个已知标签类别的训练数据集 输入没有标签的新数据
  • Netty网络编程框架

    一 简介 Netty是由JBOSS提供的一个java开源框架 Netty提供异步的 事件驱动的网络应用程序框架和工具 用以快速开发高性能 高可靠性的网络服务器和客户端程序 也就是说 Netty 是一个基于NIO的客户 服务器端编程框架 使用
  • B3:多个if(c++)

    做纸箱最少需要多少面积的硬纸板 题目描述 请问做一个尺寸为a b c 单位 厘米 的开口的立方体纸箱 只有一个面是不需要封的 其余5个面都需要封起来 这样算开口的 最少需要多少平方厘米的纸 6 1 6 输入 三个整数 abc 输出 制作该纸
  • Javascript中的every()与some()的区别和应用

    every 定义和用法 every 方法用于检测数组所有元素是否都符合指定条件 通过函数提供 every 方法使用指定函数检测数组中的所有元素 如果数组中检测到有一个元素不满足 则整个表达式返回 false 且剩余的元素不会再进行检测 如果
  • 遗传的效应,美貌与智慧奇妙的遗传

    身高是母亲的遗传大 在营养状况下的前提下 父母的遗传是决定孩子身高的主要因素 其中妈妈的身高尤其关键 妈妈长得高 孩子也大多长得比较高 智力是母亲的遗传大 智力有一定的遗传性 同时受到环境 营养 教育等后天因素的影响 据科学家评估 遗传对智
  • 南大通用&河北工业大学人工智能与数据科学学院党支部共建暨研究生培养基地合作签约仪式顺利举办

    2022年2月18日下午 天津南大通用数据技术股份有限公司 河北工业大学人工智能与数据科学学院党支部共建签约仪式暨研究生培养基地签约仪式在普天创新产业园23层会议室举行 南大通用董事长丁明峰 高级副总裁赵伟 总工办主任杨伟伟 人力资源部总监
  • python中有哪些去除重复项的操作

    Python中去除重复项的操作 常用的有以下几种方式 1 使用set 将列表转化为集合 再转化为列表 即可去重 list a 1 2 3 2 1 4 5 4 6 7 7 new list a list set list a print ne
  • JMeter----安装与介绍以及简单页面录制和移动端录制

    1 什么是JMeter 2 JMeter的安装 3 JMeter基本使用 4 JMeter运行原理 5 JMeter录制脚本 1 什么是JMeter JMeter简介 JMeter是Apache公司使用Java平台开发的一套测试工具 JMe
  • flowable实战(三):关于流程图编辑

    发现很多人讲到flowable 就是大概讲一下整合里面一些名词之类 实操偏少 或者用一个小demo演示一下 就完了 但是一涉及到具体的业务 你会发现涉及到工作流要有多麻烦 考虑很多情况进去会涉及到条件设置 逻辑判断甚至官方提供的那么多方法你
  • C++实现人机对战围棋(使用Leela Zero权重)-界面

    1 在 leela zero next 包中有一个 从人类游戏训练的 较弱的 网络的权重文件 https sjeng org zero best v1 txt zip 6残差块 128通道 2 并在 easyx吧 百度贴吧下了一个双人对战的
  • C语言-函数指针-快速排序算法

    概述 使用C语言 实现结构体多元素 排序算法 冒泡排序 这里使用示例 蓝牙信号强度排序解说 编码环境 Visual Studio 2022 1 code include
  • Python int()的有趣用法

    Python中的int 函数相信大家都不陌生 总的来说 就是int 函数用于将字符串或数字转换为整型 那么今天要说的有趣用法是什么呢 先看一行代码 并猜一下它有什么作用 int 1 200 2 初看这行代码想半天也没搞懂 于是help in
  • 2014年12月4日星期四(DEMO10-2地形生成函数)

    转眼间 2014年快过去了 数了数代码 封装后的代码也有17000行了 但是 还有很多工作量 继续进行最为敬畏的地形生成 这个DEMO的意思是说 加载256色位图 以位图颜色索引乘以一个缩放因子为高程 将每个单元格分割为三角形 并插入到物体