配置opengl,并搭建opnegl框架,使在MFC下能显示出绘制的图形
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;
}
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;
}
//控件窗口大小改变事件
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();//重置当前模型矩阵为单位矩阵
}
//刷新绘制事件
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);//释放设备上下文
}
//在此函数中绘制图形
void MyOpengl::display()
{
glColor3f(1.0, 0, 0);//设置颜色为红色
glTranslatef(0, 0, -10);//平移(X,Y,Z)
glutSolidTeapot(1.0);//绘制一个茶壶,1.0:指的是茶壶大小
}
//强制刷新重绘控件
void MyOpengl::reflesh()
{
Invalidate(false);//是控件无效
this->UpdateWindow();//更新控件
}
//构造函数,初始化变量
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;
}
//在此函数中绘制图形
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();//出栈
}
//滚轮事件
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);
}
//鼠标左键按下事件
void MyOpengl::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_MouseDownPT = point;//记录鼠标左键按下的坐标点
m_bMouseDown = true;//记录鼠标左键按下
CWnd::OnLButtonDown(nFlags, point);
}
//鼠标移动事件
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);
}
//鼠标左键弹起事件
void MyOpengl::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_bMouseDown = false;//记录鼠标左键弹起
CWnd::OnLButtonUp(nFlags, point);
}
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);
}
glEnable(GL_LIGHT0);//启动一号灯
glEnable(GL_LIGHTING);//开启光照
整个工程代码都可以下载,如果有疑惑可以留言,谢谢。