现在的位置: 首页 > 综合 > 正文

opengl: 太阳地球和月亮

2018年04月08日 ⁄ 综合 ⁄ 共 2785字 ⁄ 字号 评论关闭

// Solar.c
// OpenGL SuperBible
// Demonstrates OpenGL nested coordinate transformations
// and perspective
// Program by Richard S. Wright Jr.

/*原作者: Richard S. Wright Jr, 我在这里学习翻译一下  */

#include "../../Common/OpenGLSB.h" // System and OpenGL Stuff
#include <math.h>

// Lighting values
GLfloat  whiteLight[] = { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat  sourceLight[] = { 0.8f, 0.8f, 0.8f, 1.0f };
//光源位置
GLfloat  lightPos[] = { 0.0f, 0.0f, 0.0f, 1.0f };

// 画场景的回调函数
void RenderScene(void)
 {
 // 地球和月亮旋转角度
 static float fMoonRot = 0.0f;
 static float fEarthRot = 0.0f;

 // 清除颜色缓存和深度缓存
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

 // 保存矩阵
 glMatrixMode(GL_MODELVIEW);
 glPushMatrix();

 //向远移动场景 -移动到300 处,为地球绕太阳旋转腾出空间 
 glTranslatef(0.0f, 0.0f, -300.0f); 
 
 //设置材料,颜色
 // 太阳
    glDisable(GL_LIGHTING);
 glColor3ub(255, 255, 0);
 //在屏幕中心画球体半径15
 glutSolidSphere(15.0f, 30, 17);
    glEnable(GL_LIGHTING);

 //画完太阳,把光源置于屏幕中心!
 glLightfv(GL_LIGHT0,GL_POSITION,lightPos);

 //沿y=1旋转坐标系统 fEarthRot 角度
 glRotatef(fEarthRot, 0.0f, 1.0f, 0.0f);

 //画地球
 glColor3ub(0,0,255);
 //在距离太阳105处画半径15地球
 glTranslatef(105.0f,0.0f,0.0f);
 glutSolidSphere(15.0f, 30, 17);

 //画围绕地球旋转的月亮
 glColor3ub(200,200,200);
 //沿着y=1旋转 fMoonRot 角度
 glRotatef(fMoonRot,0.0f, 1.0f, 0.0f);
 //在距离地球30地方画半径为6月亮
 glTranslatef(30.0f, 0.0f, 0.0f);
 //月球旋转角度增量
 fMoonRot+= 15.0f;
 if(fMoonRot > 360.0f)
  fMoonRot = 0.0f;

 glutSolidSphere(6.0f, 30, 17);

 //还原矩阵
 glPopMatrix(); // Modelview matrix

 //地球旋转角度增量
 fEarthRot += 5.0f;
 if(fEarthRot > 360.0f)
  fEarthRot = 0.0f;

 //显示图像
 glutSwapBuffers();
 }

// 渲染初始化函数,上下文环境设置.
void SetupRC()
 {
 //设置灯光和坐标
 //启用深度测试,有遮挡的效果
 glEnable(GL_DEPTH_TEST);
 //逆时针为多边形正面
 glFrontFace(GL_CCW);
 //启用剔除效果,多边形背面不用光照处理
 glEnable(GL_CULL_FACE);  

 //启动灯光效果
 glEnable(GL_LIGHTING);

 //设置灯泡0
 //环境光颜色
 glLightModelfv(GL_LIGHT_MODEL_AMBIENT,whiteLight);
 //散射光强度
 glLightfv(GL_LIGHT0,GL_DIFFUSE,sourceLight);
 //光源位置
 glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
 //开灯
 glEnable(GL_LIGHT0);

 //使用颜色材质
 glEnable(GL_COLOR_MATERIAL);
 
 //设置材料反射属性, 以相同的强度反射环境光和散射光
 glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

 //黑色背景
 glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
    }

void TimerFunc(int value)
    {
    glutPostRedisplay();
    glutTimerFunc(100, TimerFunc, 1);
    }

void ChangeSize(int w, int h)
    {
    GLfloat fAspect;

    //防止被0除
    if(h == 0)
        h = 1;

    //设置视口大小
    glViewport(0, 0, w, h);

    //计算屏幕比例
    fAspect = (GLfloat)w/(GLfloat)h;

    //指定投影矩阵为当前矩阵
    glMatrixMode(GL_PROJECTION);
 //把坐标系重置为视觉坐标,即屏幕中心
    glLoadIdentity();

    //设置眼睛睁开的大小(摄像机焦距一般45合适,看到最近1,最远425处的东西),
    gluPerspective(45.0f, fAspect, 1.0, 425.0);

    //制定模型视图矩阵为当前矩阵
    glMatrixMode(GL_MODELVIEW);
 //把坐标系重置为视觉坐标,即屏幕中心
    glLoadIdentity();
    }

int main(int argc, char* argv[])
 {
 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
        glutInitWindowSize(800, 600);
 glutCreateWindow("Earth/Moon/Sun System");
 glutReshapeFunc(ChangeSize);
 glutDisplayFunc(RenderScene);
        glutTimerFunc(250, TimerFunc, 1);
 SetupRC();
 glutMainLoop();

 return 0;
 }

 

效果如下:

抱歉!评论已关闭.