opengl实现简陋的日落(sunset)日升(sunrise)

1.在visual studio 2017中搭建OpenGL环境参考博客:
https://www.cnblogs.com/FireCuckoo/p/7826615.html
注意博文最后的评论,将把#include "stdafx.h"换为#include"pch.h"才能运行成功!
2.日升

sunset

代码:

#include "pch.h"
#include 
#include 
const GLfloat PI = 3.1415926;
using namespace std;
static GLdouble a, b;

//这个函数将要被用在drawCircle中,控制颜色的变化以及保证glColor3f参数上限为1.0
GLdouble compareColor(GLdouble colorControl, GLdouble divide) {
    if (colorControl >= divide)
        colorControl = divide;
    else colorControl = colorControl + 2;
    return colorControl;
}

//画一个渐变的圆,不适合太阳,因为颜色深到浅变化方向不一样
void drawCircle(GLdouble radius, GLdouble divide,   //divide 决定了这个圆被分成多少份,有多smooth
    GLdouble redColorControl,
    GLdouble greenColorControl,
    GLdouble blueColorControl,          //colorcontrol 被用来控制颜色的变化
    GLdouble x, GLdouble y,
    GLdouble ac)                //x and y 被用来控制cloud的坐标
{
    for (GLint k = 0; k <= divide; k++)    //先画了一半圆
    {
        a = ac*radius * cos((k / 2 / divide) * 2 * PI);      //ac用来控制椭圆的方向,大于1小于1椭圆方向不同
        b = radius * sin((k / 2 / divide) * 2 * PI);
        glColor3f((redColorControl / divide), (greenColorControl / divide), (blueColorControl / divide));
        glVertex3d(b + x, -a + y, 0.0);             //attention!整个屏幕坐标原点是中心
                                                                                      //且改变a,b的前后顺序或者正负圆能从不同起点开始画,渐变效果不同
        redColorControl = compareColor(redColorControl, divide);
        greenColorControl = compareColor(greenColorControl, divide);
        blueColorControl = compareColor(blueColorControl, divide);
    }
    for (GLint k = 0; k <= divide; k++)
    {
        a = ac*radius * cos((k / 2 / divide) * 2 * PI);
        b = radius * sin((k / 2 / divide) * 2 * PI);
        glColor3f((redColorControl / divide), (greenColorControl / divide), (blueColorControl / divide));
        glVertex3d(-b + x, a + y, 0.0);             //attention!整个屏幕坐标原点是中心
        redColorControl = compareColor(redColorControl, divide);
        greenColorControl = compareColor(greenColorControl, divide);
        blueColorControl = compareColor(blueColorControl, divide);
    }
}


void drawBackGround() {
    glBegin(GL_POLYGON);

    glColor3f(0.9, 1.0, 1.0);    //左下
    glVertex3f(-1, -1, -1);

    glColor3f(0.9, 0.9, 1.0);    //右下
    glVertex3f(1, -1, 0);

    glColor3f(0.0, 0.5, 1.0);    //右上
    glVertex3f(1, 1, 0);

    glColor3f(1.0, 1.0,0.8);    //左上
    glVertex3f(-1, 1, 0);

    glEnd();
}

//画太阳
void drawSun(GLdouble radius, GLdouble divide,  GLdouble ColorControl)          
{
    GLdouble location = 0.85;
    for (GLint k = 0; k <= divide; k++)
    {
        a = radius * cos((k / 2 / divide) * 2 * PI);
        b = radius * sin((k / 2 / divide) * 2 * PI);
        glColor3f((ColorControl / divide), (ColorControl / divide), (ColorControl / divide)-0.1);    //减出去的0.1或者包括下面的0.2是用来控制颜色的
        glVertex3d(-a - location, b + location, 0.0);               //attention!太阳的坐标 (-1,1)
        ColorControl = compareColor(ColorControl, divide);
    }
    for (GLint k = 0; k <= divide; k++)
    {
        a = radius * cos((k / 2 / divide) * 2 * PI);
        b = radius * sin((k / 2 / divide) * 2 * PI);
        glColor3f((ColorControl / divide), (ColorControl / divide), (ColorControl / divide)-0.1);
        glVertex3d(a - location, -b + location, 0.0);               
    }
}

