From 38d54894f15e98f0aee37d7c1b71762fb9849903 Mon Sep 17 00:00:00 2001 From: Ivan Hernanez Date: Mon, 8 Aug 2011 07:00:23 -0500 Subject: [PATCH] Partially implemented GLdrawing --- Animation.cpp | 76 ++++++++++++++++++++++++++++++++++++++++----- Animation.h | 2 +- Background.cpp | 98 ++++------------------------------------------------------ Background.h | 2 +- Frame.h | 3 +- Game.cpp | 30 +++++++++++++++++- Level.cpp | 6 ++-- Level.h | 2 +- Sprite.cpp | 34 +++++++++++++++----- Sprite.h | 2 +- fns.h | 2 ++ game.vcxproj | 4 +-- 12 files changed, 143 insertions(+), 118 deletions(-) diff --git a/Animation.cpp b/Animation.cpp index 04fc82b..df05b43 100644 --- a/Animation.cpp +++ b/Animation.cpp @@ -9,6 +9,7 @@ #include #include "Animation.h" #include "fns.h" +#include using namespace std; Animation::Animation(std::string animFile):mName(animFile) @@ -48,7 +49,7 @@ int Animation::loadAnimation(std::string animFile) if(temp=="NumFrames:") { value>>mNumFrames; - mAnim = new SpriteFrame[mNumFrames]; + mFrames = new SpriteFrame[mNumFrames]; mBuilt = 1; } else @@ -93,7 +94,7 @@ int Animation::loadAnimation(std::string animFile) value>>yOffset; double radius; value>>radius; - mAnim[count].collisionData.push_back(new CollisionCircle(Point2D(xOffset, yOffset), radius)); + mFrames[count].collisionData.push_back(new CollisionCircle(Point2D(xOffset, yOffset), radius)); } else if(c == 'r') { @@ -103,7 +104,7 @@ int Animation::loadAnimation(std::string animFile) double width = 0.0 , height = 0.0; value>>width; value>>height; - mAnim[count].collisionData.push_back(new CollisionRectangle(Point2D(xOffset, yOffset), width, height)); + mFrames[count].collisionData.push_back(new CollisionRectangle(Point2D(xOffset, yOffset), width, height)); } value>>c; } @@ -117,16 +118,75 @@ int Animation::loadAnimation(std::string animFile) SDL_SetColorKey(temp, SDL_SRCCOLORKEY, SDL_MapRGB(temp->format, transparency[0], transparency[1], transparency[2])); /** Loads image into animation */ - mAnim[count].image = SDL_DisplayFormat(temp); + SDL_Surface* surface = SDL_DisplayFormat(temp); + mFrames[count].width=surface->w; + mFrames[count].height=surface->h; SDL_FreeSurface(temp); + + // Check that the image’s width is a power of 2 + if ( (surface->w & (surface->w - 1)) != 0 ) { + cout<<"warning: image.bmp’s width is not a power of 2"<h & (surface->h - 1)) != 0 ) { + cout<<"warning: image.bmp’s height is not a power of 2"<format->BytesPerPixel; + + GLenum texture_format=NULL; + + //contains an alpha channel + if(nofcolors==4) + { + if(surface->format->Rmask==0x000000ff) + texture_format=GL_RGBA; + else + texture_format=GL_BGRA; + } + else if(nofcolors==3) //no alpha channel + { + if(surface->format->Rmask==0x000000ff) + texture_format=GL_RGB; + else + texture_format=GL_BGR; + } + else + { + cout<<"warning: the image is not truecolor...this will break "<w, surface->h, 0, + texture_format, GL_UNSIGNED_BYTE, surface->pixels ); + /** sets frame delay and makes sure height and width are correct */ - mAnim[count].pause = pause; - mW = mAnim[count].image->w; - mH = mAnim[count].image->h; + mFrames[count].pause = pause; + mW = mFrames[count].width; + mH = mFrames[count].height; /** Set the animation Peg*/ - mAnim[count].animationPeg = Point2D(x + double(mW)/2, y + double(mH)/2); + mFrames[count].animationPeg = Point2D(x + double(mW)/2, y + double(mH)/2); count++; } diff --git a/Animation.h b/Animation.h index 36f836b..9afe2de 100644 --- a/Animation.h +++ b/Animation.h @@ -21,7 +21,7 @@ class Animation Animation(std::string animFile); Animation(std::string animFile, string name); int loadAnimation(std::string animFile);/**< Loads the Animations from a file in the specified format. */ - SpriteFrame *mAnim;/**< Pointer to the current animation. As an array of SpriteFrames */ + SpriteFrame *mFrames;/**< Pointer to the current animation. As an array of SpriteFrames */ int mBuilt,/**< Using as a bool */ mNumFrames,/**< Number of frames in this Animation */ mW,/**< Animation's current width */ diff --git a/Background.cpp b/Background.cpp index 0235d44..021db5a 100644 --- a/Background.cpp +++ b/Background.cpp @@ -23,7 +23,6 @@ mScreen(screen), cout<<"background \""<<_name<<"\" created"< X) // move it to the left til it's on the screen - x -= X; - while (y > Y) // move it up til it's on the screen - y -= Y; - while (x < 0) // move it to the right until it's in the drawable area - x += X; - while (y < 0) // move it down til it's on the screen - y += Y; - //*/ - /*if (wrapping) { - SDL_Rect source; - if (x>=0 && y>=0){ - // Top-left portion of image - dest.x = x; - dest.y = y; - source.x = 0; - source.y = 0; - source.w = X - x; - source.h = Y - y; - SDL_BlitSurface(mBackground, &source, mScreen, &dest); - - // Lower-left portion of image - dest.x = x; - dest.y = 0; - source.x = 0; - source.y = H - y; - source.w = X - x; - source.h = y; - SDL_BlitSurface(mBackground, &source, mScreen, &dest); - - // Lower-right portion of image - dest.x = 0; - dest.y = 0; - source.x = W - x;///< \todo this needs to look right. it's grabbing the wrong part of the image but when it's getting the right part it freaks out and flashes when the bg moves off to the negative. need a check to make sure there is not more background to go before it just draws a section. - source.y = H - y; - source.w = x; - source.h = y; - SDL_BlitSurface(mBackground, &source, mScreen, &dest); - - // Top-right portion of image - dest.x = 0; - dest.y = y; - source.x = W - x; - source.y = 0; - source.w = x; - source.h = Y - y; - SDL_BlitSurface(mBackground, &source, mScreen, &dest); - } - if (x<0 || y<0){ - x = -x; - y = -y; - // Top-left portion of image - dest.x = 0; - dest.y = 0; - source.x = x; - source.y = y; - source.w = X - x; - source.h = Y - y; - SDL_BlitSurface(mBackground, &source, mScreen, &dest); - - /// Lower-left portion of image \todo this be's broken - dest.x = X - x; - dest.y = 0; - source.x = 0; - source.y = H - y; - source.w = x; - source.h = Y - y; - SDL_BlitSurface(mBackground, &source, mScreen, &dest); - - // Lower-right portion of image - dest.x = X - x; - dest.y = Y - y; - source.x = 0; - source.y = 0; - source.w = x; - source.h = y; - SDL_BlitSurface(mBackground, &source, mScreen, &dest); - - // Top-right portion of image - dest.x = 0; - dest.y = Y - y; - source.x = x; - source.y = 0; - source.w = X - x; - source.h = y; - SDL_BlitSurface(mBackground, &source, mScreen, &dest); - } - } - else */if(wrapping){ + if(wrapping){ while (x < 0) // move it to the left til it's on the screen x += W; while (y < 0) // move it up til it's on the screen @@ -143,15 +54,18 @@ void Background::draw(){ dest.y = (int)mPos.y; SDL_BlitSurface(mBackground, &source, mScreen, &dest); } + //*/ + } SDL_Surface* Background::load(std::string filename){ - mBackground = LoadImage("Backgrounds/"+filename); + /*mBackground = LoadImage("Backgrounds/"+filename); cout<<"Loaded file"<w,mBackground->h);/// #include #include +#include "fns.h" struct SpriteFrame{ - SDL_Surface *image;/**< Pointer to an image. */ + Texture image;/**< Image Texture */ int pause;/**< Tells the amount of time to pause between this frame and the next. */ int width;/**< Base width of the frame's image. \todo make this and animation's match or at least sync or delete*/ int height;/**< Base height of the frame's image. \todo make this and animation's match or at least sync or delete*/ diff --git a/Game.cpp b/Game.cpp index 07bcd90..1fce064 100644 --- a/Game.cpp +++ b/Game.cpp @@ -2,9 +2,32 @@ #include "fns.h" #include #include +#include const Uint32 Game::waitTime = 1000/60; /* ms */ +using namespace std; + +void init_GL(int w = 640, int h = 480) +{ + // Set the OpenGL state after creating the context with SDL_SetVideoMode + + glClearColor( 0, 0, 0, 0 ); + + glEnable( GL_TEXTURE_2D ); // Need this to display a texture + + glViewport( 0, 0, w, h ); + + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + + glOrtho( 0, w, h, 0, -1, 1 ); + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); +} + + /** Global static pointer used to ensure a single instance of the class. */ Game* Game::m_instance = NULL; @@ -20,6 +43,9 @@ Game* Game::game(){ Game::Game() : mCurrentLevel(0), mScreen(0), ShowCollisions(false), ShowFPS(false), startclock(0), deltaclock(0), currentFPS(0) { + int screenwidth = 640; + int screenheight = 480; + /** Initialize SDL */ if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) { printf ("Couldn't initialize SDL: %s\n", SDL_GetError ()); @@ -28,7 +54,7 @@ Game::Game() : mCurrentLevel(0), mScreen(0), ShowCollisions(false), ShowFPS(fals atexit (SDL_Quit); /** Set 800x600 video mode */ - mScreen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE); + mScreen = SDL_SetVideoMode(screenwidth, screenheight, 32, SDL_OPENGL); if (!mScreen) { printf ("Couldn't set video mode: %s\n", SDL_GetError ()); exit (2); @@ -39,6 +65,8 @@ Game::Game() : mCurrentLevel(0), mScreen(0), ShowCollisions(false), ShowFPS(fals SDL_ShowCursor(0); + init_GL(screenwidth, screenheight); + /** Load Resources */ LoadResources(); diff --git a/Level.cpp b/Level.cpp index c32759b..ba366b9 100644 --- a/Level.cpp +++ b/Level.cpp @@ -1,6 +1,7 @@ #include "Level.h" #include "Game.h" #include "fns.h" +#include Level::Level(SDL_Surface* screen) : mScreen(screen) { @@ -50,8 +51,7 @@ void Level::drawScene() Uint32 color; /** Create a black mBackgroundground using the mScreen pixel format (32 bpp) */ - color = SDL_MapRGB(mScreen->format, 0, 0, 0); - SDL_FillRect(mScreen, NULL, color); + glClear(GL_COLOR_BUFFER_BIT); /** Draw BG */ if(mBackground!=NULL) @@ -64,7 +64,7 @@ void Level::drawScene() DrawCollisions(); /** Flip the working image buffer with the mScreen buffer */ - SDL_Flip (mScreen); + SDL_GL_SwapBuffers(); } void Level::DrawSprites() diff --git a/Level.h b/Level.h index c13ddc1..9533397 100644 --- a/Level.h +++ b/Level.h @@ -44,7 +44,7 @@ public: Sprite* getSprite(string name);/**< gets the first sprite with the given name \param name Name of the sprite \return Pointer to the requested Sprite */ void removeSprite(Sprite* sp);/**< remove the Sprite sp from the list of sprites \param ps Sprite to remove */ void addAnimation(Animation anim);/**< add a Actor to the list of sprites \param anim The actor to add */ - Animation* Level::getAnimation(string name);/**< get a Actor* to the list of sprites \param name Name of the actor \return Pointer to the actor we requested or null */ + Animation* getAnimation(string name);/**< get a Actor* to the list of sprites \param name Name of the actor \return Pointer to the actor we requested or null */ void removeAnimation(Animation anim);/**< remove an Actor to the list of sprites \param anim The actor to add */ void addActor(string name, Actor actor);/**< add a Actor to the list of sprites \param name Name of the actor \param actor The actor to add */ void removeActor(string name);/**< remove the Actor sp from the list of sprites \param name Name of the actor to remove */ diff --git a/Sprite.cpp b/Sprite.cpp index 140a825..bd501cb 100644 --- a/Sprite.cpp +++ b/Sprite.cpp @@ -1,6 +1,8 @@ #include "Sprite.h" #include "Game.h" #include +#include + using std::cout; using std::endl; Sprite::Sprite(SDL_Surface *screen, std::string name, Actor actor) : @@ -31,7 +33,7 @@ void Sprite::draw() if(mActor.mFrame > mActor.mAnimations[mActor.mCurrentAnimation]->mNumFrames-1) mActor.mFrame=0; //update frame so we don't need to worry - frame = &mActor.mAnimations[mActor.mCurrentAnimation]->mAnim[mActor.mFrame]; + frame = &mActor.mAnimations[mActor.mCurrentAnimation]->mFrames[mActor.mFrame]; //obtain next peg Point2D npos = frame->animationPeg; //move current position to difference of two @@ -40,21 +42,39 @@ void Sprite::draw() } } SDL_Rect dest; - dest.x = (int)mPos.x; - dest.y = (int)mPos.y; - if(mVisible == true) - SDL_BlitSurface(frame->image,NULL,mScreen,&dest); + if(mVisible == true){ + glLoadIdentity(); + glBindTexture(GL_TEXTURE_2D, frame->image); + glBegin( GL_QUADS ); + // Top-left vertex (corner) + glTexCoord2i( 0, 0 ); + glVertex3f( mPos.x, mPos.y, 0 ); + + // Bottom-left vertex (corner) + glTexCoord2i( 1, 0 ); + glVertex3f( mPos.x+frame->width, mPos.y, 0 ); + + // Bottom-right vertex (corner) + glTexCoord2i( 1, 1 ); + glVertex3f( mPos.x+frame->width, mPos.y+frame->height, 0 ); + + // Top-right vertex (corner) + glTexCoord2i( 0, 1 ); + glVertex3f( mPos.x, mPos.y+frame->height, 0 ); + glEnd(); + glLoadIdentity(); + } } vector& Sprite::getCollisionData(){ - return mActor.mAnimations[mActor.mCurrentAnimation]->mAnim[mActor.mFrame].collisionData; + return mActor.mAnimations[mActor.mCurrentAnimation]->mFrames[mActor.mFrame].collisionData; } void Sprite::drawCollisions(){ //get the frame for readability - SpriteFrame frame = mActor.mAnimations[mActor.mCurrentAnimation]->mAnim[mActor.mFrame]; + SpriteFrame frame = mActor.mAnimations[mActor.mCurrentAnimation]->mFrames[mActor.mFrame]; //center the location Point2D pt = mPos + frame.animationPeg; WorldObject::drawCollisions(frame.collisionData, pt); diff --git a/Sprite.h b/Sprite.h index e3a8840..ad75f00 100644 --- a/Sprite.h +++ b/Sprite.h @@ -18,7 +18,7 @@ class Sprite : public WorldObject public: Sprite(SDL_Surface *screen, std::string name, Actor actor); void setAnimation(int animation){ mActor.mCurrentAnimation = animation; }/**< changes to the specified animation beginning at 0. */ - SpriteFrame* getAnimation(){ return &mActor.mAnimations[mActor.mCurrentAnimation]->mAnim[mActor.mFrame]; }/**< returns active animation. (actually the current frame within the animation) \todo see if this is slower maybe undo */ + SpriteFrame* getAnimation(){ return &mActor.mAnimations[mActor.mCurrentAnimation]->mFrames[mActor.mFrame]; }/**< returns active animation. (actually the current frame within the animation) \todo see if this is slower maybe undo */ void setFrame(int frame) { mActor.mFrame = frame; }/**< cahnges to the specified frame of the animation beginning at 0. */ int getFrame() { return mActor.mFrame; }/**< returns active frame. */ void setSpeed(float speed) {mSpeed = speed;}/**< sets the Sprite's speed. */ diff --git a/fns.h b/fns.h index 2e65005..d8cfbb3 100644 --- a/fns.h +++ b/fns.h @@ -10,6 +10,8 @@ using namespace std; typedef void (*Behavior) (); ///As the name denotes, this just simply does nothing static void DoNothing(){} +///Texture name +typedef unsigned int Texture; SDL_Surface* LoadImage( std::string filename );/**< Loads supported images. */ diff --git a/game.vcxproj b/game.vcxproj index bf0a361..9c0d8fc 100644 --- a/game.vcxproj +++ b/game.vcxproj @@ -56,7 +56,7 @@ Console true C:\SDL\lib;%(AdditionalLibraryDirectories) - SDL.lib;SDL_image.lib;SDLmain.lib;SDL_draw.lib;%(AdditionalDependencies) + SDL.lib;SDL_image.lib;SDLmain.lib;SDL_draw.lib;glu32.lib;opengl32.lib;%(AdditionalDependencies) false @@ -80,7 +80,7 @@ true true C:\SDL\lib;%(AdditionalLibraryDirectories) - SDL.lib;SDL_image.lib;SDLmain.lib;SDL_draw.lib;%(AdditionalDependencies) + SDL.lib;SDL_image.lib;SDLmain.lib;SDL_draw.lib;glu32.lib;opengl32.lib;%(AdditionalDependencies) copy "C:\SDL\lib\*.dll" "$(OutputPath)\" -- 2.11.0