如何在VC_中用MFC进行OpenGL编程_胡伟

合集下载

VC++与OpenGL混合编程实现三维图形处理

VC++与OpenGL混合编程实现三维图形处理

VC++与OpenGL混合编程实现三维图形处理摘要:VC++MFC包含了基于Windows的应用框架,该框架功能十分强大,可以提供丰富的事件管理及相关的窗口函数,在面向对象编程过程中被广泛应用;而OpenGL则从某种程度上成为三维图形的开发标准,也是三维图形处理的最佳选择。

就基于OpenGL的基本框架,阐述其在VC++关键词:VC++OpenGL;三维图形处理0 引言一般情况下,工程设计和资源勘探都离不开计算机仿真技术的有效应用,尤其是在复杂地质条件赫尔工艺结构的处理过程中都需要利用教学模型建立三维立体图形结构。

所谓的三维立体图形处理主要包括切割、旋转、移动以及光照等具体操作,开发中的难点一般都是软件的强大图形能力和良好用户界面的接口。

VC++辑、编译、链接生成可执行文件等多种功能。

能够开发出良好的用户界面接口,受到广大软件开发人员的青睐。

OpenGL则是一种三维工具软件包,在交互式三维图形建模能力和编程方面和其它图形开发方面具有很强的优越性。

与传统的GDI绘图不一样的是,OpenGL开发不仅能减少代码的数量,而且可收到更好的视觉效果。

在OpenGL反馈的基础上建立的强大选择和修改功能,极大地方便了有限元网格图形的修改和处理,加快了有限元分析计算的周期。

本文在对VC++的基础上,进一步结合OpenGL的图形处理能力,以期最终能实现对三维仿真图形图像的处理,为工程应用中图形数据的可视化及仿真提供相关的借鉴。

1 VC++OpenGL1.1 VC++VC++借助微软相应的基础类库(MFC)以及应用程序框架,开发出Windows 标准界面的应用程序。

其中MFC将WindowsAPI函数进行完整的封装,从而建立起Windows光应用程序框架,其有着良好的通用性及可移植性,更利于VC++它还提供了一些诸如打印或者数据库等具有共性特征应用程序的操作支持。

在MFC框架中有APP类、DOC类以及VIEW和MAINFRAME类等4种,MFC将其进行有机的结合。

如何在vc++6.0里面使用openGl

如何在vc++6.0里面使用openGl

