<file_sep>#include "solarsystem.hpp"
#include <cstdlib>
#define REST 700
#define REST_Z (REST)
#define REST_Y (-REST)//初始视角在（x,-x,x）处

void SolarSystem::onDisplay(){

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glClearColor(.7f,.7f,.7f,.1f);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(75.0f,1.0f,1.0f,40000000);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  gluLookAt(viewX,viewY,viewZ,centerX,centerY,centerZ,upX,upY,upZ);
  glEnable(GL_LIGHT0);
  glEnable(GL_LIGHTING);
  glEnable(GL_DEPTH_TEST);

  for(int i=0;i<STARS_NUM;i++)
    stars[i]->draw();

  glutSwapBuffers();
}

#define TIMEPAST 1    //假设每次更新都经历了一天
void SolarSystem::onUpdate(){

  for(int i=0;i<STARS_NUM;i++)
    stars[i] ->update(TIMEPAST); //更新星球位置
  this ->onDisplay();//刷新显示
}

#define OFFSET 20

void SolarSystem::onKeyboard(unsigned char key,int x,int y){

  switch (key) {
    case 'w': viewY += OFFSET; break;
    case 's': viewZ += OFFSET; break;
    case 'S': viewZ -= OFFSET; break;
    case 'a': viewX -= OFFSET; break;
    case 'd': viewX += OFFSET; break;
    case 'x': viewY -= OFFSET; break;
    case 'r':
        viewX = 0;viewY = REST_Y;viewZ = REST_Z;
        centerX = centerY = centerZ = 0;
        upX = upY = 0;upZ = 1;
        break;
    case 27:exit(0);break;
    default:break;
  }

}

#define SUN_RADIUS 48.74
#define MER_RADIUS 7.32
#define VEN_RADIUS 18.15
#define EAR_RADIUS 19.13
#define MOO_RADIUS 6.15
#define MAR_RADIUS 10.19
#define JUP_RADIUS 42.90
#define SAT_RADIUS 36.16
#define URA_RADIUS 25.56
#define NEP_RADIUS 24.78

#define MER_DIS 62.06
#define VEN_DIS 115.56
#define EAR_DIS 168.00
#define MOO_DIS 26.01
#define MAR_DIS 228.00
#define JUP_DIS 333.40
#define SAT_DIS 428.10
#define URA_DIS 848.00
#define NEP_DIS 949.10

#define MER_SPEED 87.0
#define VEN_SPEED 225.0
#define EAR_SPEED 365.0
#define MOO_SPEED 30.0
#define MAR_SPEED 687.0
#define JUP_SPEED 1298.4
#define SAT_SPEED 3225.6
#define URA_SPEED 3066.4
#define NEP_SPEED 6014.8

#define SELFROTATE 3

enum STARS {Sun, Mercury, Venus, Earth, Moon,
    Mars, Jupiter, Saturn, Uranus, Neptune};

#define SET_VALUE_3(name,value0,value1,value2) \
                    ((name)[0] = (value0),(name)[1] = (value1),(name)[2] = (value2))

SolarSystem::SolarSystem(){
  viewX = 0;
  viewY = REST_Y;
  viewZ = REST_Z;
  centerX = centerY = centerZ = 0;
  upX = upY = 0;
  upZ = 1;

  GLfloat rgbaColor[3] = {1,0,0};
  stars[Sun] = new LightPlanet(SUN_RADIUS,0,0,SELFROTATE,0,rgbaColor);

  SET_VALUE_3(rgbaColor, .1, .7, 0);
  stars[Venus] = new Planet(VEN_RADIUS,VEN_DIS,VEN_SPEED,SELFROTATE,stars[Sun],rgbaColor);

  SET_VALUE_3(rgbaColor, 0, 1, 0);
  stars[Earth] = new Planet(EAR_RADIUS,EAR_DIS,EAR_SPEED,SELFROTATE,stars[Sun],rgbaColor);

  SET_VALUE_3(rgbaColor, 1, 1, 0);
  stars[Moon] = new Planet(MOO_RADIUS,MOO_DIS,MOO_SPEED,SELFROTATE,stars[Sun],rgbaColor);

  SET_VALUE_3(rgbaColor, 1, .5, .5);
  stars[Mars] = new Planet(MAR_RADIUS,MAR_DIS,MAR_SPEED,SELFROTATE,stars[Sun],rgbaColor);

  SET_VALUE_3(rgbaColor, 1, 1, .5);
  stars[Jupiter] = new Planet(JUP_RADIUS,JUP_DIS,JUP_SPEED,SELFROTATE,stars[Sun],rgbaColor);

  SET_VALUE_3(rgbaColor, .5, 1, .5);
  stars[Saturn] = new Planet(SAT_RADIUS,SAT_DIS,SAT_SPEED,SELFROTATE,stars[Sun],rgbaColor);

  SET_VALUE_3(rgbaColor, .4, .4, .4);
  stars[Uranus] = new Planet(URA_RADIUS,URA_DIS,URA_SPEED,SELFROTATE,stars[Sun],rgbaColor);

  SET_VALUE_3(rgbaColor, .5, .5, 1);
  stars[Neptune] = new Planet(NEP_RADIUS,NEP_DIS,NEP_SPEED,SELFROTATE,stars[Sun],rgbaColor);

}

