【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

这篇具有很好参考价值的文章主要介绍了【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

🍺三维数字地球系列相关文章如下🍺:
1 【小沐学GIS】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)第一期
2 【小沐学GIS】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)第二期
3 【小沐学GIS】基于OpenSceneGraph(OSG)绘制三维数字地球Earth
4 【小沐学GIS】基于C++绘制太阳系SolarSystem(OpenGL、glfw、glut)
5 【小沐学GIS】基于C#绘制三维数字地球Earth(OpenGL)

【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

1、计算公式

球的三维坐标表示为:
x 2 + y 2 + z 2 = R 2 x^2 + y^2 + z^2 = R^2 x2+y2+z2=R2

引入球的参数坐标方程进行离散化。以(u,v)表示球面上某一点的坐标,且u,v的取值范围为[0 , 1],定义(u,v)到(x,y,z)的转换如下:

{ x = R × s i n ( π × v ) c o s ( 2 π × u ) y = R × s i n ( π × v ) s i n ( 2 π × u ) z = R × c o s ( π × v ) \begin{cases} x=R×sin(\pi×v)cos(2\pi×u) \\ y=R×sin(\pi×v)sin(2\pi×u) \\ z=R×cos(\pi×v) \end{cases} x=R×sin(π×v)cos(2π×u)y=R×sin(π×v)sin(2π×u)z=R×cos(π×v)

2、绘图接口

在OpenGL中,所有图形都是通过分解成三角形的方式进行绘制。
glDrawArrays 和 glDrawElements 的作用都是从一个数据数组中提取数据渲染基本图元。

【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

  • GL_POINTS:把每一个顶点作为一个点进行处理,顶点n即定义了点n,共绘制N个点。
  • GL_LINES:连接每两个顶点作为一个独立的线段,顶点2n-1和2n之间共定义了n条线段,总共绘制N/2条线段。
  • GL_LINE_STRIP:绘制从第一个顶点到最后一个顶点依次相连的一组线段,第n和n+1个顶点定义了线段n,总共绘制n-1条线段。
  • GL_LINE_LOOP:绘制从第一个顶点到最后一个顶点依次相连的一组线段,然后最后一个顶点和第一个顶点相连,第n和n+1个顶点定义了线段n,总共绘制n条线段。
  • GL_TRIANGLES:把每三个顶点作为一个独立的三角形,顶点3n-2、3n-1和3n定义了第n个三角形,总共绘制N/3个三角形。
  • GL_TRIANGLE_STRIP:绘制一组相连的三角形,对于奇数n,顶点n、n+1和n+2定义了第n个三角形;对于偶数n,顶点n+1、n和n+2定义了第n个三角形,总共绘制N-2个三角形。
  • GL_TRIANGLE_FAN:绘制一组相连的三角形,三角形是由第一个顶点及其后给定的顶点确定,顶点1、n+1和n+2定义了第n个三角形,总共绘制N-2个三角形。

其中:
GL_TRIANGLES:V0V1V2, V3V4V5, V6V7V8……
GL_TRIANGLE_FAN:V0V1V2, V0V2V3, V0V3V4……
GL_TRIANGLE_STRIP:V0V1V2, V1V2V3, V2V3V4……

2.1 glDrawArrays

The glDrawArrays function specifies multiple primitives to render.

void WINAPI glDrawArrays(
   GLenum  mode,
   GLint   first,
   GLsizei count
);
mode:
GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_TRIANGLES, GL_QUAD_STRIP, GL_QUADS, and GL_POLYGON.

first:
The starting index in the enabled arrays.

count:
The number of indexes to render.

2.2 glDrawElements

The glDrawElements function renders primitives from array data.
The glDrawElements function is only available in OpenGL version 1.1 or later.

void WINAPI glDrawElements(
         GLenum  mode,
         GLsizei count,
         GLenum  type,
   const GLvoid  *indices
);
mode:
The kind of primitives to render. It can assume one of the following symbolic values: GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_TRIANGLES, GL_QUAD_STRIP, GL_QUADS, and GL_POLYGON.

count:
The number of elements to be rendered.

type:
The type of the values in indices. Must be one of GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, or GL_UNSIGNED_INT.

indices:
A pointer to the location where the indices are stored.

绑定VAO时也会自动绑定EBO。
不要在解绑VAO之前解绑EBO(GL_ELEMENT_ARRAY_BUFFER)。

3、代码实现

#pragma once
#include "Point3d.h"
#include <vector>

class EarthGrid3d
{
public:
	EarthGrid3d();

	void generalSphereGrid();
	void generalSphereLines();

	int _uStepsNum;
	int _vStepNum;

	float *_verticesArr;
	int _verticesNum;

	int *_indicesArr;
	int _indicesNum;

	float *_linesArr;
	int _linesNum;
};
#include "EarthGrid3d.h"

EarthGrid3d::EarthGrid3d()
{
	_uStepsNum = 120;
	_vStepNum = 120;
}

void EarthGrid3d::generalSphereGrid()
{
	double ustep = 1 / (double)_uStepsNum, vstep = 1 / (double)_vStepNum;
	int np = 0;
	int nf = 0;

	_verticesNum = (_vStepNum*_uStepsNum + 1)*(3 + 2);
	_verticesArr = new float[_verticesNum];
	
	_indicesNum = (_uStepsNum * 2 + _uStepsNum * 2 * (_vStepNum - 2)) * 3;
	_indicesArr = new int[_indicesNum];
	
	//
	// 北极的一个点
	{
		Point3d pt0 = getSpherePoint(0, 0);
		_verticesArr[5 * np] = pt0.x;
		_verticesArr[5 * np + 1] = pt0.y;
		_verticesArr[5 * np + 2] = pt0.z;
		_verticesArr[5 * np + 3] = 0.5;
		_verticesArr[5 * np + 4] = 0;
		np++;
	}

	// 中间的点
	for (int j = 1; j < _vStepNum; j++) //v-1个点(共v+1个点)
	{
		for (int i = 0; i <= _uStepsNum; i++) //u+1个点 (共u+1个点)
		{
			Point3d pt = getSpherePoint(ustep*i, vstep*j);
			_verticesArr[5 * np] = pt.x;
			_verticesArr[5 * np + 1] = pt.y;
			_verticesArr[5 * np + 2] = pt.z;
			_verticesArr[5 * np + 3] = 1 - ustep * i;
			_verticesArr[5 * np + 4] = vstep * j;
			np++;
		}
	}

	// 南极的一个点
	{
		Point3d pt1 = getSpherePoint(1, 1);
		_verticesArr[5 * np] = pt1.x;
		_verticesArr[5 * np + 1] = pt1.y;
		_verticesArr[5 * np + 2] = pt1.z;
		_verticesArr[5 * np + 3] = 0.5;
		_verticesArr[5 * np + 4] = 1;
		//np++;
	}

	//
	// 上下2行的三角形组
	for (int i = 0; i < _uStepsNum; i++) { 
		//第一层u个三角形
		_indicesArr[nf++] = 0;
		_indicesArr[nf++] = 1 + i;
		_indicesArr[nf++] = 2 + i;
		
		//最后一层u个三角形
		_indicesArr[nf++] = np - 1;
		_indicesArr[nf++] = np - 2 - i;
		_indicesArr[nf++] = np - 3 - i;
	}

	// 中间的v-2行的三角形组
	for (int j = 0; j < _vStepNum - 2; j++) {  //共v-2行
		for (int i = 0; i < _uStepsNum; i++) { //共u列

			/*
			*       |\
			*       | \
			*       |__\
			*/
			_indicesArr[nf++] = (_uStepsNum + 1)*j + 1 + i;
			_indicesArr[nf++] = (_uStepsNum + 1)*(j + 1) + 1 + i;
			_indicesArr[nf++] = (_uStepsNum + 1)*(j + 1) + 2 + i;

			/*
			*       __
			*       \  |
			*        \ |
			*         \|
			*/
			_indicesArr[nf++] = (_uStepsNum + 1)*j + 1 + i;
			_indicesArr[nf++] = (_uStepsNum + 1)*(j + 1) + 2 + i;
			_indicesArr[nf++] = (_uStepsNum + 1)*j + 2 + i;
		}
	}
}

void EarthGrid3d::generalSphereLines()
{
	double ustep = 1 / (double)_uStepsNum, vstep = 1 / (double)_vStepNum;
	int np = 0;

	_linesNum = (_vStepNum*_uStepsNum)*6;
	_linesArr = new float[_linesNum];

	// 绘制24条经线
	for (int i = 0; i < _uStepsNum; i+= _uStepsNum/24)
	{
		for (int j = 0; j < _vStepNum; j++)
		{
			Point3d pt = getSpherePoint(ustep*i, vstep*j, 1.01f);
			_linesArr[3 * np] = pt.x;
			_linesArr[3 * np + 1] = pt.y;
			_linesArr[3 * np + 2] = pt.z;
			np++;

			Point3d pt2 = getSpherePoint(ustep*i, vstep*(j+1), 1.01f);
			_linesArr[3 * np] = pt2.x;
			_linesArr[3 * np + 1] = pt2.y;
			_linesArr[3 * np + 2] = pt2.z;
			np++;
		}
	}

	// 绘制1条纬线(赤道)
	for (int i = 0; i < _uStepsNum; i++)
	{
		int j = _vStepNum / 2;
		//for (int j = 0; j < _vStepNum; j++)
		{
			Point3d pt = getSpherePoint(ustep*i, vstep*j, 1.01f);
			_linesArr[3 * np] = pt.x;
			_linesArr[3 * np + 1] = pt.y;
			_linesArr[3 * np + 2] = pt.z;
			np++;

			Point3d pt2 = getSpherePoint(ustep*(i+1), vstep*j, 1.01f);
			_linesArr[3 * np] = pt2.x;
			_linesArr[3 * np + 1] = pt2.y;
			_linesArr[3 * np + 2] = pt2.z;
			np++;
		}
	}
}

4、运行结果(3d整体地球)

4.1 opengl / glut / c++ (3d)

【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

4.2 opengl / glfw / glad / stb_image / c++ (3d)

【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

4.3 opengl / glfw / glad / stb_image /c++ (3d,天空盒,高度贴图)

【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

4.4 opengl / win32/ glew / FreeImage / c++ (3d,大气层)

【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

4.5 opengl / freeglut / glew / FreeImage / c++ (3d,法线贴图)

【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

4.6 opengl / glfw / glad / stb_image / freetype / c++ (2d/3d,加载geojson)

【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)
【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