如何在vc++6.0里面使用openGl?你既可以建立Win32项目使用API,也可以建立MFC工程(一般不用MFC框架直接用API)我给你一个例子吧,建立Win32空项目,添加一个cpp文件,编译执行就行了(这是一个经典的opengl框架了)代码如下:#pragma comment(lib,"opengl32.lib")#pragma comment(lib,"glu32.lib")#pragma comment(lib,"glaux.lib")#include <windows.h>#include <gl/gl.h>#include <gl/glu.h>#include <gl/glaux.h>HDC hDC=NULL;HGLRC hRC=NULL;HWND hWnd=NULL;HINSTANCE hInstance;BOOL keys[256];BOOL active=TRUE;BOOL fullscreen=TRUE;GLfloat rtri;GLfloat rquad;LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);GLvoid ResizeGLScene(GLsizei width,GLsizei height){if(height==0)height=1;glViewport(0,0,width,height);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);glMatrixMode(GL_MODELVIEW);glLoadIdentity();}int InitGL(GLvoid){glShadeModel(GL_SMOOTH);glClearColor(0.0f,0.0f,0.0f,0.5f);glClearDepth(1.0f);glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LEQUAL);glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); return TRUE;}int DrawGLScene(GLvoid){glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glLoadIdentity();glTranslatef(-1.5f,0.0f,-6.0f);glRotatef(rtri,0.0f,1.0f,0.0f);glBegin(GL_TRIANGLES);glColor3f(1.0f,0.0f,0.0f);glVertex3f(0.0f,1.0f,0.0f);glColor3f(0.0f,1.0f,0.0f);glVertex3f(-1.0f,-1.0f,1.0f);glColor3f(0.0f,0.0f,1.0f);glVertex3f(1.0f,-1.0f,1.0f);glColor3f(1.0f,0.0f,0.0f);glVertex3f(0.0f,1.0f,0.0f);glColor3f(0.0f,0.0f,1.0f);glVertex3f(1.0f,-1.0f,1.0f);glColor3f(0.0f,1.0f,0.0f);glVertex3f(1.0f,-1.0f,-1.0f);glColor3f(1.0f,0.0f,0.0f);glVertex3f(0.0f,1.0f,0.0f);glColor3f(0.0f,1.0f,0.0f);glVertex3f(1.0f,-1.0f,-1.0f);glColor3f(0.0f,0.0f,1.0f);glVertex3f(-1.0f,-1.0f,-1.0f);glColor3f(1.0f,0.0f,0.0f);glVertex3f(0.0f,1.0f,0.0f);glVertex3f(-1.0f,-1.0f,-1.0f); glColor3f(0.0f,1.0f,0.0f); glVertex3f(-1.0f,-1.0f,1.0f); glEnd();glLoadIdentity(); glTranslatef(1.5f,0.0f,-7.0f); glRotatef(rquad,1.0f,1.0f,1.0f); glBegin(GL_QUADS); glColor3f(0.0f,1.0f,0.0f); glVertex3f(1.0f,1.0f,-1.0f); glVertex3f(-1.0f,1.0f,-1.0f); glVertex3f(-1.0f,1.0f,1.0f); glVertex3f(1.0f,1.0f,1.0f);glColor3f(1.0f,0.5f,0.0f); glVertex3f(1.0f,-1.0f,1.0f); glVertex3f(-1.0f,-1.0f,1.0f); glVertex3f(-1.0f,-1.0f,-1.0f); glVertex3f(1.0f,-1.0f,-1.0f);glColor3f(1.0f,0.0f,0.0f); glVertex3f(1.0f,1.0f,1.0f); glVertex3f(-1.0f,1.0f,1.0f); glVertex3f(-1.0f,-1.0f,1.0f); glVertex3f(1.0f,-1.0f,1.0f);glColor3f(1.0f,1.0f,0.0f);//glVertex3f(1.0f,-1.0f,-1.0f); //glVertex3f(-1.0f,-1.0f,-1.0f); //glVertex3f(-1.0f,1.0f,-1.0f); //glVertex3f(1.0f,1.0f,-1.0f); glVertex3f(-1.0f,1.0f,-1.0f); glVertex3f(1.0f,1.0f,-1.0f); glVertex3f(1.0f,-1.0f,-1.0f); glVertex3f(-1.0f,-1.0f,-1.0f);glColor3f(0.0f,0.0f,1.0f); glVertex3f(-1.0f,1.0f,1.0f); glVertex3f(-1.0f,1.0f,-1.0f); glVertex3f(-1.0f,-1.0f,-1.0f); glVertex3f(-1.0f,-1.0f,1.0f);glVertex3f(1.0f,1.0f,-1.0f);glVertex3f(1.0f,1.0f,1.0f);glVertex3f(1.0f,-1.0f,1.0f);glVertex3f(1.0f,-1.0f,-1.0f);glEnd();rtri+=0.2f;rquad-=0.15f;return TRUE;}GLvoid KillGLWindow(GLvoid){if(fullscreen){ChangeDisplaySettings(NULL,0);ShowCursor(TRUE);}if(hRC){if(!wglMakeCurrent(NULL,NULL))MessageBox(NULL,"释放DC或RC失败","关闭错误",MB_OK|MB_ICONINFORMA TION);if(!wglDeleteContext(hRC))MessageBox(NULL,"释放RC失败","关闭错误",MB_OK|MB_ICONINFORMATION); hRC=NULL;}if(hDC && !ReleaseDC(hWnd,hDC)){MessageBox(NULL,"释放DC失败","关闭错误",MB_OK|MB_ICONINFORMATION); hDC=NULL;}if(hWnd && !DestroyWindow(hWnd)){MessageBox(NULL,"释放窗口句柄失败","关闭错误",MB_OK|MB_ICONINFORMA TION); hWnd=NULL;}if(!UnregisterClass("OpenG",hInstance)){MessageBox(NULL,"不能注销窗口类","关闭错误",MB_OK|MB_ICONINFORMATION); hInstance=NULL;}}BOOL CreateGLWindow(char* title,int width,int height,int bits,BOOL fullscreenflag){GLuint PixelFormat;WNDCLASS wc;DWORD dwExStyle;DWORD dwStyle;RECT WindowRect;WindowRect.left=(long)0;WindowRect.right=(long)width;WindowRect.top=(long)0;WindowRect.bottom=(long)height;fullscreen=fullscreenflag;hInstance=GetModuleHandle(NULL);wc.style=CS_HREDRAW|CS_VREDRAW|CS_OWNDC;wc.lpfnWndProc=(WNDPROC)WndProc;wc.cbClsExtra=0;wc.cbWndExtra=0;wc.hInstance=hInstance;wc.hIcon=LoadIcon(NULL,IDI_WINLOGO);wc.hCursor=LoadCursor(NULL,IDC_ARROW);wc.hbrBackground=NULL;wc.lpszMenuName=NULL;wc.lpszClassName="OpenG";if(!RegisterClass(&wc)){MessageBox(NULL,"注册窗口失败","错误",MB_OK|MB_ICONINFORMATION); return FALSE;}if(fullscreen){DEVMODE dmScreenSettings;memset(&dmScreenSettings,0,sizeof(dmScreenSettings));dmScreenSettings.dmSize=sizeof(dmScreenSettings);dmScreenSettings.dmPelsWidth=width;dmScreenSettings.dmPelsHeight=height;dmScreenSettings.dmBitsPerPel=bits;dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;if(ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCE SSFUL){if(MessageBox(NULL,"全屏模式设置失败!\n使用窗口模式?","OpenGL 3D游戏编程",MB_YESNO|MB_ICONEXCLAMA TION)==IDYES){fullscreen=FALSE;}else{MessageBox(NULL,"程序将被关闭","错误",MB_OK|MB_ICONINFORMA TION);return FALSE;}}}if(fullscreen){dwExStyle=WS_EX_APPWINDOW;dwStyle=WS_POPUP;ShowCursor(FALSE);}else{dwExStyle=WS_EX_APPWINDOW|WS_EX_WINDOWEDGE;dwStyle=WS_OVERLAPPEDWINDOW;}AdjustWindowRectEx(&WindowRect,dwStyle,FALSE,dwExStyle);if(!(hWnd=CreateWindowEx(dwExStyle,"OpenG",title,dwStyle|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,0,0,WindowRect.right-WindowRect.left,WindowRect.bottom-WindowRect.top,NULL,NULL,hInstance,NULL))){KillGLWindow();MessageBox(NULL,"窗口创建失败","错误",MB_OK|MB_ICONINFORMATION);return FALSE;}static PIXELFORMA TDESCRIPTOR pfd={sizeof(PIXELFORMA TDESCRIPTOR),1,PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER,PFD_TYPE_RGBA,bits,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,PFD_MAIN_PLANE,0,0,0,0};if(!(hDC=GetDC(hWnd))){KillGLWindow();MessageBox(NULL,"不能创建一个窗口设备描述表","错误",MB_OK|MB_ICONINFORMA TION);return FALSE;}if(!(PixelFormat=ChoosePixelFormat(hDC,&pfd))){KillGLWindow();MessageBox(NULL,"不能创建一个匹配的像素格式","错误",MB_OK|MB_ICONINFORMA TION);return FALSE;}if(!SetPixelFormat(hDC,PixelFormat,&pfd)){KillGLWindow();MessageBox(NULL,"不能设置像素格式","错误",MB_OK|MB_ICONINFORMATION); return FALSE;}if(!(hRC=wglCreateContext(hDC))){KillGLWindow();MessageBox(NULL,"不能创建OpenGL渲染描述表","错误",MB_OK|MB_ICONINFORMA TION);return FALSE;}if(!wglMakeCurrent(hDC,hRC)){KillGLWindow();MessageBox(NULL,"不能激活当前的OpenGL渲染描述表","错误",MB_OK|MB_ICONINFORMA TION);return FALSE;}ShowWindow(hWnd,SW_SHOW);SetForegroundWindow(hWnd);SetFocus(hWnd);ResizeGLScene(width,height);if(!InitGL()){KillGLWindow();MessageBox(NULL,"初始化失败","错误",MB_OK|MB_ICONINFORMA TION);return FALSE;}return TRUE;}LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam){switch(uMsg){case WM_ACTIV ATE:{if(!HIWORD(wParam))active=TRUE;elseactive=FALSE;return 0;}case WM_SYSCOMMAND:{switch(wParam){case SC_SCREENSA VE:case SC_MONITORPOWER:return 0;}break;}case WM_CLOSE:{PostQuitMessage(0);return 0;}case WM_KEYDOWN:{keys[wParam]=TRUE;return 0;}case WM_KEYUP:{keys[wParam]=FALSE;return 0;}case WM_SIZE:{ResizeGLScene(LOWORD(lParam),HIWORD(lParam));return 0;}}return DefWindowProc(hWnd,uMsg,wParam,lParam);}int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){MSG msg;BOOL done=FALSE;if(MessageBox(NULL,"你想在全屏模式下运行吗?","设置全屏模式",MB_YESNO|MB_ICONQUESTION)==IDNO){fullscreen=FALSE;}if(!CreateGLWindow("Win32 SDK风格OpenGL程序框架",640,480,16,fullscreen)) return 0;while(!done){if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){if(msg.message==WM_QUIT)done=TRUE;else{TranslateMessage(&msg);DispatchMessage(&msg);}}else{if(active){if(keys[VK_ESCAPE])done=TRUE;else{DrawGLScene();SwapBuffers(hDC);}}if(keys[VK_F1]){keys[VK_F1]=FALSE;KillGLWindow();fullscreen=!fullscreen;if(!CreateGLWindow("Win32 SDK风格OpenGL程序框架",640,480,16,fullscreen)) return 0;}}}KillGLWindow();return msg.wParam;}。

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(着色描述表)。

