65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.40/5 (10投票s)

2010 年 6 月 5 日

CPOL

3分钟阅读

viewsIcon

58614

downloadIcon

82

OAG 是一个用 C++ 编写的库。使用这个库,您可以创建基于 OpenGL 的应用程序。

引言

这个库是为创建基于 OpenGL 的应用程序而编写的。在本教程中,我们将设置这个库。

关于库

该库通过插件工作,您可以以 XML 格式保存和打开对象。在本教程中,我们将使用一些类来绘制 2D 几何图形。该库提供了用于 2D 几何图形、纹理和文本(True Type Font)的插件。文件 OAG_2D_Demo.zip 演示了这一点。该库可在 SourceForge 下载。

示例

此示例演示了如何在 MFC 中设置库、设置目录的目录以及设置库的目录。对于此示例,项目名称为 RenderGraphicMFC。此项目教程已使用 Visual Studio 2008 创建。

NewProject.jpg

设置项目的包含目录: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_LINESGL_LINE_STRIPGL_QUADSGL_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 日
    • 纹理更改
    • 添加了纹理映射(RectangleMappingTriangleMapping
    • 为纹理和字体添加了对象表
  • 2010 年 8 月 15 日
    • 添加了简单的 3D 对象(CubePyramidQuadrics
    • 添加了纹理映射(CubeMappingPyramidMapping)以及 Quadrics 的纹理
  • 2010 年 10 月 20 日
    • 为纹理添加了滤镜和环绕模式
    • 添加了多重纹理
    • 添加了反射和反射场景
    • 为渲染器添加了多个场景
  • 2011 年 8 月 1 日
    • 添加了 PNG 图像插件
    • 通过矩阵添加了变换。SetTranslationSetScaleSetRotation 命令已被 SetTransform 替换。
    • 对于原语,AddVertex 函数已被删除。该命令已被 SetArrayVertices 替换,它使用向量列表作为参数。
    • 添加了广告牌(oag::OAGBillboardOAGBillboardTextureItemsOAGBillboardGroup)。广告牌对 RectangleMappingTriangleMapping 类支持纹理。
© . All rights reserved.