




已阅读5页,还剩80页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
手把手教你搭建用MFC进行OpenGL编程的框架 第一步:创建项目文件 File | New | Project | MFC AppWizard (exe) | 输入Project Name | 创建一个基于SDI,View类基于CView 的工程文件;第二步:向项目文件中添加OpenGL的绘图函数 Project | Settings | 在Object/library modules:中输入opengl32.lib,glu32.lib,glaux.lib,三者之间用空 格隔开,逗号不用输入; 第三步:添加一些代码 1)在项目工作区的FileView中找到StdAfx.h,添加下面的代码: #include #include #include 2)在项目工作区的ClassView中找到CView类,右击CView类,选择Add Member Vairable,添加一个成员 变量HGLRC m_hRC;选择Add Member Founction,添加一个成员函数void DrawScene(); 3)在项目工作区的ClassView中找到CView类,右击CView类,选择Add Windows Message Handler,为 CView类添加WM_CREATE,WM_DESTORY(方法:在左边的New windows message/events中选中并 双击,然后点击OK)。 在项目工作区的ClassView中找到CView类,找到函数OnCreate(),在该函数中添加如下代码: /定义像素存储格式 PIXELFORMATDESCRIPTOR pfd= sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL,PFD_TYPE_RGBA, 24, 0,0,0,0,0,0, 0,0,0,0,0,0,0, 32, 0,0, PFD_MAIN_PLANE, 0, 0,0,0, ; CClientDC dc(this); int pixelFormat=ChoosePixelFormat(dc.m_hDC,&pfd); BOOL success=SetPixelFormat(dc.m_hDC,pixelFormat,&pfd); m_hRC=wglCreateContext(dc.m_hDC); 同理找到函数OnDestory(),在该函数中添加下面的代码: wglDeleteContext(m_hRC); 4)在类CView中的函数PreCreateWindows()中添加下面的代码: cs.style|=(WS_CLIPSIBLINGS|WS_CLIPCHILDREN); 5)在类CView中的函数OnDraw()中添加下面的代码: wglMakeCurrent(pDC-m_hDC,m_hRC); DrawScene();/用户自定义的场景绘制函数 wglMakeCurrent(pDC-m_hDC,NULL);这样,一个基于OpenGl标准的程序框架已经构造好了,用户只需在DrawScene()函数中添加程序代码即可。为了验证程序框架的是否正确,请在DrawScene()函数中添加下面的代码: glBegin(GL_TRIANGLE_STRIP); glColor3f(1.0,0.0,0.0); glVertex3f(0.0,0.0,0.0); glColor3f(0.0,1.0,0.0); glVertex3f(-0.5,0.0,0.0); glColor3f(0.0,0.0,1.0); glVertex3f(0.0,0.5,0.0); glEnd(); glFlush();然后编译执行直至在MFC窗口中绘制出了一个顶点颜色不同的三角形即可。/ MeshView.cpp : implementation of the CMeshView class / #include stdafx.h #include Mesh.h #include MeshDoc.h #include MeshView.h #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE = _FILE_; #endif / / CMeshView IMPLEMENT_DYNCREATE(CMeshView, CView) BEGIN_MESSAGE_MAP(CMeshView, CView) /AFX_MSG_MAP(CMeshView) ON_WM_PAINT() ON_WM_DESTROY() ON_WM_SIZE() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_RBUTTONDOWN() ON_WM_RBUTTONUP() ON_WM_MOUSEMOVE() ON_WM_ERASEBKGND() ON_WM_CREATE() ON_COMMAND(ID_EDIT_COPY, OnEditCopy) /AFX_MSG_MAP / Standard printing commands ON_COMMAND(ID_FILE_PRINT, CView:OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView:OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView:OnFilePrintPreview) END_MESSAGE_MAP() / / CMeshView construction/destruction CMeshView:CMeshView() / OpenGL m_hGLContext = NULL; m_GLPixelIndex = 0; / Mouse m_LeftButtonDown = FALSE; m_RightButtonDown = FALSE; / Colors m_ClearColorRed = 0.0f; m_ClearColorGreen = 0.0f; m_ClearColorBlue = 0.2f; / Animation m_StepRotationX = 0.0f; m_StepRotationY = 5.0f; m_StepRotationZ = 0.0f; InitGeometry(); CMeshView:CMeshView() /* / InitGeometry /* void CMeshView:InitGeometry(void) m_xRotation = 0.0f; m_yRotation = 0.0f; m_zRotation = 0.0f; m_xTranslation = 0.0f; m_yTranslation = 0.0f; m_zTranslation = -5.0f; m_xScaling = 1.0f; m_yScaling = 1.0f; m_zScaling = 1.0f; m_SpeedRotation = 1.0f / 3.0f; m_SpeedTranslation = 1.0f / 50.0f; m_xyRotation = 1; BOOL CMeshView:PreCreateWindow(CREATESTRUCT& cs) return CView:PreCreateWindow(cs); / / CMeshView drawing void CMeshView:OnDraw(CDC* pDC) CMeshDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); / TODO: add draw code for native data here / / CMeshView printing BOOL CMeshView:OnPreparePrinting(CPrintInfo* pInfo) / default preparation return DoPreparePrinting(pInfo); void CMeshView:OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) void CMeshView:OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) / / CMeshView diagnostics #ifdef _DEBUG void CMeshView:AssertValid() const CView:AssertValid(); void CMeshView:Dump(CDumpContext& dc) const CView:Dump(dc); CMeshDoc* CMeshView:GetDocument() / non-debug version is inline ASSERT(m_pDocument-IsKindOf(RUNTIME_CLASS(CMeshDoc); return (CMeshDoc*)m_pDocument; #endif /_DEBUG / / / OPENGL / / /* / OnCreate / Create OpenGL rendering context /* int CMeshView:OnCreate(LPCREATESTRUCT lpCreateStruct) if(CView:OnCreate(lpCreateStruct) = -1) return -1; HWND hWnd = GetSafeHwnd(); HDC hDC = :GetDC(hWnd); if(SetWindowPixelFormat(hDC)=FALSE) return 0; if(CreateViewGLContext(hDC)=FALSE) return 0; /:ReleaseDC(hWnd,hDC); / Default mode glPolygonMode(GL_FRONT,GL_FILL); glPolygonMode(GL_BACK,GL_FILL); glShadeModel(GL_SMOOTH); glEnable(GL_NORMALIZE); / Lights properties floatambientProperties = 0.7f, 0.7f, 0.7f, 1.0f; floatdiffuseProperties = 0.8f, 0.8f, 0.8f, 1.0f; floatspecularProperties = 1.0f, 1.0f, 1.0f, 1.0f; glLightfv( GL_LIGHT0, GL_AMBIENT, ambientProperties); glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuseProperties); glLightfv( GL_LIGHT0, GL_SPECULAR, specularProperties); glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, 1.0); glClearColor(m_ClearColorRed,m_ClearColorGreen,m_ClearColorBlue,1.0f); glClearDepth(1.0f); glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); / Perspective CRect rect; GetClientRect(&rect); double aspect = (rect.Height() = 0) ? rect.Width() : (double)rect.Width()/(double)rect.Height(); gluPerspective(45,aspect,0.1,1000.0); /glPolygonMode(GL_FRONT,GL_FILL); /glPolygonMode(GL_BACK,GL_POINT); / Default : lighting glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); / Default : blending glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); / Default : material floatMatAmbient = 0.0f, 0.33f, 0.50f, 1.0f; floatMatDiffuse = 0.5f, 0.5f, 0.5f, 1.0f; floatMatSpecular = 0.1f, 0.1f, 0.1f, 1.0f; floatMatShininess = 84 ; floatMatEmission = 0.0f, 0.0f, 0.0f, 1.0f; / Back : green float MatAmbientBack = 0.0f, 0.5f, 0.0f, 1.0f; glEnable(GL_DEPTH_TEST); /glDepthFunc(Gl_LESS); / Modulate : texture lighting glEnable(GL_TEXTURE_2D); TRACE(Texture parameters.n); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); return 1; / / CMeshView message handlers void CMeshView:OnPaint() / Device context for painting CPaintDC dc(this); / Model is stored in Document CMeshDoc *pDoc = (CMeshDoc *)GetDocument(); /ASSERT_VALID(pDoc); / Useful in multidoc templates HWND hWnd = GetSafeHwnd(); HDC hDC = :GetDC(hWnd); wglMakeCurrent(hDC,m_hGLContext); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); / Position / translation / scale glTranslated(m_xTranslation,m_yTranslation,m_zTranslation); glRotatef(m_xRotation, 1.0, 0.0, 0.0); glRotatef(m_yRotation, 0.0, 1.0, 0.0); glRotatef(m_zRotation, 0.0, 0.0, 1.0); glScalef(m_xScaling,m_yScaling,m_zScaling); / Start rendering. pDoc-RenderScene(); glPopMatrix(); / Double buffer SwapBuffers(dc.m_ps.hdc); glFlush(); / Release :ReleaseDC(hWnd,hDC); /* / SetWindowPixelFormat /* BOOL CMeshView:SetWindowPixelFormat(HDC hDC) PIXELFORMATDESCRIPTOR pixelDesc; pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR); pixelDesc.nVersion = 1; pixelDesc.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_STEREO_DONTCARE; pixelDesc.iPixelType = PFD_TYPE_RGBA; pixelDesc.cColorBits = 32; pixelDesc.cRedBits = 8; pixelDesc.cRedShift = 16; pixelDesc.cGreenBits = 8; pixelDesc.cGreenShift = 8; pixelDesc.cBlueBits = 8; pixelDesc.cBlueShift = 0; pixelDesc.cAlphaBits = 0; pixelDesc.cAlphaShift = 0; pixelDesc.cAccumBits = 64; pixelDesc.cAccumRedBits = 16; pixelDesc.cAccumGreenBits = 16; pixelDesc.cAccumBlueBits = 16; pixelDesc.cAccumAlphaBits = 0; pixelDesc.cDepthBits = 32; pixelDesc.cStencilBits = 8; pixelDesc.cAuxBuffers = 0; pixelDesc.iLayerType = PFD_MAIN_PLANE; pixelDesc.bReserved = 0; pixelDesc.dwLayerMask = 0; pixelDesc.dwVisibleMask = 0; pixelDesc.dwDamageMask = 0; m_GLPixelIndex = ChoosePixelFormat(hDC,&pixelDesc); if(m_GLPixelIndex = 0) / Choose default m_GLPixelIndex = 1; if(DescribePixelFormat(hDC,m_GLPixelIndex, sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)=0) return FALSE; if(!SetPixelFormat(hDC,m_GLPixelIndex,&pixelDesc) return FALSE; / CListBox return TRUE; /* / CreateViewGLContext / Create an OpenGL rendering context /* BOOL CMeshView:CreateViewGLContext(HDC hDC) m_hGLContext = wglCreateContext(hDC); if(m_hGLContext=NULL) return FALSE; if(wglMakeCurrent(hDC,m_hGLContext)=FALSE) return FALSE; return TRUE; void CMeshView:OnDestroy() if(wglGetCurrentContext() != NULL) wglMakeCurrent(NULL,NULL); if(m_hGLContext != NULL) wglDeleteContext(m_hGLContext); m_hGLContext = NULL; CView:OnDestroy(); void CMeshView:OnSize(UINT nType, int cx, int cy) CView:OnSize(nType, cx, cy); HWND hWnd = GetSafeHwnd(); HDC hDC = :GetDC(hWnd); /TRACE(Activate view, set active OpenGL rendering context.n); wglMakeCurrent(hDC,m_hGLContext); / Set OpenGL perspective, viewport and mode double aspect = (cy = 0) ? cx : (double)cx/(double)cy; glViewport(0,0,cx,cy); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45,aspect,0.1,1000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glDrawBuffer(GL_BACK); / Release :ReleaseDC(hWnd,hDC); void CMeshView:OnLButtonDown(UINT nFlags, CPoint point) m_LeftButtonDown = TRUE; m_LeftDownPos = point; SetCapture(); CView:OnLButtonDown(nFlags, point); void CMeshView:OnLButtonUp(UINT nFlags, CPoint point) m_RightButtonDown = FALSE; m_LeftButtonDown = FALSE; ReleaseCapture(); CView:OnLButtonUp(nFlags, point); void CMeshView:OnRButtonDown(UINT nFlags, CPoint point) m_RightButtonDown = TRUE; m_RightDownPos = point; SetCapture(); CView:OnRButtonDown(nFlags, point); void CMeshView:OnRButtonUp(UINT nFlags, CPoint point) m_RightButtonDown = FALSE; m_LeftButtonDown = FALSE; ReleaseCapture(); CView:OnRButtonUp(nFlags, point); void CMeshView:OnMouseMove(UINT nFlags, CPoint point) / Both : rotation if(m_LeftButtonDown & m_RightButtonDown) if(m_xyRotation) m_yRotation -= (float)(m_LeftDownPos.x - point.x) * m_SpeedRotation; m_xRotation -= (float)(m_LeftDownPos.y - point.y) * m_SpeedRotation; else m_zRotation -= (float)(m_LeftDownPos.x - point.x) * m_SpeedRotation; m_xRotation -= (float)(m_LeftDownPos.y - point.y) * m_SpeedRotation; m_LeftDownPos = point; m_RightDownPos = point; InvalidateRect(NULL,FALSE); else / Left : x / y translation if(m_LeftButtonDown) m_xTranslation -= (float)(m_LeftDownPos.x - point.x) * m_SpeedTranslation; m_yTranslation += (float)(m_LeftDownPos.y - point.y) * m_SpeedTranslation; m_LeftDownPos = point; InvalidateRect(NULL,FALSE); else / Right : z translation if(m_RightButtonDown) m_zTranslation += (float)(m_RightDownPos.y - point.y) * m_SpeedTranslation; m_RightDownPos = point; InvalidateRect(NULL,FALSE); /* TRACE(nPositionn); TRACE(Translation : %g %g %gn,m_xTranslation,m_yTranslation,m_zTranslation); TRACE(Rotation : %g %g %gn,m_xRotation,m_yRotation,m_zRotation); */ CView:OnMouseMove(nFlags, point); BOOL CMeshView:OnEraseBkgnd(CDC* pDC) return TRUE; return CView:OnEraseBkgnd(pDC); void CMeshView:OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView) HWND hWnd = GetSafeHwnd(); HDC hDC = :GetDC(hWnd); wglMakeCurrent(hDC,m_hGLContext); :ReleaseDC(hWnd,hDC); CView:OnActivateView(bActivate, pActivateView, pDeactiveView); void CMeshView:OnEditCopy() / Clean clipboard of contents, and copy the DIB. if(OpenClipboard() BeginWaitCursor(); / Snap CSize size; unsigned char *pixel = SnapClient(&size); / Image CTexture image; / Link image - buffer int success = 0; VERIFY(image.ReadBuffer(pixel,size.cx,size.cy,24); / Cleanup memory delete pixel; EmptyClipboard(); SetClipboardData(CF_DIB,image.ExportHandle(); CloseClipboard(); EndWaitCursor(); / Hand-made client snapping unsigned char *CMeshView:SnapClient(CSize *pSize) BeginWaitCursor(); / Client zone CRect rect; GetClientRect(&rect); /CSize size(CTexture:LowerPowerOfTwo(rect.Width(),rect.Height(); CSize size(rect.Width(),rect.Height(); *pSize = size; ASSERT(size.cx 0); ASSERT(size.cy 0); / Alloc unsigned char *pixel = new unsigned char3*size.cx*size.cy; ASSERT(pixel != NULL); / Capture frame buffer TRACE(Start reading client.n); TRACE(Client : (%d,%d)n,size.cx,size.cy); CRect ClientRect,MainRect; this-GetWindowRect(&ClientRect); CWnd *pMain = AfxGetApp()-m_pMainWnd; CWindowDC dc(pMain); pMain-GetWindowRect(&MainRect); int xOffset = ClientRect.left - MainRect.left; int yOffset = ClientRect.top - MainRect.top; for(int j=0;jsize.cy;j+) for(int i=0;isize.cx;i+) COLORREF color = dc.GetPixel(i+xOffset,j+yOffset); pixel3*(size.cx*(size.cy-1-j)+i) = (BYTE)GetBValue(color); pixel3*(size.cx*(size.cy-1-j)+i)+1 = (BYTE)GetGValue(color); pixel3*(size.cx*(size.cy-1-j)+i)+2 = (BYTE)GetRValue(color); EndWaitCursor(); return pixel; 【转】基于MFC的OpenGL绘图(续) 三、画图实例 下面给出一个简单的二维图形的例子(这个例子都是以上述框架为基础的)。 用Classwizard为COpenGLDemoView添加WMSIZE的消息处理函数OnSize,代码如下:void COpenGLDemoView:OnSize(UINT nType, int cx, int cy) CView:OnSize(nType, cx, cy); / TODO: Add your message handler code here GLsizei width,height; GLdouble aspect; width = cx; height = cy; if(cy=0) aspect = (GLdouble)width; else aspect = (GLdouble)width/(GLdouble)height; glViewport(0,0,width,height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0,500.0*aspect,0.0,500.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity();用Classwizard为COpenGLDemoView添加WM_PAINT的消息处理函数OnPaint,代码如下:void COpenGLDemoView:OnPaint() CPaintDC dc(this); / device context for painting / TODO: Add your message handler code here / Do not call CView:OnPaint() for painting messages glLoadIdentity(); glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_POLYGON); glColor4f(1.0f,0.0f,0.0f,1.0f); glVertex2f(100.0f,50.0f); glColor4f(0.0f,1.0f,0.0f,1.0f); glVertex2f(450.0f,400.0f); glColor4f(0.0f,0.0f,1.0f,1.0f); glVertex2f(450.0f,50.0f); glEnd(); glFlush();这个程序的运行结果是黑色背景下的一个绚丽多彩的三角形。 这里你可以看到用OpenGL绘制图形非常容易,只需要几条简单的语句就能实现 强大的功能。如果你缩放窗口,三角形也会跟着缩放。这是因为OnSize通过glViewport(0, 0, width, height)定义了视口和视口坐标。glViewport的第一、二个参数是视口左下角的像素坐标,第三、四个参数是视口的宽度和高度。 OnSize中的glMatrixMode是用来设置矩阵模式的,它有三个选项:GL_MODELVIEW、GL_PROJECTION、 GL_TEXTURE。GL_MODELVIEW表示从实体坐标系转到人眼坐标系。GL_PROJECTION表示从人眼坐标系转到剪裁坐标系。 GL_TEXTURE表示从定义纹理的坐标系到粘贴纹理的坐标系的变换。 glLoadIdentity初始化工程矩阵(project matrix);gluOrtho2D把工程矩阵设置成显示一个二维直角
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年广告策划主管职业资格考试试题及答案解析
- 课件专利申请
- 课件三维展示
- 如何做跳绳直播教学课件
- 2025年吉林安全员考试重点解析题及答案
- 初中游泳教学课件
- 读书伴我成长课件
- 2025年宠物行为训练师面试题与解析
- 2025年电子商务师职业资格考试试题及答案解析
- 2025年无人机飞手资格认证高级笔试题集
- 2024年公开招聘事业单位工作人员报名登记表
- 全国人力资源和社会保障法律法规知识网络竞赛题及答案
- GB/T 44335-2024精细陶瓷涂层试验方法基于Stoney公式的陶瓷涂层内应力测定
- 水电站进水口启闭机排架结构及配筋计算书
- 《大学英语四级强化教程》全套教学课件
- 《国有企业管理人员处分条例》学习解读课件
- 高中教师业务知识考试 语文试题及答案
- 2024年景区托管运营合作协议
- 保定市城市建设投资集团有限公司招聘笔试真题2023
- 材料设备进场验收单、样板确认、整改单
- 品牌服装设计课件
评论
0/150
提交评论