VC上部署openGL的步骤

VC上部署openGL的步骤

VC上部署openGL的步骤第⼀步:选择⼀个编译环境现在Windows系统的主流编译环境有Visual Studio,Broland C++ Builder,Dev-C++等,它们都是⽀持OpenGL的。

但这⾥我们选择VC++ 6.0作为学习OpenGL的环境。

第⼆步:安装GLUT⼯具包GLUT不是OpenGL所必须的,但它会给我们的学习带来⼀定的⽅便,推荐安装。

Windows环境下安装GLUT的步骤:1、将下载的压缩包解开,将得到5个⽂件2、以我的安装⽬录为例:(1)“d:\Program Files\Microsoft Visual Studio\VC98\include\GL⽂件夹”。

把解压得到的glut.h放到这个GL⽂件夹⾥。

没有GL⽂件夹可以⾃⼰建⼀个,⼀般都有的。

(2)“d:\Program Files\Microsoft Visual Studio\VC98\lib⽂件夹”)。

把解压得到的glut.lib和glut32.lib放到静态函数库所在⽂件夹,即lib⽂件夹。

(3)把解压得到的glut.dll和glut32.dll放到操作系统⽬录下⾯的system32⽂件夹内。

(典型的位置为:C:\Windows\System32)这是⾮常重要的动态链接库设置!第三步,创建⼯程,其步骤如下:(1)创建⼀个Win32 Console Application。

