Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / MFC

OAG Library (OpenGL) Part 2.1 - Drawing Objects 2D using the Mouse and Programatically

4.42/5 (11 votes)
13 Aug 2011CPOL3 min read 65.8K   450  
This tutorial shows Library Code for Geometries 2D how to draw them programatically and how draw to objects using the mouse in an application MFC.

Introduction

In this tutorial, I have added classes to draw Geometries 2D, textures and True Type Fonts, so you can draw the objects easier on the screen.You must download the library to compile the sample. Click here to go to the download page. Using the OAGMFC, you can save and open XML files (*.oagxml). The XML files are an alternative for collada files.

The Geometries 2D

Primline.jpgImage 2Image 3Image 4
Line PolylineRectangleTriangle

Creating Geometries 2D

To build geometries using the library, you need to create a new instance for OAGPrimitives. With the class, you can draw primitives supported by opengl such as line, lines, polylines, rectangle and triangle. After creating a new instance of OAGPrimitives, you must use the command SetGeometryType to change the primitive type that you want to draw. The supported types by SetGeometryType are GL_LINES (for lines), GL_LINE_STRIP (for polyline), GL_QUADS (for rectangle) and GL_TRIANGLES (for triangle). The example below shows how to create a line.

C++
//Creating a line
oag::OAGPrimitives* pGeo = new oag::OAGPrimitives();
peo->SetGeometryType( GL_LINES );

If you wish to draw a solid geometry, use the SetPolygonMode(GL_FILL). Using GL_FILL you tell OpenGL to draw Solid Polygons. Below is the code for drawing a solid triangle and solid rectangle.

C++
//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 );

Image 5

The Library Code For Drawing the Primitives

Here an OnDraw function uses commands for Faster Vertex in OpenGL. The commands glDrawElements and glDrawArrays do it.

C++
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();
} 

Creating Text

To create text using the library, you need to create a new instance of oag::OAGFont2D. With this class, you can draw draw 2D text in OpenGL using the libraries FTGL and FreeType. The example below shows how to create a 2D Text. The library and the demo use the file arial.ttf.

C++
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 );

The Library Code for Drawing the Text

C++
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();
 
}

The Sample

This tutorial shows how to draw geometries 2D using the mouse using classes. The classes written to draw are in the folder CadTools. This project tutorial has been created with Visual Studio 2008.

The Draw Menu for Drawing the Geometries

Image 6

Drawing the Geometries

When you call one of the Draw Menu items, one tool is created for the primitive and the document is called to create the primitive type for the menu item. See the example when you call the command line in the Draw menu.

C++
void COAGMFCView::OnDrawLine()
{
  if ( m_pTool )
    delete m_pTool;
	
   OnInsertGeometries(1);

  m_pTool = new CLineTool();
  m_pTool->SetScene( GetDocument()->m_pScene );
}

After clicking in line you have a primitive created in your scene. To start drawing, you click on the screen and move the mouse to see the primitive on the screen.

Image 7

The primitive line has two points and when you click again on the screen, you set the second point for the line and the primitive is finished.

Now let's go to the polyline. Select the Draw the menu and click on Polyline and click on the screen to start drawing. For the polyline, you can click on the screen lot of times. When your polyline is done, you must press key ESC to finish the primitive.

Image 8

The next primitive is the rectangle. Select the Draw the menu and click on Rectangle and click on the screen to start drawing. Move the mouse and see a rectangle drawing on the screen. When the rectangle is done, click on the screen to finish the primitive.

Image 9

The last primitive is the triangle. Select the Draw the menu and click on Triangle and click on the screen to start drawing. Moving the mouse, you won't see a triangle because you have just two points for the triangle. When you click on the screen again, the second point is defined and you can see a triangle on the screen if you move the mouse. When the triangle is done, click on the screen again. The triangle is finished.

Image 10

Mouse Events

When you click on the screen, the point is changed to world coordinates. After this, the point is added on the tool. The tool adds the coordinate to the primitive with the function MouseClick. If it is the first click for the primitive, the tool adds two points to the primitive.

C++
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);
}

When you move the mouse, the last point is changed and you see the primitive in real time.

C++
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);
} 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)