#include "BMD_136.h" #include //#include GLuint texture[14]; GameController gc; float backR, backG, backB; const int defR = 30; const int defG = 70; const int defB = 0; static const int texBOMB = 0; static const int texBOMBER_N = 1; static const int texBOMBER_E = 2; static const int texBOMBER_S = 3; static const int texBOMBER_W = 4; static const int texBLOCK = 5; static const int texBRICK = 6; static const int texEXPLOSION = 7; static const int texEXPLOSION_BRICK = 8; static const int texPupBOMB = 9; static const int texPupSPEED = 10; static const int texPupPOWER = 11; static const int texPupKICK = 12; static const int texPupDETO = 13; //OpenGL canvas coordinates start from bottom left. //bmdEngine coordinates start from top left //must be careful when using offsets with this double flip(double x){return -x;} void draw_texture(const double ti, const double tj, const double dH, const double dV) { glTexCoord2f(1.0, 1.0); glVertex2d(ti + dH, flip(tj)); // Top Right glTexCoord2f(0.0, 1.0); glVertex2d(ti, flip(tj)); // Top Left glTexCoord2f(0.0, 0.0); glVertex2d(ti, flip(tj) - dV); // Bottom Left glTexCoord2f(1.0, 0.0); glVertex2d(ti + dH, flip(tj) - dV); // Bottom Right } GLuint loadTexture(const char* textName) { ///////////////////////////////////////////// // NEW! - This function has been completely // rewritten to use FreeImage. ///////////////////////////////////////////// //const char textName[64] = ".\\woodfloor.tga"; // Get the image file type from FreeImage. FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(textName, 0); // Actually load the image file. FIBITMAP *dib = FreeImage_Load(fifmt, textName,0); // Now, there is no guarantee that the image file // loaded will be GL_RGB, so we force FreeImage to // convert the image to GL_RGB. dib = FreeImage_ConvertTo24Bits(dib); if( dib != NULL ) { GLuint textureID; glGenTextures( 1, &textureID ); glBindTexture( GL_TEXTURE_2D, textureID ); glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR ); // This is important to note, FreeImage loads textures in // BGR format. Now we could just use the GL_BGR extension // But, we will simply swap the B and R components ourselves. // Firstly, allocate the new bit data doe the image. BYTE *bits = new BYTE[FreeImage_GetWidth(dib) * FreeImage_GetHeight(dib) * 3]; // get a pointer to FreeImage's data. BYTE *pixels = (BYTE*)FreeImage_GetBits(dib); // Iterate through the pixels, copying the data // from 'pixels' to 'bits' except in RGB format. for(unsigned int pix=0; pixSetCurrent(); SetCurrent(); if(!initialized) { InitGL(); initialized = true; } /* clear color and depth buffers */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor (backR, backG, backB, 0.5f); glLineWidth(1.0f); //glDisable(GL_LINE_SMOOTH); glLoadIdentity(); float resH = 640.0, resV = 480.0; unsigned int nHmin = 0, nVmin = 0; unsigned int nHmax = 24, nVmax = 18; // < 48 double dH, dV; nHmax = gc.engine.getWidth(); nVmax = gc.engine.getHeight(); if((nHmax - nHmin)*resV >= (nVmax - nVmin)*resH) { dH = 2.0/ (nHmax - nHmin); dV = dH * resH / resV; } else { dV = 2.0 / (nVmax - nVmin); dH = dV * resV / resH; } /* glColor3f(1.0f,0.0f,0.0f); glBegin(GL_LINES); for(unsigned int i = nHmin; i < nHmax + 1; i++) //+1 so a true border is shown { glVertex2d(i*dH - 1.0, -1.0); glVertex2d(i*dH - 1.0, 1.0); } //glColor3f(0.0f,1.0f,0.0f); for(unsigned int i = nVmin; i < nVmax + 1; i++) //+1 so a true border is shown { glVertex2d(-1.0 , flip(i*dV - 1.0)); glVertex2d(1.0 , flip(i*dV - 1.0)); } glEnd(); */ //glEnable(GL_ALPHA_TEST); //glAlphaFunc(GL_GREATER,0.1f); double ti, tj; int temp_d; vector::iterator powerup; glEnable(GL_TEXTURE_2D); // Enable Texture Mapping glColor3f(1.0f,1.0f,1.0f); // Bright White Color glBindTexture(GL_TEXTURE_2D, texture[texPupBOMB]); // select Pbomb (powerup) image glBegin(GL_QUADS); // Draw A Textured Quad powerup = gc.engine.powerups.begin(); for(; powerup != gc.engine.powerups.end(); powerup++) { if(powerup->power_type_index == pBOMBS) { ti = (powerup->coords.x)*dH - 1.0; tj = (powerup->coords.y)*dV - 1.0; draw_texture(ti,tj,dH,dV); } } glEnd(); // Done Texturing The Box glBindTexture(GL_TEXTURE_2D, texture[texPupSPEED]); // select Pspeed (powerup) image glBegin(GL_QUADS); // Draw A Textured Quad powerup = gc.engine.powerups.begin(); for(; powerup != gc.engine.powerups.end(); powerup++) { if(powerup->power_type_index == pSPEED) { ti = (powerup->coords.x)*dH - 1.0; tj = (powerup->coords.y)*dV - 1.0; draw_texture(ti,tj,dH,dV); } } glEnd(); // Done Texturing The Box glBindTexture(GL_TEXTURE_2D, texture[texPupPOWER]); // select Ppower (powerup) image glBegin(GL_QUADS); // Draw A Textured Quad powerup = gc.engine.powerups.begin(); for(; powerup != gc.engine.powerups.end(); powerup++) { if(powerup->power_type_index == pPOWER) { ti = (powerup->coords.x)*dH - 1.0; tj = (powerup->coords.y)*dV - 1.0; draw_texture(ti,tj,dH,dV); } } glEnd(); // Done Texturing The Box glBindTexture(GL_TEXTURE_2D, texture[texPupKICK]); // select Pkicking (powerup) image glBegin(GL_QUADS); // Draw A Textured Quad powerup = gc.engine.powerups.begin(); for(; powerup != gc.engine.powerups.end(); powerup++) { if(powerup->power_type_index == pKICKING) { ti = (powerup->coords.x)*dH - 1.0; tj = (powerup->coords.y)*dV - 1.0; draw_texture(ti,tj,dH,dV); } } glEnd(); // Done Texturing The Box glBindTexture(GL_TEXTURE_2D, texture[texPupDETO]); // select Pdeto (powerup) image glBegin(GL_QUADS); // Draw A Textured Quad powerup = gc.engine.powerups.begin(); for(; powerup != gc.engine.powerups.end(); powerup++) { if(powerup->power_type_index == pDETONATION) { ti = (powerup->coords.x)*dH - 1.0; tj = (powerup->coords.y)*dV - 1.0; draw_texture(ti,tj,dH,dV); } } glEnd(); // Done Texturing The Box glBindTexture(GL_TEXTURE_2D, texture[texBOMB]); // select bomb image glBegin(GL_QUADS); // Draw A Textured Quad vector::iterator bomb = gc.engine.bombs.begin(); for (; bomb != gc.engine.bombs.end(); bomb++) { ti = (bomb->coords.x + bomb->mstate.move_fracX())*dH - 1.0; tj = (bomb->coords.y + bomb->mstate.move_fracY())*dV - 1.0; draw_texture(ti,tj,dH,dV); } glEnd(); // Done Texturing The Box //glBindTexture(GL_TEXTURE_2D, texture[texBOMBER_N]); // select bomber image vector::iterator bomber = gc.engine.bombers.begin(); for(; bomber != gc.engine.bombers.end(); bomber++) { if(bomber->is_alive()) { temp_d = bomber->mstate.get_direction(); if(temp_d == dNORTH) glBindTexture(GL_TEXTURE_2D, texture[texBOMBER_N]); else if(temp_d == dEAST) glBindTexture(GL_TEXTURE_2D, texture[texBOMBER_E]); else if(temp_d == dWEST) glBindTexture(GL_TEXTURE_2D, texture[texBOMBER_W]); else //dSOUTH or dVOID both face south glBindTexture(GL_TEXTURE_2D, texture[texBOMBER_S]); glBegin(GL_QUADS); // Draw A Textured Quad ti = (bomber->coords.x + bomber->mstate.move_fracX())*dH - 1.0; tj = (bomber->coords.y + bomber->mstate.move_fracY())*dV - 1.0; draw_texture(ti,tj,dH,dV); glEnd(); // Done Texturing The Box } } // Disable Texture Mapping glBindTexture(GL_TEXTURE_2D, texture[texBLOCK]); // select block image glBegin(GL_QUADS); // Draw A Textured Quad for(unsigned int i = nHmin; i < nHmax; i++) for(unsigned int j = nVmin; j < nVmax; j++) { if(gc.engine.check_tile_index(i,j,2)) //2 is the tile index for blocks { ti = i*dH - 1.0; tj = j*dV - 1.0; draw_texture(ti,tj,dH,dV); } } glEnd(); //glDisable(GL_TEXTURE_2D); // Disable Texture Mapping glBindTexture(GL_TEXTURE_2D, texture[texBRICK]); // select brick image glBegin(GL_QUADS); // Draw A Textured Quad for(unsigned int i = nHmin; i < nHmax; i++) for(unsigned int j = nVmin; j < nVmax; j++) { if(gc.engine.check_tile_index(i,j,1)) //1 is the tile index for blocks { ti = i*dH - 1.0; tj = j*dV - 1.0; draw_texture(ti,tj,dH,dV); } } glEnd(); glBindTexture(GL_TEXTURE_2D, texture[texEXPLOSION_BRICK]); // select explosion brick image glBegin(GL_QUADS); // Draw A Textured Quad for(unsigned int i = nHmin; i < nHmax; i++) for(unsigned int j = nVmin; j < nVmax; j++) { if(gc.engine.check_tile_index(i,j,tEXPLOSION_BRICK)) //1 is the tile index for blocks { ti = i*dH - 1.0; tj = j*dV - 1.0; draw_texture(ti,tj,dH,dV); } } glEnd(); glBindTexture(GL_TEXTURE_2D, texture[texEXPLOSION]); // select explosion image glBegin(GL_QUADS); // Draw A Textured Quad vector::iterator explosion = gc.engine.explosions.begin(); for(; explosion != gc.engine.explosions.end(); explosion++) { ti = explosion->explosion_data.center.x*dH - 1.0; tj = explosion->explosion_data.center.y*dV - 1.0; draw_texture(ti,tj,dH,dV); for(unsigned int i = 1; i <= explosion->explosion_data.dW; i++) { ti = (explosion->explosion_data.center.x - i)*dH - 1.0; tj = explosion->explosion_data.center.y*dV - 1.0; draw_texture(ti,tj,dH,dV); } for(unsigned int i = 1; i <= explosion->explosion_data.dE; i++) { ti = (explosion->explosion_data.center.x + i)*dH - 1.0; tj = explosion->explosion_data.center.y*dV - 1.0; draw_texture(ti,tj,dH,dV); } for(unsigned int i = 1; i <= explosion->explosion_data.dN; i++) { ti = explosion->explosion_data.center.x*dH - 1.0; tj = (explosion->explosion_data.center.y - i)*dV - 1.0; draw_texture(ti,tj,dH,dV); } for(unsigned int i = 1; i <= explosion->explosion_data.dS; i++) { ti = explosion->explosion_data.center.x*dH - 1.0; tj = (explosion->explosion_data.center.y + i)*dV - 1.0; draw_texture(ti,tj,dH,dV); } } glEnd(); glDisable(GL_TEXTURE_2D); // Disable Texture Mapping glFlush(); SwapBuffers(); } const int bID_QUIT = 1; const int bID_STEP = 2; const int bID_LEFT = 3; const int bID_RIGHT = 4; const int bID_UP = 5; const int bID_DOWN = 6; const int bID_PLACE = 7; const int bID_DETO = 8; const int bID_TCONTROL = 9; const int bID_FASTER = 10; const int bID_SLOWER = 11; MasterFrame::MasterFrame(const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(780, 480)) { gc.test_init(); //(defR, defG, defB); wxColor temp_color(defR,defG,defB); this->SetBackgroundColour(temp_color); //we can get his from defR,defB,defG //however if the change is rejected for any reason //this will make it look slightly better temp_color = this->GetBackgroundColour(); backR = (float)temp_color.Red() / 255.0; backG = (float)temp_color.Green() / 255.0; backB = (float)temp_color.Blue() / 255.0; int args[] = {WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_DEPTH_SIZE, 16, 0}; gl_canvas = new bmdGLCanvas(this, args); gl_canvas->Show(); quit_button = new wxButton(this, bID_QUIT, wxString("Quit"),wxPoint(660,30)); quit_button->Show(); step_button = new wxButton(this, bID_STEP, wxString("Step"),wxPoint(660, 60)); step_button->Show(); tcontrol_button = new wxButton(this, bID_TCONTROL, wxString("START"),wxPoint(660, 300)); tcontrol_button->Show(); faster_button = new wxButton(this, bID_FASTER, wxString("Step Faster"),wxPoint(660, 330)); faster_button->Show(); slower_button = new wxButton(this, bID_SLOWER, wxString("Step Slower"),wxPoint(660, 360)); slower_button->Show(); //gl_canvas->InitGL(); //gl_canvas->OnPaint(); Connect(bID_QUIT, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MasterFrame::OnQuit)); Connect(bID_STEP, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MasterFrame::OnStep)); Connect(bID_TCONTROL, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MasterFrame::OnTControl)); Connect(bID_FASTER, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MasterFrame::OnFaster)); Connect(bID_SLOWER, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MasterFrame::OnSlower)); timer = new wxTimer(); timer->SetOwner(this); Connect(wxEVT_TIMER, wxTimerEventHandler(MasterFrame::OnTTick)); Centre(); } void MasterFrame::OnTTick(wxTimerEvent& WXUNUSED(event)) { gc.run_step(); gl_canvas->Refresh(); gc.engine.bombers[0].orders.bomb_place = false; gc.engine.bombers[0].orders.detonate = false; } void MasterFrame::OnTControl(wxCommandEvent& WXUNUSED(event)) { if(timer->IsRunning()) { timer->Stop(); tcontrol_button->SetLabel(wxString("Continue")); } else { timer->Start(TIMER_DELAY); tcontrol_button->SetLabel(wxString("Pause")); } } void MasterFrame::OnFaster(wxCommandEvent& WXUNUSED(event)) { if(TIMER_DELAY > 1) TIMER_DELAY /= 2; if(timer->IsRunning()) { timer->Stop(); timer->Start(TIMER_DELAY); } } void MasterFrame::OnSlower(wxCommandEvent& WXUNUSED(event)) { if(TIMER_DELAY > 1) TIMER_DELAY *= 2; if(timer->IsRunning()) { timer->Stop(); timer->Start(TIMER_DELAY); } } void MasterFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) {Close(true);} void MasterFrame::OnStep(wxCommandEvent& WXUNUSED(event)) { gc.run_step(); gl_canvas->Refresh();} /* BEGIN_EVENT_TABLE(MasterFrame, wxFrame) EVT_BUTTON(wxID_QUIT, MasterFrame::OnQuit) END_EVENT_TABLE() */