Building a 3D Digital Earth with C++, Qt, and OpenGL

Introduction

This article demonstrates how to create a 3D digital Earth visualization using C++, the Qt framework, and OpenGL. We will cover setting up the project, rendering a spherical Earth, and entegrating map tile imagery.

Project Setup

To begin, create a new Qt Widgets Application project. Ensure you have the necessary development tools installed, including Qt and a C++ compiler.

Configuring the .pro File

The project file (.pro) needs to be configured to include the required libraries and define the target architecture.

QT += core gui widgets opengl

# Detect 32-bit or 64-bit architecture
greaterThan(QT_MAJOR_VERSION, 4) {
    TARGET_ARCH = $${QT_ARCH}
} else {
    TARGET_ARCH = $${QMAKE_HOST.arch}
}

contains(TARGET_ARCH, x86_64) {
    ARCHITECTURE = x64
} else {
    ARCHITECTURE = x86
}

# Link necessary OpenGL libraries
LIBS += -lopengl32 -lglu32

# For MSVC, you might need to specify library paths
win32 {
    contains(ARCHITECTURE, x64) {
        LIBS += -L"C:/path/to/your/qt/msvc2017_64/lib" -lfreeglut
    } else {
        LIBS += -L"C:/path/to/your/qt/msvc2017_32/lib" -lfreeglut
    }
}

Including Headers

In you're source files, include the necessary OpenGL headers:

#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
#include <QOpenGLVertexArrayObject>
#include <QMatrix4x4>
#include <QVector>
#include <QVector3D>
#include <QOpenGLTexture>
#include <QImage>

Rendering the Earth Sphere

The Earth can be approximated as a sphere. We'll generate vertices based on latitude and longitude to form a mesh.

class EarthWidget : public QOpenGLWidget, protected QOpenGLFunctions {
    Q_OBJECT

public:
    explicit EarthWidget(QWidget *parent = nullptr);

protected:
    void initializeGL() override;
    void paintGL() override;
    void resizeGL(int w, int h) override;

private:
    void generateSphere(float radius, int slices, int stacks);
    void loadTexture(const QString &path);

    QOpenGLShaderProgram *program;
    QOpenGLVertexArrayObject vao;
    QOpenGLBuffer vbo;
    QOpenGLTexture *texture;
    QMatrix4x4 projection;
    QMatrix4x4 view;
    QVector<QVector3D> vertices;
    QVector<QVector2D> texCoords;
};

void EarthWidget::generateSphere(float radius, int slices, int stacks) {
    vertices.clear();
    texCoords.clear();

    for (int i = 0; i <= stacks; ++i) {
        float lat = M_PI * (-0.5 + (float)(i) / stacks);
        float sinLat = sin(lat);
        float cosLat = cos(lat);

        for (int j = 0; j <= slices; ++j) {
            float lon = 2 * M_PI * (float)(j) / slices;
            float sinLon = sin(lon);
            float cosLon = cos(lon);

            float x = cosLat * cosLon;
            float y = sinLat;
            float z = cosLat * sinLon;

            vertices.append(QVector3D(x * radius, y * radius, z * radius));
            texCoords.append(QVector2D(1.0f - (float)(j) / slices, (float)(i) / stacks));
        }
    }
}

Loading Map Tiles

We'll use online map tile services to texture the sphere. Here's an example of loading a tile from a provider.

void EarthWidget::loadTexture(const QString &path) {
    if (texture) {
        delete texture;
    }
    texture = new QOpenGLTexture(QImage(path).mirrored());
    texture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear);
    texture->setMagnificationFilter(QOpenGLTexture::Linear);
    update();
}

Main Application

Create the main window and instantiate the Earth widget.

#include <QApplication>
#include "earthwidget.h"

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    EarthWidget earth;
    earth.resize(800, 600);
    earth.show();

    return app.exec();
}

Accessing Online Map Tiles

Various map tile providers offer imagery that can be used. Here are some examples of tile URLs:

  • ArcGIS: https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer/tile/{z}/{y}/{x}
  • Google Maps: https://mt1.google.cn/vt/lyrs=s&x={x}&y={y}&z={z}
  • OpenStreetMap: https://c.tile.openstreetmap.org/{z}/{x}/{y}.png
  • Mapbox: https://a.tiles.mapbox.com/v4/mapbox.satellite/{z}/{x}/{y}.png?access_token={your_key}

Replace {z}, {x}, and {y} with the appropriate tile coordinates and zoom level.

Tags: Qt OpenGL C++ 3D Rendering gis

Posted on Mon, 26 Oct 2026 16:28:39 +0000 by Jeb.