Jump to content
  • Advertisement
Sign in to follow this  
kubapl

OpenGL Slowness and bug-city

This topic is 3760 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey so practically finished my second game ever entirely written in C++ and OpenGL. The only problem is that my release build is unreasonably slow. I'll post my main loop at the end maybe someone could point out to why its chuggy. But first here is some art: The EVIL JELLY FISH: and the fight against good and evil the sub vs the squid: And heres the release build: http://kubapl.ath.cx/projects/SpaceInvadorsrelease.zip And heres my main game loop perhaps this is were most of the slowieness takes place:
#include <windows.h>
#include <GL/glut.h>
#include <list>
#include <cmath>
#include <iostream>
#include <cstdlib> 
#include <ctime>
#include <mmsystem.h>

#include "Object.h"
#include "Enemy.h"
#include "Projectile.h"
#include "Vector.h"
#include "Camera.h"
#include "Font.h"
#include "TGA.h"


using std::list;
using std::cout;
using std::endl;


#define SCREENHEIGHT 600 //z
#define SCREENWIDTH 900 //x
#define NUMBEROFENEMIES 8

UINT TextureArray[1];

//Game Functions
void gameLogic();
void gameLights();
short int Sprite_Collide( CObject *object1, CObject *object2 );

//BackGround objects
CObject *BackGround;
CObject *Curser;
CObject *Options;
//Game Objects
CObject *Player;
CObject *Field;
CObject *Water;
CCamera *Camera;
CEnemy  *Enemies[ NUMBEROFENEMIES ];

//Lists
list< CProjectile* >lstMissile;

bool gamePlaying = false;


void myInit()
{
	glClearColor( 0.0, 0.0, 0.0, 0.0 );
	glShadeModel( GL_FLAT );
	glEnable( GL_NORMALIZE );
	//glEnable( GL_LIGHTING );
	glEnable( GL_DEPTH_TEST ); 
		

	int nDisplayList = 0;
	nDisplayList = glGenLists( 1 );
	glNewList( nDisplayList, GL_COMPILE );
	{
		glutSolidCube( 2.0 );
	}
	glEndList();

	cout << "loading ..." << endl;

	BackGround = new CObject( true, 62, 1, 45 );
	Curser = new CObject( true, 5, 1, 5 );
	Options = new CObject( false, 45, 1, 35 );
	BackGround->loadModel( "models/plane4x4.ase" );
	BackGround->loadTexture( "texture/menu.tga" );
	BackGround->buildModel();

	Curser->loadModel( "models/cursor.ase" );
	Curser->loadTexture( "texture/cursor.tga" );
	Curser->buildModel();

	Options->loadModel( "models/plane4x4.ase" );
	Options->loadTexture( "texture/options.tga" );
	Options->buildModel();

	BackGround->setLocation( 0.0f, 1.0f, 0.0f );
	Curser->setLocation( -44.0f, 0.0f, -15.0f );
	Curser->setOrientation( 90.0f, 0.0f, 0.0f );
	Options->setLocation( 0.0, -1.0f, 0.0f );

	Player = new CObject( true, 3, 1, 3 );
	Player->loadModel( "models/plane4x4.ase" );
	Player->loadTexture( "texture/playerShip.tga" );
	Player->buildModel();
	Player->setLocation( 0.0f, 0.0f, -28.0f );

	Field = new CObject();
	Camera = new CCamera( Field );

	for( int i = 0; i < NUMBEROFENEMIES; ++i )
	{
		Enemies[ i ] = new CEnemy( true, 3, 1, 3 );
		Enemies[ i ]->loadModel( "models/plane4x4.ase" );
		Enemies[ i ]->loadTexture( "texture/squid.tga" );
		Enemies[ i ]->buildModel();
		Enemies[ i ]->setLocation( -35.0f + 10 * i, 0.0f, 35.0f );

	}

	gameLights();
}



void myReshape (int w, int h)
{
	
	glViewport (0, 0, ( GLsizei ) w, ( GLsizei ) h); 
	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();
	gluPerspective( 65.0, ( GLfloat ) w/( GLfloat ) h, 1.0, 60.0 );
}

void DrawAxis()
{
	GLboolean bLight = glIsEnabled( GL_LIGHTING );

	if( bLight )
		glDisable( GL_LIGHTING );

	glColor3f( 1.0f, 1.0f, 1.0f );
	
	glBegin( GL_LINES );
	
	glVertex3f( 0, 0, -500.0f );
	glVertex3f( 0, 0, 500.0f );

	glVertex3f( -500.0f, 0, 0 );
	glVertex3f( 500.0f, 0, 0 );
	
	glEnd();

	if( bLight )
		glEnable( GL_LIGHTING );
}

