【计算机图形学】OpenGL鼠标交互小应用

OpenGL实现:

1、鼠标画线 2、鼠标画矩形 3、鼠标画圆 4、鼠标画三角形 5、鼠标画六边形 6、鼠标画箭头

先上效果图:
在这里插入图片描述
源码(仅供参考):

#include "framework.h"
#include "Mouse.h"
#include <math.h>
#include <glut.h>
#define MAX_LOADSTRING 100

void Reshape(int w, int h);
void myMouse(int button, int state, int x, int y);
void myMotion(int x, int y);
void drawLine();
void drawRec();
void drawCir();
void drawTri();
void drawHex();
void drawArrow();
void GLUTMenus();
void processMenuEvents(int option);

#define N 1000
//单独开辟每个图形对应的坐标二维数组
int Line[N][4], xy_Line = 0;//线段
int Rec[N][4], xy_Rec = 0;//矩形
int Cir[N][4], xy_Cir = 0;//圆形
int Tri[N][4], xy_Tri = 0;//三角形
int Hex[N][4], xy_Hex = 0;//六边形
int Arrow[N][4], xy_Arrow = 0;//箭头
float PI = 3.1415;

int ww, hh;
int paint = 0;//用来定位当前的画法

void display(void)
{
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);  //设置清屏颜色
	glClear(GL_COLOR_BUFFER_BIT);   //刷新颜色缓冲区
	drawLine();
	drawRec();
	drawCir();
	drawTri();
	drawHex();
	drawArrow();

	glFlush();   //用于刷新命令队列和缓冲区,使所有尚未被执行的OpenGL命令得到执行;
}

//鼠标按钮响应事件  构造鼠标响应子函数
void myMouse(int button, int state, int x, int y)
{
	//鼠标左键按下—确定起始点
	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
	{
		//线段
		if (paint == 0) {
			Line[xy_Line][0] = x;   //线段起点x坐标
			Line[xy_Line][1] = hh - y;  //线段终点y坐标
		}
		//矩形
		if (paint == 1) {
			Rec[xy_Rec][0] = x;
			Rec[xy_Rec][1] = hh - y;
		}
		//圆形
		if (paint == 2) {
			Cir[xy_Cir][0] = x;
			Cir[xy_Cir][1] = hh - y;
		}
		//三角形
		if (paint == 3) {
			Tri[xy_Tri][0] = x;
			Tri[xy_Tri][1] = hh - y;
		}
		//六边形
		if (paint == 4) {
			Hex[xy_Hex][0] = x;
			Hex[xy_Hex][1] = hh - y;
		}
		//箭头
		if (paint == 5) {
			Arrow[xy_Arrow][0] = x;
			Arrow[xy_Arrow][1] = hh - y;
		}
	}

	//鼠标左键松开___画最后一个顶点,画线结束
	if (button == GLUT_LEFT_BUTTON && state == GLUT_UP)
	{	
		//线段
		if (paint == 0) {
			Line[xy_Line][2] = x;   //线段起点x坐标
			Line[xy_Line][3] = hh - y;   //线段终点y坐标
			xy_Line++;
		}
		//矩形
		if (paint == 1) {
			Rec[xy_Rec][2] = x;
			Rec[xy_Rec][3] = hh - y;
			xy_Rec++;
		}
		//圆形
		if (paint == 2) {
			Cir[xy_Cir][2] = x;
			Cir[xy_Cir][3] = hh - y;
			xy_Cir++;
		}
		//三角形
		if (paint == 3) {
			Tri[xy_Tri][2] = x;
			Tri[xy_Tri][3] = hh - y;
			xy_Tri++;
		}
		//六边形
		if (paint == 4) {
			Hex[xy_Hex][2] = x;
			Hex[xy_Hex][3] = hh - y;
			xy_Hex++;
		}
		//箭头
		if (paint == 5) {
			Arrow[xy_Arrow][2] = x;
			Arrow[xy_Arrow][3] = hh - y;
			xy_Arrow++;
		}
		glutPostRedisplay();
	}
}

//鼠标移动时获得鼠标移动中的坐标   构造鼠标移动子函数
void myMotion(int x, int y)//	鼠标移动__线画到哪
{
	//线段
	if (paint == 0) {
		Line[xy_Line][2] = x;   //线段起点x坐标
		Line[xy_Line][3] = hh - y;   //线段终点y坐标
	}
	//矩形
	if (paint == 1) {
		Rec[xy_Rec][2] = x;
		Rec[xy_Rec][3] = hh - y;
	}
	//圆形
	if (paint == 2) {
		Cir[xy_Cir][2] = x;
		Cir[xy_Cir][3] = hh - y;
	}
	//三角形
	if (paint == 3) {
		Tri[xy_Tri][2] = x;
		Tri[xy_Tri][3] = hh - y;
	}
	//六边形
	if (paint == 4) {
		Hex[xy_Hex][2] = x;
		Hex[xy_Hex][3] = hh - y;
	}
	//箭头
	if (paint == 5) {
		Arrow[xy_Arrow][2] = x;
		Arrow[xy_Arrow][3] = hh - y;
	}
	glutPostRedisplay();
}

void Reshape(int w, int h)  //窗口改变时自动获取显示窗口的宽w和高h
{
	glMatrixMode(GL_PROJECTION);  //投影矩阵模式
	glLoadIdentity();     //矩阵堆栈清空
	glViewport(0, 0, w, h);  //设置视区大小
	gluOrtho2D(0, w, 0, h);   //设置裁剪窗口大小
	ww = w;
	hh = h;
}

//线
void drawLine() 
{
	for (int i = 0; i <= xy_Line; i++) {
		glColor3f(1, 1, 1);
		glBegin(GL_LINE_STRIP);
		glVertex2i(Line[i][0], Line[i][1]);
		glVertex2i(Line[i][2], Line[i][3]);
		glEnd();
	}
}

