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

OAG 库 (OpenGL) 第 2.2 部分 - 使用鼠标和程序化方式绘制 2D 文本

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (4投票s)

2010 年 7 月 24 日

CPOL

2分钟阅读

viewsIcon

31571

downloadIcon

1200

本教程展示了用于 2D 文本的库代码,以及如何在 MFC 应用程序中使用鼠标和程序化方式绘制它们。

引言

在本教程中,我们将学习如何绘制 2D 字体。您必须下载库才能编译示例。点击 此处 进入下载页面。使用 OAG_2D,您可以保存和打开 XML 文件 (*.oagxml)。

绘制 2D 字体

要使用库绘制字体,您需要创建一个 oag::FontMappingTable 实例来存储字体,以及一个 oag::OAGFontMapping2D 实例。oag::FontMappingTable 类管理用于绘制的字体。选择字体并将其存储在 oag::FontMappingTable 类中后,它将被添加到 oag::FontMappingTable 类中的字体数组列表中。oag::OAGFontMapping2D 类用于使用存储在 oag::FontMappingTable 类中的字体绘制文本。

设置文档类

文档的成员

oag::ObjectsMappingTable*    pObjectsMappingTable;
oag::OAGScene*            m_pScene;

文档的操作

void CreateLibraryObjects();
void UnloadLibraryObjects();

构造函数和析构函数

COAGMFCDoc::COAGMFCDoc()
:m_pScene(NULL)
,m_pObjectsMappingTable(NULL)
{
  CreateLibraryObjects();
}
 
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;
   }
}

创建新文档时,我们需要删除所有对象并重新创建它们

BOOL COAGMFCDoc::OnNewDocument()
{
  if (!CDocument::OnNewDocument())
   return FALSE;
 
  //Deleting all library objects when a new document is started.
  //The Fonts must be deleted and created again,
  //if not they are not drawn properly
  UnloadLibraryObjects();
  CreateLibraryObjects();
    
  UpdateAllViews(NULL);
 
  return TRUE;
}

插入字体

要插入字体,请点击“TableObjects”菜单,点击“Font”,然后选择一种 True Type 字体。

选择字体后,它将以 24 的大小创建。函数 pFont->SetFontSize(24) 执行此操作。您不需要再次使用此字体来绘制 2D 文本,只需从 m_pFontMappingTable 获取此字体并使用它来绘制 2D 文本即可。

void COAGMFCDoc::OnInsertFont()
{
  CString filter;
  filter.LoadString( IDS_FONT_FILTER );
 
  CFileDialog dlg(TRUE, "*.ttf", NULL, 
                  OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST, filter );
 
  if(dlg.DoModal() == IDOK)
  {
   CString strFileName = dlg.GetPathName().GetString();
 
   POSITION pos = GetFirstViewPosition();
   COAGMFCView* pView =  (COAGMFCView*) GetNextView(pos);
 
   if ( pView->m_pWinGraphicContext->MakeCurrent() )
   {
    oag::OAGFont* pFont = oag::OAGFontLoader::LoadFontFromDisk( 
                            strFileName.GetString(), OAG_FONT_MAP_2D );
 
    if( pFont )
    {
      pFont->SetFontSize(24);
      pFont->SetFontName("arial");
      if ( pFontMapTable == NULL || 
          !m_pObjectsMappingTable->GetFontMappingTable()->AddFont( pFont ) )
         delete pFont;
      else
         pFontMapTable->AddFont( pFont );
    }
    pView->m_pWinGraphicContext->DeleteCurrent();
   }
  }
}

插入 2D 文本

要插入 2D 文本,请选择“Draw”菜单,点击“2DText”,然后在屏幕上点击以插入文本

插入 2D 文本的代码

函数 font2d->SetText 设置要在屏幕上绘制的文本,而 font2d->SetPosition 设置屏幕上的文本位置。函数 font2d->SetFontNameReference 用于在保存到 XML 文件时获取当前设置的字体。如果未使用 font2d->SetFontNameReference,则在读取 XML 文件时,字体将未设置,并且屏幕上不会绘制任何文本。

void CText2DTool::AddAllVerticesToScene()
{
   oag::OAGFontMapping2D* font2d = new oag::OAGFontMapping2D(); 
 
   if( m_pScene->GetFontMappingTable()->m_ListFont.size() > 0 )
   {
     font2d->SetFont( m_pScene->GetFontMappingTable()->m_ListFont[0]->GetFont() );
     font2d->SetFontNameReference ( 
        m_pScene->GetFontMappingTable()->m_ListFont[0]->GetFontName() );
   }    
 
   oag::OAGVector3f vec = m_arrVector[0];
   font2d->SetText("Example of 2DText"); 
   font2d->SetPosition( oag::OAGVector3f( vec.m_X, vec.m_Y, vec.m_Z ) ); 
   m_pScene->AddObject( font2d );
 
}
 