void myDisplay()
{		
	glEnable( GL_POLYGON_SMOOTH );
	glClear( GL_COLOR_BUFFER_BIT );
	glClear( GL_DEPTH_BUFFER_BIT  );
	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();
	glColor3f( 1.0, 1.0, 1.0 );
	
	Camera->Update();
	
	if( gamePlaying == false )
	{
		glDisable( GL_LIGHTING );
		BackGround->loadTexture( "texture/menu.tga" );
		BackGround->Render();
		Curser->Render();
		Options->Render();
	}
	else
	{
		glDisable( GL_LIGHTING );
		
		BackGround->loadTexture( "texture/water.tga" );
		BackGround->Render();
		//Water->Render();

		gameLogic();
		Player->Render();
		
		for( int i = 0; i < NUMBEROFENEMIES; ++i )
		{
			Enemies[ i ]->Render();
			Enemies[ i ]->enemyFall( -1, 0.05 );
		}
		
		list< CProjectile* >::iterator itMissile = lstMissile.begin();
		while( itMissile != lstMissile.end() )
		{
			
			if( (*itMissile)->IsActive() )
			{
				
				(*itMissile)->Render();	
				
				++itMissile;
			}
			else
			{
				delete (*itMissile);   
			
				itMissile = lstMissile.erase( itMissile ); 
			}
		
		}

	}
	//DrawAxis();
	
	glColor3f( 1.0, 0.5, 1.0 );


	glutSwapBuffers();
	glFlush();
	
}

void Idle()
{
	glutPostRedisplay();
}

void myKeyboard( unsigned char key, int x, int y )
{
	CVector vOri = Player->getOrientation();
	
	int nDisplayList2 = 1;
	nDisplayList2 = glGenLists( 2 );
	glNewList( nDisplayList2, GL_COMPILE );
	{
		glutSolidSphere( 0.5, 10.0, 10.0 );
	}
	glEndList();

	switch( key )
	{
		case 27:
			{
				if( gamePlaying == false )
				{
					exit(0);
				}
				else
				{
					gamePlaying = false;
				}
				break;				
			}
		case 'x': ///Toggle wireframe mode.
			{
				glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
				break;
			}

		case 'X': // Toggle wireframe mode.
			{
				glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
				break;
			}
	/*	case 'w':
			{	
				vOri.fy += 0.1f;
				break;
			}
		case 's':
			{
				vOri.fy -= 0.1f;
				break;
			}
		case 'd':
			{
				vOri.fx += 0.1f;
				break;
			}
		case 'a':
			{
				vOri.fx -= 0.1f;
				break;
			}*/
	

			
		case ' ':
			{
				CProjectile* pMissile = new CProjectile( nDisplayList2, true );
				
				pMissile->shoot( Player );
				
				lstMissile.push_back( pMissile );

				break;
			}

		case 13:
			{
				if( Curser->getLocation().fz == -15.0f )
				{
					gamePlaying = true;
					break;
				}
				if( Curser->getLocation().fz == -20.5f )
				{
					if( Options->IsActive() == false )
					{
						Options->setStatus( true );
					}
					else
					{
						Options->setStatus( false );
					}
					break;
				}
				if( Curser->getLocation().fz == -26 )
				{
					exit(0);
				}
				break;
			}
			
		default:
		break;
	}

	Player->setOrientation( vOri );
	glutPostRedisplay();
}

void SpecialKey( int nKey, int x, int y )
{
	CVector vLoc = Player->getLocation();
	CVector vCurserLoc = Curser->getLocation();

	switch( nKey )
	{
	case GLUT_KEY_RIGHT:					//right arrow key
		{
			vLoc.fx += 0.5f;
			break;
		}

	case GLUT_KEY_LEFT:					   //left arrow key
		{
			vLoc.fx -= 0.5f;
			break;
		}
	case GLUT_KEY_DOWN:
		{
			if( vCurserLoc.fz <= -26.0f )
			{
				break;
			}
			else
			{
				vCurserLoc.fz -= 5.5f;
				cout << vCurserLoc.fz << endl;
				break;
			}
			
		}
	case GLUT_KEY_UP:
		{
			if( vCurserLoc.fz >= -15.0f )
			{
				break;
			}
			else
			{
				vCurserLoc.fz += 5.5f;
				cout << vCurserLoc.fz << endl;
				break;
			}
		}

	default:
	 break;

	}

	Player->setLocation( vLoc );
	Curser->setLocation( vCurserLoc );


}

int main( int argc,  char** argv )
{
	glutInit( &argc, argv );
	glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB );
	glutInitWindowSize( SCREENWIDTH, SCREENHEIGHT ); 
	glutInitWindowPosition ( 100, 100 );
	glutCreateWindow("Space Invadors");	
	
	myInit();

	glutDisplayFunc( myDisplay );
	
	glutReshapeFunc( myReshape );
	glutKeyboardFunc( myKeyboard );
	glutSpecialFunc( SpecialKey );
	glutIdleFunc( Idle );
	glutMainLoop();


	return 0;
}

