2D图形绘制代码
百度网盘链接: https://pan.baidu.com/s/1jpILJ9PTPIMZMylH86_gew 提取码:i6wc
博主会尽量讲的详细,以最简单的说法描述整个基本过程,不过具体还是要读者自行去体会,博主所给代码已经重构过一遍,读者可以按照这个框架去改改参数,体会整个过程。(PS:该篇博客的文件及教程依然免费提供给读者)
1、与OpenGL 学习笔记(一)的步骤一样,将所有文件导入新建的项目中(注:InitShader.cpp在common文件夹中)
(一)首先当然是从main函数讲起,将main函数分为三部分来讲:
First Part:
这部分代码几乎是每次都必须要有的,注释上写的很清楚,这里就不再赘述,其实就是一系列初始化。
Second Part:
1、init()包括对顶点数组对象、顶点缓存对象的初始化,将数据拷贝到OpenGL服务端内存,读取数据、读取着色器、初始化顶点等,这部分代码基本上是固定的,差别在于自定义画图形的函数不同,比如说你自定义写个画三角形、正方形的。
2、glutDisplayFunc(display),display是自己所写的渲染函数,在自定义画图形的函数中,我们会绑定顶点的位置(通过极坐标)及颜色,那么在渲染函数中,通过明确顶点数组中哪些顶点是哪些图形的组成,指定图形所需的顶点的连接方式、起始下标,以及顶点个数,进行对应图形的渲染。
Third Part:
这段代码是让图形不断更新,比如我们后期加入各种事件操作,其实就是让glutDisplayFunc(display)不断执行。
(二)接下来我们讲init()函数,这部分挺重要的,因为理解了这部分的逻辑,就大致明白了OpenGL的工作原理。
void init()
{
vec2 vertices[TOTAL_NUM_POINTS];// 顶点
vec3 colors[TOTAL_NUM_POINTS];// 颜色
// 调用生成形状顶点位置的函数
generateTrianglePoints(vertices, colors, 0);
generateSquarePoints(vertices, colors, TRIANGLE_NUM_POINTS);
generateCirclePoints(vertices, colors, TRIANGLE_NUM_POINTS + SQUARE_NUM_POINTS);
generateEllipsePoints(vertices, colors, TRIANGLE_NUM_POINTS + SQUARE_NUM_POINTS + CIRCLE_NUM_POINTS);
// 创建顶点数组对象
GLuint vao[1];
// 分配1个顶点数组对象
glGenVertexArrays(1, vao);
// 绑定顶点数组对象
glBindVertexArray(vao[0]);
// 创建顶点缓存对象
GLuint buffer;
// 分配1个顶点数组对象
glGenBuffers(1, &buffer);
// 绑定顶点缓存对象
glBindBuffer(GL_ARRAY_BUFFER, buffer);
// 分配数据所需的存储空间,将数据拷贝到OpenGL服务端内存
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) + sizeof(colors), NULL, GL_STATIC_DRAW);
// 分别读取数据
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertices), sizeof(colors), colors);
// 读取着色器并使用
GLuint program = InitShader("vshader.glsl", "fshader.glsl");
glUseProgram(program);
// 从顶点着色器中初始化顶点的位置
GLuint pLocation = glGetAttribLocation(program, "vPosition");
// 启用顶点属性数组
glEnableVertexAttribArray(pLocation);
// 关联到顶点属性数组 (index, size, type, normalized, stride, *pointer)
glVertexAttribPointer(pLocation, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
// 从片元着色器中初始化顶点的颜色
GLuint cLocation = glGetAttribLocation(program, "vColor");
glEnableVertexAttribArray(cLocation);
glVertexAttribPointer(cLocation, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(vertices)));
// 设置了当前使用的清除颜色值,这里设置为黑色背景
glClearColor(0.0, 0.0, 0.0, 1.0);
}
(三)接下来我们讲一下绘制图形的函数
其实接下来的四个函数都是定义图形的顶点,包括顶点的位置和颜色,OpenGL是通过极坐标来定义顶点的位置,也就是以角度和极长的方式表示顶点坐标,具体体会博主所写代码。下面详细描述函数:
1.1 确定图形参数
基本参数包括颜色、点个数;
图形参数包括各种图形的大小、位置及个别默认颜色,特殊的有椭圆的长半轴和短半轴;
2.1 画三角形函数
循环中通过getTriangleAngel函数得到每个点对应的角度,用sin(x)和cos(x)得到二维坐标, 然后乘以极半径(即TRIANGLE_SCALE),最后才加上位置参数TRIANGLE_CENTER,得到一个三角形,同时每个顶点的颜色都不同,实现混色渐变。
2.2 画嵌套正方形函数
这里用二重循环,第一重循环for(int i=0; i 2.3 画圆及实现渐变色函数 首先同样在循环中得到点的角度,通过getCircleAngel函数,组成圆上的每个点的角度都是均匀围绕圆的,用cos(x)和sin(x)得到二维坐标,乘以半径CIRCLE_RADIUS,再加上位置参数CIRCLE_CENTER得到圆。重要的部分是实现渐变色,即颜色的深度随着点的的下标均匀增大,这里我采用了红色和蓝色的混合渐变色,最后呈现出来的是紫色的渐变色。 2.4 生成椭圆顶点函数 跟上述几个图形的大致过程一样,这里的点的角度仍然是采用getCircleAngel函数,唯一不同的是,根据椭圆的方程,会有一个长半轴和短半轴,即二维坐标是用(acos(x),bsin(x))来表示,再乘以极半径和加上位置参数,便得到了椭圆。 3.1 修改初始化函数init 在init函数中调用上述编写好的初始化图形顶点的函数,其余不需改动。 3.2 修改渲染函数display 指定顶点连接方式mode,图形顶点下标起点first以及该图形所需顶点数count,均调用glDrawArrays对图形进行渲染。 未完待续.....