4.7 opengl / glfw / glad / FreeImage / c++ (3d,白天层/黑夜层/云层)

【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)
【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

4.8 opengl / glut / gl3w / c++ (3d,太阳系)

【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

4.9 opengl / glut / glew / glm / openssl / c++ (3d,在线地震数据显示)

GeoJSON 是一种用于对各种地理数据结构进行编码的格式。 GeoJSON 对象可以表示几何、要素或 特征。GeoJSON 使用 JSON 标准。 GeoJSONP 源使用相同的 JSON 响应,但 GeoJSONP 响应 包装在函数调用中,eqfeed_callback。

  • 在线地震数据的请求结果json如下:
{
  type: "FeatureCollection",
  metadata: {
    generated: Long Integer,
    url: String,
    title: String,
    api: String,
    count: Integer,
    status: Integer
  },
  bbox: [
    minimum longitude,
    minimum latitude,
    minimum depth,
    maximum longitude,
    maximum latitude,
    maximum depth
  ],
  features: [
    {
      type: "Feature",
      properties: {
        mag: Decimal,
        place: String,
        time: Long Integer,
        updated: Long Integer,
        tz: Integer,
        url: String,
        detail: String,
        felt:Integer,
        cdi: Decimal,
        mmi: Decimal,
        alert: String,
        status: String,
        tsunami: Integer,
        sig:Integer,
        net: String,
        code: String,
        ids: String,
        sources: String,
        types: String,
        nst: Integer,
        dmin: Decimal,
        rms: Decimal,
        gap: Decimal,
        magType: String,
        type: String
      },
      geometry: {
        type: "Point",
        coordinates: [
          longitude,
          latitude,
          depth
        ]
      },
      id: String
    },
    …
  ]
}

