#pragma once #include "cscreen.h" #define SET_OWNER_COLOR glColor3d( 0, 255, 0 ) #define SET_OPPO_COLOR glColor3d( 255, 0, 0 ) namespace Game { float CScreen::fHypo; void CScreen::Set2DMode( ) { glDisable( GL_DEPTH_TEST ); glMatrixMode( GL_PROJECTION ); glLoadIdentity( ); gluOrtho2D( 0, ScreenWidth, ScreenHeigth, 0 ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity( ); } void CScreen::DrawPoint( int x, int y ) { glVertex2d( x, y ); } void CScreen::DrawLine( int x, int y, int x1, int x2 ) { glPointSize( 1.0 ); glVertex2d( x, y ); glVertex2d( x1, x2 ); } void CScreen::DrawMesh( ) { Set2DMode( ); glPushMatrix( ); glColor3d( 0, 0, 0 ); glBegin( GL_LINES ); for( int i = CellSize; i < ScreenWidth; i += CellSize ) { DrawLine( i, ScreenHeigth, i, -ScreenWidth ); } for( int i = CellSize; i < ScreenHeigth; i += CellSize ) { DrawLine( -ScreenHeigth, i, ScreenWidth, i ); } glEnd( ); glPopMatrix( ); } void CScreen::DrawPlayersPoints( ) { Set2DMode( ); glPushMatrix( ); glPointSize( ( float )CellSize * 0.4 ); for( auto it = CGlobals::m_vPointInfo.begin( ); it < CGlobals::m_vPointInfo.end( ); it++ ) { if( it->IsOppo( &CGlobals::m_LocalPlayer ) ) { glColor3d( 255, 0, 0 ); } else { glColor3d( 0, 255, 0 ); } glBegin( GL_POINTS ); cml::vector2i nearest = CScreen::GetNearestPoint( it->GetPoint( )->To2DVector( ) ); CScreen::DrawPoint( nearest[ 0 ], nearest[ 1 ] ); glEnd( ); } glPopMatrix( ); } void CScreen::DrawAreas( ) { Set2DMode( ); glPushMatrix( ); glPointSize( 1.0 ); PointInfoList vecPoints; for( auto it = CGlobals::m_vPointInfo.begin( ); it < CGlobals::m_vPointInfo.end( ); it++ ) { vecPoints.push_back( *it ); CScreen::JoinNearestPoints( *it, vecPoints ); } glPopMatrix( ); } void CScreen::JoinNearestPoints( CPointInfo pointInfo, PointInfoList vecRealPoints ) { cml::vector2i currentPoint = pointInfo.GetPoint()->To2DVector(); for( auto it = vecRealPoints.begin( ); it < vecRealPoints.end( ); it++ ) { Vector2DI nextPoint = it->GetPoint()->To2DVector( ); if( currentPoint == nextPoint ) { continue; } if( pointInfo.IsOppo( it->GetOwner( ) ) ) { continue; } if( pointInfo.GetOwner( )->GetPlayerName( ) == CGlobals::m_LocalPlayer.GetPlayerName( ) ) { SET_OWNER_COLOR; } else { SET_OPPO_COLOR; } glBegin( GL_LINES ); float fDistance = Vector2DI( currentPoint - nextPoint ).length( ); if( fDistance <= fHypo ) // PYTHAGORAAAAAAAAAAAAARTA { if( fDistance == fHypo ) { Vector2dList vecPoints = CScreen::GetNearestOppoCoords( pointInfo, vecRealPoints ); if( CScreen::GetNearestPointsCount( nextPoint, vecPoints ) == 2 ) { continue; } } DrawLine( currentPoint[0], currentPoint[1], nextPoint[0], nextPoint[1] ); } glEnd( ); } } int CScreen::GetNearestPointsCount( Vector2DI point, Vector2dList vecNearestPoints ) { int count; for( auto it = vecNearestPoints.begin(); it < vecNearestPoints.end(); it++ ) { if( Vector2F( point - *it ).length( ) < fHypo ) { count++; } } return count; } Vector2dList CScreen::GetNearestOppoCoords( CPointInfo pointInfo, PointInfoList vecPointInfo ) { Vector2dList vecPoints; cml::vector2i currentPoint = pointInfo.GetPoint()->To2DVector(); for( auto it = vecPointInfo.begin( ); it < vecPointInfo.end( ); it++ ) { if( pointInfo.IsOppo( it->GetOwner( ) ) ) { cml::vector2i nextPoint = it->GetPoint( )->To2DVector( ); if( cml::vector2d( currentPoint - nextPoint ).length( ) <= fHypo ) { vecPoints.push_back( nextPoint ); } continue; } } return vecPoints; } void CScreen::RenderScene( ) { glClear( GL_COLOR_BUFFER_BIT ); DrawMesh( ); DrawPlayersPoints( ); DrawAreas( ); glutSwapBuffers( ); } void CScreen::UpdateScreen( int width, int heigth ) { float fRatio; if( !heigth ) { heigth = 1; } glViewport( 0, 0, width, heigth ); glMatrixMode( GL_PROJECTION ); glLoadIdentity( ); fRatio = (float)width / (float)heigth; if( width <= heigth ) { glOrtho( -100, 100, -100.0 / fRatio, 100.0 / fRatio, 1, -1 ); } else { glOrtho( -100 * fRatio, 100 * fRatio, -100, 100, 1, -1 ); } glMatrixMode( GL_MODELVIEW ); glLoadIdentity( ); } Vector2DI CScreen::GetNearestPoint( CPoint point ) { return CScreen::GetNearestPoint( Vector2DI( point.GetX(), point.GetY() ) ); } Vector2DI CScreen::GetNearestPoint( Vector2DI point ) { Vector2DI nearest( 0, 0 ); for( int i = CellSize; i < ScreenWidth; i += CellSize ) { for( int k = CellSize; k < ScreenHeigth; k += CellSize ) { Vector2DI newPoint( i, k ); if( (newPoint - point).length( ) < ( nearest - point ).length( ) ) { nearest = newPoint; } } } return nearest; } bool CScreen::HaveSamePoint( Vector2DI newPoint ) { if( !CGlobals::m_vPointInfo.empty( ) ) { for( auto it = CGlobals::m_vPointInfo.begin( ); it < CGlobals::m_vPointInfo.end( ); it++ ) { Vector2DI oldPoint = it->GetPoint( )->To2DVector( ); if( oldPoint == newPoint ) { return true; } } } return false; } }