SolarSystem::~SolarSystem(){
  for(int i = 0; i < STARS_NUM; i++)
      delete stars[i];
}
<file_sep>#ifndef stars_hpp
#define stars_hpp

#ifdef __APPLE__
    #include <GLUT/glut.h>
#else
    #include <GL/glut.h>
#endif

class Star{
public:
  GLfloat radius;//运行半径
  GLfloat speed,selfSpeed;//公转 自转速度
  GLfloat distance;//星球中心与父节点星球中心的距离
  GLfloat rgbaColor[4];//星球的颜色

  Star* parentStar;//父节点颜色

  Star(GLfloat radius,GLfloat distance,GLfloat speed,//构造函数
       GLfloat selfSpeed,Star* parent);

  void drawStar();//对一般的星球的移动 旋转等活动进行绘制

  virtual void draw(){
    drawStar();//提供默认实现 负责调用drawStar()
  }

  virtual void update(long timeSpan);//参数为每次刷新画面时的时间跨度

protected:
  GLfloat alphaSelf, alpha;
};//当前的自转角度  公转角度

class  Planet:public Star{
public:
  Planet(GLfloat radius,GLfloat distance,
    GLfloat speed,GLfloat selfSpeed,
    Star* parent,GLfloat rgbaColor[3]);

void drawPlanet();//增加对具备自身材质的行星绘制材质

virtual void draw(){
  drawPlanet(); drawStar();}//继续向其子类开放重写功能

};

class LightPlanet:public Planet{
public:
  LightPlanet(GLfloat Radius,GLfloat Distance,
    GLfloat Speed,GLfloat SelfSpeed,
    Star* Parent,GLfloat rgbaColor[]);

  void drawLight();//增加对提供光源的恒星绘制光照
  virtual void draw(){
    drawLight();drawPlanet();drawStar();
  }
};

#endif
<file_sep># Shiyanlou
实验楼C++学习项目
<file_sep>#include "stars.hpp"
#include <cmath>

#define PI 3.141592635

Star::Star(GLfloat radius,GLfloat distance,GLfloat speed,GLfloat selfSpeed,Star* parent){
  this->radius = radius;
  this->selfSpeed = selfSpeed;
  this->alphaSelf = this->alpha = 0;
  this->distance = distance;

  for(int i= 0;i < 4,i++;)
    this->rgbaColor[i] = 1.0f;

  this->parentStar = parent;
  if(speed > 0)
    this->speed = 360.0f / speed;
  else
    this->speed = 0.0f;
}

void Star::drawStar(){

  glEnable(GL_LINE_SMOOTH);
  glEnable(GL_BLEND);

  int n = 1440;

  glPushMatrix();//保存OpenGL当前的工作环境
  {
    // 公转

    // 如果是行星，且距离不为0，那么 且向原点平移一个半径
    // 这部分用于处理卫星
    if (parentStar != 0 && parentStar -> distance >0){
      //将绘制的图形沿Z轴旋转alpha
      glRotatef(parentStar -> alpha,0,0,1);
      //X轴方向上平移distance,y,z 方向不变
      glTranslatef(parentStar ->distance,0.0,0.0);
    }
    //绘制运行轨道
    glBegin(GL_LINES);
    for(int i=0;i<n;++i)
      glVertex2f(distance * cos(2*PI*i/n),distance*sin(2*PI*i/n));
    glEnd();
    glRotatef(alpha,0,0,1);
    glTranslatef(distance,0.0,0.0);
    glRotatef(alphaSelf,0,0,1);
    //绘制行星颜色
    glColor3f(rgbaColor[0],rgbaColor[1],rgbaColor[2]);
    glutSolidSphere(radius,40,32);
  }
  glPopMatrix();//恢复当前矩阵环境
}

void Star::update(long timeSpan){
  alpha += timeSpan * speed;
  alphaSelf += selfSpeed;
}

Planet::Planet(GLfloat radius,GLfloat distance,GLfloat speed,
  GLfloat selfSpeed,Star* parent,GLfloat rgbaColor[3]):
  Star(radius,distance,speed,selfSpeed,parent){
    rgbaColor[0] = rgbaColor [0];
    rgbaColor[1] = rgbaColor [1];
    rgbaColor[2] = rgbaColor [2];
    rgbaColor[3] = 1.0f;
  }
//不发光的星球
void Planet::drawPlanet(){
  GLfloat mat_ambient[] = {0.0f,0.0f,0.5f,1.0f};
  GLfloat mat_diffuse[] = {0.0f,0.0f,0.5f,1.0f};
  GLfloat mat_specular[] = {0.0f,0.0f,1.0f,1.0f};
  GLfloat mat_emission[] = {rgbaColor[0],rgbaColor[1],rgbaColor[2],rgbaColor[3]};
  GLfloat mat_shininess = 90.0f;

  glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
  glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);
  glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
  glMaterialfv(GL_FRONT,GL_EMISSION,mat_emission);
  glMaterialf(GL_FRONT,GL_SHININESS,mat_shininess);
}