【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)
中国地震台网中心:
http://news.ceic.ac.cn/index.html?time=1674619089

  • 显示最近三天内的地震情况:
    【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

  • 显示最近一个月内的地震情况:
    【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

4.10 opengl / fltk / glew / curl / openssl / c++ / geojson (3d,在线地震数据显示2)

  • 显示最近小时内的地震情况:
    【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)
  • 显示最近一个月内的地震情况:
    【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

5、运行结果(3d瓦片地球)

5.1 opengl / glfw / glew / curl / proj4 / gdal / stb_image / c++ (3d,瓦片贴图)

  • 加载卫星影像图
    【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

  • 加载行政地图
    【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

  • 加载shp(shapefile)文件和显示:
    【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

  • 绘制自定义的图形元素(线、面等)
    【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

  • 切换地球底图的瓦片图源

【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

5.2 opengl / glfw / glad / boost::asio / proj4 / stb_image / c++ (3d,瓦片贴图)

【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

6、运行结果(2d瓦片地球)

6.1 opengl / sdl / boost::asio / c++ (2d,瓦片贴图)

【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)

以上章节所有地球代码,均在VS2017开发环境编译通过。

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)
感谢各位童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)
文章来源地址https://www.toymoban.com/news/detail-416291.html

到了这里,关于【GIS开发】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 三维GIS开发:利用Cesium加载 M3D 地质体模型(附代码)

    实现步骤 Step 1.  引用开发库 : 本示例引用 local 本地【include-cesium-local.js】开发库,完成此步骤后才可调用三维 WebGL 的功能; Step 2.  创建布局 : 创建 id=\\\'GlobeView\\\' 的 div 作为三维视图的容器,并设置其样式; Step 3.  构造三维场景控件 : 实例化 Cesium.WebSceneControl 对象,完成

    2024年02月10日
    浏览(28)
  • 基于C++开发的医院医学影像PACS 可二次开发,三维重建

    医学影像PACS系统源码,集成三维影像后处理功能,包括三维多平面重建、三维容积重建、三维表面重建、三维虚拟内窥镜、最大/小密度投影、心脏动脉钙化分析等功能。系统功能强大,代码完整。有演示。 本套PACS系统专门针对医院工作流程设计的,完全符合医院需要,配置

    2023年04月23日
    浏览(28)
  • 爱心代码html或c++调用opengl库两种实现(二维三维动态也可键盘交互)

    最近打火机与公主裙电视剧追疯了!!!谁还没有李峋爱心代码!!快来领!!沉浸式追剧大学生今天午觉没睡怒干爱心代码现有三分资源如下: 效果: 1)、公主两个for循环二维C++控制台输出爱心; 2)、原创C++语言利用openGL库实现三维动态旋转粉色爱心; 以上两者可以在

    2024年02月13日
    浏览(42)
  • 手机上获取地图某个定位的经纬度坐标的方法 - 查询经度、纬度 - 百度地图app、高德地图app、Earth地球

    拖动、定位、获得左上角的 东经、北纬等信息,就是经度、纬度了。 手机安装app 苹果: Earth-地球 安卓、鸿蒙: Earth地球   打开软件,拖动地图   左上角的坐标就是 经度、纬度     百度地图app、高德地图app都无法获取坐标、经度、纬度   手机也可以用 网页版坐标拾取系

    2024年02月09日
    浏览(125)
  • GIS工具maptalks开发手册(四)01——渲染地图信息框之添加绘制工具、获取点的坐标数据信息框进行展示

    GIS工具maptalks开发手册(四)01——渲染地图信息框之添加绘制工具、获取点的坐标数据信息框进行展示 1、官网示例 官网示例-地图信息框——https://maptalks.org/examples/cn/ui-control/ui-map-infownd/#ui-control_ui-map-infownd 效果 代码 index.html 2、官网示例改造版 效果 index.html 3、获取图层的坐标

    2024年02月05日
    浏览(36)
  • Unity WebGL三维地球

    1.支持arcgis,天地图,bingmap,谷歌地图,高德地图等影像加载 2.支持高程三维地形加载 3.支持在线,离线数据加载 4.支持unity坐标和经纬度坐标互相转换 5.支持fbx模型放置在地球上 6.支持倾斜摄影数据放置在地球上 7.支持pc,webgl平台发布 weixin:huazaikv 相关视频: unity三维地球_W

    2024年02月12日
    浏览(24)
  • 自主三维GIS引擎笔记-实现三维球045

    最小GIS迷你地球实现(实现一套最小的三维GIS球体)  V1.0.0.0版本 数据加代码比较大(主要是数据,数据有1G多,代码约5000行), 无法上传,如需要微信联系(17381925156) 效果图:   相机推进后: 1.1 实现基本的卫片数据浏览 1.2 实现高程数据的浏览 1.3   实现基本的三维操作,平

    2024年02月08日
    浏览(25)
  • GIS数据格式坐标转换(地球坐标WGS84、GCJ-02、火星坐标、百度坐标BD-09、国家大地坐标系CGCS2000)

    地理信息系统 (GIS) 是一个创建、管理、分析和绘制所有类型数据的系统。GIS 将数据连接到地图,将位置数据(事物所在位置)与所有类型的描述性信息(事物在该位置的情况)集成到一起。这可以为适用于自然科学和几乎所有行业的制图和分析提供基础。GIS 帮助用户了解模

    2023年04月16日
    浏览(29)
  • 基于Solidworks的三维光路结构示意图绘制实例演示-技术细节

    基于Solidworks对光路结构进行绘制,最重要的一步是如何 获取光学元件的三维模型 。当准备好三维模型后,第二步则是需要 激光光束 的绘制。最后一步是

    2024年02月11日
    浏览(30)
  • 【Lidar】基于Python的三维点云数据转二维平面+散点图绘制

            最近一直在搞点云相关的操作,有时候在处理点云数据时需要查看处理后的数据是否满足需求,所以就想着写一套展示点云的代码。之前已经分享过如何可视化点云了,感兴趣的可以自己去看下:【Lidar】基于Python的Open3D库可视化点云数据。但是这个是3维展示,不满

    2024年02月21日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包