Click here to Skip to main content
15,884,099 members
Articles / Multimedia / OpenGL

OAG Library (OpenGL) Part 2.3 - Drawing 2D Textures Using the Mouse and Programatically

Rate me:
Please Sign up or sign in to vote.
4.29/5 (6 votes)
22 Oct 2010CPOL3 min read 34K   1.3K   17  
This tutorial shows library code for 2D Textures and how to draw them programatically using the mouse in an MFC application.
#ifdef _MSC_VER
#include "..\..\include\oag\OAGPrimitives.h"
#endif



oag::OAGPrimitives::OAGPrimitives(void)
:m_GeometryType( GL_LINES )
,m_GeometryData(NULL)
,m_ArraySize(0)
,m_nIndices(NULL)
,m_nVectorPos(0)
{
}

oag::OAGPrimitives::~OAGPrimitives(void)
{
	if( m_GeometryData )
		delete[] m_GeometryData;

	if( m_nIndices )
		delete[] m_nIndices;
}

//Operations

void oag::OAGPrimitives::AddVertex(float x, float y, float z)
{
    m_GeometryData[m_nVectorPos] = oag::OAGVector3f(x, y, z) ;
	m_nVectorPos++;

	switch( m_GeometryType )
	{
	case GL_TRIANGLES:
	case GL_TRIANGLE_FAN:
	case GL_TRIANGLE_STRIP:
		{
			SetIndiceSize( GetVertexCount() );
		}
		break;
	}
}

void oag::OAGPrimitives::SetArraySize(int arraySize)
{
	if( m_GeometryData )
		delete[] m_GeometryData;

	m_nVectorPos = 0;
	m_ArraySize = arraySize;
	m_GeometryData = NULL;
	m_GeometryData = new oag::OAGVector3f[m_ArraySize];
}

void oag::OAGPrimitives::SetIndiceSize(int indiceSize)
{
	if( m_nIndices )
		delete[] m_nIndices;

	m_nIndices = NULL;
	m_nIndices = new GLubyte[m_ArraySize];

	for(int i=0; i < indiceSize; i++ )
		m_nIndices[i] = i;
}

//Checks if the objects is selected by mouse point
bool oag::OAGPrimitives::IntersectsWithCursorInPoint(int x, int y)
{

	if(GetVertexCount() < 2)
		return false;

	//Defining rect sides from x, y 
	oag::OAGVector3f a, b, c, d;
	float size = 2.f;
	bool bIntersect = false;

	a.SetVertex(x-size, y-size, 0);
	b.SetVertex(x-size, y+size, 0);
	c.SetVertex(x+size, y+size, 0);
	d.SetVertex(x+size, y-size, 0);

	switch( m_GeometryType )
	{
	case GL_LINES:
	case GL_LINE_LOOP:
	case GL_LINE_STRIP:
		{
			for( int i=0; i< GetVertexCount()-1; ++i)
			{
				if(!bIntersect)
				{
					oag::OAGVector3f vec1 = m_GeometryData[i];
					oag::OAGVector3f vec2 = m_GeometryData[i+1];

					if( !LineIntersection(&vec1, &vec2, &a, &b ) )
					{
						if( !LineIntersection(&vec1, &vec2, &b, &c) )
						{
							if( !LineIntersection(&vec1, &vec2, &c, &d) )
							{
								if( LineIntersection(&vec1, &vec2, &d, &a) )
								{
									bIntersect = true;break;
								}
							} 
							else { bIntersect = true; break; }
						}
						else { bIntersect = true;	break; }			
					}
					else { bIntersect = true; break; }
				}	
			}

			this->SetSelected(bIntersect);
		}
		break;

	}

	return IsSelected();
}

