美文网首页
c++ opengl绘制地球围绕太阳旋转

c++ opengl绘制地球围绕太阳旋转

作者: 一路向后 | 来源:发表于2024-08-10 21:47 被阅读0次

1.源码实现

#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <cmath>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

//void glGenerateMipmap (GLenum target);

float angle = 0.0;
float angle_earth = 0.0;
float earth_k = 0;

GLuint textureID;
GLuint textureEarthID;

float R_SUN = 0.4;
float R_EARTH = 30 * 6371 / 696000.0 * R_SUN;
float A_EARTH = 149600000.0 / 696000.0 / 100 * R_SUN;
float E_EARTH = 0.016722;
float A_E_ORBIT = 23.43;

void init()
{
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_MULTISAMPLE);
    //glEnable(GL_LIGHTING);
    //glEnable(GL_LIGHT0);
    //glEnable(GL_TEXTURE_2D);

    glDepthFunc(GL_LEQUAL);
    glClearDepth(1.0f);

    //生成纹理对象
    glGenTextures(1, &textureID);

    glBindTexture(GL_TEXTURE_2D, textureID);

    //加载图片并设置纹理参数
    int width, height, channels;
    unsigned char *image = stbi_load("sun.jpg", &width, &height, &channels, STBI_rgb);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);

    glGenerateMipmapEXT(GL_TEXTURE_2D);

    stbi_image_free(image);

    //生成纹理对象
    glGenTextures(1, &textureEarthID);

    glBindTexture(GL_TEXTURE_2D, textureEarthID);

    //加载图片并设置纹理参数
    //int width, height, channels;
    image = stbi_load("earth.jpg", &width, &height, &channels, STBI_rgb);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);

    glGenerateMipmapEXT(GL_TEXTURE_2D);

    stbi_image_free(image);
}

void update(int value)
{
    angle += 0.2f;
    angle_earth += (24.47f * 0.2f);

    earth_k += (1 / (24.47f * 0.2f)) * 5.0;

    if(angle_earth > 360)
    {
        angle_earth -= 360;
    }

    if(earth_k > 360)
        earth_k -= 360;

    if(angle > 360)
    {
        angle -= 360;
    }

    glutPostRedisplay();

    glutTimerFunc(32, update, 0);
}

void drawEllipse(float centerX, float centerY, float majorAxis, float eccentricity, int numSegments)
{
    float minorAxis = majorAxis * sqrt(1-eccentricity*eccentricity);

    glBegin(GL_LINE_LOOP);

    glColor3f(0.0, 1.0, 1.0);

    for(int i=0; i<numSegments; i++)
    {
        float theta = 2.0f * 3.1415926f * float(i) / float(numSegments);
        float x = majorAxis * cosf(theta);
        float y = minorAxis * sinf(theta);

        glVertex2f(x+centerX, y+centerY);
    }

    glEnd();
}

void getEllipsePos(float centerX, float centerY, float majorAxis, float eccentricity, int numSegments, int k, float &x, float &y)
{
    float minorAxis = majorAxis * sqrt(1-eccentricity*eccentricity);
    float theta = 2.0f * 3.1415926f * float(k) / float(numSegments);

    x = majorAxis * cosf(theta);
    y = minorAxis * sinf(theta);
}

void drawSphere()
{
    glColor3f(1.0, 1.0, 1.0);

    GLUquadric *quadric = gluNewQuadric();
    gluQuadricTexture(quadric, GL_TRUE);
    gluQuadricDrawStyle(quadric, GLU_FILL);
    gluQuadricOrientation(quadric, GLU_OUTSIDE);
    gluQuadricNormals(quadric, GLU_SMOOTH);

    gluSphere(quadric, R_SUN, 100, 100);

    gluDeleteQuadric(quadric);
}

void drawEarthSphere()
{
    glColor3f(1.0, 1.0, 1.0);

    GLUquadric *quadric = gluNewQuadric();
    gluQuadricTexture(quadric, GL_TRUE);
    gluQuadricDrawStyle(quadric, GLU_FILL);
    gluQuadricOrientation(quadric, GLU_OUTSIDE);
    gluQuadricNormals(quadric, GLU_SMOOTH);

    gluSphere(quadric, R_EARTH, 100, 100);

    gluDeleteQuadric(quadric);
}

