基于MFC的OpenGL绘图程序框架
MFC下OpenGL入门讲述
MFC下OpenGL入门源文件1,建一工程文件,我这里命名为first,现在first工程里面我们没有添加任何东西,所有的东西都是MFC自动帮我们创建的。
2,添加链接库。
这一步很关键。
打开菜单栏下的项目->属性->配置属性->链接器->输入->附加依赖项里加入OpenGL32.lib GLu32.lib GLaux.lib,如图3,加头文件,在stdafx里面添加opengl的头文件。
如下代码所示://-----------------------Tramp---添加OpenGL库头文件----------------------------->#include "stdio.h"#include "math.h"#include "gl\gl.h"#include "gl\glu.h"#include "gl\glaux.h"//---------------------------------------------------------------------------<代码4, CCY457OpenGLView类的属性栏,为下述消息加入消息处理函数:WM_CREATE (for OnCreate), WM_DESTROY (for OnDestroy), WM_SIZE (forOnSize), WM_ERASEBACKGROUND (for OnEraseBkground).如下图:5,设置窗口显示风格。
窗口创建之前我们必须设置窗口风格包含WS_CLIPCHILDREN 和WS_CLIPSIBLINGS,从而避免OpenGL绘制到其他窗口中去。
这些应该放在PreCreateWindow()中。
B OOL CfirstView::PreCreateWindow(CREATESTRUCT& cs){// TODO: 在此处通过修改// CREATESTRUCT cs 来修改窗口类或样式cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;//Trampreturn CView::PreCreateWindow(cs);}代码6,在CfirstView.h中加入如下语句:/************************************************************************//* 设置的变量是Rendering Context(着色描述表)。
基于MFC的OpenGL绘图
基于MFC的OpenGL绘图本文更新版本请点击[置顶]《基于MFC的OpenGL编程》系列文章一、简介GDI是通过设备句柄(Device Context以下简称"DC")来绘图,而OpenGL则需要绘制环境(Rendering Context,以下简称"RC")。
每一个GDI命令需要传给它一个DC,但与GDI不同,OpenGL使用当前绘制环境(RC)。
一旦在一个线程中指定了一个当前RC,在此线程中其后所有的OpenGL命令都使用相同的当前RC。
虽然在单一窗口中可以使用多个RC,但在单一线程中只有一个当前RC。
下面我将首先产生一个OpenGL RC并使之成为当前RC,这将分为三个步骤:设置窗口像素格式;产生RC;设置为当前RC。
二、MFC中的OpenGL基本框架1、首先创建工程用AppWizard产生一个MFC EXE项目,其他默认即可。
2、将此工程所需的OpenGL文件和库加入到工程中在工程菜单中,选择"Build"下的"Settings"项。
单击"Link"标签,选择"General"目录,在Object/Library Modules的编辑框中输入"opengl32.lib glu32.lib glut.lib glaux.lib"(注意,输入双引号中的内容,各个库用空格分开;否则会出现链接错误),选择"OK"结束。
然后打开文件"stdafx.h",加入下列头文件:#include <gl\gl.h>#include <gl\glu.h>3、改写OnPreCreate函数并给视图类添加成员函数和成员变量OpenGL需要窗口加上WS_CLIPCHILDREN(创建父窗口使用的Windows风格,用于重绘时裁剪子窗口所覆盖的区域)和WS_CLIPSIBLINGS(创建子窗口使用的Windows风格,用于重绘时剪裁其他子窗口所覆盖的区域)风格。
MFC下基于OpenGL绘图程序的开发步骤和框架
。 能 体 整 和 识 意 任 责 员 高 提 范 规 描 位 岗 、 操 认 确 述 口 指 手 实 落 面 作 工 训 培 育 教 术 技 全 安 抓 狠 设 ”建 基 “双 化 深 断 不 , 织 组 合 理 管 学 科
int m_GLPixelIndex; 其它具体函数及其参数含义,大家可以通过 OpenGL 手册或者 MSDN 查询。这里不作累述。 (2)现在绘制窗口像素格式已经定义好,下一步工作是产生绘制上下文(RC)并使之成为当 前绘制上下文。在视类中加入一个私有型成员函数 BOOL CreateViewGLContext(HDC hDC)。 其中,m_hGLContext 为在视类中添加的一私有型的成员变量: HGLRC m_hGLContext;HGLRC 是一个指向 rendering context 的句柄。 (3)最后,在视类的 OnCreate 函数(OnCreate 函数相应 Window 消息 WM_CREATE,可以通 过 VC 的类向导 Class Wizard Ctrl+W 进行添加,如图)中实现上述两个函数的调用,实现 RC 的定义、产生以及和当前视区窗口 DC 的通讯。 6、添加绘图函数 视类函数 OnDraw 主要负责视区的绘图工作。为了在视区窗口利用 OpenGL 绘制图形,我 们自定义一个绘图函数 DrawScene(), 并 OnDraw 函数中调用该函数, 从而实现在视区窗口绘图。 7、修改视类 OnSize 函数 当视区绘图窗口大小变化时,应及时将新的窗口大小通知 OpenGL,才能在绘图窗口以正 确的比例显示图形。当视区窗口大小变化时,WM_SIZE 消息被触发,所以可以通过 VC 的类向 导 Class Wizard Ctrl+W 添加 WM_SIZE 的消息映射函数 OnSize。 然后对 OnSize 函数做修改。 8、修改视类 OnEraseBkgnd 函数 仿造第 7 步的方法通过类向导 Class Wizard 添加视类对消息 WM_ERASEBKGND 的映射函 数 OnEraseBkgnd,并对该函数进行修改。修改该函数的主要原因是:OpenGL 自身具有重绘能 力,通过修改该函数屏蔽 Window 的重绘操作,从而可以防止窗口频繁刷新时产生的闪烁现象。 9、回收 RC 所占用的资源 通过 VC 的类向导 Class Wizard Ctrl+W 添加 Window 消息 WM_DESTROY 的映射函数 OnDestroy 函数。在该函数中调用 OpenGL 函数 wglDeleteContext 对 RC 所占资源进行回收。注 意,回收之前需要先使用 OpenGL 函数 wglMakeCurrent 断开 RC 与 DC 的连接。 10、初始化绘图数据 编辑视类构造函数,初始化绘图数据。 至此,我们已构造好了框架,使该工程可以利用 OpenGL 进行绘图了。假设现在绘制一个 三角形,只需要在第 6 步添加的 DrawScene 函数中添加绘制三角形的函数, (二)生成三维物体 1) 首先,在 OnSize()中,把 gluOrtho2D(0.0, 500.0*aspect,0.0, 500.0)换成 gluPerspective(60, aspect, 1, 10.0);这样就实现了三维透视坐标系的设置。该语句说明了视点在原点,透视角是 60 度,近裁剪面在 z=1 处,远裁剪面在 z=10.0 处。 2) 在 DrawScene 函数中生成三维图形;
手把手教你搭建用MFC进行OpenGL编程的框架
手把手教你搭建用MFC进行OpenGL编程的框架手把手教你搭建用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#include2)在项目工作区的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_TYP E_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()函数中添加程序代码即可。
VC(MFC)开发OPENGL程序
VC(MFC)开发OPENGL程序作者:李英江日期: 2006-08-10 19:07:00网站:转载请保留作者内容!利用使用VC开发OPENGL程序,运用MFC库,做一个简单例子我简单介绍一下图形接口,现在流行的两大图形接口Direct3D 和OpenGL,Direct3D主要是针对游戏,像starcaft星际争霸,它支持DX5.0以上的版本,但是不少游戏同时支持两种图形加速,如CS,魔兽争霸。
OpenGL主要是针对专业的图形应用,在军事,医学,GIS地理信息系统,动画(3dsmax,maya...),电影,等应用广泛,并且可以在不同的平台上应用,DX相对来说就只能限于Windows操作系统了。
1.运用MFC向导,生成一个单文档应用程序,不做任何事的MFC 框架程序。
2.视图类中添加窗口样式。
/************************************************************** *******/BOOL CMfc_basicView::PreCreateWindow(CREATESTRUCT& cs){// Add Window styles required for OpenGL before window iscreatedcs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CS_OWNDC);return CView::PreCreateWindow(cs);}/************************************************************** *******/3.在afxcmn.h中包含OPENGL头文件。
/************************************************************** *******/#include <afxcmn.h>// MFC support for Windows Common Controls// Inserted these files for openGL#include <gl.h>#include <glut.h>#include <glu.h>#include <glaux.h>#endif // _AFX_NO_AFXCMN_SUPPORT/************************************************************** *******/4.视图类中 .h文件中加入四个public 成员变量/************************************************************** *******/HGLRC m_hRC; // Permanent Rendering ContextHDC m_myhDC; // Private GDI Device Contextint m_height; // Stores the height of the Viewint m_width; // Stores the width of the view/************************************************************** *******/5.视图类中右键添加一个BOOL成员函数SetupPixelFormat/************************************************************** *******/BOOL COglm_demoView::SetupPixelFormat(){GLuint PixelFormat;static PIXELFORMATDESCRIPTOR pfd= {sizeof(PIXELFORMATDESCRIPTOR),// Size Of This Pixel Format Descriptor1,// Version Number (?)PFD_DRAW_TO_WINDOW | // Format Must Support WindowPFD_SUPPORT_OPENGL | // Format Must Support OpenGL PFD_DOUBLEBUFFER, // Must Support Double Buffering PFD_TYPE_RGBA, // Request An RGBA Format24, // Select A 24Bit Color Depth0, 0, 0, 0, 0, 0, // Color Bits Ignored (?)0, // No Alpha Buffer0, // Shift Bit Ignored (?)0, // No Accumulation Buffer0, 0, 0, 0, // Accumulation Bits Ignored (?)16, // 16Bit Z-Buffer (Depth Buffer)0, // No Stencil Buffer0, // No Auxiliary Buffer (?)PFD_MAIN_PLANE, // Main Drawing Layer0, // Reserved (?)0, 0, 0 // Layer Masks Ignored (?)};m_myhDC = ::GetDC(m_hWnd); // Gets A Device Context For The WindowPixelFormat = ChoosePixelFormat(m_myhDC, &pfd); // Finds The Closest Match To The Pixel Format We Set Aboveif (!PixelFormat){::MessageBox(0,"Can't Find A Suitable PixelFormat.","Error",MB_OK|MB_ICONERROR);PostQuitMessage(0);// This Sends A 'Message' Telling The Program To Quitreturn false ; // Prevents The Rest Of The Code From Running}if(!SetPixelFormat(m_myhDC,PixelFormat,&pfd)){::MessageBox(0,"Can't Set The PixelFormat.","Error",MB_OK|MB_ICONERROR);PostQuitMessage(0);return false;}m_hRC = wglCreateContext(m_myhDC);if(!m_hRC){::MessageBox(0,"Can't Create A GL Rendering Context.","Error",MB_OK|MB_ICONERROR);PostQuitMessage(0);return false;}if(!wglMakeCurrent(m_myhDC, m_hRC)){::MessageBox(0,"Can't activate GLRC.","Error",MB_OK|MB_ICONERROR);PostQuitMessage(0);return false;}// Now that the screen is setup we can// initialize OpenGL();InitGL();return true;}/************************************************************** *******/6.关闭WM_ERASEBACKGROUND消息,不关闭的话,画图时会闪动.在视图类中选择“Add Windows Message Handler”加入消息处理函数./************************************************************** *******/BOOL CMfc_basicView::OnEraseBkgnd(CDC* pDC){return FALSE;}/************************************************************** *******/7.初始化OPENGL 添加InitGL()函数./************************************************************** *******/void CMfc_basicView::InitGL(){// Enables Depth TestingglEnable(GL_DEPTH_TEST);// Enable the point size for selected pointsglPointSize(5.0f);// This Will Clear The Background Color To BlackglClearColor(.4, 0.2, 0.0, 0.0f);// Reset the current projection matrixSetProjection();glMatrixMode(GL_MODELVIEW);glLoadIdentity();//Enable back face culling, defaults to Clock wise vertices.glEnable(GL_CULL_FACE);glEnable(GL_COLOR_MATERIAL);glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);glShadeModel(GL_SMOOTH);glPolygonMode(GL_FRONT, GL_FILL);}/************************************************************** *******/8. 在视图类中添加调窗口大小的处理函数OnSize() 消息句柄/************************************************************** *******/void CMfc_basicView::OnSize(UINT nType, int cx, int cy){CView::OnSize(nType, cx, cy);glMatrixMode(GL_MODELVIEW);glLoadIdentity();// Make the rendering context currentwglMakeCurrent(m_myhDC,m_hRC);// Reset The Current Viewport And Perspective TransformationglViewport(0, 0, cx, cy);m_height= cy;m_width = cx;// Calculate The Aspect Ratio Of The WindowgluPerspective(60.0f,(GLfloat)cx/(GLfloat)cy,0.1f,1000.0f);}9.添加SetPorjection()函数void CMfc_basicView::SetProjection(){glViewport(0, 0, m_width, m_height);// Reset The Projection MatrixglMatrixMode(GL_PROJECTION);glLoadIdentity();// It's a perspective projection// Calculate The Aspect Ratio Of The WindowgluPerspective(60.0f,(GLfloat)m_width/(GLfloat)m_height, 0.1f,3000.0f);}/************************************************************** *******/10.在Project 菜单选择Settings. 单击Link 选项页Object/library Module添加库文件.opengl32.lib glu32.lib glut.lib glaux.lib11.在视图类中加入OnCreate消息句柄/*********************************************************************/int CMfc_basicView::OnCreate(LPCREATESTRUCT lpCreateStruct){if (CView::OnCreate(lpCreateStruct) == -1)return -1;SetupPixelFormat();wglMakeCurrent(NULL,NULL);return 0;}/************************************************************** *******///现在编译程序的话,会看到一个无法刷新的应用程序了。
用VisualC_中的MFC和OpenGL建立三维图形应用环境
用Visual C++中的MFC和OpenGL建立三维图形应用环境哈尔滨工业大学现代生产技术中心(150001) 凌 云 储林波摘 要:使用Visual C++的基本类库MFC建立面向对象的OpenGL三维图形应用程序的开发环境。
关键词:三维图形编程 OpenGL三维图形库 M FC类库O penGL是一个功能强大的三维图形库,它与操作系统无关,用O penGL编写的应用程序可以很容易地移植到支持O penG L的操作系统上,例如U N IX。
在Windo ws N T和W indo w s95中提供了对OpenGL的支持,在Window s N T和W indow s95上可以使用V i-sual C++V2.0以上版本来开发OpenGL的应用程序。
而V isual C++完善的基本类库M FC和应用向导A ppW izard使得开发一个复杂的应用程序变得轻松自如。
如果将二者结合起来,便可开发出相当有水平的Windo ws下三维图形应用程序。
1 OpenGL绘图环境初始化使用OpenGL函数库之前,需要以特定的过程进行初始化。
因为O penG L函数库和操作系统无关,它有自已的独特设计,与W indo ws的图形设备接口GDI 模型以及多数M FC应用程序的建立方法不太一致。
Windo ws为此提供了一些专门的A P I函数。
下面简要介绍一下Win32下使用O penG L函数库特殊的初始化过程。
首先,必须重新设置画图窗口的象素格式,使其符合O penGL对象素格式的需要。
为此需声明一个P IX-ELF O RM A T D ESCR IPT OR结构的变量,并适当地设置某些结构成员的值,使其支持O penG L及其颜色模式。
变量的声明见后面SetupPix elFo rma t()函数的描述。
再以此变量为参数调用Choo seP ix elFo rmat()函数分配1个象素格式号,然后调用SetPix elF or mat()将其设置为当前象素格式。
基于MFC的OpenGL简易绘图系统
基于MFC的OpenGL简易绘图系统作者:尤王杰来源:《计算机应用文摘》2022年第07期关键词:MFC;OpenGL;绘图系统;C++面向对象中图法分类号:TP391 文献标识码:A1概述MFC 是微软公司开发的一个类库,以C++类的形式封装了Windows 的API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量。
其中,MFC包含大量Windows 句柄封装类和很多Windows 的内建控件和组件的封装类[1] 。
OpenGL 是一个开放式图形库,是用于渲染2D 和3D 矢量图形的跨语言、跨平台的应用程序编程接口,是一个功能强大、支持底层绘制和造型能力的软件图形函数库。
它独立于硬件和窗口系统,为程序员进行图形学相关的程序编写提供了极大的帮助[2] 。
绘图软件一般指基于计算机绘制图形的软件,如Windows 自带的画图软件等。
它的开发语言和技术已经十分成熟。
本系统实现了基于基本类库MFC 和OpenGL 图形库面向对象的二维图形绘制应用程序,可以实现绘图的功能同时也可以让软件开发人员对软件开发过程有进一步了解。
2软件开发环境软件主要使用C++编程语言编写,使用了C++的基本库类MFC 和图形库OpenGL 以及C++常用库;开发软件的操作系统环境为Windows 10;软件的集成开发环境为Viusal Studio 2017;软件开发的硬件环境为16GB 内存,intel Core i5⁃9400F CPU(2.9GHz);软件支持跨平台使用,可以在不同操作系统中实现功能,同时可以进行本地保存[3] 。
3系统框架设计本系统采用了C++编程语言以及面向对象的编程风格,其基本思想是将现实世界的事物抽象成对象,现实世界中的关系抽象成类、继承,帮助人们实现对现实世界的抽象与数字建模。
通过面向对象的方法,更利于用人理解的方式对复杂系统进行分析、设计与编程。
同时,面向对象能有效提高编程的效率,通过封装技术,可以更高效地开发出一个全新的系统[4] 。
实验二结合MFC与OpenGL实现三维应用程序的显示
实验二结合MFC与OpenGL实现三维应用程序的显示1.实验目的●熟悉OpenGL的编程环境设置●熟悉MFC的基本编程框架●MFC与OpenGL混合编程的设置●OpenGL中基本图元的绘制2.实验内容●创建MFC+OpenGL的编程环境●利用三角形和四边形等基本图元绘制底面圆圆心在坐标原点,半径为r,高为h,方向沿z轴方向的圆柱3.实验指导3.1MFC应用程序框架在Visual C++ 2.0以后的版本中,Microsoft公司推出了MFC(Microsoft Foundation Class)类库。
MFC类库是用来编写Windows程序的C++类集。
使用MFC类库,可以简化应用程序的开发,从而缩短开发周期,而且代码的可靠性和可重用性也大大提高。
3.1.1MFC应用程序的文档/视图结构概述MFC提供了一个典型且实用的基于文档与视图的应用程序框架模板,按照其应用程序生成向导的导引步骤(MFC AppWizard)就可以创建一个基于文档/视图结构的MFC应用程序框架。
在此框架的基础上,设计和插入相关的对象,就可以实现交互式的用户界面、几何模型的管理和操作、图形图像的显示,以及其他各种专业功能。
在MFC的文档/视图结构的应用程序框架中,文档类和视图类是成对出现的。
文档用于管理应用程序的数据;而视图用于显示文档中的数据,并处理与用户的交互信息。
MFC通过文档类和视图类的划分,使数据的存储和显示既相对独立又相互关联。
在MFC所提供的框架结构中,文档与视图的关系可以由图0.1简要表示。
MFC中的视图和文档是由视图类(CView Class)和文档类(CDocument Class)分别表示的。
视图类可以调用其本身的成员函数GetDocument(),获得一个指向文档类的指针,从而能够访问文档类中的数据。
例如:在视图类中的OnDraw()函数中,视图类通过调用GetDocument()函数获得一个指向文档累的指针,然后通过这个指针获取文档类中的数据,并使用CDC类(负责处理应用程序显示设备接口的MFC类)中的函数将这些数据绘制在视图窗口中。
基于MFC的绘图软件设计
摘要绘图软件在多种工作中都有着很多的运用,而当前很多办公中的中小型绘图软件的缺乏使得小型绘图软件的开发显得十分必要。
因此论文着眼于当前使用较多的C++语言作为软件的开发语言。
运用C++软件中的软件基础库类(MFC)进行实用的绘图软件的开发。
MFC作为C++封装技术的主要体现,不仅拥有C++语言在绘图方面上的各类优势,同时与Windows系统能够有较多的信息交互。
因此基于MFC的绘图软件可以较好的将被处理的图片从抽象变成直观。
同时使用MFC设计绘图软件的过程中运用图形设备接口(GDI)来与Windows进行互相的信息交互。
运用MFC技术编写出的绘图软件有着界面简洁、功能较多等诸多优点。
因此基于MFC的绘图软件设计为很多中小型企业或工作室的绘图提供一套较为完善的解决方案。
关键字:绘图软件,MFC1AbstractDrawing software in a variety of work has a lot of use, and many of the current office in the lack of small and medium drawing software is the use of graphics software development is very necessary. So the paper focuses on the current use of more C + + language as a software development tools. The use of C + + software in the software base library (MFC) for practical drawing software development. MFC as the main embodiment of C + + encapsulation technology, not only has the C ++ language in the drawing of various advantages, while the Windows system can have more information exchange. So MFC-based drawing software can be better to be processed from the abstract image into an intuitive. At the same time the use of MFC design graphics software in the process of using the graphical device interface (GDI) to communicate with each other Windows information. The use of MFC technology to write the graphics software has a simple interface, more features and many other advantages. So MFC-based drawing software design for many small and medium enterprises or studio drawings to provide a more complete solution.Keywords:Drawing software,MFC21、绪论1.1 课题来源及意义随着计算机绘图辅助设计系统(即CAD系统)的渐渐成熟,图形绘制软件已经成为学校,工厂及各种小型工作室等不可缺的一大工具,大型绘图软件AutoCad ,Solidworks,Pro/E,MatLab也被人们广泛使用,但由于占用资源过大,运行速度慢,界面操作较为复杂,不能很好满足大部分普通人需求。
使用MFC实现OpenGL应用程序的开发
0 / n lh u e , / oa abf r p
0,/ hf i i o e /s i bt g rd t n
P D DRA F W
— —
的应 用提供 了 完备 的支 持 。对 于 应用 V C+ +编
程 的软件开 发领域来 说 , 利用 MF C搭 建 的框 架来 实现 O eG pn L的应 用 的 目的 和 意 义 在 于 , M C 将 F 系统 和 O eG pn L系统 进 行 有机 的 结 合 , 而 驱 除 从 了 MF C系统 本身 的 复杂 性 给 程序 设 计 带来 的影 响 , 得 我 们 可 以 高 效 率 地 编 写 出 高 品 质 的 使 O eG 应 用程序 。 pn L
{
PX L O I E F RMA D S R P O f = T E C IT R pd {
s ef( I E O MA D S R P O , / i o P X I R T E C IT R) / z
sz ft i f ‘ ie o h sp d 1 1,/ eso u /v rin n mbe r
库) 因其具 有独 立 于硬件 、 立 于 窗 口系统 、 以 独 可 在不 同的操作 系统 平 台之 间进 行 移 植 , 支 持 网 并
络环 境下 以客 户/ 务器模 式 工作 的特 点 , 服 已经成
以及 时而方便 的输 出文本 信息 ; 是 , 完备 的方 但 更
法是 使用 O eG pn L渲 染 系 统 自行 绘 制控 制 台。 下 面 就用这种 方法 阐述 O e G p n L编程模式 :
维普资讯
第 5期
安 阳 师范 学 院学 报
基于MFC的OpenGL绘图
基于MFC的OpenGL绘图一、简介GDI是通过设备句柄(Device Context以下简称"DC")来绘图,而OpenGL则需要绘制环境(Rendering Context,以下简称"RC")。
每一个GDI命令需要传给它一个DC,但与GDI不同,OpenGL使用当前绘制环境(RC)。
一旦在一个线程中指定了一个当前RC,在此线程中其后所有的OpenGL命令都使用相同的当前RC。
虽然在单一窗口中可以使用多个RC,但在单一线程中只有一个当前RC。
下面我将首先产生一个OpenGL RC并使之成为当前RC,这将分为三个步骤:设置窗口像素格式;产生RC;设置为当前RC。
二、MFC中的OpenGL基本框架1、首先创建工程用AppWizard产生一个MFC EXE项目,其他默认即可。
2、将此工程所需的OpenGL文件和库加入到工程中在工程菜单中,选择"Build"下的"Settings"项。
单击"Link"标签,选择"General"目录,在Object/Library Modules的编辑框中输入"opengl32.lib glu32.lib glut.lib glaux.lib"(注意,输入双引号中的内容,各个库用空格分开;否则会出现链接错误),选择"OK"结束。
然后打开文件"stdafx.h",加入下列头文件:3、改写OnPreCreate函数并给视图类添加成员函数和成员变量一旦设定了一个DC的位图格式,该DC所联系的窗口的位图格式随之设定。
该窗口若含有子窗口或者有兄弟窗口,这些兄弟/子窗口的位图格式没有设成与对应RC一致的格式,OpenGL在它们上面作图就容易出错。
故而OpenGL需要窗口加上WS_CLIPCHILDREN(创建父窗口使用的Windows风格,用于重绘时裁剪子窗口所覆盖的区域)和WS_CLIPSIBLINGS(创建子窗口使用的Windows风格,用于重绘时剪裁其他子窗口所覆盖的区域)风格。
mfc+opengl画几何图形,屏幕坐标与OpenGl坐标关系。
mfc+opengl画几何图形,屏幕坐标与OpenGl坐标关系。
MFC和OpenGL一起画几何图形可以使绘图更简单和有效。
使用MFC和OpenGL绘制几何图形时,屏幕坐标系与OpenGL坐标系有一定的关系。
MFC使用屏幕坐标系来定位图形,而OpenGL使用OpenGL坐标系,它基于3D空间对象,但在使用绘图功能时来定位图形,所以它们之间有一
定的关系。
屏幕坐标系是以用户屏幕左上角的点作为原点,且屏幕方向的X,Y轴
的正方向是右、下方向的,简单的来说它就是用窗口内显示的坐标系。
而OpenGL坐标系是一个三维坐标系,它相对于屏幕坐标系的原点有一
定的偏移,它的坐标轴的方向与屏幕的坐标轴是正交的。
在MFC和OpenGL联合绘制几何图形时,需要把屏幕坐标系中的坐标全
部转换为OpenGL坐标系中的坐标,才能在屏幕上正确的显示图形。
这
个转换需要根据OpenGL空间中的不同位置和方向来进行转换,从而实
现准确的转换,从而使得MFC和OpenGL联合绘制几何图形更加有效。
基于MFC的对话框Dialog的OpenGL程序框架
基于MFC的对话框Dialog的OpenGL程序框架基于MFC的对话框Dialog的OpenGL程序框架收藏建⽴⼀个基于对话框的⼯程(名称:OpenGL)并且在设置的Link⾥加⼊库opengl32.lib glu32.lib glaux.lib为对话框添加picture control 控件,ID:IDC_RENDER主要程序:// OpenGLDlg.cpp : implementation file//#include "stdafx.h"#include "OpenGL.h"#include "OpenGLDlg.h"#include#include#include#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CAboutDlg dialog used for App Aboutclass CAboutDlg : public CDialog{public:CAboutDlg();// Dialog Data//{{AFX_DATA(CAboutDlg)enum { IDD = IDD_ABOUTBOX };//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CAboutDlg)protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support//}}AFX_VIRTUAL// Implementationprotected://{{AFX_MSG(CAboutDlg)//}}AFX_MSGDECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD){//{{AFX_DATA_INIT(CAboutDlg)//}}AFX_DATA_INIT}void CAboutDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CAboutDlg)//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)//{{AFX_MSG_MAP(CAboutDlg)// No message handlers//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// COpenGLDlg dialogCOpenGLDlg::COpenGLDlg(CWnd* pParent /*=NULL*/): CDialog(COpenGLDlg::IDD, pParent){//{{AFX_DATA_INIT(COpenGLDlg)// NOTE: the ClassWizard will add member initialization here//}}AFX_DATA_INIT// Note that LoadIcon does not require a subsequent DestroyIcon in Win32 PixelFormat=0;m_yRotate = 0;m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}void COpenGLDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(COpenGLDlg)// NOTE: the ClassWizard will add DDX and DDV calls here//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(COpenGLDlg, CDialog)//{{AFX_MSG_MAP(COpenGLDlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_WM_TIMER()//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// COpenGLDlg message handlersBOOL COpenGLDlg::OnInitDialog(){CDialog::OnInitDialog();// Add "About..." menu item to system menu.// IDM_ABOUTBOX must be in the system command range.ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){CString strAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBOX);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); }}// Set the icon for this dialog. The framework does this automatically// when the application’s main window is not a dialogSetIcon(m_hIcon, TRUE); // Set big iconSetIcon(m_hIcon, FALSE); // Set small icon///////////////////////OPENGL INIT/////////////////////////CWnd *wnd=GetDlgItem(IDC_RENDER);hrenderDC=::GetDC(wnd->m_hWnd);if(SetWindowPixelFormat(hrenderDC)==FALSE)return 0;if(CreateViewGLContext(hrenderDC)==FALSE)return 0;glPolygonMode(GL_FRONT,GL_FILL);glPolygonMode(GL_BACK,GL_FILL);///////////////////////////////////////////glEnable(GL_TEXTURE_2D);glShadeModel(GL_SMOOTH);glViewport(0,0,259,231);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(45,1,0.1,100.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();glShadeModel(GL_SMOOTH); // Enable Smooth ShadingglClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black BackgroundglClearDepth(1.0f); // Depth Buffer SetupglEnable(GL_DEPTH_TEST); // Enables Depth TestingglDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do/////////////////////////////////////////////////////////////////////////glEnableClientState(GL_VERTEX_ARRAY);glEnableClientState(GL_TEXTURE_COORD_ARRAY);SetTimer(1,10,0);////////////////////////////////////////////////////////////////// TODO: Add extra initialization herereturn TRUE; // return TRUE unless you set the focus to a control}void COpenGLDlg::OnSysCommand(UINT nID, LPARAM lParam){if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialog::OnSysCommand(nID, lParam);}}// If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework.void COpenGLDlg::OnPaint(){if (IsIconic()){CPaintDC dc(this); // device context for paintingSendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangleint cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;// Draw the icondc.DrawIcon(x, y, m_hIcon);}else{CDialog::OnPaint();}}// The system calls this to obtain the cursor to display while the user drags // the minimized window.HCURSOR COpenGLDlg::OnQueryDragIcon(){return (HCURSOR) m_hIcon;}BOOL COpenGLDlg::SetWindowPixelFormat(HDC hDC){PIXELFORMATDESCRIPTOR pixelDesc;pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);pixelDesc.nVersion =1;pixelDesc.dwFlags = PFD_DRAW_TO_WINDOW |PFD_SUPPORT_OPENGL |PFD_DOUBLEBUFFER |PFD_TYPE_RGBA;pixelDesc.iPixelType = PFD_TYPE_RGBA;/doc/2c11546334.htmlolorBits = 32;pixelDesc.cRedBits = 0;pixelDesc.cRedShift = 0;pixelDesc.cGreenBits = 0;pixelDesc.cGreenShift = 0;pixelDesc.cBlueBits = 0;pixelDesc.cBlueShift = 0;pixelDesc.cAlphaBits = 0;pixelDesc.cAlphaShift = 0;pixelDesc.cAccumBits = 0;pixelDesc.cAccumRedBits = 0;pixelDesc.cAccumGreenBits = 0;pixelDesc.cAccumBlueBits = 0;pixelDesc.cAccumAlphaBits = 0;pixelDesc.cDepthBits = 0;pixelDesc.cStencilBits = 1;pixelDesc.cAuxBuffers = 0;pixelDesc.iLayerType = PFD_MAIN_PLANE; pixelDesc.bReserved = 0;pixelDesc.dwLayerMask = 0;pixelDesc.dwVisibleMask = 0;pixelDesc.dwDamageMask = 0;PixelFormat = ChoosePixelFormat(hDC,&pixelDesc);if(PixelFormat==0) // Choose default{PixelFormat = 1;if(DescribePixelFormat(hDC,PixelFormat,sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0) {return FALSE;}}if(SetPixelFormat(hDC,PixelFormat,&pixelDesc)==FALSE) {return FALSE;}return TRUE;}BOOL COpenGLDlg::CreateViewGLContext(HDC hDC) {hrenderRC = wglCreateContext(hDC);if(hrenderRC==NULL)return FALSE;if(wglMakeCurrent(hDC,hrenderRC)==FALSE)return FALSE;return TRUE;}void COpenGLDlg::RenderScene(){/////////////////////////////////////////////////glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glLoadIdentity();glTranslatef(0.0f,0.0f,-6.0f); // Move Left 1.5 Units And Into The Screen 6.0glRotated(m_yRotate, 0.0, 1.0, 0.0);glBegin(GL_TRIANGLES); // Drawing Using TrianglesglVertex3f( 0.0f, 1.0f, 0.0f); // TopglVertex3f(-1.0f,-1.0f, 0.0f); // Bottom LeftglVertex3f( 1.0f,-1.0f, 0.0f); // Bottom RightglEnd(); // Finished Drawing The TriangleSwapBuffers(hrenderDC);}void COpenGLDlg::OnTimer(UINT nIDEvent) //实时绘制场景{// TODO: Add your message handler code here and/or call defaultRenderScene();m_yRotate +=3;CDialog::OnTimer(nIDEvent);}// OpenGLDlg.h : header file//#if !defined(AFX_OPENGLDLG_H__8E962FCE_4DD3_4AE0_BA13_D93DE3FBA4A1__INCLUDED_) #define AFX_OPENGLDLG_H__8E962FCE_4DD3_4AE0_BA13_D93DE3FBA4A1__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000/////////////////////////////////////////////////////////////////////////////// COpenGLDlg dialogclass COpenGLDlg : public CDialog{// Constructionpublic:COpenGLDlg(CWnd* pParent = NULL); // standard constructorBOOL SetWindowPixelFormat(HDC hDC); //设定象素格式BOOL CreateViewGLContext(HDC hDC); //View GL Contextvoid RenderScene(); //绘制场景HDC hrenderDC; //DCHGLRC hrenderRC; //RCfloat m_yRotate; //转速int PixelFormat;// Dialog Data//{{AFX_DATA(COpenGLDlg)enum { IDD = IDD_OPENGL_DIALOG };// NOTE: the ClassWizard will add data members here//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(COpenGLDlg)protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support//}}AFX_VIRTUAL// Implementationprotected:HICON m_hIcon;// Generated message map functions//{{AFX_MSG(COpenGLDlg)virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();afx_msg void OnTimer(UINT nIDEvent);//}}AFX_MSGDECLARE_MESSAGE_MAP()};//{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_OPENGLDLG_H__8E962FCE_4DD3_4AE0_BA13_D93DE3FBA4A1__INCLUDED_)。
基于MFC的Opengl编程
3D图形学基本概念PerspectivePerspective refers to the angles between the lines that lend the illusion of three dimensions.Colors and ShadingMoving beyond line drawing, we need to add color to create a solid object. Shading refers to the way the color is applied to the polygon. Shading can be of two types in OpenGL - Flat or Smooth.Lights and ShadowsPlain solid color doesn’t offer enough realism. By applying Lighting effects we can make objects appear as they would in reality depending on their material properties and the lighting parameters. Adding a shadow further increases realism.Texture MappingWith Texture Mapping we can have wood grains, cloth textures, brick like textures etc instead of plain materials. This technique of applying an image to the surface of a polygon is called Texture Mapping. The image we use is called the Texture and the individual elements of the texture are called Texels.FogFog is an atmospheric effect that adds haziness to objects in a scene depending on how far the objects are from the viewer.Blending and TransparencyBlending is the combination of colors of objects on the screen. This effect can be used for a variety of purposes. By varying the amount each object is blended with the scene we can make objects look transparent.Anti-AliasingAliasing is an effect that is visible on screen due to the fact that an image consists of discrete pixels. By carefully blending the lines with the background color we can eliminate jagged edges and give them a smooth appearance. This blending technique is called anti-aliasing.第一个OpenGL程序复制代码//Simple.cpp - First OpenGL Program#include <windows.h> //Required for every Windows Program#include <gl\glut.h> //Required for using the GLUT library//Perform OpenGL Initialization herevoid SetupRC(){//Set the background clearing color to blueglClearColor(0.0f,0.0f,1.0f,1.0f);//设置背景色为蓝色}//The drawing callback functionvoid RenderScene(){//Clear the color bufferglClear(GL_COLOR_BUFFER_BIT);//Flush the rendering pipelineglFlush();}void main(){//Choose the display mode settingsglutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//初始化显示模式(单缓冲,RGB)//Create the WindowglutCreateWindow("Simple");//创建窗口//Set the RenderScsne function as the display callbackglutDisplayFunc(RenderScene);//绘制回调函数,当窗口需要绘制时,GLUT会调用此函数//Initialize OpenGLSetupRC();//初始化OpenGL//Start the GLUT frameworkglutMainLoop();//开始消息循环}WGL – Windows的OpenGL扩展层The WGL extension consists of a set of functions (wglCreateContext, wglDeleteContext etc.) and structures (such as PIXELFORMATDESCRIPTOR, GLYPHMETRICSFLOAT) etc. Thus every OpenGL implementation has a platform-specific portion which has to be set up and used according to the particular platform.设备上下文The Windows Graphical Device Interface (GDI) is capable of drawing to screen, to memory, to printers or to any other device that provides a GDI interface layer and that can process GDI calls. GDI accomplishes this by a rendering handle to the currently selected device, which is called the device context, or DC.绘制上下文A rendering context is the OpenGL equivalent of the GDI DC. All OpenGL calls are rendered to the device through a RC. The rendering context maintains OpenGL state variables such as current background color, current color etc. just as the DC maintains GDI state variables such as current pen, current brush etc.像素格式Pixel formats are the translation layer between OpenGL calls and the rendering operation that Windows performs.举个例子,若像素格式只支持很少一部分颜色值,则OpenGL在用RGB值(128,120,135)绘制一个像素时,就可能使用转换后的值(128,128,128)来绘制.The pixel format selected essentially describes such things as how colors are displayed, depth of field resolution and what additional capabilities are supported by the rendering context created.第一个基于MFC的OpenGL应用程开发环境:VC6.01,首先下载需要的GLUT头文件,DLL和Lib文件,下载链接: glutdlls37beta.zip (149 kilobytes),解压缩后把gltu.h放到"VC98/Include/GL"下,把glut.lib和glut32.lib放到"VC9/Lib" 下,glut32.dll和glut.dll放到你创建的应用程序的运行目录下2,创建一个MFC SDI应用程序,在项目属性中加入所需要链接的库文件1,在stdafx.h中加入下列语句://OpenGL Headers#include <gl/gl.h>#include <gl/glu.h>#include <gl/glut.h>#include <gl/glaux.h>2,打开ClassWizard,选择CCY457OpenGLView类,为下述消息加入消息处理函数:WM_CREATE (for OnCreate), WM_DESTROY (for OnDestroy), WM_SIZE (for OnSize),WM_ERASEBACKGROUND (for OnEraseBkground).3,在窗口创建之前我们必须设置窗口风格包含WS_CLIPCHILDREN和WS_CLIPSIBLINGS,从而避免OpenGL绘制到其他窗口中去。
MFC实现Opengl作图框架
在stdafx.h中添加的头文件(参照项目OpenGL)//////////////////////////////////////////////////////////////////////////// // 包含有关OpenGL函数的头文件#include<gl/gl.h>#include<gl/glu.h>#include<gl/glaux.h>#include<gl/glut.h>////////////////////////////////////////////////////////////////////////////项目-属性-链接器-输入 Opengl32.lib;glu32.lib;glaux.lib添加的变量和函数:BOOL RenderScene();BOOL SetupPixelFormat(void);void SetLogicalPalette(void);BOOL InitializeOpenGL(CDC* pDC);HGLRC m_hRC; //OpenGL绘制描述表HPALETTE m_hPalette; //OpenGL调色板CDC* m_pDC; //OpenGL设备描述表添加的消息映射:ON_WM_CREATE()ON_WM_DESTROY()ON_WM_SIZE()ON_WM_TIMER()◎PreCreateWindow(CREATESTRUCT& cs)//设置窗口类型cs.style |=WS_CLIPCHILDREN | WS_CLIPSIBLINGS;WS_CLIPCHILDREN,使得父窗体在绘制时留出其上的子窗体的位置不去画它,而那片区域留WS_CLIPSIBLING,必须用于子窗体,使得该子窗体在收到WM_PAINT时同时令其共父的诸多子窗体也会被PAINT。
①OnCreate(LPCREATESTRUCT lpCreateStruct)//初始化OpenGL和设置定时器m_pDC = new CClientDC(this);//设备描述表赋值SetTimer(1, 500, NULL);InitializeOpenGL(m_pDC); //涵盖了glutInit ()和glutInitDisplayMode()的功能///////////////////////////////////////////////////////m_pDC = new CClientDC(this);//设备描述表赋值//SetTimer(1, 500, NULL);InitializeOpenGL(m_pDC); //涵盖了glutInit ()和glutInitDisplayMode()的功能/////////////////////////////////////////////////////////////////////////////②OnSize(UINT nType, int cx, int cy)// 相当于GLUT中的glutReshapeFunc()函数//设置投影变换矩阵,设置视窗glMatrixMode(GL_PROJECTION); //设置当前矩阵为投影矩阵glLoadIdentity();//用单位矩阵初始化当前矩阵glFrustum(-1.0,1.0,-1.0,1.0,3.0,7.0);glViewport(0,0,cx,cy);////////////////////////////////////////////glViewport(0, 0, cx, cy);glMatrixMode(GL_PROJECTION);glLoadIdentity();if ((GLfloat)cx <= (GLfloat)cy)glOrtho(-35, 35, -35 * (GLfloat)cy / (GLfloat)cx, 35 * (GLfloat)cy / (GLfloat)cx, -50, 50);elseglOrtho(-35 * (GLfloat)cx / (GLfloat)cy, 35 * (GLfloat)cx / (GLfloat)cy, -35, 35, -50, 50);////////////////////////////////////③OnDraw(CDC* pDC)glClearColor(0.8f,0.8f,0.0f,1.0f);glClearDepth(1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glMatrixMode(GL_MODELVIEW);//设置当前矩阵为模型矩阵glLoadIdentity();//用单位矩阵初始化当前矩阵RenderScene(); //渲染场景SwapBuffers(wglGetCurrentDC());//当窗口需要被重绘时调用绘制的图形相当于glutDisplayFunc(display);glClear()语句的作用是用当前缓冲区清除值,也就是glClearColor或者glClearD epth等函数所指定的值来清除指定的缓冲区。
在MFC单文档中使用OpenGL
OpenGL(Fancy_mage)(参考《实战OpenGL三维可视化系统开发与源码精解》,吕希奎,周小平著)一、OpenGL像素格式1、像素格式设置像素格式是OpenGL窗口的重要属性,它包括是否使用双缓冲,颜色位数和类型以及深度位数等。
像素格式可由Windows系统定义的所谓像素格式描述子结构来定义(PIXELFORMATDESCRIPTOR),该结构定义在windows.h中(与BMP头文件BITMAPINFOHEADER相似,在windows.h中,结构体不需要单独定义)。
在该结构中包含有26个属性信息,其形式为:typedef structtagPIXELFORMATDESCRIPTOR{WORD nSize; //该结构所占内存空间。
WORD nVersion;//版本号,当前为。
DWORD dwFlags;/* PFD_DRAW_TO_BITMAP 支持内存中绘制位图PFD_DRAW_TO_WINDOW 支持屏幕绘图PFD_DOUBLEBUFFER 支持双缓冲PFD_CENERIC_FORMAT 指定选择GDI支持的像素格式PFD_NEED_PALETTE 指定需要逻辑调色板PFD_NEED_SYSTEM_PALETTE 指定需要硬件调色板PFD_STEREO NT 不支持PFD_SUPPORT_OPENGL 支持OpenGLPFD_SUPPORT_GDI 支持GDI,此时不可使用PFD_DOUBLEBUFFER*/BYTE iPixelType;//像素颜色模式,可选项为PFD_TYPE_RGBA或PFD_TYPE_INDEX,分别对应于RGBA模式和颜色索引模式。
BYTE cColorBits;//指定颜色的位数。
BYTE cRedBits; //采用RGBA模式时,红色组分占用位数BYTE cRedShift; //采用RGBA模式时,红色组分占偏移量BYTE cGreenBits;//采用RGBA模式时,绿色组分占用位数BYTE cGreenShift;//采用RGBA模式时,绿色组分偏移量BYTE cBlueBits; //采用RGBA模式时,蓝色组分占用位数BYTE cBlueShift; //采用RGBA模式时,蓝色组分偏移量BYTE cAlphaBits;//采用RGBA模式时,Alpha组分占用位数。
基于MFC的OpenGL简易绘图系统
基于MFC的OpenGL简易绘图系统
尤王杰
【期刊名称】《计算机应用文摘》
【年(卷),期】2022(38)7
【摘要】文章研究了基于C++的基本类库MFC和OpenGL图形库建立面向对象的二维图形绘制应用程序,实现了简单多边形的绘制以及自由绘制等功能。
重点应用面向对象的编程思想和基于MFC的OpenGL图形库,希望为软件开发初学者以及绘图应用使用者提供一定的帮助。
【总页数】3页(P32-34)
【关键词】MFC;OPENGL;绘图系统;C++面向对象
【作者】尤王杰
【作者单位】苏州大学计算机科学与技术学院
【正文语种】中文
【中图分类】TP391
【相关文献】
1.基于MFC和OpenGL的相贯线焊接仿真系统设计
2.基于MFC和OpenGL的三维车载导航系统
3.基于OpenGL的三维绘图系统设计
4.基于MFC与OpenGL 的可视化机械仿真设计系统
5.基于OpenGL的三维绘图系统设计
因版权原因,仅展示原文概要,查看原文内容请购买。
PictureControl控件中使用OpenGL绘图
PictureControl控件中使用OpenGL绘图如果你已经看到这篇文章,具体使用OpenGL的原因相信你比我清楚。
我是MFC兼OpenGL初学者,以下的知识是本人摸索试验出来的,只为了解决在PictureControl中正常使用OpenGL。
想在MFC对话框中使用OpenGL首先需要OpenGL静态库的支持#include"gl\gl.h"#include"gl\glu.h"#include"gl\glaux.h"具体配置方式网上有很多,并实践可行。
这里我只说明MFC中网上缺少的必要步骤。
第一步:包含头文件。
不一定像网上说的一定要包含于stdafx.h文件中。
可以写到任何CPP文件头部。
第二步:OpenGL的初始化。
定义InitializeOpenGL();函数体如下:IDC_IMAGE_DRAW为PictureControl控件IDBOOLCopenGLDlg::InitializeOpenGL(){m_pDC=newCClientDC(GetDlgItem(IDC_IMAGE_DRAW));〃获取设备DC,该DC为PictureControl的设备if(m_pDC==NULL){〃如果返回DC为空,则创建DC失败returnFALSE;}if(!SetupPixelFormat()){//像素格式化函数,简单的说就是指定绘图要用的像素格式,必须格式化,下面有像素格式化的函数体。
returnFALSE;}//创建绘图描述表m_hRC=::wglCreateContext(m_pDC->GetSafeHdc());if(m_hRC==0){//创建失败returnFALSE;}//使绘图描述表为当前调用现程的当前绘图描述表if(::wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC)==FALSE){returnFALSE;}//设置清除色::glClearColor(0.0f,0.0f,0.0f,0.0f);::glClearDepth(1.0f);::glEnable(GL_DEPTH_TEST);returnTRUE;//到此绘图环境初始化完成第三步;像素格式化函数体BOOLCopenGLDlg::SetupPixelFormat() {staticPIXELFORMATDESCRIPTORpfd={sizeof(PIXELFORMATDESCRIPTOR),1,PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER,PFD_TYPE_RGBA,24,0,0,0,0,0,0,0,0,0,buffer //sizeofthispfd//versionnumber//supportwindow//supportOpenGL//doublebuffered //RGBAtype//24-bitcolordepth //colorbitsignored //noalphabuffer//shiftbitignored //noaccumulation0,0,0,0, 16, 0, 0,PFD_MAIN_PLANE, 0, 0,0,0 };intmnPixelFormat=::ChoosePixelFormat(m_pDC->GetSafeHdc(),&p fd);if(m_nPixelFormat==0) {returnFALSE; }if(::SetPixelFormat(m_pDC->GetSafeHdc(),m_nPixelFormat,&pfd)==FALSE){returnFALSE; }returnTRUE;//accumbitsignored //16-bitz-buffer //nostencilbuffer //noauxiliarybuffer //mainlayer //reserved//layermasksignored}//这个函数网上描述的很清除,不解释作用第四步:获取画图的位置。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于MFC的OpenGL绘图程序框架一、简介GDI是通过设备句柄(Device Context以下简称"DC")来绘图,而OpenGL则需要绘制环境(Rendering Context,以下简称"RC")。
每一个GDI命令需要传给它一个DC,但与GDI 不同,OpenGL使用当前绘制环境(RC)。
一旦在一个线程中指定了一个当前RC,在此线程中其后所有的OpenGL命令都使用相同的当前RC。
虽然在单一窗口中可以使用多个RC,但在单一线程中只有一个当前RC。
下面我将首先产生一个OpenGL RC并使之成为当前RC,这将分为三个步骤:设置窗口像素格式;产生RC;设置为当前RC。
二、MFC中的OpenGL基本框架1、首先创建工程用AppWizard产生一个MFC EXE项目,其他默认即可。
2、将此工程所需的OpenGL文件和库加入到工程中在工程菜单中,选择"Build"下的"Settings"项。
单击"Link"标签,选择"General"目录,在Object/Library Modules的编辑框中输入"opengl32.lib glu32.lib glut.lib glaux.lib"(注意,输入双引号中的内容,各个库用空格分开;否则会出现链接错误),选择"OK"结束。
然后打开文件"stdafx.h",加入下列头文件:#include <gl\gl.h>#include <gl\glu.h>3、改写OnPreCreate函数并给视图类添加成员函数和成员变量OpenGL需要窗口加上WS_CLIPCHILDREN(创建父窗口使用的Windows风格,用于重绘时裁剪子窗口所覆盖的区域)和WS_CLIPSIBLINGS(创建子窗口使用的Windows风格,用于重绘时剪裁其他子窗口所覆盖的区域)风格。
把OnPreCreate改写成如下所示:BOOL COpenGLDemoView::PreCreateWindow(CREATESTRUCT&cs){//TODO: Modify the Window class or styles here by modifying//the CREATESTRUCT cs cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS);return CView::PreCreateWindow(cs);}产生一个RC的第一步是定义窗口的像素格式。
像素格式决定窗口着所显示的图形在内存中是如何表示的。
由像素格式控制的参数包括:颜色深度、缓冲模式和所支持的绘画接口。
在下面将有对这些参数的设置。
我们先在COpenGLDemoView的类中添加一个保护型的成员函数BOOL SetWindowPixelFormat(HDC hDC)(用鼠标右键添加)和保护型的成员变量:int m_GLPixelIndex;并编辑其中的代码如下:BOOL COpenGLDemoView::SetWindowPixelFormat(HDC hDC){//定义窗口的像素格式PIXELFORMATDESCRIPTOR pixelDesc={sizeof(PIXELFORMATDESCRIPTOR),1,PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER|PFD_SUPPORT_GDI,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};this->m_GLPixelIndex = ChoosePixelFormat(hDC,&pixelDesc);if(this->m_GLPixelIndex==0){this->m_GLPixelIndex = 1;if(DescribePixelFormat(hDC,this->m_GLPixelIndex,sizeof(PIXELFORMATDESCRIPTO R),&pixelDesc)==0){return FALSE;}}if(SetPixelFormat(hDC,this->m_GLPixelIndex,&pixelDesc)==FALSE){return FALSE;}return TRUE;4、用ClassWizard添加WM_CREATE的消息处理函数OnCreate至此,OpenGL工程的基本框架就建好了。
但如果你现在运行此工程,则它与一般的MFC 程序看起来没有什么两样。
5、代码解释现在我们可以看一看Describe-PixelFormat提供有哪几种像素格式,并对代码进行一些解释:PIXELFORMATDESCRIPTOR包括了定义像素格式的全部信息。
DWFlags定义了与像素格式兼容的设备和接口。
通常的OpenGL发行版本并不包括所有的标志(flag)。
wFlags能接收以下标志:PFD_DRAW_TO_WINDOW 使之能在窗口或者其他设备窗口画图;PFD_DRAW_TO_BITMAP 使之能在内存中的位图画图;PFD_SUPPORT_GDI 使之能调用GDI函数(注:如果指定了PFD_DOUBLEBUFFER,这个选项将无效);PFD_SUPPORT_OpenGL 使之能调用OpenGL函数;PFD_GENERIC_FORMAT 假如这种象素格式由Windows GDI函数库或由第三方硬件设备驱动程序支持,则需指定这一项;PFD_NEED_PALETTE 告诉缓冲区是否需要调色板,本程序假设颜色是使用24或32位色,并且不会覆盖调色板;PFD_NEED_SYSTEM_PALETTE 这个标志指明缓冲区是否把系统调色板当作它自身调色板的一部分;PFD_DOUBLEBUFFER 指明使用了双缓冲区(注:GDI不能在使用了双缓冲区的窗口中画图);PFD_STEREO 指明左、右缓冲区是否按立体图像来组织。
PixelType定义显示颜色的方法。
PFD_TYPE_RGBA意味着每一位(bit)组代表着红、绿、蓝各分量的值。
PFD_TYPE_COLORINDEX 意味着每一位组代表着在彩色查找表中的索引值。
本例都是采用了PFD_TYPE_RGBA方式。
● cColorBits定义了指定一个颜色的位数。
对RGBA来说,位数是在颜色中红、绿、蓝各分量所占的位数。
对颜色的索引值来说,指的是表中的颜色数。
● cRedBits、cGreenBits、cBlue-Bits、cAlphaBits用来表明各相应分量所使用的位数。
●cRedShift、cGreenShift、cBlue-Shift、cAlphaShift用来表明各分量从颜色开始的偏移量所占的位数。
一旦初始化完我们的结构,我们就想知道与要求最相近的系统象素格式。
我们可以这样做:m_hGLPixelIndex = ChoosePixelFormat(hDC, &pixelDesc);ChoosePixelFormat接受两个参数:一个是hDc,另一个是一个指向PIXELFORMATDESCRIPTOR结构的指针& pixelDesc;该函数返回此像素格式的索引值。
如果返回0则表示失败。
假如函数失败,我们只是把索引值设为1并用DescribePixelFormat得到像素格式描述。
假如你申请一个没得到支持的像素格式,则Choose-PixelFormat将会返回与你要求的像素格式最接近的一个值。
一旦我们得到一个像素格式的索引值和相应的描述,我们就可以调用SetPixelFormat设置像素格式,并且只需设置一次。
现在像素格式已经设定,我们下一步工作是产生绘制环境(RC)并使之成为当前绘制环境。
在COpenGLDemoView中加入一个保护型的成员函数BOOL CreateViewGLContext(HDC hDC),并加入一个保护型的成员变量HGLRC m_hGLContext;HGLRC是一个指向rendering context的句柄。
BOOL COpenGLDemoView::CreateViewGLContext(HDC hDC){this->m_hGLContext =wglCreateContext(hDC);if(this->m_hGLContext==NULL){//创建失败return FALSE;}if(wglMakeCurrent(hDC,this->m_hGLContext)==FALSE){//选为当前RC失败return FALSE;}return TRUE;}在OnCreate函数中调用此函数:int COpenGLDemoView::OnCreate(LPCREATESTRUCT lpCreateStruct){if (CView::OnCreate(lpCreateStruct) == -1)return -1;//TODO: Add your specialized creation code here HWND hWnd = this->GetSafeHwnd();HDC hDC =::GetDC(hWnd);if(this->SetWindowPixelFormat(hDC)==FALSE){return 0;}if(this->CreateViewGLContext(hDC)==FALSE){return 0;}return 0;}添加WM_DESTROY的消息处理函数Ondestroy( ),使之如下所示:void COpenGLDemoView::OnDestroy(){CView::OnDestroy();//TODO: Add your message handler code here if(wglGetCurrentContext()!=NULL){wglMakeCurrent(NULL,NULL);}if(this->m_hGLContext!=NULL){wglDeleteContext(this->m_hGLContext);this->m_hGLContext =NULL;}}最后,编辑COpenGLDemoView的构造函数,使之如下所示:COpenGLDemoView::COpenGLDemoView(){//TODO: add construction code here this->m_GLPixelIndex = 0;this->m_hGLContext =NULL;}至此,我们已经构造好了框架,使程序可以利用OpenGL进行画图了。