美文网首页
opengl实现简陋的日落(sunset)日升(sunrise)

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

作者: 嬴小政今天好好吃饭了吗 | 来源:发表于2018-11-11 10:49 被阅读0次

    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 <math.h>
    #include <GL/glut.h>
    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 <math.h>
    #include <GL/glut.h>
    
    #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)

          本文链接:https://www.haomeiwen.com/subject/pfazxqtx.html