LightPlanet::LightPlanet(GLfloat radius,GLfloat distance,GLfloat speed,
  GLfloat selfSpeed,Star* parent,GLfloat rgbaColor[3]):
  Planet(radius,distance,speed,selfSpeed,parent,rgbaColor){
    ;
  }

void LightPlanet::drawLight(){

  GLfloat light_position[] = {0.0f,0.0f,0.0f,1.0f};
  GLfloat light_ambient[] = {0.0f,0.0f,0.0f,1.0f};
  GLfloat light_diffuse[] = {1.0f,1.0f,1.0f,1.0f};
  GLfloat light_specular[] = {1.0f,1.0f,1.0f,1.0f};
  glLightfv(GL_LIGHT0,GL_POSITION,light_position);
  glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient);
  glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse);
  glLightfv(GL_LIGHT0,GL_SPECULAR,light_specular);

}
<file_sep>/*
思路：
1,初始化星球对象
2.初始化OpenGL引擎，实现onDraw和onUpdate;
3.星球应该自己负责处理自己的属性,绕行关系，变换相关绘制，因此在设计星球的类时应该提供一个绘制draw()的方法；
4.星球也应该处理自己自转公转等更新显示的绘制，因此提供更新方法update();
5.在onDraw（）中应该调用星球draw()方法；
6.在onUpdate()中调用星球update()方法；
7.在onKeyboard()调整整个太阳系的显示；
*/
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include "solarsystem.hpp"

//创建图形窗口的基本宏
#define WINDOW_X_POS 50
#define WINDOW_Y_POS 50
#define WIDTH 700
#define HEIGHT 700

SolarSystem solarsystem;
 //用于注册GLUT的回调
void onDisplay(void){
  solarsystem.onDisplay();
}

void onUpdate(void){
  solarsystem.onUpdate();
}

void onKeyboard(unsigned char key,int x,int y) {
  solarsystem.onKeyboard(key,x,y);
}

int main(int argc,char* argv[]){
  glutInit(&argc,argv);    //对GLUT进行初始化，并处理所有的命令行参数
  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);//使用RGBA模式韩式索引模式；双缓冲窗口
  glutInitWindowPosition(WINDOW_X_POS,WINDOW_Y_POS);//设置窗口被创建时左上角位于屏幕上的位置
  glutCreateWindow("My solarsystem");//窗口的标题
  glutDisplayFunc(onDisplay);//
  glutIdleFunc(onUpdate);
  glutKeyboardFunc(onKeyboard);
  glutMainLoop();
  return 0;
}
<file_sep>#ifndef solarsystem_hpp
#define solarsystem_hpp

#ifdef __APPLE__
    #include <GLUT/glut.h>
#else
    #include<GL/glut.h>
#endif

#include "stars.hpp"

//#define TIMEPAST 1
//#define SELFROTATE 3

#define STARS_NUM 10

class SolarSystem{

public:

  SolarSystem();
  ~SolarSystem();

  void onDisplay();
  void onUpdate();
  void onKeyboard(unsigned char key,int x,int y);

private:
  Star* stars[STARS_NUM];

//定义观察视角的参数
  GLdouble viewX, viewY, viewZ;
  GLdouble centerX, centerY, centerZ;
  GLdouble upX, upY, upZ;
};

#endif
<file_sep>//白色方框
/*#include <GL/glut.h>
void display(){
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_POLYGON);
    glVertex2f(-0.5,-0.5);
    glVertex2f(-0.5,0.5);
    glVertex2f(0.5,0.5);
    glVertex2f(0.5,-0.5);
    glEnd();
    glFlush();
}
int main(int argc,char *argv[]){
    glutInit(&argc,argv);
    glutCreateWindow("Simple");
    glutDisplayFunc(display);
    glutMainLoop();
    return 0;
}
*/


// 红色网格状茶壶
// 编译命令  gcc -o test test.c -lGL -lGLU -lglut

#include <GL/glut.h>

  void init(void)
   {
       glClearColor(0.0, 0.0, 0.0, 0.0);
       glMatrixMode(GL_PROJECTION);
       glOrtho(-5, 5, -5, 5, 5, 15);
       glMatrixMode(GL_MODELVIEW);
       gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);

       return;
   }

   void display(void)
   {
       glClear(GL_COLOR_BUFFER_BIT);
       glColor3f(1.0, 0, 0);
       glutWireTeapot(3);
       glFlush();

       return;
   }

   int main(int argc, char *argv[])
   {
       glutInit(&argc, argv);
       glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
       glutInitWindowPosition(0, 0);
       glutInitWindowSize(300, 300);
       glutCreateWindow("OpenGL 3D View");
       init();
       glutDisplayFunc(display);
       glutMainLoop();

       return 0;
   }
