so I got this program...

Started by
11 comments, last by clint8565 19 years, 4 months ago
main.cpp
/*
  Name: OpenGL Test
  Author: Clint Dramnitzke
  Start Date: 18/11/04 12:43
  Copyright: 2004 Clint Dramnitzke
*/

//include everything
#include "general.h"

/**************************
 * Function Declarations
 *
 **************************/

LRESULT CALLBACK WndProc (HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC);
void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC);

bool LoadTGA(Texture *, char *);
Texture tex[2], back[5],grass, tank[5];
int iback;

int LoadGLTextures()											// Load Bitmaps And Convert To Textures
{
	int Status=FALSE;											// Status Indicator

	// Load The Bitmap, Check For Errors.
	if (LoadTGA(&tex[0], "pics/shot.tga") && LoadTGA(&tex[1],"pics/shot2.tga") && LoadTGA(&back[0], "pics/back1.tga")
      && LoadTGA(&back[1],"pics/back2.tga") && LoadTGA(&back[2],"pics/back3.tga") && LoadTGA(&back[3],"pics/back5.tga")
       && LoadTGA(&back[4],"pics/back6.tga") && LoadTGA(&grass,"pics/grass.tga") && LoadTGA(&tank[0],"pics/black.tga")
        && LoadTGA(&tank[1],"pics/blue.tga") && LoadTGA(&tank[2],"pics/green.tga") && LoadTGA(&tank[3],"pics/red.tga")
         && LoadTGA(&tank[4],"pics/white.tga"))
	{
		Status=TRUE;											// Set The Status To TRUE

    for(int a=0;a<2;a++)
    {
      glGenTextures(1, &tex[a].texID);				// Create The Texture ( CHANGE )
      glBindTexture(GL_TEXTURE_2D, tex[a].texID);
      glTexImage2D(GL_TEXTURE_2D, 0, 4, tex[a].width, tex[a].height, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex[a].imageData);
      glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
      if (tex[a].imageData)						// If Texture Image Exists ( CHANGE )
        free(tex[a].imageData);					// Free The Texture Image Memory ( CHANGE )
    }  
    for(int a=0;a<5;a++)
    {
      glGenTextures(1, &back[a].texID);				// Create The Texture ( CHANGE )
      glBindTexture(GL_TEXTURE_2D, back[a].texID);
      glTexImage2D(GL_TEXTURE_2D, 0, 4, back[a].width, back[a].height, 0, GL_RGBA, GL_UNSIGNED_BYTE, back[a].imageData);
      glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
      if (back[a].imageData)						// If Texture Image Exists ( CHANGE )
        free(back[a].imageData);					// Free The Texture Image Memory ( CHANGE )
      glGenTextures(1, &tank[a].texID);				// Create The Texture ( CHANGE )
      glBindTexture(GL_TEXTURE_2D, tank[a].texID);
      glTexImage2D(GL_TEXTURE_2D, 0, 4, tank[a].width, tank[a].height, 0, GL_RGBA, GL_UNSIGNED_BYTE, tank[a].imageData);
      glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
      if (tank[a].imageData)						// If Texture Image Exists ( CHANGE )
        free(tank[a].imageData);					// Free The Texture Image Memory ( CHANGE )
    }  
    glGenTextures(1, &grass.texID);				// Create The Texture ( CHANGE )
    glBindTexture(GL_TEXTURE_2D, grass.texID);
    glTexImage2D(GL_TEXTURE_2D, 0, 4, grass.width, grass.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, grass.imageData);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    if (grass.imageData)						// If Texture Image Exists ( CHANGE )
      free(grass.imageData);					// Free The Texture Image Memory ( CHANGE )
	}
	return Status;												// Return The Status
}