void gameLogic()
{	
	list< CProjectile* >::iterator itMissile = lstMissile.begin();

	while( itMissile != lstMissile.end() )
	{
		if( (*itMissile)->IsActive() )
		{
			if( (*itMissile)->getLocation().fz >= 30.0f )
			{
				cout << "missile out" << endl;
				(*itMissile)->setStatus( false );
			}
			for( int i = 0; i < NUMBEROFENEMIES; ++i )
			{
				if( Enemies[ i ]->IsActive() )
				{
					if( Sprite_Collide( (*itMissile), Enemies[ i ] ) )
					{
						cout << "hit" << endl;
						(*itMissile)->setStatus( false );
						Enemies[ i ]->setStatus( false );
					}
				
				}
			}
			++itMissile;
		}
		else
		{
			delete (*itMissile);

			itMissile = lstMissile.erase( itMissile );
		}
	
	}

	for( int i = 0; i < NUMBEROFENEMIES; ++ i )
	{
		if( Enemies[ i ]->getLocation().fz <= -28.0f )
		{
			//cout << "you lose" << endl;
		}
	}

	
}


void gameLights()
{
	glEnable( GL_FOG ); 
	GLfloat fogColor[ 4 ] = { 1.0, 1.0, 1.0, 1.0 }; //Fog color set to black
	glFogi ( GL_FOG_MODE, GL_EXP2 );
	glFogfv( GL_FOG_COLOR, fogColor );
	glFogf ( GL_FOG_DENSITY, 0.019 );
	glHint ( GL_FOG_HINT, GL_DONT_CARE );
	glFogf ( GL_FOG_START, -20.0 );
	glFogf ( GL_FOG_END, 100.0 );

	glEnable( GL_BLEND ); 

	glEnable( GL_LIGHTING ); // turned the lights on
	//created a array of clorage
					 	   //R		G		B		ALPHA
	float vAmbient[]	= { 0.5f,   0.5f,	0.5f,	1.0f };
	float vRed[]		= { 1.0f,	0.0f,	0.0f,	1.0f };
	float vGreen[]		= { 0.0f,	1.0f,	0.0f,	1.0f };
	float vBlue[]		= { 0.0f,	0.0f,	1.0f,	1.0f };
	float vDiffuse[]	= { 0.5f,   0.5f,	0.5f,	1.0f };
	float vSpecific[]	= { 0.5f,   0.5f,	1.0f,	1.0f };
						   // x    y       z      anglE?
	float vPosition[]  = { 450.0f, -50.0f, 300.0f, 0.0f };
	float vDirection[] = { 450.0f,   1.0f, 300.0f, 0.0f };

	glLightModelfv( GL_LIGHT_MODEL_AMBIENT, vAmbient );

	glEnable( GL_COLOR_MATERIAL );
	glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );

	glLightfv( GL_LIGHT0, GL_AMBIENT, vSpecific );
	glLightfv( GL_LIGHT0, GL_DIFFUSE, vDiffuse );

	glLightfv( GL_LIGHT0, GL_POSITION, vPosition );
	glLightfv( GL_LIGHT0, GL_SPOT_DIRECTION, vDirection );

	glLightf( GL_LIGHT0, GL_SPOT_CUTOFF, 45.0f );
	glLightf( GL_LIGHT0, GL_SPOT_EXPONENT, -2.0f );

	glEnable( GL_LIGHT0 );
	
	glLightfv( GL_LIGHT1, GL_AMBIENT, vRed );
	glLightfv( GL_LIGHT1, GL_DIFFUSE, vDiffuse );

	glLightfv( GL_LIGHT1, GL_POSITION, vPosition );
	glLightfv( GL_LIGHT1, GL_SPOT_DIRECTION, vDirection );

	glLightf( GL_LIGHT1, GL_SPOT_CUTOFF, 45.0f );
	glLightf( GL_LIGHT1, GL_SPOT_EXPONENT, -2.0f );

	glEnable( GL_LIGHT1 );

	glLightfv( GL_LIGHT2, GL_AMBIENT, vGreen );
	glLightfv( GL_LIGHT2, GL_DIFFUSE, vDiffuse );

	glLightfv( GL_LIGHT2, GL_POSITION, vPosition );
	glLightfv( GL_LIGHT2, GL_SPOT_DIRECTION, vDirection );

	glLightf( GL_LIGHT2, GL_SPOT_CUTOFF, 45.0f );
	glLightf( GL_LIGHT2, GL_SPOT_EXPONENT, -2.0f );

	glEnable( GL_LIGHT2 );

	glLightfv( GL_LIGHT3, GL_AMBIENT, vBlue );
	glLightfv( GL_LIGHT3, GL_DIFFUSE, vDiffuse );

	glLightfv( GL_LIGHT3, GL_POSITION, vPosition );
	glLightfv( GL_LIGHT3, GL_SPOT_DIRECTION, vDirection );

	glLightf( GL_LIGHT3, GL_SPOT_CUTOFF, 45.0f );
	glLightf( GL_LIGHT3, GL_SPOT_EXPONENT, -2.0f );

	glEnable( GL_LIGHT3 );
}

