1.在visual studio 2017中搭建OpenGL环境参考博客:
https://www.cnblogs.com/FireCuckoo/p/7826615.html
注意博文最后的评论,将把#include "stdafx.h"换为#include"pch.h"才能运行成功!
2.日升
代码:
#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.日落(采用全英文注释,改变日升中的一些颜色值就可以实现)
#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();
}
注:做出来的不是一般丑,但是有学到东西。