void display()
{
    float earth_x, earth_y;

    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();

    glPushMatrix();

    glRotatef(90, 1.0f, 0.0f, 0.0f);
    glRotatef(30, 0.0f, 0.0f, 1.0f);
    glRotatef(A_E_ORBIT, 0.0f, 1.0f, 0.0f);

    drawEllipse(0.0, 0.0, A_EARTH, E_EARTH, 100);

    glPushMatrix();

    getEllipsePos(0.0, 0.0, A_EARTH, E_EARTH, 360, earth_k, earth_x, earth_y);

    glTranslatef(earth_x, earth_y, 0.0f);
    glRotatef(90, 0.0f, 0.0f, 1.0f);
    glRotatef(-A_E_ORBIT, 1.0f, 0.0f, 0.0f);
    glRotatef(angle_earth, 0.0f, 0.0f, 1.0f);

    glEnable(GL_TEXTURE_2D);

    glBindTexture(GL_TEXTURE_2D, textureEarthID);

    glBegin(GL_TRIANGLES);

    drawEarthSphere();

    glEnd();

    glPopMatrix();
    glPopMatrix();

    glPushMatrix();

    glRotatef(-angle, 0.0f, 1.0f, 0.0f);
    glRotatef(90, 0.0f, 0.0f, 1.0f);

    glEnable(GL_TEXTURE_2D);

        glBindTexture(GL_TEXTURE_2D, textureID);

    glBegin(GL_TRIANGLES);

    drawSphere();

    glEnd();

    glDisable(GL_TEXTURE_2D);

    glPopMatrix();

    glFlush();

    glutSwapBuffers();
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH|GLUT_MULTISAMPLE);
    glutInitWindowSize(800, 800);

    glutCreateWindow("OpenGL The Sun and Earth");

    init();
    glutDisplayFunc(display);
    glutTimerFunc(16, update, 0);

    glutMainLoop();

    return 0;
}

2.素材图片

sun.jpg
earth.jpg

3.编译源码

$ g++ -o example example.cpp -std=c++11 -I/opt/apps/wxwidget/include -L/opt/apps/wxwidget/lib -lGL -lGLU -lglut -Wl,-rpath=/opt/apps/wxwidget/lib

4.运行结果

屏幕截图 2024-08-11 214621.png

相关文章

  • 好的习惯是一点一滴养成的

    我们知道,宇宙中普遍存在一种惯性。 比方,地球必须围绕太阳旋转,月亮一直围绕地球旋转。 惯性一旦形成,若想改变,是...

  • 宇宙中的太阳

    置身地球看太阳, 它从东方升起,从西方落下。 置身太空看太阳,它是宇宙的中心, 地球在围绕它旋转。 置身地球看太阳...

  • 只想做围绕着你旋转的小行星——水彩插画技法解读1

    地球围绕着太阳旋转,太阳围着银河系旋转,而我只想围绕着你这颗星球旋转。 今天的水彩画主体是三个星球,错落有致,大小...

  • JavaScript设计模式之组合模式

    我们知道地球和一些其他行星围绕着太阳旋转,也知道在一个原子中,有许多电子围绕着原子核旋转。我曾经想象,我们的太阳系...

  • 无题

    太阳即将落山, 黑夜潜伏着降临, 人群开始骚动, 路灯默默张开眼睛…… 地球闪烁着微弱的烛火, 缓慢地围绕太阳旋转...

  • JavaScript 设计模式之组合模式

    引 我们知道地球和一些其他行星围绕着太阳旋转,也知道在一个原子中,有许多电子围绕着原子核旋转。我曾经想象,我们的太...

  • 地球为什么在第三轨道上?

    太阳系有八大行星,其中地球在第三轨道上围绕着太阳旋转运动,要是问:地球为什么在第三轨道上运动呢?这是因为,以前太阳...

  • 我们一起数星星,看月亮

    45亿年前,围绕年幼的太阳旋转的尘埃和岩石经过碰撞形成了地球。 在年轻的太阳系中,地球还得独自承受着彗星和小行星的...

  • 星空的证明

    永不变化的星空 群星围绕北极星旋转,形成完美的圆圈星空轨迹图。 如果按照地球论,地球、太阳、银河系都在不断移动,我...

  • 从一株蔷薇追溯

    蔷薇所需的水从哪来的?45亿年前,围绕太阳旋转的碎石和尘埃聚合成为行星,地球就是由这些靠近太阳、正向太阳聚拢的物质...

网友评论

      本文标题:c++ opengl绘制地球围绕太阳旋转

      本文链接:https://www.haomeiwen.com/subject/hxjlkjtx.html