【计算机图形学】使用OpenGL C++语言,橡皮筋技术/交互式绘制三角形 【100行代码】

唐伟
2023-12-01

使用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;
}
 类似资料: