欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MFC+OPENGL配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]

程序员文章站 2022-07-14 09:50:42
...

MFC+OPENGL配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]

一、开发环境说明

  • 操作系统:windows
  • 开发软件:VS2017
  • 编程语言:基于MFC对话框下的opengl
  • 最终效果图:
  • MFC+OPENGL配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]

二、配置操作

配置opengl,并搭建opnegl框架,使在MFC下能显示出绘制的图形

1、打开vs2017软件,依次点击【文件】–【新建】–【项目】,选择“Visual C++”下面的 MFC,如下图所示

MFC+OPENGL配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]

2、点击【确定】–【下一步】选择【基于对话框】,点击【完成】。如图所示

MFC+OPENGL配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]
MFC+OPENGL配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]

3、在左侧【解决方案资源管理器】中,右键单击【project】选择【添加】–【类©】 如图所示

MFC+OPENGL配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]

4、点击“添加”,填写内容如图所示 ,然后点击完成;

MFC+OPENGL配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]

5、下载glut.h,glut32.lib 放在当前工程所在的文件夹下面,如图所示

MFC+OPENGL配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]

6、在类视图下面,右键单击【MyOpengl】,选择类向导,添加如图三个消息函数 ,点击【编辑代码】

MFC+OPENGL配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]
MFC+OPENGL配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]

7、在“Myopengl.h”添加如图所示代码

MFC+OPENGL配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]

8、在【Myopengl.cpp】中函数SetupPixelFormat(HDC hdc) 代码如下
BOOL MyOpengl::SetupPixelFormat(HDC hdc)//设置像素格式
{
	PIXELFORMATDESCRIPTOR pfd =     //像素格式
	{
		sizeof(PIXELFORMATDESCRIPTOR),
		1,
		PFD_DRAW_TO_WINDOW | //绘制到窗口
		PFD_SUPPORT_OPENGL |//支持opengl
		PFD_DOUBLEBUFFER,//采用双缓冲
		PFD_TYPE_RGBA,//像素类型 RGBA
		24,//像素位数 4*8- 32
		0, 0, 0, 0, 0, 0,//
		0,
		0,
		0,
		0, 0, 0, 0,
		16,//深度缓冲区位数
		0,//模板缓冲
		0,
		PFD_MAIN_PLANE,//
		0,
		0, 0, 0
	};
	int pixelformat;
	if (0 == (pixelformat =ChoosePixelFormat(hdc, &pfd)))//匹配像素格式的索引
	{return FALSE;
     }
	if (FALSE == ::SetPixelFormat(hdc,pixelformat, &pfd))//设置像素格式
	{return FALSE;
	}
	return TRUE;
}
9、在【Myopengl.cpp】中函数OnCreate 实现代码如下
int MyOpengl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	// TODO:  在此添加您专用的创建代码
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	hdc = ::GetDC(m_hWnd);//hdc设备上下文,m_hWnd窗口句柄
	SetupPixelFormat(hdc);//设置像素格式
	//CPaintDC dc(this);
	hglrc = wglCreateContext(hdc);//hglrc :opengl设备上下文
	wglMakeCurrent(hdc, hglrc);//hglrc绑定hdc; 绘制到当前设备上下文

	glClearDepth(1.0f);//1.0是最大深度([0.0,1.0])
	glEnable(GL_DEPTH_TEST);//启动深度检测
	return 0;
}
10、在【Myopengl.cpp】中函数OnSize 实现代码如下
//控件窗口大小改变事件
void MyOpengl::OnSize(UINT nType, int cx, int cy)
{
	CWnd::OnSize(nType, cx, cy);

	// TODO: 在此处添加消息处理程序代码
	GLdouble aspect_ratio;//窗口长宽比
	if (0 >= cx || 0 >= cy)//窗口长、宽必须大于0
		return;
	glViewport(0, 0, cx, cy);//根据窗口的实时变化重绘窗口
	aspect_ratio = (GLdouble)cx / (GLdouble)cy;//长宽比
	glMatrixMode(GL_PROJECTION);//对投影矩阵应用随后的矩阵操作
	glLoadIdentity();//重置当前投影矩阵指定的矩阵为单位矩阵	
	gluPerspective(45.0f, aspect_ratio, 0.1f, 10000.0f);//谁知投影矩阵
	glMatrixMode(GL_MODELVIEW);//对模型视景矩阵堆栈应用随后的矩阵操作	
	glLoadIdentity();//重置当前模型矩阵为单位矩阵
}
11、在【Myopengl.cpp】中函数OnPaint 实现代码如下
//刷新绘制事件
void MyOpengl::OnPaint()
{
	CPaintDC dc(this); // device context for painting
					   // TODO: 在此处添加消息处理程序代码
					   // 不为绘图消息调用 CWnd::OnPaint()
	wglMakeCurrent(hdc, hglrc);//hglrcopengl设备上下文--》绑定-->hdc当前设备上下文
	glClearColor(0.3f, 0.3f, 0.3f, 1.0f);//背景颜色
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除颜色缓冲以及深度缓冲 
	display();//绘制函数,在这个函数中绘制自己的图形
    glFinish();//绘制结束
	SwapBuffers(hdc);//交换前后缓冲区
	wglMakeCurrent(hdc, NULL);//释放设备上下文
}
12、在【Myopengl.cpp】中函数display 实现代码如下
//在此函数中绘制图形
void MyOpengl::display()
{
	glColor3f(1.0, 0, 0);//设置颜色为红色
	glTranslatef(0, 0, -10);//平移(X,Y,Z)
	glutSolidTeapot(1.0);//绘制一个茶壶,1.0:指的是茶壶大小
}
13、在【Myopengl.cpp】中函数reflesh 实现代码如下
//强制刷新重绘控件
void MyOpengl::reflesh()
{
	Invalidate(false);//是控件无效
	this->UpdateWindow();//更新控件
}
14、在【CprojectDlg.h】文件中添加代码如下