//draw everything
void Render(NewEarth &Earth, NewTank &Player)
{
  glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
  glClear (GL_COLOR_BUFFER_BIT);
  glColor3f(1.0f,1.0f,1.0f);
  
  glEnable(GL_BLEND);
  glBindTexture(GL_TEXTURE_2D, back[iback].texID);
  glBegin(GL_QUADS);
  glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f);
  glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, 610.0f);
  glTexCoord2f(1.0f, 1.0f); glVertex2f(800.0f, 610.0f);
  glTexCoord2f(1.0f, 0.0f); glVertex2f(800.0f, 0.0f);
  glEnd();
  
  glBindTexture(GL_TEXTURE_2D,Player.tex.texID);
  glBegin(GL_QUADS);
  glTexCoord2f(Player.tloc[0],Player.tloc[1]);
  glVertex2f(Player.Physics.loc[0],Player.Physics.loc[1]);
  glTexCoord2f(Player.tloc[0],Player.tloc[3]);
  glVertex2f(Player.Physics.loc[0]-(Player.Physics.uvec[1]*32.0f),Player.Physics.loc[1]+(Player.Physics.uvec[0]*32.0f));
  glTexCoord2f(Player.tloc[2],Player.tloc[3]);
  glVertex2f(Player.Physics.loc[2]-(Player.Physics.uvec[1]*32.0f),Player.Physics.loc[3]+(Player.Physics.uvec[0]*32.0f));
  glTexCoord2f(Player.tloc[2],Player.tloc[1]);
  glVertex2f(Player.Physics.loc[2],Player.Physics.loc[3]);
  glEnd();
  
  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  for(int a=0;a<16;a++)
  {
    if(Player.Pshot[a].active)
    {
      glBindTexture(GL_TEXTURE_2D, Player.Pshot[a].tex.texID);
      glBegin(GL_QUADS);
      glTexCoord2f(0.0f, 0.0f); glVertex2f(Player.Pshot[a].loc[0]-2.0f, Player.Pshot[a].loc[1]-2.0f);
      glTexCoord2f(0.0f, 1.0f); glVertex2f(Player.Pshot[a].loc[0]-2.0f, Player.Pshot[a].loc[1]+2.0f);
      glTexCoord2f(1.0f, 1.0f); glVertex2f(Player.Pshot[a].loc[0]+2.0f, Player.Pshot[a].loc[1]+2.0f);
      glTexCoord2f(1.0f, 0.0f); glVertex2f(Player.Pshot[a].loc[0]+2.0f, Player.Pshot[a].loc[1]-2.0f);
      glEnd();
    }
  }
  for(int a=0;a<8;a++)
  {
    if(Player.Sshot[a].active)
    {
      glBindTexture(GL_TEXTURE_2D, Player.Sshot[a].tex.texID);
      glBegin(GL_QUADS);
      glTexCoord2f(0.0f, 0.0f); glVertex2f(Player.Sshot[a].loc[0]-4.0f, Player.Sshot[a].loc[1]-4.0f);
      glTexCoord2f(0.0f, 1.0f); glVertex2f(Player.Sshot[a].loc[0]-4.0f, Player.Sshot[a].loc[1]+4.0f);
      glTexCoord2f(1.0f, 1.0f); glVertex2f(Player.Sshot[a].loc[0]+4.0f, Player.Sshot[a].loc[1]+4.0f);
      glTexCoord2f(1.0f, 0.0f); glVertex2f(Player.Sshot[a].loc[0]+4.0f, Player.Sshot[a].loc[1]-4.0f);
      glEnd();
    }
  }
  
  glBindTexture(GL_TEXTURE_2D, grass.texID);
  glBegin(GL_LINES);
  for(int a=0;a<800;a++)
  {
    glTexCoord2f(Earth.Dirt[a].loc[0]*0.00375f,Earth.Dirt[a].loc[1]*0.00495f);
    glVertex2f(Earth.Dirt[a].loc[0],Earth.Dirt[a].loc[1]);
    glTexCoord2f(Earth.Dirt[a].loc[2]*0.00375f,Earth.Dirt[a].loc[3]*0.00495f);
    glVertex2f(Earth.Dirt[a].loc[2],Earth.Dirt[a].loc[3]);
  }
  glEnd();    
  glBegin(GL_QUADS);
  for(int a=0;a<128;a++)
  {
    if(Earth.Chunk[a].active)
    {
      glTexCoord2f(0.0f,0.0f);
      glVertex2f(Earth.Chunk[a].loc[0]-1.5f,Earth.Chunk[a].loc[1]-1.5f);
      glTexCoord2f(0.0f,0.1f);
      glVertex2f(Earth.Chunk[a].loc[0]-1.5f,Earth.Chunk[a].loc[1]+1.5f);
      glTexCoord2f(0.1f,0.1f);
      glVertex2f(Earth.Chunk[a].loc[0]+1.5f,Earth.Chunk[a].loc[1]+1.5f);
      glTexCoord2f(0.1f,0.0f);
      glVertex2f(Earth.Chunk[a].loc[0]+1.5f,Earth.Chunk[a].loc[1]-1.5f);
    }  
  }
  glEnd();
  
  glDisable(GL_BLEND);
  glBegin(GL_LINES);
  for(int a=0;a<=Player.pwait;a++)
  {
    glColor3f(1.0f,0.0f,0.0f);
    glVertex2f(50.0+(a*2.0f),550.0f);
    glVertex2f(50.0+(a*2.0f),540.0f);
  }
  glEnd();
  glBegin(GL_LINES);
  for(int a=0;a<=Player.swait;a+=10)
  {
    glColor3f(0.0f,0.0f,1.0f);
    glVertex2f(50.0+(a/5.0f),535.0f);
    glVertex2f(50.0+(a/5.0f),525.0f);
  }
  glEnd();
  glBegin(GL_LINES);
  for(int a=0;a<=Player.jet;a+=2)
  {
    glColor3f(0.0f,1.0f,0.0f);
    glVertex2f(50.0+a,520.0f);
    glVertex2f(50.0+a,510.0f);
  }  
  glEnd();
  
  glFlush();
}

