OAG 库 (OpenGL) 第 2.1 部分 - 使用鼠标和编程方式绘制 2D 对象






4.42/5 (11投票s)
本教程展示了 Geometry 2D 的库代码,说明了如何以编程方式绘制它们,以及如何在 MFC 应用程序中使用鼠标绘制对象。
引言
在本教程中,我添加了类来绘制 Geometry 2D、纹理和 True Type 字体,以便您可以更轻松地在屏幕上绘制对象。您必须下载该库才能编译示例。点击这里转到下载页面。使用 OAGMFC,您可以保存和打开 XML 文件 (*.oagxml)。 XML 文件是 collada 文件的替代方案。
Geometry 2D
![]() |
![]() |
![]() |
![]() |
---|---|---|---|
Line | Polyline | 矩形 | 三角形 |
创建 Geometry 2D
要使用该库构建几何体,您需要为 OAGPrimitives
创建一个新实例。 使用该类,您可以绘制 opengl 支持的图元,例如线、线段、折线、矩形和三角形。 在创建 OAGPrimitives
的新实例后,您必须使用命令 SetGeometryType
来更改您要绘制的图元类型。 SetGeometryType
支持的类型包括 GL_LINES
(用于线)、GL_LINE_STRIP
(用于折线)、GL_QUADS
(用于矩形)和 GL_TRIANGLES
(用于三角形)。 下面的例子展示了如何创建一条线。
//Creating a line
oag::OAGPrimitives* pGeo = new oag::OAGPrimitives();
peo->SetGeometryType( GL_LINES );
如果您希望绘制一个实心几何体,请使用 SetPolygonMode(GL_FILL)
。 使用 GL_FILL
您告诉 OpenGL 绘制实心多边形。 下面是绘制实心三角形和实心矩形的代码。
//solid rectangle
oag::OAGPrimitives* pQuad = new oag::OAGPrimitives();
pQuad->SetGeometryType( GL_QUADS );
pQuad->SetPolygonMode(GL_FILL);
//Adding vertices for the rectangle
std::vector<:oagvector3f> lstQuadVector;
lstQuadVector.push_back( oag::OAGVector3f( 20.f, 132.f, 0.f ));
lstQuadVector.push_back( oag::OAGVector3f( 20.f, 145.f, 0.f ));
lstVector.push_back( oag::OAGVector3f( 127.45f, 64.f, 0.f ));
lstVector.push_back( oag::OAGVector3f( 127.45f, 132.f, 0.f ));
pQuad->SetArrayVertices( lstQuadVector );
m_pScene->AddObject( pQuad );
//Solid Triangle
oag::OAGPrimitives* pTri = new oag::OAGPrimitives();
pTri->SetGeometryType( GL_TRIANGLES );
pTri->SetPolygonMode(GL_FILL);
//Adding vertices for the triangle
std::vector<:oagvector3f> lstTriVector;
lstTriVector.push_back( oag::OAGVector3f( 57.f, 39.f, 0.f ));
lstTriVector.push_back( oag::OAGVector3f( 112.f, 128.f, 0.f ));
lstTriVector.push_back( oag::OAGVector3f( 176.f, 64.f, 0.f ));
pTri->SetArrayVertices( lstTriVector );
m_pScene->AddObject( pTri );
用于绘制图元的库代码
这里的 OnDraw
函数使用命令在 OpenGL 中更快地使用顶点。 命令 glDrawElements
和 glDrawArrays
做到这一点。
void oag::OAGPrimitives::OnDraw()
{
if( m_ArraySize < 1 )
return;
::glPushMatrix();
::glLoadIdentity();
::glColor4ubv( m_Color.GetColor4ubv() );
::glPolygonMode(m_PolygonFace, m_PolygonMode);
switch( m_GeometryType )
{
case GL_LINES:
case GL_LINE_LOOP:
case GL_LINE_STRIP:
case GL_QUADS:
{
::glEnableClientState(GL_VERTEX_ARRAY);
::glVertexPointer(3, GL_FLOAT, 0, m_GeometryData);
::glDrawArrays( m_GeometryType, 0, m_ArraySize );
::glDisableClientState(GL_VERTEX_ARRAY);
}
break;
case GL_TRIANGLES:
case GL_TRIANGLE_FAN:
case GL_TRIANGLE_STRIP:
{
::glEnableClientState(GL_VERTEX_ARRAY);
::glVertexPointer(3, GL_FLOAT, 0, m_GeometryData);
::glDrawElements(m_GeometryType, GetVertexCount(), GL_UNSIGNED_BYTE, m_nIndices);
::glDisableClientState(GL_VERTEX_ARRAY);
}
break;
}
::glPopMatrix();
}
创建文本
要使用该库创建文本,您需要创建 oag::OAGFont2D
的新实例。 使用此类,您可以使用 FTGL 和 FreeType 库在 OpenGL 中绘制 2D 文本。 下面的例子展示了如何创建 2D 文本。 该库和演示程序使用文件 arial.ttf。
oag::OAGFont2D* font2d = new oag::OAGFont2D();
m_pWinGraphicContext->MakeCurrent();
font2d->Initialize();
m_pWinGraphicContext->DeleteCurrent();
font2d->SetText("Example of 2DText");
font2d->SetFontSize(20);
//Font Position
oag::Matrix4x4 mt;
mt.SetTranslation(vec.m_X, vec.m_Y, vec.m_Z);
font2d->SetTransform( mt );
m_pScene->AddObject( font2d );
用于绘制文本的库代码
void oag::OAGFontMapping2D::OnDraw()
{
if ( m_pFont == NULL )
return;
::glPushMatrix();
::glLoadIdentity();
::glColor4ubv( m_Color.GetColor4ubv() );
::glPolygonMode(m_PolygonFace, m_PolygonMode);
::glLoadMatrixf( m_ObjectMatrix.GetData() );
m_pFont->Render(m_strText.c_str());
::glPopMatrix();
}
示例
本教程展示了如何使用类使用鼠标绘制几何体 2D。 编写用于绘制的类位于 CadTools 文件夹中。 本项目教程是使用 Visual Studio 2008 创建的。
用于绘制几何体的绘图菜单
绘制几何体
当您调用其中一个“绘图”菜单项时,会为图元创建一个工具,并调用该文档来为菜单项创建图元类型。 有关调用“绘图”菜单中的命令行的示例,请参见示例。
void COAGMFCView::OnDrawLine()
{
if ( m_pTool )
delete m_pTool;
OnInsertGeometries(1);
m_pTool = new CLineTool();
m_pTool->SetScene( GetDocument()->m_pScene );
}
在点击直线后,您会在场景中创建一个图元。 要开始绘制,您可以点击屏幕并移动鼠标以在屏幕上查看图元。
图元线有两个点,当您再次点击屏幕时,您将为该线设置第二个点,图元就完成了。
现在让我们转到折线。 选择“绘制”菜单并点击“折线”,然后在屏幕上点击以开始绘制。 对于折线,您可以多次点击屏幕。 完成折线后,必须按 ESC 键才能完成图元。
下一个图元是矩形。 选择“绘制”菜单并点击“矩形”,然后在屏幕上点击以开始绘制。 移动鼠标并查看在屏幕上绘制的矩形。 完成矩形后,点击屏幕以完成图元。
最后一个图元是三角形。 选择“绘制”菜单并点击“三角形”,然后在屏幕上点击以开始绘制。 移动鼠标,您将看不到三角形,因为您只有三角形的两个点。 再次点击屏幕时,会定义第二个点,如果您移动鼠标,您可以在屏幕上看到一个三角形。 完成三角形后,再次点击屏幕。 三角形已完成。
鼠标事件
当您点击屏幕时,该点会更改为世界坐标。 之后,该点被添加到工具中。 该工具使用函数 MouseClick
将坐标添加到图元中。 如果这是图元的第一次点击,该工具会将两个点添加到图元中。
void COAGMFCView::OnLButtonDown(UINT nFlags, CPoint point)
{
oag::OAGVector3d center;
oag::OAGVector3f pt(point.x, point.y, 0);
m_pRender->ScreenToWorld(&pt, ¢er, 1);
if( m_pTool && !m_pTool->IsFinished() )
{
oag::OAGVector3f vec( (float)center.m_X, (float)center.m_Y, 0.f );
m_pTool->OnMouseClick( vec );
Invalidate(FALSE);
}
CView::OnLButtonDown(nFlags, point);
}
当您移动鼠标时,最后一个点会更改,您会实时看到该图元。
void COAGMFCView::OnMouseMove(UINT nFlags, CPoint point)
{
if( m_pTool && m_pTool->IsStarted() && !m_pTool->IsFinished() )
{
oag::OAGVector3d center;
oag::OAGVector3f pt(point.x, point.y, 0);
oag::OAGVector3f vec;
m_pRender->ScreenToWorld(&pt, ¢er, 1);
oag::OAGVector3f vecPoint( (float)center.m_X, (float)center.m_Y, 0.f );
vec.m_X = vecPoint.m_X; vec.m_Y = vecPoint.m_Y;
m_pTool->OnMouseMove( vec );
Invalidate(FALSE);
}
CView::OnMouseMove(nFlags, point);
}