代码都放在一起了,如果接下来的实验有需要私信一下就好哦
链接: https://pan.baidu.com/s/1cBTTbbzRCVBCX_H4jf6qMA 提取码: kj8w
实验三 三角形光栅化算法
一、实验原理
本次实验利用OpenGL的GLFW库进行操作,实现了用户通过键盘输入点的坐标和颜色绘制出三角形。三角形光栅化算法可以封装为一个函数,把光栅化三角形算法生成的像素点覆盖vertices[]数组中的点,并通过glDrawArrays(GL_POINTS, 0, counts)画出来,counts为直线上像素点的个数。
GLFW是一个用于OpenGL应用程序开发的可移植库。它处理与OpenGL上下文创建、窗口管理、分辨率切换、键盘、鼠标、操纵杆和时间输入以及基本线程设施相关的系统特定任务。
GLEW能自动识别当前平台所支持的全部OpenGL高级扩展涵数。只要包含glew.h头文件,就能使用gl,glu,glext,wgl,glx的全部函数。GLEW支持目前流行的各种操作系统
实验过程中,利用VAO、VBO来存储直线或者图案的点集vertices,然后用OpenGL的绘制功能glDrawArrays将直线或者图案绘制出来。
二、代码设计和说明
本次实验的主要思路是把光栅化三角形算法生成的像素点用vector向量计算出来保存,然后覆盖vertices[]数组中的点,并通过glDrawArrays(GL_POINTS, 0, counts)画出来。
直线的计算代码,以及一小部分点集存储代码都封装成了函数,减少主函数中不必要的冗余。
由于代码量比较大,所以这里只简要说明一下核心设计,完整的代码文件在作业中提交。
1、最小值函数floor
float floor(float x1, float x2, float x3) {
float x = min(x1, x2);
x = min(x, x3);
return x;
}
2、最大值函数ceiling
float ceiling(float x1, float x2, float x3) {
float x = max(x1, x2);
x = max(x, x3);
return x;
}
3、重心坐标算子f
float f(float x, float y, float x0, float y0, float x1, float y1) {
return (y0 - y1) * x + (x1 - x0) * y + x0 * y1 - x1 * y0;
}
4、画三角形函数drawTriangle
void drawTriangle(float x0,float x1,float x2,float y0,float y1,float y2) {
float ymin, xmin, ymax, xmax;
ymin = floor(y0, y1, y2);
xmin = floor(x0, x1, x2);
ymax = ceiling(y0, y1, y2);
xmax = ceiling(x0, x1, x2);
float i, j, k1, k2, k3;
for (i = xmin; i <= xmax; i++) {
for (j = ymin; j <= ymax; j++) {
k1 = f(i, j, x1, y1, x2, y2) / f(x0, y0, x1, y1, x2, y2);//重心坐标
k2 = f(i, j, x2, y2, x0, y0) / f(x1, y1, x2, y2, x0, y0);//重心坐标
k3 = 1 - k1 - k2; //重心坐标
if (k1 >= 0 && k2 >= 0 && k3 >= 0) {
vertices.push_back(i); //横坐标
vertices.push_back(j); //纵坐标
vertices.push_back(k1); //R
vertices.push_back(k2); //G
vertices.push_back(k3); //B
}
}
}
}
三、实验运行结果(包含用户输入和输出)
drawTriangle(400, 400, 800, 400, 800, 800); //x0,y0,x1,y1,x2,y2
drawTriangle(400, 400, 0, 400, 0, 0);
drawTriangle(400, 0, 0, 400, 400, 800);
drawTriangle(400, 800, 800, 400, 400, 0);
//drawTriangle(0, 0, 400, 0, 400, 400);
//drawTriangle(400, 0, 400, 800, 800, 400);
//drawTriangle(800, 800, 400, 400, 800, 400);
//drawTriangle(400, 800, 400, 0, 0, 400);
四、实验总结(收获和感想)
实验过程中,有碰到诸如染色无法实现的情况,通过修改frag的命令也得到了解决。也出现了三角形只有边缘有颜色的情况,调整了数组中颜色向量得以解决。通过实验我对三角形光栅化有了一个更熟悉的认识,也对glfw里面的函数印象跟加深了一步。