/**************************
 * WinMain
 *
 **************************/

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
{
  WNDCLASS wc;
  HWND hWnd;
  HDC hDC;
  HGLRC hRC;        
  MSG msg;
  BOOL bQuit = FALSE;
  DWORD t, ct;

  /* register window class */
  wc.style = CS_OWNDC;
  wc.lpfnWndProc = WndProc;
  wc.cbClsExtra = 0;
  wc.cbWndExtra = 0;
  wc.hInstance = hInstance;
  wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
  wc.hCursor = LoadCursor (NULL, IDC_ARROW);
  wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
  wc.lpszMenuName = NULL;
  wc.lpszClassName = "GLTest";
  RegisterClass (&wc);

  /* create main window */
  hWnd = CreateWindow ("GLTest", "OpenGL Test", WS_BORDER | WS_POPUPWINDOW | WS_VISIBLE,
                        0, 0, 800, 600, NULL, NULL, hInstance, NULL);

  /* enable OpenGL for the window */
  EnableOpenGL (hWnd, &hDC, &hRC);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glMatrixMode(GL_MODELVIEW);
  glDisable(GL_DEPTH_TEST);
  glEnable(GL_TEXTURE_2D);
  glTranslatef(-1.0f,-1.0f,0.0f);
  glScalef(0.0025f,0.0033f,0.0f);
  
  timeBeginPeriod(1);
  //seed random # generator
  srand(static_cast<unsigned>(time(0)));
  iback=rand()%5;
  
  //textures
  if(!LoadGLTextures())
    bQuit=true;
  
  //init dirt
  NewEarth Earth;
  for(int a=0;a<800;a++)
  {
    Earth.Dirt[a].strength=(rand()%4);
    Earth.Dirt[a].loc[0]=a;
    Earth.Dirt[a].loc[1]=0.0f;
    Earth.Dirt[a].loc[2]=a;
    Earth.Dirt[a].loc[3]=(rand()%320)+50;
  }
  for(int a=0;a<128;a++)
  {
    ResetChunk(Earth.Chunk[a]);
  }  
  
  //init Tank
  NewTank Player;
  InitTank(Player);
  Player.tex=tank[1];
  for(int a=0;a<16;a++)
    Player.Pshot[a].tex=tex[0];
  for(int a=0;a<8;a++)
    Player.Sshot[a].tex=tex[1];
  
  /* program main loop */
  while (!bQuit)
  {
    t=timeGetTime(); //get time in milliseconds
    /* check for messages */
    if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
    {
      /* handle or dispatch messages */
      if (msg.message == WM_QUIT)
      {
        bQuit = TRUE;
      }
      else
      {
        TranslateMessage (&msg);
        DispatchMessage (&msg);
      }
    }
    else
    {
      Sleep(1);
      //check for landslide
      Landslide(Earth);
      
      //do stuff...
      ct=timeGetTime();
      if(Player.jet<100)
        Player.jet+=ct-t;
      Hover(Player,Earth,ct,t);
  
      Controls(Player,bQuit,t,ct);
      Move(Player,Earth,t,ct);
      
      //draw everything
      Render(Earth,Player);
      
      SwapBuffers (hDC);
    }
  }
  
  timeEndPeriod(1);
  /* shutdown OpenGL */
  DisableOpenGL (hWnd, hDC, hRC);

  /* destroy the window explicitly */
  DestroyWindow (hWnd);

  return msg.wParam;
}


/********************
 * Window Procedure
 *
 ********************/

LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

  switch (message)
  {
    case WM_CREATE:
      return 0;
    case WM_CLOSE:
      PostQuitMessage (0);
      return 0;

    case WM_DESTROY:
      return 0;

    case WM_KEYDOWN:
      switch (wParam)
      {
      case VK_ESCAPE:
        PostQuitMessage(0);
        return 0;
      }
      return 0;

    default:
    return DefWindowProc (hWnd, message, wParam, lParam);
  }
}


/*******************
 * Enable OpenGL
 *
 *******************/

void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC)
{
  PIXELFORMATDESCRIPTOR pfd;
  int iFormat;

/* get the device context (DC) */
  *hDC = GetDC (hWnd);

/* set the pixel format for the DC */
  ZeroMemory (&pfd, sizeof (pfd));
  pfd.nSize = sizeof (pfd);
  pfd.nVersion = 1;
  pfd.dwFlags = PFD_DRAW_TO_WINDOW | 
    PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
  pfd.iPixelType = PFD_TYPE_RGBA;
  pfd.cColorBits = 24;
  pfd.cDepthBits = 16;
  pfd.iLayerType = PFD_MAIN_PLANE;
  iFormat = ChoosePixelFormat (*hDC, &pfd);
  SetPixelFormat (*hDC, iFormat, &pfd);

  /* create and enable the render context (RC) */
  *hRC = wglCreateContext( *hDC );
  wglMakeCurrent( *hDC, *hRC );
}


/******************
 * Disable OpenGL
 *
 ******************/

void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC)
{
  wglMakeCurrent (NULL, NULL);
  wglDeleteContext (hRC);
  ReleaseDC (hWnd, hDC);
}
functions.cpp
#include "general.h"

//check for landslides
void Landslide(NewEarth &Earth)
{
  if(Earth.Dirt[0].loc[3]-Earth.Dirt[1].loc[3]>Earth.Dirt[0].strength)
  {
    Earth.Dirt[0].loc[3]--; Earth.Dirt[1].loc[3]++;
  }
  for(int c=1;c<800;c++)
  {
    if(Earth.Dirt[c].loc[3]-Earth.Dirt[c+1].loc[3]>Earth.Dirt[c].strength)
    {
      Earth.Dirt[c].loc[3]--; Earth.Dirt[c+1].loc[3]++;
    }
    if(Earth.Dirt[c].loc[3]-Earth.Dirt[c-1].loc[3]>Earth.Dirt[c].strength)
    {
      Earth.Dirt[c].loc[3]--; Earth.Dirt[c-1].loc[3]++;
    }
  }
  if(Earth.Dirt[799].loc[3]-Earth.Dirt[798].loc[3]>Earth.Dirt[799].strength)
  {
    Earth.Dirt[799].loc[3]--; Earth.Dirt[798].loc[3]++;
  }
}

