使用OpenGL C++语言,橡皮筋技术/交互式绘制三角形
完整代码见最后
大部分理解都写在代码注释里面了,有疑问可以直接评论区问UP。
之前在网上参考了很多类似的代码,他们都有庞大的头文件,个别代码还引用了C++的万能头文件(这玩意在VS2019中不能直接运行,还需要配置),但最后我发现,如果只是想画个交互式三角形,其实就需要一个gl包即可。
不废话了,直接贴完整代码
#include <gl/glut.h>
#include <stdio.h>
#define NUM 3 //设置顶点数量
int alreadyFirstPoint = 0; //标记是否已经开始绘制折线
int winWidth = 800, winHeight = 600;
int Mousex, Mousey; //当前鼠标的位置
int n = 0; //记录折线数量
struct LineNode {//定义一条线,包含两个点,四个数据
int x1;
int y1;
int x2;
int y2;
}Line[NUM];
void Initial(void)//非逻辑代码,初始化
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); //设置窗口颜色
}
void ChangeSize(int w, int h)//非逻辑代码,控制窗口size
{
winWidth = w;
winHeight = h;
glViewport(0, 0, w, h); //指定窗口显示区域
glMatrixMode(GL_PROJECTION); //指定设置投影参数
glLoadIdentity(); //调用单位矩阵,去掉以前的投影参数设置
gluOrtho2D(0.0, winWidth, 0.0, winHeight); //设置投影参数
}
void PassiveMouseMove(GLint xMouse, GLint yMouse)//非逻辑代码,修正鼠标坐标
{
Mousex = xMouse;
Mousey = winHeight - yMouse;
glutPostRedisplay();
}
/*
Display()方法才是真正画线的方法
*/
void Display()
{
int i, j;
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //线性模式画图
glClear(GL_COLOR_BUFFER_BIT); //用当前背景色填充窗口
glColor3f(0, 0, 0); //指定当前的绘图颜色
for (i = 0; i < n; i++) {//循环+glBegin维持已经画好的线段
glBegin(GL_LINES); //绘制直线
//设置一条线的两个顶点:
glVertex2i(Line[i].x1, Line[i].y1);//设置第一个点
glVertex2i(Line[i].x2, Line[i].y2);//设置第二个点
glEnd();
}
if (alreadyFirstPoint == 1) {//当点击鼠标之后,一条线的第二个点将跟随鼠标移动
glBegin(GL_LINES);
if (n < 2) {
glVertex2i(Line[i].x1, Line[i].y1);//始发点确定坐标
glVertex2i(Mousex, Mousey);//落点跟随鼠标移动
}
else {//当画出两条线之后,停止鼠标橡皮筋,并且首尾相连成为三角形
glVertex2i(Line[0].x1, Line[0].y1);
glVertex2i(Line[1].x2, Line[1].y2);
}
glEnd();
//printf("测试\n");
}
glutSwapBuffers(); //交换缓冲区
}
/*
控制鼠标拖拽的函数,这段代码是橡皮筋的核心
*/
void MouseDraw(GLint button, GLint action, GLint xMouse, GLint yMouse) {
if (button == GLUT_LEFT_BUTTON && action == GLUT_DOWN) {//这行就是一个普通的鼠标按键事件
if (alreadyFirstPoint == 0) {
alreadyFirstPoint = 1;//标记出鼠标点击了第一个点
Line[n].x1 = xMouse;
Line[n].y1 = winHeight - yMouse;//修正y的坐标
}
else {
if (n < 2) {//人为规定最多只能画三条线
Line[n].x2 = xMouse;
Line[n].y2 = winHeight - yMouse;
//printf("测试,你画了一条新的线段\n");
n++;//折线数量+1
}
//折线的第二点作为下一段线的第一个的点
Line[n].x1 = Line[n - 1].x2;
Line[n].y1 = Line[n - 1].y2;
}
}
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);//使用双缓存及RGB模型
glutInitWindowSize(winWidth, winHeight); //指定窗口的尺寸
glutInitWindowPosition(100, 100); //指定窗口在屏幕上的位置
glutCreateWindow("作业2-交互式画三角形"); //创建窗口
glutDisplayFunc(Display);
glutReshapeFunc(ChangeSize); //指定窗口回调函数
glutMouseFunc(MouseDraw); //指定鼠标响应函数
glutPassiveMotionFunc(PassiveMouseMove); //指定鼠标移动响应函数
Initial(); //开始初始化
glutMainLoop(); //启动主GLUT事件处理循环
return 0;
}