MFC+OPENGL配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]

15、在【CprojectDlg.cpp】中函数OnInitDialog添加代码如下

MFC+OPENGL配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]

16 在【资源视图】下双击【Dialog】文件夹下面的【IDD_PROJECT_DIALOG】,删除文本控件和按钮,如图所示

MFC+OPENGL配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]

17 opengl配置完成,可以点击菜单栏【调试】–【开始执行】效果如图所示

MFC+OPENGL配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]

三、添加平移、缩放、旋转交互操作和光照效果

1、在【Myopengl.h】定义变量,如图所示

MFC+OPENGL配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]

2、在【Myopengl.cpp】中构造函数MyOpengl()中初始化变量
//构造函数,初始化变量
MyOpengl::MyOpengl()
{
	//用于平移,对应X Y Z 平移量。按键W:上  S:下   A:左  D:右
	m_tranlate[0] = 0;
	m_tranlate[1] = 0;
	m_tranlate[2] = -10;

	//用于旋转,分别是绕X轴 和Y轴旋转的角度,用鼠标左键控制
	m_rorate[0] = 0;
	m_rorate[1] = 0;

	//用于缩放,用鼠标中间滚轮控制
	m_scale = 1.0;

	//记录鼠标坐标点,用于控制旋转角度;
	m_MouseDownPT.x = 0;
	m_MouseDownPT.y = 0;

	//记录鼠标左键是否按下,按下为true,初始值为false
	 m_bMouseDown = false;
}
3、在【Myopengl.cpp】中函数display添加代码如下
//在此函数中绘制图形
void MyOpengl::display() 
{
	glPushMatrix();//压栈
	glColor3f(1.0, 0, 0);//设置颜色为红色
	glTranslatef(m_tranlate[0], m_tranlate[1], m_tranlate[2]);//平移(X,Y,Z)
	glRotatef(m_rorate[0], 1, 0, 0);//旋转 绕X轴
	glRotatef(m_rorate[1], 0, 1, 0);//旋转 绕Y轴
	glScalef(m_scale, m_scale, m_scale);//缩放(X,Y,Z)
	glutSolidTeapot(1.0);//绘制一个茶壶,1.0:指的是茶壶大小
	glPopMatrix();//出栈
}
4、添加 鼠标左键按下、鼠标左键弹起、鼠标滚轮滚动、鼠标移动事件(如图所示)和按键事件 ,点击【编辑代码】

MFC+OPENGL配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]

5、实现缩放:通过鼠标滚轮滚动,如果向上滚动则放大,向下滚动则缩小
//滚轮事件
BOOL MyOpengl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if(zDelta>0)m_scale += 0.1;//放大
	if (zDelta < 0)m_scale -= 0.1;//缩小
	if (m_scale < 0.1) m_scale = 0.1;//最小倍数为0.1
	reflesh();//刷新控件
	return CWnd::OnMouseWheel(nFlags, zDelta, pt);
}
6、实现旋转:通过鼠标左键按下后移动鼠标来实现旋转角度的变化
6.1检测鼠标左键是否按下
//鼠标左键按下事件
void MyOpengl::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_MouseDownPT = point;//记录鼠标左键按下的坐标点
	m_bMouseDown = true;//记录鼠标左键按下
	CWnd::OnLButtonDown(nFlags, point);
}
6.2在鼠标左键按下的情况下通过移动鼠标进行旋转
//鼠标移动事件
void MyOpengl::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (m_bMouseDown)//如果鼠标左键按下
	{
		m_rorate[0] += point.y - m_MouseDownPT.y;//通过滑动鼠标改变旋转的角度
		m_rorate[1] += point.x - m_MouseDownPT.x;//通过滑动鼠标改变旋转的角度

		m_MouseDownPT = point;//记录当前点
	}
	reflesh();//刷新控件
	CWnd::OnMouseMove(nFlags, point);
}
6.3鼠标左键弹起,结束旋转
//鼠标左键弹起事件
void MyOpengl::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_bMouseDown = false;//记录鼠标左键弹起
	CWnd::OnLButtonUp(nFlags, point);
}
7、实现平移:通过监控键盘按键,改变平移变量的值,从而平移物体
BOOL MyOpengl::PreTranslateMessage(MSG* pMsg)
{
	// TODO: 在此添加专用代码和/或调用基类
	if (pMsg->message == WM_KEYDOWN)
	{
		switch (pMsg->wParam) 
		{
		case'W'://上移动	
			m_tranlate[1] += 0.1;
			return TRUE;	
		case'S'://下移动	
			m_tranlate[1] -= 0.1;
			return TRUE;
		case'A'://左移动	
			m_tranlate[0] -= 0.1;
			return TRUE;
		case'D'://右移动
			m_tranlate[0] += 0.1;
			return TRUE;
		}
		
	}
	reflesh();//刷新控件	
	return CWnd::PreTranslateMessage(pMsg);
}
8、实现光照:启动光照
glEnable(GL_LIGHT0);//启动一号灯
glEnable(GL_LIGHTING);//开启光照
9、大功告成,点击菜单栏【调试】–【开始执行】 效果图如图所示

MFC+OPENGL配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]

旋转 平移 缩放

MFC+OPENGL配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]

四、工程代码下载

整个工程代码都可以下载,如果有疑惑可以留言,谢谢。

相关标签: opengl mfc