void Hover(NewTank &Player, NewEarth &Earth, DWORD ct, DWORD t)
{
  double dist, vec[2];
  //fall
  Player.Physics.vel[1]-=(Player.Physics.w[0]*0.1f)-(Player.Physics.idle*0.1f);
  Player.Physics.vel[3]-=(Player.Physics.w[1]*0.1f)-(Player.Physics.idle*0.1f);
  if(Player.Physics.loc[1]>Player.Physics.loc[3] && Player.Physics.vel[1]>Player.Physics.vel[3])
    Player.Physics.vel[1]-=Player.Physics.w[0]*0.1f; 
  else if(Player.Physics.loc[3]>Player.Physics.loc[1] && Player.Physics.vel[3]>Player.Physics.vel[1])
    Player.Physics.vel[3]-=Player.Physics.w[1]*0.1f;
  
  //float if close to ground
  if(Player.Physics.loc[1]<Earth.Dirt[int(Player.Physics.loc[0])].loc[3]+15 && Player.Physics.vel[1]<Player.Physics.w[0])
  {
    if(Player.Physics.loc[1]<=Earth.Dirt[int(Player.Physics.loc[0])].loc[3])
      Player.Physics.vel[1]=Player.Physics.w[0]*2.0f;  
    Player.Physics.vel[1]+=Player.Physics.w[0]*0.2f;
  }
  if(Player.Physics.loc[1]<Earth.Dirt[int(Player.Physics.loc[0])].loc[3])
    Player.Physics.loc[1]=Earth.Dirt[int(Player.Physics.loc[0])].loc[3];
  if(Player.Physics.loc[3]<Earth.Dirt[int(Player.Physics.loc[2])].loc[3]+15 && Player.Physics.vel[3]<Player.Physics.w[1])
  {  
    if(Player.Physics.loc[3]<=Earth.Dirt[int(Player.Physics.loc[2])].loc[3])
      Player.Physics.vel[3]=Player.Physics.w[1]*2.0f; 
    Player.Physics.vel[3]+=Player.Physics.w[1]*0.5f;
  }
  if(Player.Physics.loc[3]<Earth.Dirt[int(Player.Physics.loc[2])].loc[3])
    Player.Physics.loc[3]=Earth.Dirt[int(Player.Physics.loc[2])].loc[3];
  
  //keep correct length
  dist=sqrt(((Player.Physics.loc[2]-Player.Physics.loc[0])*(Player.Physics.loc[2]-Player.Physics.loc[0]))
              +((Player.Physics.loc[3]-Player.Physics.loc[1])*(Player.Physics.loc[3]-Player.Physics.loc[1])));
  Player.Physics.uvec[0]=(Player.Physics.loc[2]-Player.Physics.loc[0])/dist;
  Player.Physics.uvec[1]=(Player.Physics.loc[3]-Player.Physics.loc[1])/dist;
  vec[0]=Player.Physics.uvec[0]*64.0f;
  vec[1]=Player.Physics.uvec[1]*64.0f;
  if(dist!=64.0f)
  {
    Player.Physics.loc[2]=Player.Physics.loc[0]+vec[0];
    Player.Physics.loc[3]=Player.Physics.loc[1]+vec[1];
  }
  
  Player.Physics.loc[0]+=Player.Physics.vel[0]*(ct-t);
  Player.Physics.loc[1]+=Player.Physics.vel[1]*(ct-t);
  Player.Physics.loc[2]+=Player.Physics.vel[2]*(ct-t);
  Player.Physics.loc[3]+=Player.Physics.vel[3]*(ct-t);
  
  //keep on screen
  //sides
  if(Player.Physics.loc[0]<0)
  {
    Player.Physics.loc[2]-=Player.Physics.loc[0];
    Player.Physics.loc[0]-=Player.Physics.loc[0];
    Player.Physics.vel[0]=0.0f;
    Player.Physics.vel[2]=0.0f;
  }  
  else if(Player.Physics.loc[0]>=800.0f)
  {
    Player.Physics.loc[2]-=Player.Physics.loc[0]-800.0f;
    Player.Physics.loc[0]-=Player.Physics.loc[0]-800.0f;
    Player.Physics.vel[0]=0.0f;
    Player.Physics.vel[2]=0.0f;
  }  
  if(Player.Physics.loc[2]<0.0f)
  {
    Player.Physics.loc[0]-=Player.Physics.loc[2];
    Player.Physics.loc[2]-=Player.Physics.loc[2];
    Player.Physics.vel[0]=0.0f;
    Player.Physics.vel[2]=0.0f;
  }  
  else if(Player.Physics.loc[2]>=800.0f)
  {
    Player.Physics.loc[0]-=Player.Physics.loc[2]-800.0f;
    Player.Physics.loc[2]-=Player.Physics.loc[2]-800.0f;
    Player.Physics.vel[0]=0.0f;
    Player.Physics.vel[2]=0.0f;
  }
  //top 
  if(Player.Physics.loc[1]>=600.0f)
  {
    Player.Physics.loc[3]-=Player.Physics.loc[1]-600.0f;
    Player.Physics.loc[1]-=Player.Physics.loc[1]-600.0f;
    Player.Physics.vel[1]=0.0f;
    Player.Physics.vel[3]=0.0f;
  }
  if(Player.Physics.loc[3]>=600.0f)
  {
    Player.Physics.loc[1]-=Player.Physics.loc[3]-600.0f;
    Player.Physics.loc[3]-=Player.Physics.loc[3]-600.0f;
    Player.Physics.vel[1]=0.0f;
    Player.Physics.vel[3]=0.0f;
  }
}

