Click here to Skip to main content
Click here to Skip to main content

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

By , 13 Aug 2011
 

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.jpg
Line Polyline Rectangle Triangle

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.

//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.

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

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.

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.

 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

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

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.

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.

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.

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.

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.

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.

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.

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)

About the Author

Eduardo Tucci
Software Developer
Brazil Brazil
Member
I live in Matão, a small city in Brazil. I studied as Programmer in a College for Software Development in Database.
After finishing the College I have been working with java, c# and Computer Graphics with searches for OpenGL.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionCannot open include file: 'OAGScene.h': No such file or directorymembermasoudrad22 Oct '12 - 9:58 
Hi, I run your source code but this error stopped compiling: Cannot open include file: 'OAGScene.h': No such file or directory I haven't this Header "OAGScene.h" on my include folder. I request help me. thank you.
Questionlibrary down page not found.memberwaterharbin9 Aug '11 - 15:02 
Hello,Eduardo.I can not find your libraries.Can you update your download page again?
AnswerRe: library down page not found. [modified]memberEduardo Tucci12 Aug '11 - 7:29 
I am sorry. The link has been fixed. Wait the article to be uptaded. You can download the library on http://sourceforge.net/projects/oag/files/ Thanks you. modified on Friday, August 12, 2011 3:50 PM
GeneralTriangle tool redundantmemberSharjith25 Oct '10 - 11:22 
The article is nice! Just an observation... Is the Triangle tool really required when there is a Polyline tool? Just make a Polyline with closed/open option and it serves for open Polylines, triangles squares and all other polygons. Regards N. Sharjith
GeneralRe: Triangle tool redundantmemberEduardo Tucci26 Oct '10 - 5:35 
Hi   I Have made one tool for each 2D geometry. In this case the polyline tool and triangle tool are different. With the polilyne tool you can draw lot of vertices and for triangle tool you draw three vertices to draw a triangle.   You are right. I should have used the polyline...
GeneralRe: very good.memberEduardo Tucci16 Jun '10 - 7:15 
I did not understand your question. If you can, write with others words.
GeneralAllocationg objects on the heapmemberNemanja Trifunovic15 Jun '10 - 5:08 
Out of curiosity, is there any particular reason you create all your objects on the heap?   I.e.   oag::OAGPrimitives* pGeo = new oag::OAGPrimitives();   rather than simply:   oag::OAGPrimitives Geo;   In general, manually pairing new-delete is a recipe for...
GeneralRe: Allocationg objects on the heapmemberEduardo Tucci15 Jun '10 - 14:47 
I use oag::OAGPrimitives* pGeo = new oag::OAGPrimitives(); because the class oag::OAGScene works with objects in the memory. For the demo I have objects for each document. When a document is deleted all the objects are deleted too using the function m_pScene->DeleteAllObjects();. You can have...
GeneralA transparent back groundmemberkzhao66@yahoo.com15 Jun '10 - 4:47 
All your examples are black background. I would like to know can you make an example with transparent background? I need drawing 2D geometries with a transparent background. It's that possible? Do you have an example in your next section?   Thanks
GeneralRe: A transparent back groundmemberEduardo Tucci15 Jun '10 - 14:14 
This function is in the previous article. Use m_pRender->SetBackGroundColor( ); to change the background Color.
GeneralRe: A transparent back groundmemberkzhao66@yahoo.com16 Jun '10 - 4:48 
Thanks for your help, but I trying to get the background to be transparent (I'm trying to get the drawings to appear over my desktop). Any ideas?
GeneralRe: A transparent back groundmemberEduardo Tucci16 Jun '10 - 4:58 
Sorry, I did not undertand what background should be transparent. if is a window transparent I do not know how to do this.   Did you like of this library? If you have others code for this library and you can help me to implement other objects I get your code.   if you want add me...
GeneralRe: A transparent back groundmembersanthosh4gCode20 Jun '10 - 14:48 
The following method will provide a transparent window with opengl rendering.   // Creating a Layared Window g_hWnd = CreateWindowEx( WS_EX_LAYERED, "MY_WINDOWS_CLASS", "OpenGL – Layered Rendering", WS_OVERLAPPEDWINDOW | WS_VISIBLE, ...

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 13 Aug 2011
Article Copyright 2010 by Eduardo Tucci
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid