OAG 库 (OpenGL) 第 1 部分 - 为 MFC 应用程序设置库






4.40/5 (10投票s)
OAG 是一个用 C++ 编写的库。使用这个库,您可以创建基于 OpenGL 的应用程序。
引言
这个库是为创建基于 OpenGL 的应用程序而编写的。在本教程中,我们将设置这个库。
关于库
该库通过插件工作,您可以以 XML 格式保存和打开对象。在本教程中,我们将使用一些类来绘制 2D 几何图形。该库提供了用于 2D 几何图形、纹理和文本(True Type Font)的插件。文件 OAG_2D_Demo.zip 演示了这一点。该库可在 SourceForge 下载。
示例
此示例演示了如何在 MFC 中设置库、设置目录的目录以及设置库的目录。对于此示例,项目名称为 RenderGraphicMFC。此项目教程已使用 Visual Studio 2008 创建。
 
 
设置项目的包含目录:OAGLibrary 文件夹是存储库的文件夹。OpenGL 文件夹存储 OpenGL 应用程序的类。
 
 
设置项目的库目录:bin 文件夹存储库。VC9 文件夹存储 Visual Studio 2008 的库。
 
 
设置视图类
oag::Win32Renderer 类是一个渲染器,oag::WinGraphicContext 类用于在 MFC 应用程序中设置 OpenGL。
oag::WinRenderer*		m_pRender;
oag::WinGraphicContext*		m_pWinGraphicContext;
现在我们将创建 OnInitialUpdate 方法来初始化库,以及 EraseBkgnd 方法。这样 OpenGL 就会被初始化并准备好在屏幕上绘制对象。
void COAGMFCView::OnInitialUpdate()
{
    CView::OnInitialUpdate();
   //Delete the current m_pWinGraphicContext, 
   //m_pRender and tool if a new document is called
   UnloadData();
   m_pWinGraphicContext = new oag::WinGraphicContext(this);
   m_pRender = new oag::WinRenderer(m_pWinGraphicContext, false);
   m_pRender->SetBackGroundColor(0, 0, 0);
   if ( m_pWinGraphicContext->MakeCurrent() )
   {
      GetDocument()->m_pObjectsMappingTable->LoadOpenGLExtensions();
      m_pWinGraphicContext->DeleteCurrent();
   }
}
BOOL COAGMFCView::OnEraseBkgnd(CDC* pDC)
{
	// TODO: Add your message handler code here and/or call default
	return FALSE;
}
现在我们将创建 OnSize 方法来更新窗口大小以及窗口大小改变时屏幕上的对象。我们需要在 OnDraw 函数中调用渲染器使用的 RenderScene 方法来在屏幕上绘制对象。
void COAGMFCView::OnSize(UINT nType, int cx, int cy)
{
    CView::OnSize(nType, cx, cy);
    if ( m_pWinGraphicContext )
	    m_pWinGraphicContext->OnSize(cx, cy);
}
void COAGMFCDoc::OnDraw(CDC* pDC)
{
  COAGMFCDoc* pDoc = GetDocument();
  ASSERT_VALID(pDoc);
  if (!pDoc)
   return;
  if( m_pRender )
  {
    m_pRender->SetScene( pDoc->m_pScene );
    m_pRender->RenderScene();
  }
}
设置文档类
oag::OAGScene 类存储对象并在屏幕上绘制它们。
oag::OAGScene* m_pScene; 
oag::ObjectsMappingTable* m_pObjectsMappingTable;
实现构造函数和析构函数
COAGMFCDoc::COAGMFCDoc()
:m_pScene(NULL)
,m_pObjectsMappingTable(NULL)
{
  CreateLibraryObjects();
}
删除对象
我们有两种删除对象的方法。您可以调用 m_pScene->DeleteAllObjects(),或者在用户添加对象的类中删除对象。对于演示,我使用 m_pScene->DeleteAllObjects(),因为对象仅添加到场景中。
COAGMFCDoc::~COAGMFCDoc()
{
   UnloadLibraryObjects();
}
void COAGMFCDoc::CreateLibraryObjects()
{
  if( m_pObjectsMappingTable == NULL)
     m_pObjectsMappingTable = new oag::ObjectsMappingTable();
  if( m_pScene == NULL )
  {
     m_pScene = new oag::OAGScene();
     m_pScene->SetFontMappingTable(  m_pObjectsMappingTable->GetFontMappingTable() );
     m_pScene->SetTextureMappingTable( m_pObjectsMappingTable->GetTextureMappingTable() );
  }
}
void COAGMFCDoc::UnloadLibraryObjects()
{
   //Deletes the scene and all objects from the memory
   if ( m_pScene )
   {
	   m_pScene->DeleteAllObjects();
     delete m_pScene;
     m_pScene = NULL;
   }
   if ( m_pObjectsMappingTable )
   {
	   delete m_pObjectsMappingTable;
      m_pObjectsMappingTable = NULL;
   }
}
编译应用程序,您将看到一个带有黑色背景的窗口
 
 
在屏幕上显示对象
首先要做的就是修改视图中的 OnInitialUpdate 函数。下面的代码片段显示了该函数的所有行。我们只需要为 CreateObjects() 添加一行。
void COAGMFCView::OnInitialUpdate()
{
  CView::OnInitialUpdate();
  m_pWinGraphicContext = new oag::WinGraphicContext(this);
  m_pRender = new oag::WinRenderer(m_pWinGraphicContext, false);
  m_pRender->SetBackGroundColor(0, 0, 0);
   if ( m_pWinGraphicContext->MakeCurrent() )
   {
      GetDocument()->m_pObjectsMappingTable->LoadOpenGLExtensions();
      m_pWinGraphicContext->DeleteCurrent();
   }
  CreateObjects();
}
第二件事是创建 CreateObjects 函数,该函数创建对象并将其添加到场景中。这样场景就可以在屏幕上绘制对象了。
void COAGMFCView::CreateObjects()
{
   //Creating a lines
   oag::OAGPrimitives* pLine = new oag::OAGPrimitives();
   pLine->SetGeometryType(GL_LINES);
   GetDocument()->m_pScene->AddObject( pLine );
   pLine->SetArraySize( 4 );
   pLine->AddVertex(450, 100, 0 );
   pLine->AddVertex(450, 200, 0 );
   pLine->AddVertex(400, 150, 0 );
   pLine->AddVertex(500, 150, 0 );
   //Creating a rectangle
   oag::OAGPrimitives* pQuad = new oag::OAGPrimitives();
   pQuad->SetGeometryType(GL_QUADS);
   GetDocument()->m_pScene->AddObject( pQuad );
   pQuad->SetArraySize( 4 );
   pQuad->AddVertex( 100, 100, 0);
   pQuad->AddVertex( 100, 200, 0);
   pQuad->AddVertex( 200, 200, 0);
   pQuad->AddVertex( 200, 100, 0);
}

