(切记)使用OpenGL画图时首先要创建并显示一个窗口,然后再绘制,这一点新手常常会忘记。

#include "pch.h"
#include<windows.h> //包含了WGL函数
#include<GL/GL.h> //OpenGL库
#include<GL/GLU.h> //OpenGL库
#include<GL/glut.h> //处理窗口管理操作
#include <iostream>
#include<stdio.h> //标准输入输出函数
#include<stdlib.h> //最常用的系统函数
#include<math.h> //数学函数



//初始化操作
void init()
{
	glClearColor(1.0, 1.0, 1.0, 0.0);//清除窗口背景色为白色(red,green,blue,alpha透明度),该背景颜色不显示
	//接下来告诉OpenGL如何将图形投影到显示器中,二维线在OpenGL中被视为三维线的特例进行处理
	glMatrixMode(GL_PROJECTION);//设置投影矩阵,说明接下来要对投影进行一系列操作。
	                            /*glMatrixMode()函数就是对接下来要做什么进行一下说明,
								也就是在要做下一步之前告诉计算机我要对“什么”进行操作,
								GL_PROJECTION(投影),GL_MODELVIEW(模型视图),GL_TEXTURE(纹理)。
								如果参数是GL_PROJECTION,就是要对投影进行相关操作,
								也就是要把一个物体投影到一个平面上。*/
	gluOrtho2D(0.0, 200.0, 0.0, 150.0);//gluOrtho2D(lift,right,bottom,top)是指屏幕区域对应的模型坐标范围,
	                                   //本次投影操作横向范围是0到200,纵向是0到150
     //只要是在该矩阵内定义的对象,都会显示在窗口上
}

//显示直线
void lineSegment(void)
{
	glClear(GL_COLOR_BUFFER_BIT);//把窗口显示为当前缓冲区的颜色(背景色未显示出来),
							  //GL_COLOR_BUFFER_BIT为颜色缓冲区,用来指定颜色缓存中的位值,
							//是glClearColor函数中指定的值
	glColor3f(0.0, 1.0, 0.0);         //设置显示对象颜色,此时为绿色。glColor3f(R,G,B),
								 //对窗口显示的对象进行颜色设定,三元素值最小是0(不显示),最大是1

	glBegin(GL_LINES);            //对元素类型进行操作 glBegin(GLenum mode),mode为元素类型
	                              //GL_LINES绘制一组直线。使用此常量可连接每一组相邻端点而得到一组直线段,
	                              //在glBegin/glEnd中如果只指定一个点,则什么也不显示,如果指定的是奇数个点,则最后一个点忽略。
	                             /*OpenGL空间使用的是右手系的定义,与屏幕水平方向一致,并方向向右的是x轴;
								 与屏幕垂直方向一致,并方向向上的是y轴;与屏幕垂直方向,并方向向外的是z轴
								 */
	glVertex2i(10, 145);
	glVertex2i(180,15);          //指定顶点坐标,2表示二维,有两个参数;i表示32位整数(GLint、GLsizei)
	glColor3f(1.0, 0.0, 0.0);     //下一条线为红色
	glVertex2i(10, 25);
	glVertex2i(180,145);
	glEnd();

	glFlush();                  //强制清空缓冲区,并将指令送往缓硬件立即执行,将指令传送完毕之后会立即返回。
	                            //而glFinish将缓冲区的指令立即送往硬件执行,但是要一直等到硬件执行完这些指令之后才返回。
}

int main(int argc, char *argv[]) {
	glutInit(&argc,argv);//初始化GLUT
	/*这个函数用来初始化GLUT库.这个函数从main函数获取其两个参数.对应main函数的形式应是 : int main(int argc, char* argv[]);
	在这个部分我们将在我们的程序里建立一个main函数,这个main函数将完成必须的初始化和开启事件处理循环。
	所有的GLUT函数都有glut前缀并且那些完成一些初始化的函数有glutInit前缀。你首先要做的是调用函数glutInit()。*/
	/*GLUT(OpenGL Utility Toolkit)OpenGL的程式工具库,负责处理和底层操作系统的呼叫以及I/O*/
	glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);//设置窗口的缓存和颜色模式,默认单缓冲和RGB颜色
	glutInitWindowPosition(50, 100);//设置窗口出现在屏幕上的位置
	glutInitWindowSize(400,300);//设置窗口大小
	glutCreateWindow("An Example OpenGL Program");//创建窗口并显示窗口标题
	init();
	glutDisplayFunc(lineSegment);//将图赋值给显示窗口。glutDisplayFunc用于窗口变化时刷新窗口内容
	//glutDisplayFunc(&display)在程序运行时是自动调用的,即程序会自动调用display函数重绘窗口
	glutMainLoop();//进入GLUT事件处理循环,让所有的与“事件”有关的函数调用无限循环。一旦调用,永不返回
}

/*GLUT的基本功能:

包括窗口初始化功能、事件处理、窗口和菜单管理、回调函数注册和几何建模功能。

窗口初始化功能,它有4个函数。主要用于处理初始化并以及命令行参数,初始化显示模式,指定窗口左上角在屏幕上的位置和窗口大小,以像素为单位。

事件处理只有一个函数,它用于显示创建的窗口、处理输入的事件、触发回调函数、进入循环直到程序退出。

窗口管理包含18个函数,用于建立、销毁窗口及可能的子窗口,管理和设置窗口的属性。

在GLUT中有20个回调函数,用于响应用户事件。最重要的回调函数是glutDisplayFunc,当GLUT认为需要重新显示窗口内容时,
都将执行这一函数注册的回调函数。另外一些重要的回调函数注册函数有:函数glutRe-shapeFunc用于注册窗口大小改变这一事件发生时GLUT将调用的函数。
glutKeyboardFunc和glutMouseFunc用于注册键盘和鼠标事件发生时的回调函数。函数glutMotionFunc注册鼠标移动事件的回调函数。
这3个函数用于人机交互处理。在没有其他事件处理时,GLUT将调用函数glutldleFunc注册的函数,而函数glutTimerFunc则注册处理定时器事件的函数。

OpenGL绘图函数只能生成点、直线、多边形等简单的几何图元,GLUT提供了18个创建三维物体的函数。
利用它们可以创建9种三维物体,如圆锥体、立方体、球体等,每一物体有线框和实体2种方式。

我们看到的以glut 开头的函数都是 glut 库的一部分,如处理参数的,和设置窗口的,我们在这里主要讨论glut 支持的各种消息处理*/




// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门提示: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件