(以我创建的为例,⼯程名为simpleGL)(2)链接OpenGL libraries:在Visual C++中先单击Project,再单击Settings,再找到Link单击,最后在Object/library modules 的最前⾯加上opengl32.lib Glut32.lib Glaux.lib glu32.lib 。

(3)单击Project Settings中的C/C++标签,将Preprocessor definitions 中的_CONSOLE改为__WINDOWS。

MFC+OpenGL 编程入门

MFC+OpenGL 编程入门

MFC+OpenGL 编程入门OpenGL 作图非常方便,故日益流行,但对许多人来说,是在微机上进行的,首先碰到的问题是,如何适应微机环境。

这往往是最关键的一步,虽然也是最初级的。

下面介绍如何在VC++ 上进行OpenGL 编程。

其实相当简单明快,只因国内缺少这方面的资料与例子,致使许多小细节要一个一个地试,耗去大量时间。

希望各位有什么心得体会,也公布出来,从而节省每个人都要试试的时间。

言归正传,下面以画一条Bezier 曲线为例,详细介绍VC++ 上OpenGL编程的方法。

这里实际上也给出了个C++ 良好封装性编程的范例。

文中给出了详细注释,以便给初学者明确的指引。

一步一步地按所述去做,你将顺利地画出第一个OpenGL 平台上的图形来。

