//============================================================================== // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Library General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //============================================================================== //============================================================================== // File: cAnimation.cpp // Project: Shooting Star // Author: Jarmo Hekkanen // Copyrights (c) 2003 2ndPoint ry (www.2ndpoint.fi) //------------------------------------------------------------------------------ // Revision history //============================================================================== //============================================================================== // Includes #include "cAnimation.hpp" #include #include #include #include #include #include "cTextureManager.hpp" #include "Debug.hpp" //------------------------------------------------------------------------------ // Namespaces using namespace ShootingStar; //============================================================================== //============================================================================== //! Constructor //------------------------------------------------------------------------------ cAnimation::cAnimation (void): mDisplayList (0), mListRange (0) { // Empty }; //============================================================================== //============================================================================== //! Destructor //------------------------------------------------------------------------------ cAnimation::~cAnimation (void) { if ( mDisplayList != 0 ) glDeleteLists (mDisplayList, mListRange); }; //============================================================================== //! Load configuration from file void cAnimation::LoadConfig (string filename) { ifstream fin; try { // Clear frames mFrames.clear (); // Open file for reading fin.open (filename.c_str ()); if ( !fin ) { dbgError () << "Unable to open file " << filename << " for reading\n"; throw runtime_error ("Unable to open the animation file"); } char buffer[80]; // Read "ANIMATION" fin.getline (buffer, 80); if ( !fin ) throw runtime_error ("Unable to read animation from file"); if ( strcmp (buffer, "ANIMATION") != 0 ) throw runtime_error ("File is not a valid animation file"); // Read frame size int frameWidth, frameHeight; fin.getline (buffer, 80, ':'); // Skip the "Frame size:" fin.getline (buffer, 80, ','); frameWidth = atoi (buffer); fin.getline (buffer, 80); frameHeight = atoi (buffer); if ( !fin ) throw runtime_error ("Unable to read animation frame size from file"); //dbgInfo () << "Animation frame size: " << frameWidth << ' ' << frameHeight << '\n'; SetFrameSize (frameWidth, frameHeight); cTextureManager &texManager = cTextureManager::GetInstance (); while ( !fin.eof () ) { int x, y, w, h; Uint32 texture; fin.getline (buffer, 80, ':'); // Skip the "Frame ??:" if ( fin.eof () ) break; // Read texture fin.getline (buffer, 80, ','); texture = texManager.LoadTexture (buffer); if ( texture == 0 ) dbgWarning () << "Unable to load texture for animation frame\n"; // Get texure size int texWidth, texHeight; texManager.GetTextureSize (buffer, texWidth, texHeight); // Read X fin.getline (buffer, 80, ','); x = atoi (buffer); // Read Y fin.getline (buffer, 80, ','); y = atoi (buffer); // Read W fin.getline (buffer, 80, ','); w = atoi (buffer); // Read H fin.getline (buffer, 80); h = atoi (buffer); //dbgInfo () << "Adding frame " << x << " " << y << " " << w << " " << h << endl; AddFrame (texture, float (x) / texWidth, float (y) / texHeight, float (w) / texWidth, float (h) / texHeight); } // Close the file fin.close (); } catch ( ... ) { fin.close (); throw; } } //============================================================================== //! Add frame to animation //------------------------------------------------------------------------------ void cAnimation::AddFrame (Uint32 texture, float x, float y, float w, float h) { tAnimationFrame frame = {texture, x, y, w, h}; mFrames.push_back (frame); } //============================================================================== //============================================================================== //! Compile animation //------------------------------------------------------------------------------ Uint32 cAnimation::Compile (void) { if ( mDisplayList != 0 ) glDeleteLists (mDisplayList, mListRange); mListRange = mFrames.size (); mDisplayList = glGenLists (mListRange); for ( int i = 0; i < mListRange; i++ ) { glNewList (mDisplayList + i, GL_COMPILE); RenderFrame (i); glEndList (); } GLenum error = glGetError (); while ( error != GL_NO_ERROR ) { dbgError () << "cAnimation: OpenGL error: " << gluErrorString (error) << '\n'; error = glGetError (); } return mDisplayList; } //============================================================================== //============================================================================== //! Render frame //------------------------------------------------------------------------------ void cAnimation::RenderFrame (Uint16 frame) { if ( frame >= mFrames.size () ) return; // Set texture glBindTexture (GL_TEXTURE_2D, mFrames[frame].mTextureID); // Render frame glBegin (GL_QUADS); glTexCoord2f (mFrames[frame].mX, mFrames[frame].mY); glVertex2f (-mWidth / 2, -mHeight / 2); glTexCoord2f (mFrames[frame].mX, mFrames[frame].mY + mFrames[frame].mH); glVertex2f (-mWidth / 2, mHeight / 2); glTexCoord2f (mFrames[frame].mX + mFrames[frame].mW, mFrames[frame].mY + mFrames[frame].mH); glVertex2f (mWidth / 2, mHeight / 2); glTexCoord2f (mFrames[frame].mX + mFrames[frame].mW, mFrames[frame].mY); glVertex2f (mWidth / 2, -mHeight / 2); glEnd (); } //============================================================================== //============================================================================== // EOF //==============================================================================