//两个建筑物
void drawBuldings(GLfloat x, GLfloat y) {
    //右建筑
    glBegin(GL_POLYGON);

    glColor3f(0.7, 0.7, 0.7);
    glVertex3f(x, y, 0);    //左下

    glColor3f(0.9, 0.9, 0.9);
    glVertex3f(x + 0.5, y, 0);    //右下

    glColor3f(1.0, 1.0, 1.0);
    glVertex3f(x + 0.5, y + 0.9, 0);    //右上

    glColor3f(0.9, 0.9, 0.9);
    glVertex3f(x, y + 0.9, 0);    //左上

    glEnd();

    //左建筑
    x = x + 0.5;
    glBegin(GL_POLYGON);

    glColor3f(0.8, 0.8, 0.8);
    glVertex3f(x, y, 0);    //左下

    glColor3f(0.9, 0.9, 0.9);
    glVertex3f(x + 0.3, y, 0);    //右下

    glColor3f(1.0, 1.0, 1.0);
    glVertex3f(x + 0.3, y + 0.4, 0);    //右上

    glColor3f(0.9, 0.9, 0.9);
    glVertex3f(x, y + 0.4, 0);    //左上

    glEnd();
}

//云
void drawCloud() {
    GLint countx;
    GLint county;           //控制每朵云的坐标
    for (county = 0; county < 2; county++) {        //云有两层
        for (countx = 0; countx < 3; countx++) {
            glBegin(GL_POLYGON);
            drawCircle((0.4 - county / 10.0) / 2 + 0.05, 100, county * 10.0 + 50, 75, 75, countx * 0.3 + county * 0.15, 0.5 + county * 0.15,0.6);
            glEnd();
        }
    }
}

//草丛
void drawGrass() {
    GLint countx;
    GLint county;       //控制每片草的坐标
    for (county = 0; county < 3; county++) {        //草有三层
        for (countx = 0; countx <3; countx++) {
            glBegin(GL_POLYGON);
            drawCircle((0.4 - county / 10.0) / 4 + 0.05, 100,0, 100,  40,  countx * 0.5 +  county * 0.15-0.4, -1 + county * 0.1,1.5);    //drawCircle里面的参数比较复杂,需要一次一次尝试
            glEnd();
        }
    }
}

void init() {
    glClearColor(1.0, 1.0, 1.0, 1.0);
}
void displayFcn(void) {
    glClear(GL_COLOR_BUFFER_BIT);

    drawBackGround();

    glBegin(GL_POLYGON);
    drawSun(0.18, 100, 70);
    glEnd();

    drawBuldings(-0.8, -1.0);

    glBegin(GL_POLYGON);
    drawCloud();
    glEnd();
    
    glBegin(GL_POLYGON);
    drawGrass();
    glEnd();

    glFlush();
}

void main(GLint argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(window_width, window_height);
    glutCreateWindow("Sunrise");

    init();
    glutDisplayFunc(displayFcn);
    glutMainLoop();
}

3.日落(采用全英文注释,改变日升中的一些颜色值就可以实现)


sunset
#include "pch.h"
#include 
#include 

#define window_width 500
#define window_height 500

const GLfloat PI = 3.1415926;
using namespace std;
static GLdouble a, b;

//this functionwill be used in the function drawCircle
GLdouble compareColor(GLdouble colorControl, GLdouble divide) {
    if (colorControl >= divide)
        colorControl = divide;
    else colorControl = colorControl + 2;
    return colorControl;
}

//can not be used to draw sun
void drawCircle(GLdouble radius, GLdouble divide,   //divide is to control the number of accuracy of the circle(how smooth th circle is)
    GLdouble redColorControl,
    GLdouble greenColorControl,
    GLdouble blueColorControl,          //colorcontrol is used to control the range of color change
    GLdouble x, GLdouble y,             //x and y are use to control the location of the cloud
    GLdouble ac)                        //to create an ellipse
{
    for (GLint k = 0; k <= divide; k++)
    {
        a = radius * cos((k / 2 / divide) * 2 * PI);
        b = ac * radius * sin((k / 2 / divide) * 2 * PI);
        glColor3f((redColorControl / divide) - 0.2, (greenColorControl / divide) - 0.3, (blueColorControl / divide) - 0.4);
        glVertex3d(a + x, b + y, 0.0);              //attention!the center is (0,0)
        redColorControl = compareColor(redColorControl, divide);
        greenColorControl = compareColor(greenColorControl, divide);
        blueColorControl = compareColor(blueColorControl, divide);
    }
    for (GLint k = 0; k <= divide; k++)
    {
        a = radius * cos((k / 2 / divide) * 2 * PI);
        b = ac * radius * sin((k / 2 / divide) * 2 * PI);
        glColor3f((redColorControl / divide) - 0.2, (greenColorControl / divide) - 0.3, (blueColorControl / divide) - 0.4);
        glVertex3d(-a + x, -b + y, 0.0);                
        redColorControl = compareColor(redColorControl, divide);
        greenColorControl = compareColor(greenColorControl, divide);
        blueColorControl = compareColor(blueColorControl, divide);
    }
}