(本文例子以VC++ 5.0 为背景)一、产生程序框架Test.dswNew Project | MFC Application Wizard (EXE) | "Test" | OK*注* : 加“”者指要手工敲入的字串二、导入Bezier 曲线类的文件。

用下面方法产生BezierCurve.hBezierCurve.cpp 两个文件:WorkSpace | ClassView | Test Classes| <右击弹出> New Class| Generic Class(不用MFC类) | "CBezierCurve" | OK三、编辑好Bezier 曲线类的定义与实现。

写好下面两个文件:BezierCurve.hBezierCurve.cpp四、设置编译环境:1. 在BezierCurve.h 和TestView.h 内各加上:#include <GL/gl.h>#include <GL/glu.h>#include <GL/glaux.h>2. 在集成环境中,Project | Settings | Link | Object/library module| "opengl32.lib glu32.lib glaux.lib" | OK五、设置OpenGL 工作环境:(下面各个操作,均针对TestView.cpp )1. 处理PreCreateWindow(): 设置OpenGL 绘图窗口的风格cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CS_OWNDC;2. 处理OnCreate():创建OpenGL 的绘图设备。

手把手教你搭建用MFC进行OpenGL编程的框架

手把手教你搭建用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;}/************************************************************** *******///现在编译程序的话,会看到一个无法刷新的应用程序了。

用MFC实现OpenGL编程

用MFC实现OpenGL编程用MFC实现OpenGL编程一、OpenGL简介众所周知,OpenGL原先是Silicon Graphics Incorporated(SGI 公司)在他们的图形工作站上开发高质量图像的接口。

但最近几年它成为一个非常优秀的开放式三维图形接口。

实际上它是图形软件和硬件的接口,它包括有120多个图形函数,"GL"是"GRAPHIC LIBRARY"的缩写,意思是“图形库”。

OpenGL的出现使大多数的程序员能够在PC机上用C语言开发复杂的三维图形。

微软在Visual C++ 7中已提供了三个OpenGL的函数库(glu32.lib, glau.lib,OpenGL32.lib),可以使我们方便地编程,简单、快速地生成美观、漂亮的图形。

例如,Windows NT中的屏幕保护程序中的花篮和迷宫等都给人们留下了深刻的印象。

二、生成OpenGL程序的基本步骤和条件本文将给出一个例子,这个例子是一个用OpenGL显示图像的Windows程序,通过这个程序我们也可以知道用OpenGL编程的基本要求。

我们知道,GDI是通过设备句柄(Device Context以下简称"DC")来绘图,而OpenGL则需要绘制环境(Rendering Context,以下简称"RC")。

每一个GDI命令需要传给它一个DC,与GDI不同,OpenGL使用当前绘制环境(RC)。

一旦在一个线程中指定了一个当前RC,所有在此线程中的OpenGL命令都使用相同的当前RC。

虽然在单一窗口中可以使用多个RC,但在单一线程中只有一个当前RC。