通过命令行构建几何图形
要使用该库构建几何图形,您需要创建 OAGPrimitives 的新实例。使用该类,您可以绘制 OpenGL 支持的原语,例如线、折线、矩形和三角形。创建 OAGPrimitives 的新实例后,您必须使用 SetGeometryType 命令来更改要绘制的原语类型。SetGeometryType 支持的类型为 GL_LINES、GL_LINE_STRIP、GL_QUADS 和 GL_TRIANGLES。下面的 CreateNewGeometry2D 函数展示了如何创建原语并将其添加到场景中。本教程未显示 CreateNewGeometry2D 函数。
void COAGMFCDoc::CreateNewGeometry2D(int nType)
{
	switch( nType )
	{
	case 1: //Line
		{
           oag::OAGPrimitives* pGeo = new oag::OAGPrimitives();
           pGeo->SetGeometryType( GL_LINES );
           m_pScene->AddObject( pGeo );
		}
		break;
	case 2: //Polyline
		{
          oag::OAGPrimitives* pGeo = new oag::OAGPrimitives();
          pGeo->SetGeometryType( GL_LINE_STRIP );
          m_pScene->AddObject( pGeo );
		}
		break;
	case 3: //Rectangle
		{
          oag::OAGPrimitives* pGeo = new oag::OAGPrimitives();
          pGeo->SetGeometryType( GL_QUADS );
          m_pScene->AddObject( pGeo );
		}
		break;
	case 4: //Triangle
		{
          oag::OAGPrimitives* pGeo = new oag::OAGPrimitives();
          pGeo->SetGeometryType( GL_TRIANGLES );
          m_pScene->AddObject( pGeo );
		}
		break;
	}
}
历史
- 2010 年 6 月 5 日
- 初始版本
- 2010 年 6 月 11 日
- 添加了图像插件(BMP、JPG、TGA、PCX)
- 2010 年 6 月 19 日
- 添加了 True Type 字体插件
- 添加了纹理和字体的 XML
- 2010 年 7 月 23 日
- 纹理更改
- 添加了纹理映射(RectangleMapping和TriangleMapping)
- 为纹理和字体添加了对象表
- 2010 年 8 月 15 日
- 添加了简单的 3D 对象(Cube、Pyramid和Quadrics)
- 添加了纹理映射(CubeMapping和PyramidMapping)以及 Quadrics 的纹理
- 2010 年 10 月 20 日
- 为纹理添加了滤镜和环绕模式
- 添加了多重纹理
- 添加了反射和反射场景
- 为渲染器添加了多个场景
- 2011 年 8 月 1 日
- 添加了 PNG 图像插件
- 通过矩阵添加了变换。SetTranslation、SetScale、SetRotation命令已被SetTransform替换。
- 对于原语,AddVertex函数已被删除。该命令已被SetArrayVertices替换,它使用向量列表作为参数。
- 添加了广告牌(oag::OAGBillboard、OAGBillboardTextureItems、OAGBillboardGroup)。广告牌对RectangleMapping和TriangleMapping类支持纹理。