void drawBackGround() {
    glBegin(GL_POLYGON);

    glColor3f(1.0, 0.8, 0.0);
    glVertex3f(-1, -1, -1);

    glColor3f(0.1, 0.5, 0.6);
    glVertex3f(1, -1, 0);

    glColor3f(0.0, 0.5, 1.0);
    glVertex3f(1, 1, 0);

    glColor3f(1.0, 0.2, 0.0);
    glVertex3f(-1, 1, 0);

    glEnd();
}

//sun
void drawSun(GLdouble radius, GLdouble divide,      //divide is to control the number of accuracy of the circle(how smooth th circle is)
    GLdouble ColorControl)                          //colorcontrol is used to control the range of color change
{
    GLdouble location = 0.85;
    for (GLint k = 0; k <= divide; k++)
    {
        a = radius * cos((k / 2 / divide) * 2 * PI);
        b = radius * sin((k / 2 / divide) * 2 * PI);
        glColor3f((ColorControl / divide), (ColorControl / divide) - 0.6, (ColorControl / divide) - 0.8);
        glVertex3d(-a - location, b + location, 0.0);               //attention!the center is (0,0),and the sun is (-1,1)
        ColorControl = compareColor(ColorControl, divide);
    }
    for (GLint k = 0; k <= divide; k++)
    {
        a = radius * cos((k / 2 / divide) * 2 * PI);
        b = radius * sin((k / 2 / divide) * 2 * PI);
        glColor3f((ColorControl / divide), (ColorControl / divide) - 0.6, (ColorControl / divide) - 0.8);
        glVertex3d(a - location, -b + location, 0.0);               //attention!the center is (0,0)
    }
}

//building
void drawBuldings(GLfloat x, GLfloat y) {
    //right buliding
    glBegin(GL_POLYGON);

    glColor3f(0.9, 0.7, 0.6);
    glVertex3f(x, y, 0);//left-bottom

    glColor3f(1.0, 0.7, 0.5);
    glVertex3f(x + 0.5, y, 0);//right-bottom

    glColor3f(0.8, 0.7, 0.6);
    glVertex3f(x + 0.5, y + 0.9, 0);//right-top

    glColor3f(1.0, 0.9, 0.9);
    glVertex3f(x, y + 0.9, 0);//left-top

    glEnd();

    //left buliding
    x = x + 0.5;
    glBegin(GL_POLYGON);

    glColor3f(0.9, 0.7, 0.6);
    glVertex3f(x, y, 0);//left-bottom

    glColor3f(0.9, 0.6, 0.5);
    glVertex3f(x + 0.3, y, 0);//right-bottom

    glColor3f(0.8, 0.7, 0.6);
    glVertex3f(x + 0.3, y + 0.4, 0);//right-top

    glColor3f(1.0, 0.9, 0.9);
    glVertex3f(x, y + 0.4, 0);//left-top

    glEnd();
}

//cloud
void drawCloud() {
    GLint countx;
    GLint county;                                   //to control the location of every cloud
    for (county = 0; county < 2; county++) {        //there are 2 floors of cloud 
        for (countx = 0; countx < 3; countx++) {
            glBegin(GL_POLYGON);
            drawCircle((0.4 - county / 10.0) / 2 + 0.05, 100, county * 10.0 + 50, 30, 10, countx * 0.3 + county * 0.15, 0.5 + county * 0.15, 0.6);
            glEnd();
        }
    }
}

//grass
void drawGrass() {
    GLint countx;
    GLint county;                                   //to control the location of every grass
    for (county = 0; county < 3; county++) {        //there are three floors of grass 
        for (countx = 0; countx < 3; countx++) {
            glBegin(GL_POLYGON);
            drawCircle((0.4 - county / 10.0) / 4 + 0.05, 100, 90, 40, 10, countx * 0.5 + county * 0.15 - 0.4, -1 + county * 0.1, 1.5);
            glEnd();
        }
    }
}

void init() {
    glClearColor(1.0, 1.0, 1.0, 1.0);
}
void displayFcn(void) {
    glClear(GL_COLOR_BUFFER_BIT);

    drawBackGround();

    glBegin(GL_POLYGON);
    drawSun(0.18, 100, 60);
    glEnd();

    drawBuldings(-0.8, -1.0);

    glBegin(GL_POLYGON);
    drawCloud();
    glEnd();

    glBegin(GL_POLYGON);
    drawGrass();
    glEnd();

    glFlush();
}

void main(GLint argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(window_width, window_height);
    glutCreateWindow("Sunset");

    init();
    glutDisplayFunc(displayFcn);
    glutMainLoop();
}

注:做出来的不是一般丑,但是有学到东西。

你可能感兴趣的:(opengl实现简陋的日落(sunset)日升(sunrise))