本例将首先产生一个OpenGL RC并使之成为当前RC,分为三个步骤:设置窗口像素格式;产生RC;设置为当前RC。

1、首先创建工程用AppWizard产生一个EXE文件,选择工程目录,并在工程名字中输入"OpenGL",保持其他的不变;第一步、选单文档(SDI);第二步、不支持数据库;第三步、不支持OLE;第四步、不选中浮动工具条、开始状态条、打印和预览支持、帮助支持的复选框,选中三维控制(3D Controls);第五步、选中产生源文件注释并使用MFC为共享动态库;第六步、保持缺省选择。

用MFC实现基于OpenGL的三维图形ActiveX控件

用MFC实现基于OpenGL的三维图形ActiveX控件
作者:叶钦媚, 黎绍发, 梁宇涛
作者单位:华南理工大学电教中心计算机科学与工程学院,广东,广州,510641
刊名:
机电工程技术
英文刊名:MECHANICAL & ELECTRICAL ENGINEERING TECHNOLOGY
年,卷(期):2003,32(3)
被引用次数:3次
1.胡伟;王弘如何在VC++中用MFC进行OpenGL编程[期刊论文]-计算机应用 2001(08)
2.赵国庆;刘家彬用MFC开发ActiveX控件以激活Web页面[期刊论文]-计算机应用 2001(09)
3.费广正;乔林Visual C++6.0高级编程技术-OpenGL篇
1.梁文娟.王惠南三维动态仿真技术在网络中的应用[期刊论文]-仪器仪表用户 2005(3)
2.杨日容.杨承志.杨晓洪基于OpenGL的ActiveX控件的实现[期刊论文]-昆明理工大学学报(理工版) 2005(1)
3.冯喆分布交互视景实时运行支撑体系结构研究[学位论文]硕士 2005
本文链接:/Periodical_jxkf200303011.aspx。

用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()将其设置为当前象素格式。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

收稿日期:2001-02-28 作者简介:胡伟(1976-),男,硕士研究生,主要研究方向:CAD 、图形学应用; 王弘(1948-),男,副教授,主要研究方向:CIMS 系统规划及应用研究.文章编号:1001-9081(2001)08-0087-03如何在VC ++中用MFC 进行OpenGL 编程胡 伟,王 弘(华中科技大学动力工程系,湖北武汉430074)摘 要:介绍了OpenGL 的基本概念及其基本程序结构,通过对用标准C 和用MFC 这两种方法进行OpenGL 编程的相通点的分析,详细叙述了如何在VC ++中用MFC 编写OpenGL 程序的一般过程。

关键词:OpenGL ;MFC ;设备描述表(DC );绘制描述表(RC )中图分类号:TN911.73 文献标识码:A1 简介随着三维图形的应用越来越广泛,计算机图形学的发展也越来越迅速,各种图形应用软件也就随之应运而生。

Open GL (Open Graphic Library ,开放性图形库)是目前比较完善的三维图形标准,已被广泛的用于可视化技术、实体造型、CAD /CAM 、模拟仿真等诸多领域。

OpenGL 作为一种硬件图形的软件接口,其优点是作为一个独立的工作平台,独立于硬件设备、窗口系统和操作系统,用它编写的软件可以在Unix 、Windows95OSR2、Windows98/NT /2000等系统间移植。

Open GL 编程类似于C 编程,实际接口就是C ,所以市面上的很多有关OpenGL 的书中的程序都是使用标准C (或是Win32Console Application )调用OpenGL 函数实现的。

这样做,只是为了使读者尽快地掌握Open GL 的基本操作。

但是,Open GL 仅仅是一个包含120多个图形函数的图形库,并没有窗口函数(尽管Open GL 的辅助库提供了一些窗口和事件管理的函数,但是这些函数在实际应用中是远远不够的。

),它缺乏面向对象能力,不符合当前流行的软件设计思想。

因此我们需要借助一个“窗口”系统来完成OpenGL 三维图形的制作。