//矩形
void drawRec() 
{
	for (int i = 0; i <= xy_Rec; i++) {
		glColor3f(0, 1, 1);
		glRectf(Rec[i][0], Rec[i][1], Rec[i][2], Rec[i][3]);
	}
}

//圆形
void drawCir() 
{
	int x0 = 0;
	int y0 = 0;
	for (int i = 0; i <= xy_Cir; i++) {
		glColor3f(1, 1, 0);
		int x = Cir[i][0] - Cir[i][2];

		int y = Cir[i][1] - Cir[i][3];
		int R = sqrt(pow(x, 2) + pow(y, 2));
		x0 = Cir[i][0];
		y0 = Cir[i][1];

		glBegin(GL_POLYGON);
		for (int i = 0; i < 1000; i++) {
			glVertex2f(x0 + R * cos(2 * PI / 1000 * i), y0 + R * sin(2 * PI / 1000 * i));
		}
		glEnd();
	}
}

//三角形
void drawTri() {
	glColor3f(0, 1, 0);
	glBegin(GL_TRIANGLES);
	for (int i = 0; i <= xy_Tri; i++) {
		int x = Tri[i][0] - Tri[i][2];
		int y = Tri[i][1] - Tri[i][3];

		glVertex2f(Tri[i][0], Tri[i][1]);
		glVertex2f(Tri[i][2], Tri[i][3]);
		glVertex2f(Tri[i][2] + 50, Tri[i][3] + 60);
	}
	glEnd();
}

//六边形
void drawHex()
{
	for (int i = 0; i <= xy_Hex; i++) {
		glColor3f(1, 0, 1);
		glBegin(GL_POLYGON);
		int x = Hex[i][0] - Hex[i][2];
		int y = Hex[i][1] - Hex[i][3];
		//求出半径
		int R = sqrt(pow(x, 2) + pow(y, 2));
		if (R != 0) {
			glVertex2f(Hex[i][0] + R * cos(0 * 2 * PI / 6), Hex[i][1] + R * sin(0 * 2 * PI / 6));
			glVertex2f(Hex[i][0] + R * cos(1 * 2 * PI / 6), Hex[i][1] + R * sin(1 * 2 * PI / 6));
			glVertex2f(Hex[i][2], Hex[i][3]);
			glVertex2f(Hex[i][0] + R * cos(3 * 2 * PI / 6), Hex[i][1] + R * sin(3 * 2 * PI / 6));
			glVertex2f(Hex[i][0] + R * cos(4 * 2 * PI / 6), Hex[i][1] + R * sin(4 * 2 * PI / 6));
			glVertex2f(Hex[i][0] + R * cos(5 * 2 * PI / 6), Hex[i][1] + R * sin(5 * 2 * PI / 6));
		}
		glEnd();
	}
}

//箭头
void drawArrow() 
{
	for (int i = 0; i <= xy_Arrow; i++) {
		glColor3f(0, 0, 1);
		glBegin(GL_LINE_LOOP);
		int x = Arrow[i][2] - Arrow[i][0];
		//int y = Arrow[i][3] - Arrow[i][1];
		if (x != 0) {//松开时以左上角的点为结束点
			glVertex2f(Arrow[i][0], Arrow[i][1]);
			glVertex2f(Arrow[i][0] + x * 2 / 3, Arrow[i][1]);
			glVertex2f(Arrow[i][0] + x * 2 / 3, Arrow[i][1] + 10);
			glVertex2f(Arrow[i][2], Arrow[i][3]);

			glVertex2f(Arrow[i][2] - x * 1 / 3, Arrow[i][3] - 20);
			glVertex2f(Arrow[i][2] - x * 1 / 3, Arrow[i][3] - 10);
			glVertex2f(Arrow[i][0], Arrow[i][1] - 20);
		}
		glEnd();
	}
}

void GLUTMenus() {
	int menu;
	//菜单处理事件
	menu = glutCreateMenu(processMenuEvents);
	//菜单项
	glutAddMenuEntry("Line", 1);
	glutAddMenuEntry("Rectangle", 2);
	glutAddMenuEntry("Circle", 3);
	glutAddMenuEntry("Triangle", 4);
	glutAddMenuEntry("Hexagon", 5);
	glutAddMenuEntry("Arrow", 6);

	//通过鼠标右键打开菜单
	glutAttachMenu(GLUT_RIGHT_BUTTON);
}

void processMenuEvents(int option) {
	//option是传递过来的值
	switch (option)
	{
	case 1:
		paint = 0; break;
	case 2:
		paint = 1; break;
	case 3:
		paint = 2; break;
	case 4:
		paint = 3; break;
	case 5:
		paint = 4; break;
	case 6:
		paint = 5; break;
	default:
		break;
	}
}

int APIENTRY _tWinMain(HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPTSTR    lpCmdLine,
	int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

	char *argv[] = { (char*)"hello ", (char*)" " };
	int argc = 2; 
	glutInit(&argc, argv);    //初始化GLUT库;
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);   //设置显示模式;(缓冲,颜色类型)
	glutInitWindowSize(500, 500); //绘图窗口大小
	glutInitWindowPosition(1024 / 2 - 250, 768 / 2 - 250); //窗口左上角在屏幕的位置
	glutCreateWindow("鼠标交互小应用");
	glutDisplayFunc(display);  //用于绘制当前窗口;

	glutMouseFunc(myMouse);
	glutMotionFunc(myMotion);
	glutReshapeFunc(Reshape);  //注册窗口改变回调函数

	GLUTMenus();
	glutMainLoop();   //表示开始运行程序,用于程序的结尾;
	return 0;
}
  • 2
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值