OpenGL的配置以及在MFC框架上的使用(附上源代码)
来源:互联网 发布:最好的搜索软件 编辑:程序博客网 时间:2024/06/14 03:47
一.配置MFC环境
首先创建一个单文档的MFC文档,相信学过MFC的朋友应该都知道。我这里取名为openGLForm,下面就是配置环境。
1. 添加链接库
笔者这里将opengl库放在项目文件夹里,使用相对路径进行配置,便于转移到另外的计算机时不用费时间去配置。
库目录和include目录都是相对路径:../OpenGL,如图:
在附加依赖项上加上OpenGL32.lib GLu32.lib GLaux.lib;
做完配置以后可以自己运行一下,没有出现报错就说明配置成功,可以进行下一步啦。
2.头文件和添加响应函数
在stdafx里面添加opengl的头文件(当然也可以在其他文件中添加,比如绘图一般都是在视图中的,可以在xxxView.cpp文件中包含头文件)。如下代码所示:
include < glaux.h>
include < glut.h>;
COpenGLFormView类的属性栏,为下述消息加入消息处理函数:WM_CREATE (for OnCreate), WM_DESTROY (for OnDestroy), WM_SIZE (for OnSize), WM_ERASEBACKGROUND (for OnEraseBkground).
3.编写函数
设置窗口显示风格。窗口创建之前我们必须设置窗口风格包含WS_CLIPCHILDREN和 WS_CLIPSIBLINGS,从而避免OpenGL绘制到其他窗口中去。这些应该放在PreCreateWindow()中。
BOOL CfirstView::PreCreateWindow(CREATESTRUCT& cs){ // TODO: 在此处通过修改 // CREATESTRUCT cs 来修改窗口类或样式 cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;//Tramp return CView::PreCreateWindow(cs);}
在CfirstView.h中加入如下语句:
HGLRC m_hRC; //Rendering Context着色描述表 CDC* m_pDC; //Device Context设备描述表 BOOL InitializeOpenGL(); //Initialize OpenGL BOOL SetupPixelFormat(); //Set up the Pixel Format void RenderScene(); //Render the Scene
在OnCreate中我们将通过建立像素格式和绘制上下文来初始化OpenGL. 在InitializeOpenGL()中会创建一个设备上下文(DC),为这个DC选择一个像素格式,创建和这个DC相关的绘制上下文(RC),然后选择这个RC.这个函数会调用SetupPixelFormat()来建立像素格式。
int Clesson1View::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 在此添加您专用的创建代码
InitializeOpenGL();//初始化openGL绘图
return 0;
}
//初始化opengl绘制
BOOL CfirstView::InitializeOpenGL()
{
//Get a DC for the Client Aream_pDC = new CClientDC(this);//Failure to Get DCif(m_pDC == NULL){ //::MessageBox("Error Obtaining DC"); return FALSE;}//Failure to set the pixel formatif(!SetupPixelFormat()){ return FALSE;}
//Create Rendering Context
m_hRC = ::wglCreateContext (m_pDC->GetSafeHdc ());
//Failure to Create Rendering Context
if(m_hRC == 0)
{
// MessageBox("Error Creating RC"); return FALSE;
}
//Make the RC Current
if(::wglMakeCurrent (m_pDC->GetSafeHdc (), m_hRC)==FALSE)
{
// MessageBox("Error making RC Current"); return FALSE;
}
//Specify Black as the clear color
::glClearColor(0.0f,0.0f,0.0f,0.0f);
//Specify the back of the buffer as clear depth
::glClearDepth(1.0f);
//Enable Depth Testing
::glEnable(GL_DEPTH_TEST);
return TRUE;
}
//设置像素格式
BOOL CfirstView::SetupPixelFormat()
{
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd 1, // version number PFD_DRAW_TO_WINDOW | // support window PFD_SUPPORT_OPENGL | // support OpenGL PFD_DOUBLEBUFFER, // double buffered PFD_TYPE_RGBA, // RGBA type 24, // 24-bit color depth 0, 0, 0, 0, 0, 0, // color bits ignored 0, // no alpha buffer 0, // shift bit ignored 0, // no accumulation buffer 0, 0, 0, 0, // accum bits ignored 16, // 16-bit z-buffer 0, // no stencil buffer 0, // no auxiliary buffer PFD_MAIN_PLANE, // main layer 0, // reserved 0, 0, 0 // layer masks ignored
};
int m_nPixelFormat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);
if ( m_nPixelFormat == 0 )
{
return FALSE;
}
if ( ::SetPixelFormat(m_pDC->GetSafeHdc(), m_nPixelFormat, &pfd) == FALSE)
{
return FALSE;
}
return TRUE;
}
在OnSize()中一般用来设置视口和视锥,因为这些是和窗口大小相关的。基本操作包括设置视口,选择投影矩阵,设置模型视图矩阵。
void CfirstView::OnSize(UINT nType, int cx, int cy){ CView::OnSize(nType, cx, cy); // TODO: 在此处添加消息处理程序代码 GLdouble aspect_ratio; // width/height ratio if ( 0 >= cx || 0 >= cy ) { return; } // select the full client area ::glViewport(0, 0, cx, cy); // compute the aspect ratio // this will keep all dimension scales equal aspect_ratio = (GLdouble)cx/(GLdouble)cy; // select the projection matrix and clear it ::glMatrixMode(GL_PROJECTION); ::glLoadIdentity(); // select the viewing volume ::gluPerspective(45.0f, aspect_ratio, .01f, 200.0f);//画三维 //::gluOrtho2D(-10.0f, 10.0f, -10.0f, 10.0f); //二维 // switch back to the modelview matrix and clear it ::glMatrixMode(GL_MODELVIEW); ::glLoadIdentity();}
在绘制场景时,一般包括如下步骤:1)清空缓存。2)绘制场景。3)Flush掉渲染流水线。4)若设置了双缓冲,则交换前后台缓冲区。
void CfirstView::OnDraw(CDC* /*pDC*/){ CfirstDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; // TODO: 在此处为本机数据添加绘制代码 // Clear out the color & depth buffers ::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); RenderScene();//绘图都放在这 // Tell OpenGL to flush its pipeline ::glFinish(); // Now Swap the buffers ::SwapBuffers( m_pDC->GetSafeHdc() );}
为了使改变窗口大小时严重的闪烁,在OnEraseBkgnd里做一些操作,避免windows自己的窗口刷新闪烁。
BOOL CfirstView::OnEraseBkgnd(CDC* pDC){// TODO: 在此添加消息处理程序代码和/或调用默认值return TRUE;}
为了避免内存泄露,我们要将在SetupPixelFormat()中使用了new运算符来为CClientDC对象分配的内存在程序关闭时delete掉。
void CfirstView::OnDestroy(){ CView::OnDestroy(); // TODO: 在此处添加消息处理程序代码 //Make the RC non-current if(::wglMakeCurrent (0,0) == FALSE) { MessageBox(_T("Could not make RC non-current")); } //Delete the rendering context if(::wglDeleteContext (m_hRC)==FALSE) { MessageBox(_T("Could not delete RC")); } //Delete the DC if(m_pDC) { delete m_pDC; } //Set it to NULL m_pDC = NULL;}
下面写主绘图函数,RenderScene(),在窗口画了一个正方体、一个四面体。
void CfirstView::RenderScene(){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer glLoadIdentity(); // Reset The Current Modelview Matrix glTranslatef(-1.5f,0.0f,-6.0f); // Move Left 1.5 Units And Into The Screen 6.0 glRotatef(30,0.0f,1.0f,0.0f); // Rotate The Triangle On The Y axis ( NEW ) glBegin(GL_TRIANGLES); // Start Drawing A Triangle glColor3f(1.0f,0.0f,0.0f); // Red glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Front) glColor3f(0.0f,1.0f,0.0f); // Green glVertex3f(-1.0f,-1.0f, 1.0f); // Left Of Triangle (Front) glColor3f(0.0f,0.0f,1.0f); // Blue glVertex3f( 1.0f,-1.0f, 1.0f); // Right Of Triangle (Front) glColor3f(1.0f,0.0f,0.0f); // Red glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Right) glColor3f(0.0f,0.0f,1.0f); // Blue glVertex3f( 1.0f,-1.0f, 1.0f); // Left Of Triangle (Right) glColor3f(0.0f,1.0f,0.0f); // Green glVertex3f( 1.0f,-1.0f, -1.0f); // Right Of Triangle (Right) glColor3f(1.0f,0.0f,0.0f); // Red glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Back) glColor3f(0.0f,1.0f,0.0f); // Green glVertex3f( 1.0f,-1.0f, -1.0f); // Left Of Triangle (Back) glColor3f(0.0f,0.0f,1.0f); // Blue glVertex3f(-1.0f,-1.0f, -1.0f); // Right Of Triangle (Back) glColor3f(1.0f,0.0f,0.0f); // Red glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Left) glColor3f(0.0f,0.0f,1.0f); // Blue glVertex3f(-1.0f,-1.0f,-1.0f); // Left Of Triangle (Left) glColor3f(0.0f,1.0f,0.0f); // Green glVertex3f(-1.0f,-1.0f, 1.0f); // Right Of Triangle (Left) glEnd(); // Done Drawing The Pyramid glLoadIdentity(); // Reset The Current Modelview Matrix glTranslatef(1.5f,0.0f,-7.0f); // Move Right 1.5 Units And Into The Screen 7.0 glRotatef(25,1.0f,1.0f,1.0f); // Rotate The Quad On The X axis ( NEW ) glBegin(GL_QUADS); // Draw A Quad glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Top) glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Top) glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top) glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top) glColor3f(1.0f,0.5f,0.0f); // Set The Color To Orange glVertex3f( 1.0f,-1.0f, 1.0f); // Top Right Of The Quad (Bottom) glVertex3f(-1.0f,-1.0f, 1.0f); // Top Left Of The Quad (Bottom) glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Bottom) glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Bottom) glColor3f(1.0f,0.0f,0.0f); // Set The Color To Red glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front) glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front) glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Front) glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Front) glColor3f(1.0f,1.0f,0.0f); // Set The Color To Yellow glVertex3f( 1.0f,-1.0f,-1.0f); // Top Right Of The Quad (Back) glVertex3f(-1.0f,-1.0f,-1.0f); // Top Left Of The Quad (Back) glVertex3f(-1.0f, 1.0f,-1.0f); // Bottom Left Of The Quad (Back) glVertex3f( 1.0f, 1.0f,-1.0f); // Bottom Right Of The Quad (Back) glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left) glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Left) glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Left) glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Left) glColor3f(1.0f,0.0f,1.0f); // Set The Color To Violet glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Right) glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right) glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Right) glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Right) glEnd(); // Done Drawing The Quad}
到这里点击编译运行,就可以看到如图所示的效果
网上一般到这里配置就完成了,笔者在这里提供了实现坐标交互的方法,大家有兴趣的可以看一下:
在OpenGlFormView.h添加
//控制旋转和位置的变量
GLfloat m_xAngle;//GLfloat m_yAngle;GLfloat m_xPos;GLfloat m_yPos;CPoint m_MouseDownPoint;
在构造函数进行变量初始化
COpenGlFormView::COpenGlFormView(){ // TODO: 在此处添加构造代码 m_xPos=-1.5f; m_yPos=0.0f; m_xAngle=30; m_yAngle=40;}
添加鼠标移动响应函数,添加代码:
void COpenGlFormView::OnMouseMove(UINT nFlags, CPoint point){ // TODO: 在此添加消息处理程序代码和/或调用默认值 m_xAngle+=(point.y-m_MouseDownPoint.y)/3.6; m_yAngle+=(point.x-m_MouseDownPoint.x)/3.6; //Set the mouse point m_MouseDownPoint=point; InvalidateRect(NULL,true); CView::OnMouseMove(nFlags, point); }
修改RenderScene()函数:
`void COpenGlFormView::RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth BufferglLoadIdentity();glTranslatef(m_xPos, m_yPos, -5.0f);glRotatef(m_xAngle, 1.0f,0.0f,0.0f);glRotatef(m_yAngle, 0.0f,1.0f,0.0f);glBegin(GL_TRIANGLES); // Start Drawing A TriangleglColor3f(1.0f,0.0f,0.0f); // RedglVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Front)glColor3f(0.0f,1.0f,0.0f); // GreenglVertex3f(-1.0f,-1.0f, 1.0f); // Left Of Triangle (Front)glColor3f(0.0f,0.0f,1.0f); // BlueglVertex3f( 1.0f,-1.0f, 1.0f); // Right Of Triangle (Front)glColor3f(1.0f,0.0f,0.0f); // RedglVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Right)glColor3f(0.0f,0.0f,1.0f); // BlueglVertex3f( 1.0f,-1.0f, 1.0f); // Left Of Triangle (Right)glColor3f(0.0f,1.0f,0.0f); // GreenglVertex3f( 1.0f,-1.0f, -1.0f); // Right Of Triangle (Right)glColor3f(1.0f,0.0f,0.0f); // RedglVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Back)glColor3f(0.0f,1.0f,0.0f); // GreenglVertex3f( 1.0f,-1.0f, -1.0f); // Left Of Triangle (Back)glColor3f(0.0f,0.0f,1.0f); // BlueglVertex3f(-1.0f,-1.0f, -1.0f); // Right Of Triangle (Back)glColor3f(1.0f,0.0f,0.0f); // RedglVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Left)glColor3f(0.0f,0.0f,1.0f); // BlueglVertex3f(-1.0f,-1.0f,-1.0f); // Left Of Triangle (Left)glColor3f(0.0f,1.0f,0.0f); // GreenglVertex3f(-1.0f,-1.0f, 1.0f); // Right Of Triangle (Left)glEnd(); // Done Drawing The Pyramid
/*
glLoadIdentity();glTranslatef(m_xPos, m_yPos, -5.0f);glRotatef(m_xAngle, 1.0f,0.0f,0.0f);glRotatef(m_yAngle, 0.0f,1.0f,0.0f);glBegin(GL_QUADS); // Draw A QuadglColor3f(0.0f,1.0f,0.0f); // Set The Color To GreenglVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Top)glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Top)glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top)glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top)glColor3f(1.0f,0.5f,0.0f); // Set The Color To OrangeglVertex3f( 1.0f,-1.0f, 1.0f); // Top Right Of The Quad (Bottom)glVertex3f(-1.0f,-1.0f, 1.0f); // Top Left Of The Quad (Bottom)glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Bottom)glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Bottom)glColor3f(1.0f,0.0f,0.0f); // Set The Color To RedglVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front)glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front)glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Front)glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Front)glColor3f(1.0f,1.0f,0.0f); // Set The Color To YellowglVertex3f( 1.0f,-1.0f,-1.0f); // Top Right Of The Quad (Back)glVertex3f(-1.0f,-1.0f,-1.0f); // Top Left Of The Quad (Back)glVertex3f(-1.0f, 1.0f,-1.0f); // Bottom Left Of The Quad (Back)glVertex3f( 1.0f, 1.0f,-1.0f); // Bottom Right Of The Quad (Back)glColor3f(0.0f,0.0f,1.0f); // Set The Color To BlueglVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left)glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Left)glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Left)glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Left)glColor3f(1.0f,0.0f,1.0f); // Set The Color To VioletglVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Right)glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right)glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Right)glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Right)glEnd(); // Done Drawing The Quad*/
}`
源码链接地址:http://download.csdn.net/detail/tracy_n/9190191
到这里运行就能实现跟图形进行交互啦,其实笔者也是刚刚入门opengl,学习中还有很多不懂得地方,大家有问题可以留言交流,加QQ都可以,其实笔者也有一个问题,如何在MFC框架用Openmesh读取off文件,再用Opengl进行显示?欢迎大家来讨论,留言!
- OpenGL的配置以及在MFC框架上的使用(附上源代码)
- 在MFC中使用OpenGL相关配置的整理总结
- OpenGL的MFC框架
- 大数据的加法、减法、乘法以及阶乘的计算问题(源代码附上)
- 教你在mac上配置adb环境变量!!附上adb无法识别M2的解决办法
- OpenGL在windows上的配置
- MFC框架下的OPENGL
- 搭建OpenGL的MFC框架
- OpenGL在vs2015上的配置(蓝宝书win10)
- 在QT和SDL搭建的框架中使用OPENGL在SDL窗口上进行绘图
- 直接在MFC的对话框上利用OpenGL绘制图形
- ant的安装配置以及在Eclipse上集成使用
- OpenGL在MFC中的使用总结(二)——派生的OpenGL类
- Ubuntu 下使用OpenGL/GLUT的配置以及在Codeblocks中使用GLUT
- 在MFC下使用OpenGL的一个简单的例子
- 在MFC下使用OpenGL的一个简单的例子
- 在Visual Studio 2013下利用MFC框架配置OpenGL
- Yaf框架在window上的配置
- 使用Servlet3.0提供的API实现文件上传
- OC设计模式浅析
- C语言的分支语句解析
- JSONKit总结笔记
- 最近学习感悟
- OpenGL的配置以及在MFC框架上的使用(附上源代码)
- Linux 终端与控制台的区别
- Android中最佳常量定义方法
- STLport和Dinkumware STL区别
- 链表的基本操作,建立,测长,删除,打印,插入
- 文章标题
- 编程
- 基础c注意点(一)
- ubuntu 下的PDF阅读器(超级好使)