VC ++中的MFC 包含了强大的基于Windows 的应用框架,提供了丰富的窗口和事件管理函数,已经成为当前一种比较流行的工作平台。

于是我们可以使用MFC 调用OpenGL 函数来实现三维图形的制作。

2 OpenGL 的基本程序结构2.1 定义窗口即定义所制作的三维图形在Windows 屏幕坐标系中的显示位置,定义所显示图形窗口的大小、窗口的性质。

2.2 初始化包括初始化一些基本操作,如清缓存区(buffer )、定义光照模型、定义纹理映射、安装显示列表、定义雾等基本操作的初始化状态、设置三维视景体、定义视口。

总之,是为下一步的Open GL 图形显示作准备,初始化OpenGL 的状态变量,使显示三维OpenGL 图形更方便,节省显示图形的时间。

2.3 绘制和显示图形按照应用的具体要求,绘制和显示三维图形包括建立三维模型、设置物体在立体空间的运动轨迹、变更Open GL 的状态变量、协调合理地结合运用Open GL 各基本操作、实现完美的三维图形显示。

例1.1用一个简单的例子(标准C 编写)来说明Open GL 的程序结构。

例1.1 OpenGL 例程sample .c#include <window .h >#include <GL /gl .h >#include <GL /glu .h >#include <GL /glaux .h >#include <stdio .h >void myinit (void );void CALLBACK myReshape (GLs izei w ,Glsizei h );void CALLBACK display (void );/*Initialize antialiasing for RGBA mode ,includin g alpha blending ,hint ,and line width .*/void myinit (void )狖glClearColor (0.0,0.0,0.0,0.0);//将窗口清为黑色狚/*display ()draws an octahedron with a large alpha value ,1.0.*/void CALLBACK display (void )狖glClear (GL —COLOR —BUFFER —BIT );//将当前颜色缓存清为窗口的颜色glColor4f (0.2,0.6,1.0,1.0);//设置颜色glRotatef (60.0,1.0,1.0,1.0);//设置坐标auxWireCube (1.0);//绘制立方体glFlush ();//强制绘图完成狚第21卷第8期2001年8月计算机应用Computer Applications Vol .21,No .8Aug .,2001void CALLB ACK my Reshape(GLsizei w,Glsizei h)狖gl Viewport(0,0,w,h);狚/*Main LoopOpen windows with initial window size,title bar,RGB A display mode,and handle input events.*/void main(void)狖auxInitDisplayMode(AUX—SINGLE AUX—RGBA);auxInitPosition(0,0,400,400);auxInitWindow(″sample.c″);myinit();auxRes hapeFunc(myReshape);auxMainLoop(display);狚运行这个程序和运行标准C编写的C程序一样,只是在连接的时候要加入三个静态库,这三个静态库是opengl32.lib、glu32.lib和glaux.lib。

无论多复杂的Open GL程序设计都是由上述的三个模块组成,而且这三部分是紧密相关的。

3 MFC中的OpenGL编程3.1 定义窗口在VC++中,当创建一个项目是会自动产生一个窗口,因此我们不需要再重新定义窗口,而只需在所需的窗口内绘图即可。

但若要使用OpenGL在窗口内绘图,则必须对定义窗口的一些函数进行修改,以下就这些函数分别进行讨论。

·PreCreateWindow函数Open GL窗口必须具有WS—CLIPCHILDREN(创建父窗口使用的Windows风格,用于重绘时裁剪子窗口所覆盖的区域)或WS—CLIPSIBLINGS(创建子窗口使用的Windows风格,用于重绘时裁剪其它子窗口所覆盖的区域)属性。

此外,窗口类属性不能包括CS—PARENTDC。

具体程序实现如下:BOOL CExmView::PreCreateWindow(CR EATESTR UCT&cs)狖cs.st yle=WS—CLIPSIBLINGS WS—CLIPCHILDR EN;//指定窗口的风格ret urn CView::PreCreateWindow(cs);狚·OnCreate函数要是窗口支持OpenGL绘图,必须对窗口进行初始化。

