基于MFC框架的OpenGL绘图:画直线

效果图

一、环境配置

参考链接:计算机图形学OpenGL中的MFC框架划线功能实现

二、画线功能实现

(一) 基本思路

鼠标按下时确定绘制起点,抬起时确定终点,两点自动连线即可。需要用到鼠标响应函数和画线函数。参考链接:MFC之绘制线条

(二) 开始画线

MFC中能直接调用 MoveToExLineTo 函数画线,或者使用 SetPixel 函数一个点一个点地把直线描出来。这两种方法都非常的便捷,但是!好巧不巧,我们想用的是OpenGL库里的 glVertex 方法。这就有点折磨了……

1. 首先要有一个坐标变换

是的没错画个线居然要涉及到坐标变换。参考 MFC坐标系之间的关系 我们可以发现,鼠标坐标的原点是在左上角,长宽貌似为视口长宽(cx,cy);而视口的坐标原点是在视口中心,高度固定为2(即无论视口大小高度都为2),宽度则为2*cx/cy。结合老师画的图更好理解:
鼠标坐标系
视口坐标系
所以二者的对应关系是这样:

	//传入鼠标坐标
	float x,y;
	CRect rc;
	GetClientRect(rc);
	/*
	输出视口长宽信息
	CString strDlg;
	strDlg.Format(L"%d,%d,%d,%d", rc.left, rc.top, rc.right, rc.bottom);
	MessageBox(strDlg);
	*/
	float width = rc.right - rc.left;
	float height = rc.top - rc.bottom;
	// 变换为视口坐标
	// x = -(x / width * width / height * 2 - width / height);
	x = (width - 2 * x) / height;
	y = y / height * 2 + 1;

这时在Display函数里就能用glVertex2f函数正常画线了!

2. 数组存储多条线段

要想避免画好的线段直接被扬了,就得把它好好地保存下来,以后每次调用Display函数都再画一次。定义一个CPoint类型的二维数组,在鼠标抬起时存入线段即可:

CPoint linePoints[1000][2];
// linePoints[x][0]是起点,linePoints[x][1]是终点,x代表线段数

3. DDA算法沿线画圆

参考链接:DDA直线生成算法|MFC|计算机图形学
就是我们的坐标都是浮点型的,算着可能会慢点?
画圆也是用OpenGL的方法就好了:

	glBegin(GL_TRIANGLE_FAN);
	for (int i = 0; i <= 360; i += 30) 
	{
		float p = (float)(i * 3.14 / 180);
		glVertex2f(x + (float)sin(p) * gridGap * 0.5f, y + (float)cos(p) * gridGap * 0.5f);
		// 起点(x,y),半径是网格gridGap的一半
	}
	glEnd();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值