//reset dirt chunks
void ResetChunk(NewChunk &Chunk)
{
  Chunk.active=false;
  Chunk.vel[0]=0.0f;
  Chunk.vel[1]=0.0f;
  Chunk.loc[0]=0.0f;
  Chunk.loc[1]=0.0f;
  Chunk.w=((rand()%10)+2)/10.0f;
}  

//init tank
void InitTank(NewTank &Player)
{
  Player.comp=false;
  Player.pwait=0;
  Player.swait=0;
  Player.jet=100;
  Player.tloc[0]=0.0f;
  Player.tloc[1]=0.0f;
  Player.tloc[2]=1.0f;
  Player.tloc[3]=1.0f;
  Player.Physics.dist=64.0f;
  Player.Physics.loc[0]=300.0f;
  Player.Physics.loc[1]=400.0f;
  Player.Physics.loc[2]=364.0f;
  Player.Physics.loc[3]=400.0f;
  Player.Physics.vel[0]=0.0f;
  Player.Physics.vel[1]=0.0f;
  Player.Physics.vel[2]=0.0f;
  Player.Physics.vel[3]=0.0f;
  Player.Physics.idle=0.05f;
  Player.Physics.w[0]=0.15f;
  Player.Physics.w[1]=0.15f;
  Player.Physics.uvec[0]=0.0f;
  Player.Physics.uvec[1]=0.0f;
  for(int a=0;a<32;a++)
  {
    Player.Pshot[a].active=false;
    Player.Pshot[a].r=10;
    Player.Pshot[a].vel[0]=0.0f;
    Player.Pshot[a].vel[1]=0.0f;
    Player.Pshot[a].loc[0]=0.0f;
    Player.Pshot[a].loc[1]=0.0f;
    Player.Pshot[a].w=0.1f;
  }
  for(int a=0;a<8;a++)
  {
    Player.Sshot[a].active=false;
    Player.Sshot[a].r=20;
    Player.Sshot[a].vel[0]-0.0f;
    Player.Sshot[a].vel[1]=0.0f;
    Player.Sshot[a].loc[0]=0.0f;
    Player.Sshot[a].loc[1]=0.0f;
    Player.Sshot[a].w=0.25f;
  }  
}   

void MoveChunk(NewChunk &Chunk, NewEarth &Earth, DWORD t, DWORD ct)
{
  Chunk.vel[1]-=Chunk.w*0.1f;
  Chunk.loc[0]+=Chunk.vel[0]*(ct-t);
  Chunk.loc[1]+=Chunk.vel[1]*(ct-t);
  if(Chunk.loc[1]<Earth.Dirt[int(Chunk.loc[0])].loc[3])
  {
    Earth.Dirt[int(Chunk.loc[0])].loc[3]+=5.0f;
    ResetChunk(Chunk);
  }
  else if(Chunk.loc[0]<=0 || Chunk.loc[0]>=800)
    ResetChunk(Chunk);
}  

void Explode(NewShot &Shot, NewEarth &Earth)
{
  double i=Shot.w*40;
  for(int a=0;a<128;a++)
  {
    if(!Earth.Chunk[a].active && i>0)
    {
      Earth.Chunk[a].active=true;
      Earth.Chunk[a].vel[0]=(((rand()%10)-4.5f)+(Shot.vel[0]/2.0f))/2.0f;
      Earth.Chunk[a].vel[1]=((rand()%5)+1)/2.0f;
      Earth.Chunk[a].loc[0]=Shot.loc[0];
      Earth.Chunk[a].loc[1]=Shot.loc[1];
      if(Earth.Chunk[a].loc[1]<10)
        Earth.Chunk[a].loc[1]=10;
      i--;
    }  
  }  
}  

//when shot hits ground
void Hit(NewShot &Shot, NewEarth &Earth)
{
  double x,h,k,b,c,p;
  h=Shot.loc[0];
  k=Shot.loc[1];
  b=-k-k;
  for(int a=-Shot.r;a<=Shot.r;a++)
  {
    x=Shot.loc[0]+a;
    c=((x-h)*(x-h))+(k*k)-(Shot.r*Shot.r);
    
    if((b*b)-(4*c)>0)
    {
      p=(-b-sqrt((b*b)-(4*c)))/2;
      if(p<Earth.Dirt[int(x)].loc[3])
        Earth.Dirt[int(x)].loc[3]=p;
    }
  }
  for(int a=0;a<800;a++)
  {
    if(Earth.Dirt[a].loc[3]<5.0f+Earth.Dirt[a].strength)
      Earth.Dirt[a].loc[3]=5.0f+Earth.Dirt[a].strength;
  }
  
  Explode(Shot,Earth);
  Shot.active=false;
} 

//attack ground
void Attack(NewShot &Shot, NewEarth &Earth, DWORD t, DWORD ct)
{
  Shot.vel[1]-=Shot.w*0.1f;
  Shot.loc[0]+=Shot.vel[0]*(ct-t);
  Shot.loc[1]+=Shot.vel[1]*(ct-t);
  if(Shot.loc[1]<Earth.Dirt[int(Shot.loc[0])].loc[3])
    Hit(Shot,Earth);
  else if(Shot.loc[0]<=0 || Shot.loc[0]>=800)
    Shot.active=false;
}