1)定义象素结构(PIXELFOR MAT)由于OpenGL窗口要求有自己的象素格式,即只有那些从Open GL窗口客户区域获得的Device Contexts(设备描述表,简称DC,下同)才允许在窗口内绘图。

函数ChoosePixel Format使用有DC支持的与所给定的PIXELFORMATDESCRIPTOR(象素格式描述)最相匹配的象素格式,从而可以满足用户所需求的象素格式;函数SetPixelFormat将DC中的象素格式置为由参数iPixelFormat所指定的象素格式。

OpenGL可采用双缓存技术,所谓双缓存技术是指Open GL 为了获得逼真的动画效果,需要先在内存中生成下一幅图像,然后把已经生成的图像从内存中显示到屏幕上的一种技术。

于是看起来所有的画面都是连续的。

在定义象素格式时,我们可以将PIXELFORMATDESCRIPTOR结构中的d wFlags位置为PFD—DOUBLEBUFFER。

值得注意的是,在绘制物体结束时,我们一定要加上SwapBu ffers(wglGetCurrentDC())语句,即交换前台和后台缓存。

2)定义RGB调色板(PALETTE)OpenGL应用了一些专门的函数来指定三维模型的颜色,我们可以选择两种颜色模式:RGB A模式和颜色索引模式。

在RGBA模式下,所有的颜色定义全用R、G、B三个值来表示,有时也加上Alpha值(与透明度有关);在颜色索引模式下,每一个象素的颜色使用颜色索引表中的某个颜色索引值表示,而这个索引值指向了相应的R、G、B值。

3)创建RC在VC++中,绘图是离不开DC的,它是一个定义了Graphic Objects(图形对象)和Graphic Modes(图形模式)的数据结构。

这里的Graphic Objects是指用于绘图的pen(画笔)、brush(绘刷)、bitmap(位图)、palette(调色板)、region(区域)等一系列资源。

若想在指定的窗口内绘图必须找到它的句柄(handle)。

而在Open GL编程中,需要使用Rendering Contexts(绘制描述表,简称RC,下同)。

RC并不等同于DC,它适合于在由hdc (用来产生RC的DC的句柄)指定的设备上画图。

绘图时,要先定义DC的象素格式,然后创建RC,并把它作为当前线程的RC,最后调用OpenGL函数。

当用RC完成绘图后,必须将它释放。

我们用wglCreateContext函数来创建一个OpenGL的RC。

用wgl MakeCurrent函数是给定的Open GL RC成为当前调用线程的RC,线程后来的OpenGL调用均画在有hdc指定的设备上。

具体程序实现如下:int CExmVie w::OnCreate(L PCREATESTRUCT lpCreateStruct)狖if(CView::OnCreate(lpCreateStruct)==-1)return-1;PIXEL FOR MA TD ESCRIPTOR pfd=狖sizeof(PIXELFOR MATDESCR IP TOR),//pfd的大小1,//版本号PFD—DR AW—TO—WIND OW//支持窗口PFD—SUPPORT—OPEN GL//支持OpenGLPFD—D OUBLEBU FFER,//双缓存PFD—TY PE—R GBA,//R GBA类型24,//24位颜色深度0,0,0,0,0,0,//忽略颜色位0,//无alpha缓存0,//忽略转换位0,//无累计缓存0,0,0,0,//忽略累计位88 计算机应用2001年32,//32位深度缓存0,//无模板缓存0,//无辅助缓存PFD—MAIN—PL ANE,//主层(main layer)0,//保留(res erved)0,0,0,狚;CClientD C clientdc(this);//得到当前D C的句柄int pf=Choos ePi xelFormat(cl ientdc.m—hD C,&pfd);//返回最佳匹配的象素格式BOOL rt=SetPixelFormat(clientdc.m—hDC,pf,&pfd);//设置象素格式hglrc=wglCreateContext(clientdc.m—hDC);//创建R Cret urn0;狚·OnSize函数在屏幕窗口内可以定义一个矩形,称为视口(Viewport),视景体投影后的图形就在视口内显示。

相关文档
最新文档