//Virtual
void oag::OAGPrimitives::OnDraw()
{

	if( m_ArraySize < 1 )
		return;

	::glPushMatrix();
	::glLoadIdentity();

	::glColor4ubv( m_Color.GetColor4ubv() );

	::glPolygonMode(m_PolygonFace, m_PolygonMode);

	::glTranslated(m_position.m_X, m_position.m_Y, m_position.m_Z);

	switch( m_GeometryType )
	{
	case GL_LINES:
	case GL_LINE_LOOP:
	case GL_LINE_STRIP:
	case GL_POINTS:
	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();	
}

void oag::OAGPrimitives::ReadNodeXML(CXmlNode* pNode)
{
	oag::OAGObject::ReadNodeXML( pNode );

	CXmlNode* pNodeGeometryType = NULL;

	pNodeGeometryType = pNode->GetNode("Lines");
	if ( pNodeGeometryType )
		SetGeometryType(GL_LINES);

	if ( pNodeGeometryType == NULL )
	{
		pNodeGeometryType = pNode->GetNode("IndexedLines");
		if ( pNodeGeometryType )
		{
			if ( pNodeGeometryType->GetAttribute("Closed").compare("False") == 0 )
				SetGeometryType(GL_LINE_STRIP);
			else 
				SetGeometryType(GL_LINE_LOOP);
		}
	}

	if ( pNodeGeometryType == NULL )
	{
		pNodeGeometryType = pNode->GetNode("Rects");
		if ( pNodeGeometryType )
			SetGeometryType(GL_QUADS);
	}

	if ( pNodeGeometryType == NULL )
	{
		pNodeGeometryType = pNode->GetNode("Triangles");
		if ( pNodeGeometryType )
			SetGeometryType(GL_TRIANGLES);
	}

	if ( pNodeGeometryType == NULL )
	{
		pNodeGeometryType = pNode->GetNode("Points");
		if ( pNodeGeometryType )
			SetGeometryType(GL_POINTS);
	}

	if ( pNodeGeometryType )
	{
		//Creating the coordinates
		CXmlNode* pNodeCoords = pNodeGeometryType->GetNode("Coordinates");

		if ( pNodeCoords )
		{		
			CXmlNodeList* pNodePoints = pNodeCoords->GetNodeList();

			if ( pNodePoints )
			{
				if ( pNodePoints->Count() > 0 )
				{
					SetArraySize(  pNodePoints->Count() );

					for( std::vector<int>::size_type i = 0; i < pNodePoints->Count(); ++i )
					{
						float x =  (float)atof ( pNodePoints->GetAt(i)->GetAttribute("x").c_str() );
						float y =  (float)atof ( pNodePoints->GetAt(i)->GetAttribute("y").c_str() );
						float z =  (float)atof ( pNodePoints->GetAt(i)->GetAttribute("z").c_str() );

						AddVertex(x, y, z);
					}
				}

				delete pNodePoints;
			}
		}
	}
}

void oag::OAGPrimitives::SaveNodeXML(CXmlNode* pNode)
{

	CXmlNode* pNodePrimitive = new CXmlNode("Primitive");
	pNode->AppendChild( pNodePrimitive );

	pNodePrimitive->AddAttribute( "Name", m_strName );

	//Creating the color node
	pNodePrimitive->AppendChild( CreateNodeColor() );

	if ( m_ArraySize > 0 )
	{
		CXmlNode* pNodeGeometry = NULL;
		

		//Creating the node for the primitive type
		switch( m_GeometryType )
		{
		case GL_POINTS:
			{
				pNodeGeometry = new CXmlNode("Points");
				pNodePrimitive->AppendChild( pNodeGeometry );				
			}
			break;
		case GL_LINES:
			{
				pNodeGeometry = new CXmlNode("Lines");
				pNodePrimitive->AppendChild( pNodeGeometry );
			}
			break;
		case GL_LINE_LOOP:
		case GL_LINE_STRIP:
			{
				pNodeGeometry = new CXmlNode("IndexedLines");
				pNodePrimitive->AppendChild( pNodeGeometry );

				bool bClosed = ( m_GeometryType == GL_LINE_STRIP ) ? false : true;
				std::string strClosed = ( bClosed ) ? "True" : "False";
				pNodeGeometry->AddAttribute("Closed", strClosed );

			}
			break;
		case GL_QUADS:
			{
				pNodeGeometry = new CXmlNode("Rects");
				pNodePrimitive->AppendChild( pNodeGeometry );				
			}
			break;
		case GL_TRIANGLES:
			{
				pNodeGeometry = new CXmlNode("Triangles");
				pNodePrimitive->AppendChild( pNodeGeometry );
			}
			break;
			
		}

		CXmlNode* pNodeCoordinates = new CXmlNode("Coordinates");
		pNodeGeometry->AppendChild( pNodeCoordinates );

		//Creating the coordinates
		for( int i=0; i < GetVertexCount(); ++i )
		{
			CXmlNode* pNodePoints = CreateVectorNodeAttribute( &m_GeometryData[i], "Point");
			pNodeCoordinates->AppendChild( pNodePoints );
		}

	}

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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


Written By
Software Developer
Brazil Brazil
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.

Comments and Discussions