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

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

一、开发环境说明

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

二、配置操作

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]_第11张图片

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

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

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

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

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

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

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

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

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

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配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]_第16张图片

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配置+显示三维图形实现 旋转平移缩放+光照效果[对话框篇]_第17张图片

旋转 平移 缩放

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

四、工程代码下载

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

你可能感兴趣的:(Opengl)