//move stuff
void Move(NewTank &Player, NewEarth &Earth, DWORD t, DWORD ct)
{
  for(int a=0;a<16;a++)
  {
    if(Player.Pshot[a].active)
      Attack(Player.Pshot[a],Earth,t,ct);
  }
  for(int a=0;a<8;a++)
  {
    if(Player.Sshot[a].active)
      Attack(Player.Sshot[a],Earth,t,ct);
  }  
  for(int a=0;a<128;a++)
  {
    if(Earth.Chunk[a].active)
      MoveChunk(Earth.Chunk[a],Earth,t,ct);
  }
  Player.pwait-=ct-t;
  Player.swait-=ct-t; 
}  

//controls
void Controls(NewTank &Player, bool exit, DWORD t, DWORD ct)
{
  UpdateKeyStates();
  //movement
  if(IsKeyPressed(VK_NUMPAD8) && Player.jet>0) //up
  {
    Player.Physics.vel[0]+=-Player.Physics.uvec[1]*0.02f;
    Player.Physics.vel[1]+=Player.Physics.uvec[0]*0.02f;
    Player.Physics.vel[2]+=-Player.Physics.uvec[1]*0.02f;
    Player.Physics.vel[3]+=Player.Physics.uvec[0]*0.02f;
    Player.jet-=(ct-t)*3;
  }
  else if(IsKeyPressed(VK_NUMPAD7) && Player.jet>0) //left up
  {
    Player.Physics.vel[0]+=-Player.Physics.uvec[1]*0.02f;
    Player.Physics.vel[1]+=Player.Physics.uvec[0]*0.02f;
    Player.jet-=(ct-t)*2;
  }  
  else if(IsKeyPressed(VK_NUMPAD9) && Player.jet>0) //right up
  {
    Player.Physics.vel[2]+=-Player.Physics.uvec[1]*0.02f;
    Player.Physics.vel[3]+=Player.Physics.uvec[0]*0.02f;
    Player.jet-=(ct-t)*2;
  }  
  else if(IsKeyPressed(VK_NUMPAD5)) //down
  {
    Player.Physics.vel[0]-=-Player.Physics.uvec[1]*0.02f;
    Player.Physics.vel[1]-=Player.Physics.uvec[0]*0.02f;
    Player.Physics.vel[2]-=-Player.Physics.uvec[1]*0.02f;
    Player.Physics.vel[3]-=Player.Physics.uvec[0]*0.02f;
  }  
  if(IsKeyPressed(VK_NUMPAD6) && Player.Physics.vel[0]<1.5f) //right
  {
    Player.tloc[0]=1.0f;
    Player.tloc[2]=0.0f;
    if(Player.Physics.loc[1]>350.0f)
    {
      if(Player.jet>0)
      {
        Player.Physics.vel[0]+=0.02f*Player.Physics.uvec[0];
        Player.Physics.vel[1]+=0.02f*Player.Physics.uvec[1];
        Player.Physics.vel[2]+=0.02f*Player.Physics.uvec[0];
        Player.Physics.vel[3]+=0.02f*Player.Physics.uvec[1];
        Player.jet-=(ct-t)*3;
      }  
    }
    else
    {
      Player.Physics.vel[0]+=0.02f*Player.Physics.uvec[0];
      Player.Physics.vel[1]+=0.02f*Player.Physics.uvec[1];
      Player.Physics.vel[2]+=0.02f*Player.Physics.uvec[0];
      Player.Physics.vel[3]+=0.02f*Player.Physics.uvec[1];
    }
  }  
  else if(IsKeyPressed(VK_NUMPAD4) && Player.Physics.vel[0]>-1.5f) //left
  {
    Player.tloc[0]=0.0f;
    Player.tloc[2]=1.0f; 
    if(Player.Physics.loc[1]>350.0f)
    {
      if(Player.jet>0)
      {
        Player.Physics.vel[0]-=0.02f*Player.Physics.uvec[0];
        Player.Physics.vel[1]-=0.02f*Player.Physics.uvec[1];
        Player.Physics.vel[2]-=0.02f*Player.Physics.uvec[0];
        Player.Physics.vel[3]-=0.02f*Player.Physics.uvec[1];
        Player.jet-=(ct-t)*3;
      }  
    }
    else
    {
      Player.Physics.vel[0]-=0.02f*Player.Physics.uvec[0];
      Player.Physics.vel[1]-=0.02f*Player.Physics.uvec[1];
      Player.Physics.vel[2]-=0.02f*Player.Physics.uvec[0];
      Player.Physics.vel[3]-=0.02f*Player.Physics.uvec[1];
    }
  }
  else if(IsKeyPressed(VK_NUMPAD2) && Player.jet>=100 && Player.Physics.loc[1]<350.0f) //reset/flip
  {
    for(int a=0;a<4;a++)
      Player.Physics.vel[a]=0.0f;
    Player.Physics.loc[1]+=50.0f;
    Player.Physics.loc[2]=Player.Physics.loc[0]+64.0f;
    Player.Physics.loc[3]=Player.Physics.loc[1];
    Player.jet=0;
  }
  
  //shoot
  if(IsKeyPressed(VK_NEXT) && Player.pwait<=0) //primary
  {
    for(int a=0;a<16;a++)
    {
      if(!Player.Pshot[a].active)
      {
        Player.Pshot[a].active=true;
        if(Player.Physics.loc[1]<Player.Physics.loc[3])
        {
          Player.Pshot[a].loc[0]=(Player.Physics.loc[0]+32.0f)-(Player.Physics.uvec[1]*32.0f);
          Player.Pshot[a].loc[1]=Player.Physics.loc[1]+(Player.Physics.uvec[0]*32.0f);
        }
        else
        {
          Player.Pshot[a].loc[0]=(Player.Physics.loc[0]+32.0f)-(Player.Physics.uvec[1]*32.0f);
          Player.Pshot[a].loc[1]=Player.Physics.loc[3]+(Player.Physics.uvec[0]*32.0f);
        }
        if(Player.tloc[0]==0.0f)
        {
          Player.Pshot[a].vel[0]=Player.Physics.vel[0]-(Player.Physics.uvec[0]*2.0f);
          Player.Pshot[a].vel[1]=-Player.Physics.uvec[1];
        }  
        else if(Player.tloc[0]==1.0f)
        {
          Player.Pshot[a].vel[0]=Player.Physics.vel[0]+(Player.Physics.uvec[0]*2.0f);
          Player.Pshot[a].vel[1]=Player.Physics.uvec[1];
        }
        Player.pwait=50;
        break;
      }  
    }  
  }
  else if(IsKeyPressed(VK_END) && Player.swait<=0) //secondary
  {
    for(int a=0;a<8;a++)
    {
      if(!Player.Sshot[a].active)
      {
        Player.Sshot[a].active=true;
        if(Player.Physics.loc[1]<Player.Physics.loc[3])
        {
          Player.Sshot[a].loc[0]=(Player.Physics.loc[0]+32.0f)-(Player.Physics.uvec[1]*32.0f);
          Player.Sshot[a].loc[1]=Player.Physics.loc[1]+(Player.Physics.uvec[0]*32.0f);
        }
        else
        {
          Player.Sshot[a].loc[0]=(Player.Physics.loc[0]+32.0f)-(Player.Physics.uvec[1]*32.0f);
          Player.Sshot[a].loc[1]=Player.Physics.loc[3]+(Player.Physics.uvec[0]*32.0f);
        }
        if(Player.tloc[0]==0.0f)
        {
          Player.Sshot[a].vel[0]=Player.Physics.vel[0]-(Player.Physics.uvec[0]*2.0f);
          Player.Sshot[a].vel[1]=-Player.Physics.uvec[1];
        }  
        else if(Player.tloc[0]==1.0f)
        {
          Player.Sshot[a].vel[0]=Player.Physics.vel[0]+(Player.Physics.uvec[0]*2.0f);
          Player.Sshot[a].vel[1]=Player.Physics.uvec[1];
        }
        Player.Sshot[a].vel[1]+=0.1f;
        Player.swait=500;
        break;
      }  
    }
  }  
  
  //quit
  if(IsKeyPressed(VK_ESCAPE))
    exit=true;
}
general.h
#ifndef general
#define general

