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 <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();
}

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,429评论 25 707
  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 12,691评论 2 59
  • 最近为了给xmake实现预编译头文件的支持,研究了下各大主流编译器处理预编译头的机制以及之间的一些差异。 现在的大...
    waruqi阅读 1,556评论 0 51
  • 搬运自CSDN博客:向MFC嵌入OpenGL 本人上计算机图形学课时要做的大作业是基于MFC框架用OpenGL实现...
    hmta_dhs阅读 4,894评论 0 5
  • 明州当地时间晚上八点,明大主场对阵俄勒冈州立。 作为美式文化无法分割的元素之一的橄榄球赛,据说凡有赛...
    石筒子阅读 192评论 0 0