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.素材图片
![](https://img.haomeiwen.com/i16386400/2696e31ea1307e2a.jpg)
sun.jpg
![](https://img.haomeiwen.com/i16386400/854cf05a21ec6cad.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.运行结果
![](https://img.haomeiwen.com/i16386400/9f337a928f5435d4.png)
屏幕截图 2024-08-11 214621.png
网友评论