short int Sprite_Collide( CObject *object1, CObject *object2 ) 
{
    int left1, left2;
    int right1, right2;
    int top1, top2;
    int bottom1, bottom2;

    left1 = object1->getLocation().fx;// - 1; //object1->col_x_offset;
    left2 = object2->getLocation().fx;// + 1; //object2->col_x_offset;
    right1 = left1 + 2; //object1->col_width;
    right2 = left2 + 2; //object2->col_width;
    top1 = object1->getLocation().fz + 1; //object1->col_y_offset;
    top2 = object2->getLocation().fz + 1; //object1->col_y_offset;
    bottom1 = top1 + 2; //object1->col_height;
    bottom2 = top2 + 2; //object2->col_height;

	//glBegin( GL_POINTS );
	//{
	//	glVertex2f( top1, top2 );
	//	glVertex2f( bottom1, bottom2 );
	//}
	//glEnd();


    if (bottom1 < top2) 
	{
		//cout << "HIT! bottom1 < top2\n";
		return(0);
	}
    if (top1 > bottom2)
	{
		//cout << "HIT! top1 > bottom2\n";
		return(0);
	}
  
    if (right1 < left2) 
	{
		//cout << "HIT! right1 < left2\n";
		return(0);
	}
    if (left1 > right2) 
	{
		//cout << "HIT! left1 > right2\n";
		return(0);
	}

    return(1);

};

Other then that tell me what you think!

Share this post


Link to post
Share on other sites
Advertisement
Just a cursory examination, but it looks like you are reloading some textures every frame? Taken from your myDisplay function:


BackGround->loadTexture( "texture/menu.tga" );


Unless that function name is misleading, you definitely only want to load textures only once. That should GREATLY speed things up.

Share this post


Link to post
Share on other sites
Just ran your game. Yes it runs very slow. Definitely looks like you might be reloading the textures every time the screen is drawn. Also, you could look into using smaller texture files. I opened up some of your TGAs and it looks like the texture is in the bottom left part of the image each time, with the rest of the image just wasted space.

Share this post


Link to post
Share on other sites
Oh yeah that deffinately solved the problem. The way I was thinking was that I only need 1 background type of quad and I'd switch between a menu texture and a game texture. But I just split it making menu having its own background and the actual game have its own water.

And the reason for the white space is that its actualy a UV map that is generated from 3dmax, so if I do put anything in the white space it will be drawn on the other side.

So I think the next direction I'll take is perhaps putting in some boss after a few wave . . .maybe this boss will fire lazer beems.

But maybe in all seriousness I should add in some sort of FPS limiter any ideas on that?

Share this post


Link to post
Share on other sites
Quote:
Original post by kubapl
But maybe in all seriousness I should add in some sort of FPS limiter any ideas on that?


It's an outdated and slightly flawed way of regulating your game's speed - instead look at movement by delta time.

Share this post


Link to post
Share on other sites
Quote:
Original post by deadstar

It's an outdated and slightly flawed way of regulating your game's speed - instead look at movement by delta time.


I dont think I understand what you mean are you saying to make some sort of timer and then for every like 1 second limit a number amount of movements?

Share this post


Link to post
Share on other sites
No, you should calculate the amount of time that passes between frames. Then you should use this value to scale all movement. In this way, no matter how much FPS you get, your movements will be the same.

Share this post


Link to post
Share on other sites
Also another benefit is that when your computer can run the game at 70 fps, the animations will all be smoother since the position/orientation will update 70 times a second.

Share this post


Link to post
Share on other sites
basically you get the time at the beginning and the end of your frame and calculate duration = end - start (generally duration is expressed in seconds). That frame duration is used for the next frame: position += duration * speed.

Getting time on windows:


double getTime()
{
//for better performance move the following 3 lines to a initializer function
LARGE_INTEGER freq;
::QueryPerformanceFrequency(&freq);
double secondsPerTick = (LsReal)(1.0/freq.QuadPart);

LARGE_INTEGER time;
::QueryPerformanceCounter(&time);
double time = time.QuadPart * secondsPerTick;

return time;
}


Your frame the would look like this:

frame()
{
start = getTime();

.... //render something
position += duration * speed;
.... //render something

end = getTime();

duration = end - start;
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!