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

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
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容