//include necesarry files
#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include "wglfont.h"
#include "WinKeys.h"
#include "texture.h"
using namespace std;

typedef struct
{
  double loc[4], vel[4], w[2], dist, idle, uvec[2];
}NewHover;  

typedef struct
{
  bool active;
  int r;
  double vel[2], loc[2], w;
  Texture tex;
}NewShot;

typedef struct
{
  bool comp;
  int pwait, swait, jet;  //primary & secondary weapons, jump jets
  double tloc[4];
  Texture tex;
  NewHover Physics;
  NewShot Pshot[16];
  NewShot Sshot[8];
}NewTank;  

typedef struct
{
  GLuint tex;
}NewTexs;

typedef struct
{
  bool active;
  double vel[2], loc[2], w;
}NewChunk; 

typedef struct
{
  int strength;
  double loc[4];
}NewDirt;

typedef struct
{
  NewDirt Dirt[800];
  NewChunk Chunk[128];
}NewEarth;  

//Functions
extern void Landslide(NewEarth &Earth);
extern void Hover(NewTank &Player, NewEarth &Earth, DWORD ct, DWORD t);
extern void ResetChunk(NewChunk &Chunk);
extern void InitTank(NewTank &Player);
extern void MoveChunk(NewChunk &Chunk, NewEarth &Earth, DWORD t, DWORD ct);
extern void Explode(NewShot &Shot, NewEarth &Earth);
extern void Hit(NewShot &Shot, NewEarth &Earth);
extern void Attack(NewShot &Shot, NewEarth &Earth, DWORD t, DWORD ct);
extern void Move(NewTank &Player, NewEarth &Earth, DWORD t, DWORD ct);
extern void Controls(NewTank &Player, bool exit, DWORD t, DWORD ct);

#endif
Now... you're probably like why the heck did he put all that. It's because I can't figure out why my terrain's (NewEarth Earth) first 10 or so members have a different Earth.Dirt[whatever].loc[2] than Earth.Dirt[same whatever].loc[0] (top x and bottom x locations) but before I added the physics for the hovering they were fine, now the first few are crooked which makes for a very ugly looking left edge of the terrain. Can someone please help me.
Advertisement
Ok, I took a first glance at your code, and simply it was too much for me to look through. I can't give you the solution now, but I tell you: debug your code. Use assertions, make some outputs (maybe a log file), comment stuff out until it works again. Just try to narrow the error down as much as possible.
Indeterminatus--si tacuisses, philosophus mansisses--
for(int c=1;c<800;c++)  {    if(Earth.Dirt[c].loc[3]-Earth.Dirt[c+1].loc[3]>Earth.Dirt[c].strength)    {      Earth.Dirt[c].loc[3]--; Earth.Dirt[c+1].loc[3]++;    }    if(Earth.Dirt[c].loc[3]-Earth.Dirt[c-1].loc[3]>Earth.Dirt[c].strength)    {      Earth.Dirt[c].loc[3]--; Earth.Dirt[c-1].loc[3]++;    }  }  if(Earth.Dirt[799].loc[3]-Earth.Dirt[798].loc[3]>Earth.Dirt[799].strength)  {    Earth.Dirt[799].loc[3]--; Earth.Dirt[798].loc[3]++;  }}

