《图形编程技术学习》(二十四)OpenGL入门级日地月模型

一、效果图

《图形编程技术学习》(二十四)OpenGL入门级日地月模型_第1张图片

二、源码

//
//  main.cpp
//  LearnOpenGL
//
//  Created by yingyingzhu on 2019/9/7.
//  Copyright © 2019 yingyingzhu. All rights reserved.
//
#include 
#include 
#include 

using namespace std;


#define PI 3.1415926
void Rotate();
static float year = 0, day = 0,sunYear=0,month=0;
float light_angle = 0;
float light_radius = 8.0;
double x=0,y=0;
double aix_x = 0.0,aix_y = 0.5,aix_z = 0.5;
GLdouble angle = 100.0;

void lPosition()
{
    float y,z;
    y = light_radius*cos(light_angle);
    z = light_radius*sin(light_angle);
    float light_position[] = {3.0,y,z,0.0};
    glLightfv(GL_LIGHT0,GL_POSITION,light_position);
    //void glLightfv (GLenum light, GLenum pname, const GLfloat *params);
    //创建指定的光源,light可以是GL_LIGHT0、GL_LIGHT1,pname定义的是光源的属性,它指定了一个命名参数。params表示表示pname属性将要被设置的值
}

void init(void)
{
    glClearColor(0.0,0.0,0.0,0.0);
    lPosition();
    glShadeModel(GL_SMOOTH);   //将制定的两点颜色进行平滑插值
    glEnable(GL_LIGHTING);     //启用灯源
    glEnable(GL_LIGHT0);       //启用0号灯光源
    glEnable(GL_DEPTH_TEST);   //启用深度测试。根据坐标的远近自动隐蔽被遮挡的图形
    glEnable(GL_COLOR_MATERIAL);  //执行后,图形将根据光线的照耀进行反射。
}

void material_sun()          //设置太阳材质
{
    GLfloat mat_specular[] = {1.0,0.0,0.0,1.0};
    GLfloat mat_shininess[] = {50.0};
    GLfloat lmodel_ambient[] = {1.0,0.0,0.0,1.0};  //太阳颜色为红色
    GLfloat white_light[] = {1.0,1.0,1.0,1.0};
    //指定用于计算的当前材质属性。
    //    void WINAPI glMaterialfv(
    //                             GLenum face,
    //                             GLenum pname,
    //                             const GLfloat *params
    //                             );
    //指定用于光照计算的当前材质属性。参数face的取值GL_FRONT,GL_BACK或GL_FRONT_AND_BACK,指出材质属性将应用于物体的哪面。
    //pname指出要设置的哪种材质属性。param为要设置的属性值,是一个指向数组的指针(向量版本)或一个数值(非向量版本)。只有设置参数值是GL_SHININESS,才能使用非向量版本。
    glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
    glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);
    glMaterialfv(GL_FRONT,GL_DIFFUSE,lmodel_ambient);
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT,lmodel_ambient);
}

void material_moon()
{
    GLfloat mat_specular[] = {1.0,0,0,0.0,1.0};
    GLfloat mat_shininess[] = {50.0};
    GLfloat lmodel_ambient[] = {1.0,1.0,0.0,1.0};
    GLfloat white_light[] = {1.0,1.0,1.0,1.0};
    
    glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
    glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);
    glMaterialfv(GL_FRONT,GL_DIFFUSE,lmodel_ambient);
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT,lmodel_ambient);
}

void material_earth()
{
    GLfloat mat_specular[] = { 1.0, 0.0, 0.0, 1.0 };
    GLfloat mat_shininess[] = { 50.0 };
    GLfloat lmodel_ambient[]={0.1,0.2,0.6,1.0};
    GLfloat white_light[]={1.0, 1.0,1.0, 1.0};
    
    
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, lmodel_ambient);
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
}

void sun()
{
    glPushMatrix();
    material_sun();
    glTranslatef(-15,0,0);
    glRotatef((GLfloat)day,0.0,1.0,0.0);//太阳自转
    glutSolidSphere(10,200,200); //画球体
    glPopMatrix();
}

void earth()
{
    glPushMatrix();
    material_earth();
    glTranslatef(-15,0,0);
        glRotatef((GLfloat) year,aix_x,aix_y,aix_z);
    glTranslatef(15,0,0);
    glTranslatef(-2,0,0);
        glRotatef((GLfloat) day,0.0,1.0,0.0);
    glTranslatef(2,0,0);
        glutSolidSphere(1.0, 20, 16);
    material_moon();
    glRotatef(month/100,0.0,0.0,1.0);
    glTranslatef(2,0.0,0.0);
    glutSolidSphere(0.3,10,10);
    glPopMatrix();
}

void display(void)
{
    lPosition();
    
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    //可以用|运算符组合不同的缓冲标志位,表明要清除的缓冲,上述表示要清除颜色缓冲以及深度缓冲,可以使用以下标志位
    //GL_COLOR_BUFFER_BIT:当前可写的颜色缓冲
    //GL_DEPTH_BUFFER_BIT:深度缓冲
    //GL_ACCUM_BUFFER_BIT:累积缓冲
    //GL_STENCIL_BUFFER_BIT:模板缓冲
    
    sun();
    earth();

    Rotate();
    glutSwapBuffers(); //交换两个缓冲区指针
}


void myidle()
{
    day += 10.0;
    if(day >= 360)
        day = day - 360;
    glutPostRedisplay();
}

void Rotate()          //设置地球的公转周期
{

    //  year=(year+0.8)%360;
    year+=0.08;
    if(year>=360)
        year-=360;
    glutPostRedisplay();
    month+=0.03;
    if(month>=360)
        month-=360;
}

void reshape(int w,int h)
{
    glViewport(0,0,(GLsizei) w,(GLsizei) h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(angle,(GLfloat) w/(GLfloat) h,1.0,200.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslated(0.0, 0.0, -50.0);
}
int main(int argc, char** argv)
{
    cout<

 

你可能感兴趣的:(图形编程技术)