void CText2DTool::OnMouseClick(oag::OAGVector3f& ptMouse)
{
  switch( m_nStep )
  {
   case 0:
   {
     m_arrVector.Add( ptMouse );
     AddAllVerticesToScene();
     CTool::OnFinalize();
    }
    break;
   }
}

XML文件

在下面的 XML 中,节点 Tables 存储一个节点 Fonts。节点 Fonts 存储用于绘制文本的字体。对于此示例,我们使用了大小为 24 的 arial.tff。节点 <Font Name="" FileName="arial.ttf" Size="24."/> 显示了这一点。

节点 Objects 存储要绘制在屏幕上的 2D 文本。节点 Text2D 显示了这一点

<?xml version="1.0" encoding="ISO-8859-1"?>
<OAGLibrary>
  <Tables>
    <Fonts>
      <Font Name="arial" FileName="arial.ttf" Size="24."/>
    </Fonts>
  </Tables>
  <Scene Type="Draw">
    <Objects>
      <Text2D Name="">
        <UseFont Name="arial"/>
        <String Value="Example of 2DText"/>
        <Color Red="1." Green="1." Blue="1." Alpha="1."/>
        <Transform>
          <Translation x="161." y="148." z="0."/>
          <Scale x="1." y="1." z="1."/>
          <Rotation x="0." y="0." z="0."/>
        </Transform>
      </Text2D>
    </Objects>
  </Scene>
</OAGLibrary>

类 oag::Font

class OAGFont
{
    public:
        OAGFont(void);
        virtual ~OAGFont(void);
 
    //Attributes
    protected:
        bool                m_bIsDone;
        int                    m_nFontSize;
        OAG_FONT_MAPPING    m_enumFontMapping;
        FTFont*                m_pFont;
 
        std::string            m_strName;
        std::string            m_strFolderPath, m_strFilename;
 
 
    //Operations
    public:
        
        //Gets the FileName used by the font
        std::string GetFileName()
        {
            return m_strFilename;
        }
 
        FTFont* GetFont()
        {
            return m_pFont;
        }
 
        int GetFontSize()
        {
            return m_nFontSize;
        }
            
        //Gets the current name set for the texture
        std::string GetFontName()
        { 
            return m_strName; 
        }
 
 
        //Sets the Font Size
    
        void SetFontSize(int nFontSize)
        {
            int newSize = nFontSize;
            if ( m_pFont )
            {
                if ( m_pFont->FaceSize( newSize ) )
                    m_nFontSize = nFontSize;
            }
        }
 
        //Sets a for the object
        void SetFontName(std::string strName)
        {
            m_strName = strName; 
        }
 
        void SetIOSystemFilter(std::string folderPath, std::string fileName)
        {
            m_strFolderPath = folderPath;
            m_strFilename = fileName;
        }
 
 
        //bool IsInitialized()    { return m_bIsInitialized; };
 
    //Virtual
    public:
        virtual void LoadFontFromDisk(std::string strFileName){}
    };
    
//Constructor
oag::OAGFont::OAGFont(void)
:m_bIsDone(false)
,m_pFont(NULL)
,m_nFontSize(10)
{
}
 
//Destructor
oag::OAGFont::~OAGFont(void)
{
    if( m_pFont )
    {
        delete m_pFont;
        m_pFont = NULL;
    }
}

类 oag::OAGFontMapping

class OAGFontMapping : public oag::OAGObject
{
    public:
        OAGFontMapping(void);
        virtual ~OAGFontMapping(void);
 
    //Attributes
    protected:
        std::string        m_strText;
        FTFont*            m_pFont;
        std::string        m_strFontNameReference;
    
    //Operations
    public:
        std::string GetText()
        {
            return m_strText;
        }
 
        void SetFontNameReference(std::string strFontNameReference)
        {
            m_strFontNameReference = strFontNameReference;
        }
 
        void SetText(std::string strText)
        { 
            m_strText = strText;
        }
 
        void SetFont(FTFont* pFont)
        {
            m_pFont = pFont;
        }
    //Virtual
    public:
        virtual    void OnDraw(){};
        virtual void ReadNodeXML(CXmlNode* pNode);
        virtual void SaveNodeXML(CXmlNode* pNode);
};
© . All rights reserved.