建立并修改程序
----建立一个MFC SDI Windows应用工程Text,除单文档属 性外,使用其他的所有默认选择。在菜单Project打开Settings对话框,在Link属性页的 object/library modules编辑框中加入opengl32.lib glu32.lib glaux.lib三个GL库。我们利用这些 库函数完成图形编辑工作。
----为使VC++的AppWizard产生的SDI应用程序能使用 OpenGL绘图,还需要作一些修改,说明如下。
----1.介绍PreCreateWindow函数
---- OpenGL窗口必须具有WS_CLIPCHILDREN(创建父窗口 使用的Windows风格,用于重绘时剪裁子窗口所覆盖的区域)和WS_CLIPIBLINGS(创 建子窗口使用的Windows风格,用于重绘时剪裁其他子窗口所覆盖的区域)两种风格。 此外,窗口类属性不能包括CS_PARENTDC风格。具体程序实现如下:
BOOL CTextView::PreCreateWindow
(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
//An OpenGL window must be created with the following flag
// and must not include CS_PARENTIDC for the class style.
cs.style|=WS_CLIPSIBLINGS|WS_CLIPCHILDREN;
return CView::PreCreateWindow(cs);
}
----2.OnCreate函数中定义像素格式PIXELFORMAT和创建 RC
----要使窗口支持OpenGL绘图,必须对窗口进行初始化。其 中包括定义像素格式PIXELFORMAT和创建RC,为OpenGL指定一个合适的像素格式, 创建着色上下文并将它和窗口的设备上下文关联起来。着色上下文保存着当前着色环境 的信息。可在OnCreate中调用一个自建视口成员函数SetupPixelFormat(),具体函数如下:
BOOL CTextView::SetupPixelFormat()
{
//Create a rendering context
CDC* m_pDC=GetDC();
if(m_pDC==NULL) //failure to get DC
{
MessageBox(“Could't get a valid DC.");
return FALSE;
}
//Default pixel format is a single-buffered,
//OpenGL support hardware-accelerated,RGBA mode format
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),//Structure size.
1,
// Structure version number.Property flags(特性标志):
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA, // RGBA type
24, // 32-bit color.
0, 0, 0, 0, 0, 0, // Not concerned with these:不涉及的属性
0, // No alpha :无alpha缓存
0, // Shift bit ignored:忽略转换位
0, 0, 0, 0, 0,// No accum buffer:没有累积缓存
32, // 32-bit depth buffer.
0, // No stencil:无模板缓存
0, // No auxliliary buffers:无辅助缓存
PFD_MAIN_PLANE, // Main layer type.:主层类型
0, // Reserved.:保留结构数
0, 0, 0 // Unsupported.:不支持结构数
};
int nPixelFormat=
ChoosePixelFormat(m_pDC->GetSafeHdc(),&pfd);
if( nPixelFormat ==0)
{
MessageBox(“ChoosePixelFormat failed.");
return FALSE;
}
if(SetPixelFormat(m_pDC->GetSafeHdc(),
nPixelFormat,&pfd)==0)
{
MessageBox(“SetPixelFormat failed.");
return FALSE;
}
if( (m_hRC=wglCreateContext(m_pDC->
GetSafeHdc())) ==0)
{
MessageBox(“wglCreateContext failed.");
return FALSE;
}
if( (wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC)) ==0)
{
MessageBox(“wglMakeCurrent failed.");
return FALSE;
}
if(m_pDC) ReleaseDC(m_pDC);
return TRUE;
}
----3.在OnCreate()函数中调用初始化背景函数 InitializeOpenGL()
void CTextView::InitializeOpenGL()
{
glClearColor(0.2f,0.2f,0.2f,0.0f);
glClearDepth(1.0);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
}
----4.在OnCreate()中启动动画定时器
SetTimer(0,40,NULL);
----5.在收到WM_SIZE消息时要重新计算场景尺寸,用OnSize 设置图形显示模式
----为了使物体能合适的显示,必须要经过投影和确定视口的 工作。
void CTextView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
//Save the wide and height of the current window Client
GLsizei nWidth=(GLsizei)cx;
GLsizei nHeight=(GLsizei)cy;
ratio=(double)cx/(double)cy;
//Coupute the aspect ratio
GLdouble dAspect=(GLdouble)nWidth/(GLdouble)nHeight;
glViewport(0,0,nWidth,nHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective
(FOV,dAspect,NEARPLANE,FARPLANE);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
----6.在OnDraw()中简单调用DrawScene()以执行OpenGL函数
void CTextView::OnDraw(CDC* pDC)
{
CTextDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
DrawScene();
//Invalidate();
}
----7.撤销视窗时删除上下文并撤销定时器
void CTextView::OnDestroy()
{
CView::OnDestroy();
// TODO: Add your message handler code here
//This call makes the current RC not current
if(wglMakeCurrent(0,0)==FALSE)
MessageBox(“wglMakeCurrent failed.");
//delete the RC
if(m_hRC && (wglDeleteContext(m_hRC)==FALSE))
MessageBox(“wglDeleteContext fail.");
KillTimer(1);
}
----8.当40ms定时器时间到时,简单地将整个场景的客户区 置无效,使之重画
void CTextView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
Invalidate();
CView::OnTimer(nIDEvent);
}
修改界面
---- 删除菜单IDR_MAINFRAME中File下除去Exit菜单项 外的所有选项,添加“显示GDI文字” “列表制作文字”“列表三维文字”三个菜单项, 并给他们分配适当的ID。使用ClassWizard为这三个菜单项在视类中添加命令处理函数和 界面更新函数,其中显示GDI文字的对应的函数如下:
void CTextView::OnGdiText()
{
// TODO: Add your command handler code here
m_iWhichText=0;
Invalidate();
}
void CTextView::OnUpdateGdiText(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
if(m_iWhichText==0) pCmdUI->SetCheck();
else pCmdUI->SetCheck(0);
}
----增加Draw3DText()、DrawListText()和DrawGdiText()三个 函数用于三种不同的文本绘制方法。增加DrawScene()函数,它被OnDraw函数调用,用于 绘制场景。在DrawScene()函数中,当m_iWhichText为0、1、2时,分别调用 DrawGdiText()、DrawListText()和Draw3DText()显示文本。具体函数实现如下:
void CTextView::OnDraw(CDC* pDC)
{
CTextDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
DrawScene();
//Invalidate();
}
void CTextView::DrawScene()
{
glClear
(GL_COLOR_BUFFERBIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(0.0f,0.0f,-FARPLANE);
//TextureMap();
glPopMatrix();
glPushMatrix();
glTranslatef
(0.0f,0.0f,-(FARPLANE+NEARPLANE)/2);
if(m_iWhichText==1) DrawListText();
if(m_iWhichText==2) Draw3DText();
glPopMatrix();
glFinish();
SwapBuffers(wglGetCurrentDC());
if(m_iWhichText==0) DrawGdiText();
}
GDI 显示文本
---- 调用wglGetCurrentDC()函数取得当前的设备上下文,使 用TextOut函数显示文本,不过要注意在DoubleBuffer模式下,绘制函数要在glFinish()和 SwapBuffers(wglGetCurrentDC())函数之后调用,否则会产生闪烁,在绘制OpenGL结束之前 使用GDI函数,要除去闪烁则只能使用SingleBuffer模式,具体函数如下:
void CTextView::DrawGdiText()
{
HDC hdc=wglGetCurrentDC();
::SetBkMode( hdc, TRANSPARENT );
::SetTextColor( hdc, RGB(250,0,0) );
CString sState(“显示GDI文本。");
::TextOut(hdc,5,5,sState,sState.GetLength());
}
wglUseFontBitmaps
函数显示文字
----使用wglUseFontBitmaps()将ASCII字符装入显示列表, 然后使用glCallLists()函数利用显示列表序列显示文本。wglUseFontBitmaps有四个参数, 分别是当前使用的DC、从第几个ASCII字符起始装入列表、装入列表的ASCII字符数和 起始的列表序号。glListBase()指定glCallLists执行的起始列表序列号。glCallLists()含有三 个参数:执行列表序列的个数、列表值的类型和所要显示的文本。注意如果所要显示的 文本是字符串,它所提供的信息是相对于起始装入ASCII字符的偏移量,因此最终所显 示的ASCII字符是从glListBase()所指定的列表起始号在经过glCallLists()中偏移后的列表, 因此wglUseFontBitmaps的从第几个ASCII字符起始装入列表参数、glListBase()指定的 glCallLists执行的起始列表序列号和glCallLists()中的所要显示的文本参数都可以影响最终 显示结果。由于显示的是ASCII 字符,因此不能显示汉字。glRasterPos3f函数决定在 OpenGL视景体坐标系下的偏移。具体函数实现如下:
void CTextView::DrawListText()
{
wglUseFontBitmaps(wglGetCurrentDC(),0,256,1000);
glListBase(1000);
glRasterPos3f(-5.0f,0.0f,0.0f);
glCallLists(20,GL_UNSIGNED
_BYTE,“Draw with List Text.");
}
wglUseFontOutlines
函数显示三维文字
----wglUseFontOutlines使得OpenGL可以显示三维文字。它 的用法与wglUseFontBitmaps函数大致相同,但是多了内插计算参数、字体深度、显示方 式和装载字模的缓存四个参数,且只能显示TrueType字体,显示前应该先选择字体类型。 具体函数实现如下:
void CTextView::Draw3DText()
{
GLYPHMETRICSFLOAT agmf[256];
// create display lists for glyphs 0 through 255
// with 0.1 extrusion and default deviation.
//The display list numbering starts at 1000
(it could be any number)
wglUseFontOutlines(wglGetCurrentDC(),
0,255,1000,0.3f,0.8f, WGL_FONT_LINES ,agmf);
// Set up transformation to draw the string
glTranslatef(-15.0f,0.0f,0.0f);
glScalef(4.0f, 4.0f, 4.0f);
// Display a string
glListBase(1000);
// Indicates the start of display lists for the glyphs
// Draw the characters in a string
glCallLists(26, GL_UNSIGNED_BYTE,
“Draw outline list 3D text.");
}
分享到:
相关推荐
OpenGL是用于创建2D和3D图形的强大框架,而MFC(Microsoft Foundation Classes)是微软提供的C++库,用于简化Windows应用程序开发。本教程“OpenGL + MFC编程初步”将引领初学者进入这两个领域的结合,旨在帮助...
在"OpenGL+MFC的框架"中,我们将探讨如何将OpenGL集成到MFC应用程序中,以便利用OpenGL的强大图形功能。首先,我们需要确保系统已安装支持OpenGL的图形驱动,并且开发环境(如Visual Studio)配置正确。在MFC项目中...
课程大作业用opengl+MFC单文档 实现的3D扫雷
OPENGL+MFC工程,具备鼠标操作(缩放、旋转、平移)。 倒腾了一天,好多都不鞥呢使用,故将本人可用工程传上。 文件中也包含了我使用的gl库文件
在本项目中,“OpenGL+mfc+单文档”意味着我们将使用MFC框架来构建一个支持OpenGL图形渲染的SDI应用程序。 动画是指在连续的时间间隔内改变图形状态以创建动态视觉效果的技术。在OpenGL中,通常通过定时器或事件...
opengl+mfc仿真动画与贴图
相应的博客链接:OpenGL+MFC对三维点云的法向量实现可视化 - HW140701的博客 - CSDN博客 http://blog.csdn.net/hw140701/article/details/77899725
OpenGL是用于渲染2D、3D图形的跨语言、跨平台的应用程序编程接口(API),而MFC(Microsoft Foundation Classes)是微软提供的一套C++库,用于简化Windows应用程序的开发。将OpenGL与MFC结合使用,可以创建功能丰富的...
3D基础:opengl 显示点云数据,MFC框架下
在本项目中,我们看到一个基于VS2010的MFC应用程序,它利用OpenGL进行3D图形渲染,实现了物体的旋转、缩放和平移功能。 OpenGL是一个跨语言、跨平台的编程接口,用于生成2D和3D图形。它提供了一系列的函数,允许...
本程序是在上次的画直线、画圆的程序上修改的,添加了扫描线填充算法,使用OpenGL+MFC实现。 填充算法的使用说明: 1、选择菜单中的“种子填充”--〉“鼠标画边界”,然后在绘图区域左键点击若干个点作为多边形的...
用到了OpenGL与MFC相结合的有关知识以及复杂三维模型导入的相关技术。 2. 利用OpenGL编程实现子弹击中目标的过程,并能手动输入参数实现对子弹的控制。利用mfc制作交互界面,与OpenGL相结合。 3. 实现3d复杂模型的...
在“opengl+MFC做的模仿谷歌地球(超炫)”项目中,开发者利用OpenGL的强大图形渲染能力,结合MFC的窗口管理和事件处理机制,实现了类似谷歌地球的3D地球模型。这个项目可能包含以下几个核心知识点: 1. **OpenGL...
在"opengl+mfc图形裁剪"的场景中,我们将探讨如何结合这两者实现图形的裁剪功能,并通过右键单击和双击事件进行交互式操作。 图形裁剪是图形处理中的一个重要环节,通常用于显示或编辑图像的特定部分。在OpenGL中,...
用OPENGL和MFC框架编写可对三维图形进行绘制
基于OpenGL和MFC单文档的三维图像平台,实现图形的平移、旋转、缩放等功能,对初学者有很大的帮助。
在这个项目中,采用了OpenGL和MFC这两个技术进行开发。OpenGL是一种强大的图形库,主要用于渲染2D和3D图形,而MFC(Microsoft Foundation Classes)是微软提供的一套C++类库,用于构建Windows应用程序,特别是用户...
在这个项目中,"用OPENGL+MFC编的三维地形,还加了纹理贴图"是一个结合了这两者的应用,它利用OpenGL进行3D渲染,而MFC作为框架来构建用户界面。 首先,我们来看看OpenGL在三维地形中的应用。OpenGL提供了基础的...
在这个场景中,我们将探讨如何结合OpenGL和MFC来实现一个功能,即通过左键单击绘制包围线,然后通过右键单击进行内部填充。 首先,我们需要在MFC应用中集成OpenGL。这通常涉及创建一个OpenGL窗口,该窗口继承自`...