that last if statement seems redundant. i doubt you need it.
if(Player.Physics.loc[1]<Earth.Dirt[int(Player.Physics.loc[0])].loc[3])    Player.Physics.loc[1]=Earth.Dirt[int(Player.Physics.loc[0])].loc[3];

it seems like a loss of precision here. i take it Player.Physics.loc is a double or float.
Player.Pshot[a].loc[1]=Player.Physics.loc[1]+(Player.Physics.uvec[0]*32.0f);else if(Player.tloc[0]==1.0f)Player.Pshot[a].vel[0]=Player.Physics.vel[0]+(Player.Physics.uvec[0]*2.0f);

i don't know why you are comparing doubles to floats but again the loss of precision could be affecting the way your terrain is being rendered.

hope i helped.

Beginner in Game Development?  Read here. And read here.

 

I've been trying that I just thought somebody might be able to find it faster... I'm pretty sure it's not in the main.cpp and the general.h is just for your reference so you can see how things go together
Alpha - you mean take the f off the end of the decimals? I just put it there cause that's what I was told when I was just starting
from what I can figure out the problem must be in InitTank or Render because I commented everything else out and the problem is still there
yep.

you putting a 'f' next to the a number like 0.00 makes it a float. (ex: 0.00f)
leave it as 0.00 so it will stay a double since you have declared many of your array and variables as doubles.

also are you sure all the conversions back and forth (double to int or double to float) isn't messing up your rendering?

another hint you'll learn again sooner or later, floats or doubles are not exact.
for example:
double example = 1.2;if (example == 1.2)   cout << "This is right." << endl;  //this is wrong actually // it should be ....if ( (example - 1.2) < .001 )   cout << "This is right." << endl;  //this is "more" correct


because doubles and floats are stored as appromixations in memory you have to give the comparision a certain margin of error (just i have done in the second code example). you probably don't have to do this for this project but you should start on your next.

again, hope this helps.


edit: also the gl Functions you use take return and i assume take in floats. i have no idea if the function converting your doubles into floats is causing an error as well. maybe you should change all your variables that you declare double to float (and therefore, if you do that, keep the 'f's by the numbers).

Beginner in Game Development?  Read here. And read here.

 

ok thanks, I'll put how it turns out when I finish killing all the little "f"ers lol
hey clint,

i edited my post while you posted and it ended up posting after yours.
please read the edit. thanks.
sorry for the confusion.

Beginner in Game Development?  Read here. And read here.

 

You have huge amounts of parallel copy-and-pasted code and magic numbers all over the place.

"Doctor, it hurts when I do that."

// One example of cleaning things up. This part could be improved upon further,// even, but the main thing I want to illustrate is getting rid of redundancy.#include <sstream>Texture tex[2], back[5],grass[1], tank[5];// Yeah, I put the grass into its own array, for uniformity.// You could just as well use a single array for all textures, and offsets to// each "set" of textures. Or for that matter, use a std::vector.std::string intToString(int x) {  // Of course there are templated versions of this about too.  std::stringstream ss; ss<<x;  std::string result; ss>>result;  return result;}bool loadTexArray(std::string name, Texture* target, int count) {  // We're going to generate filenames in a loop as well as using the loop to  // do the GL stuff for each loaded image. You will need to change your   // filenames a bit... there are other ways to set this up of course;  for (int i = 0; i < count; i++) {    // Create the file name as a std::string    std::string filename = "pics/";    filename = filename + name + intToString(count) + ".tga";    // Bail out if we can't load it    if (!LoadTGA(&target, filename.c_str())) return false;    // Actually, you really should make your Texture class do this part    // and why are you using "free" anyway? Prefer delete (and thus new) in C++.    glGenTextures(1, &target.texID); // Create The Texture ( CHANGE )    glBindTexture(GL_TEXTURE_2D, target.texID);    glTexImage2D(GL_TEXTURE_2D, 0, 4, target.width, target.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, target.imageData);    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);    if (target.imageData)  // If Texture Image Exists ( CHANGE )    free(target.imageData); // Free The Texture Image Memory ( CHANGE )  }  return true; // all loaded ok.}bool LoadGLTextures() {  // And now, the cool part. The GL stuff only gets written once (above)!  return   loadTexArray("shot", tex, 2) && // "shot0","shot1"  loadTexArray("back", back, 5) && // "back0" to "back4"  loadTexArray("grass", grass, 1) && // "shot0","shot1"  loadTexArray("tank", tank, 5); // "tank0" to "tank4"}// Although, you really ought to Do Something(TM) if it fails. And with this// structure, if one of the image loads fails, you don't know how many// succeeded...


Please show me your texture.cpp so I can follow up on my comments (making the class do the work that it is supposed to do).

This topic is closed to new replies.

Advertisement