diff --git a/SDL#3/Sprite.cpp b/SDL#3/Sprite.cpp index 4759779..8f83e6a 100644 --- a/SDL#3/Sprite.cpp +++ b/SDL#3/Sprite.cpp @@ -1,89 +1,130 @@ /* [DESTRUCTOR] Destruction de la surface =========================================================*/ Sprite::~Sprite(){ - SDL_FreeSurface( _surface ); + SDL_DestroyTexture( _texture ); + _manager = NULL; } /* [CONSTRUCTOR] Construction de la surface vide =========================================================*/ -Sprite::Sprite(SDL_Rect r){ - _surface = SDL_CreateRGBSurface(0, r.w, r.h, 32, 0, 0, 0, 0); - - // On definit les dimensions - _rect = (SDL_Rect){r.x, r.y, r.w, r.h}; - _origin = (SDL_Rect){0, 0, r.w, r.h}; - - // On applique les offset - SDL_SetClipRect( _surface, &_rect ); - +Sprite::Sprite(sdltl *m){ + _manager = m; + _texture = NULL; } /* [CONSTRUCTOR] Construction de la surface avec couleur =========================================================*/ -Sprite::Sprite(const int rgb[], SDL_Rect r){ - cout << "a: [" << (sizeof(rgb)/sizeof(*rgb)) << "]" << endl; - - _surface = SDL_CreateRGBSurface(0, r.w, r.h, 32, 0, 0, 0, rgb[3]); - - // On recupere la couleur - Uint32 color = SDL_MapRGBA( _surface->format, rgb[0], rgb[1], rgb[2], rgb[3]); - - // On remplit avec la couleur - SDL_FillRect( _surface, NULL, color ); - - // On definit les dimensions - _rect = (SDL_Rect){r.x, r.y, r.w, r.h}; - _origin = (SDL_Rect){0, 0, r.w, r.h}; +Sprite::Sprite(sdltl *m, const int rgb[]){ + _manager = m; + _texture = NULL; - // On applique les offset - SDL_SetClipRect( _surface, &_rect ); + cout << "a: [" << (sizeof(rgb)/sizeof(*rgb)) << "]" << endl; + + SDL_Surface *surf = SDL_CreateRGBSurface(0, 0, 0, 32, 0, 0, 0, rgb[3]); + + // On recupere la couleur + Uint32 color = SDL_MapRGBA( surf->format, rgb[0], rgb[1], rgb[2], rgb[3]); + + + // On cree la texture a partir de la surface + _texture = SDL_CreateTextureFromSurface(_manager->renderer(), surf); + + + // On libere la surface inutile maintenant + SDL_FreeSurface( surf ); + surf = NULL; + } /* [CONSTRUCTOR] Construction de la surface avec image =========================================================*/ -Sprite::Sprite(const char url[], SDL_Rect r, SDL_Rect clip){ +Sprite::Sprite(sdltl *m, const char *url){ + + _manager = m; + _texture = NULL; /* (1) On cree la surface (avec image) */ - _surface = IMG_Load( url ); + _texture = IMG_LoadTexture(_manager->renderer(), url); // Gestion erreur - if( _surface == NULL ) + if( _texture == NULL ) return; - - // On definit les dimensions - _rect = (SDL_Rect){r.x, r.y, r.w, r.h}; - _origin = (SDL_Rect){clip.x, clip.y, r.w, r.h}; - - // On applique le clip - SDL_SetClipRect( _surface, &clip ); - } - -/* [APPENDTO] Ajoute le Sprite au rendu +/* [DIMENSIONS] Definition des dimensions par defaut =========================================================*/ -void Sprite::appendTo(sdltl *mgr){ - _texture = SDL_CreateTextureFromSurface(mgr->renderer(), _surface); +void Sprite::dimensions(){ + cout <<"A"<add(_texture, &_origin, &_rect); + /* (1) On recupere les informations de la texture */ + int w, h; + SDL_QueryTexture(_texture, NULL, NULL, &w, &h); + + + /* (2) On definit les dimensions par defaut */ + _dst = (SDL_Rect){0, 0, w, h}; + _src = (SDL_Rect){0, 0, w, h}; } -/* [REMOVEFROM] Retire une sprite du rendu + +/* [DIMENSIONS] Definition des dimensions de la texture =========================================================*/ -void Sprite::removeFrom(sdltl *mgr){ - mgr->remove( _texture ); +void Sprite::dimensions(SDL_Rect r){ + cout <<"B"<push(_texture, &_src, &_dst); +} + +/* [PULL] Retire une sprite du rendu +=========================================================*/ +void Sprite::pull(){ + _manager->pull( _texture ); +} + +/* [UPDATE] Mise a jour du rendu +=========================================================*/ +void Sprite::update(){ + _manager->update(); +} + + +/* [TEXTURE] Retourne la texture +=========================================================*/ +SDL_Texture *Sprite::texture(){ return _texture; } + +/* [MANAGER] Retourne le manager +=========================================================*/ +sdltl *Sprite::manager(){ return _manager; } @@ -132,18 +173,27 @@ void SpriteGroup::remove(Sprite *s){ } -/* [APPENDTO] Ajoute tous les Sprite du groupe a une surface parente +/* [PUSH] Ajoute tous les Sprite du groupe a une surface parente =========================================================*/ -void SpriteGroup::appendTo(sdltl *mgr){ +void SpriteGroup::push(){ for( int i = 0 ; i < _sprites.size() ; i++ ) - _sprites[i]->appendTo( mgr ); + _sprites[i]->push(); } -/* [REMOVEFROM] Retire une sprite de la surface parents +/* [PULL] Retire une sprite de la surface parents =========================================================*/ -void SpriteGroup::removeFrom(sdltl *mgr){ +void SpriteGroup::pull(){ for( int i = 0 ; i < _sprites.size() ; i++ ) - _sprites[i]->removeFrom( mgr ); + _sprites[i]->pull(); +} + + + +/* [UPDATE] Mise a jour du rendu +=========================================================*/ +void SpriteGroup::update(){ + if( _sprites.size() > 0 ) + _sprites[0]->update(); } @@ -158,7 +208,7 @@ Sprite* SpriteGroup::get(int i){ /* [TRHEAD] Process de l'animation =========================================================*/ -void SpriteGroupAnimation(sdltl *mgr, SpriteGroup *sg, int t, int flags){ +void SpriteGroupAnimation(SpriteGroup *sg, int t, int flags){ int length = sg->_sprites.size(); int timer = 0; int step = 1; @@ -175,13 +225,13 @@ void SpriteGroupAnimation(sdltl *mgr, SpriteGroup *sg, int t, int flags){ // On retire le sprite precedent if( lastindex > -1 ) - sg->_sprites[lastindex]->removeFrom( mgr ); + sg->get(lastindex)->pull(); // On ajoute le sprite - sg->_sprites[i]->appendTo( mgr ); + sg->get(i)->push(); // On met a jour le rendu - // mgr->update(); + // sg->get(i)->update(); if( SDL_GetTicks()-timer < t ) @@ -212,8 +262,8 @@ void SpriteGroupAnimation(sdltl *mgr, SpriteGroup *sg, int t, int flags){ /* [ANIMATE] Modifie le Sprite dans l'ordre du SpriteGroup =========================================================*/ -thread* SpriteGroup::animate(sdltl *mgr, int t, int flags){ - _animation = new thread(SpriteGroupAnimation, mgr, this, t, flags); +thread* SpriteGroup::animate(int t, int flags){ + _animation = new thread(SpriteGroupAnimation, this, t, flags); // On attends pas le thread _animation->detach(); diff --git a/SDL#3/Sprite.h b/SDL#3/Sprite.h index ef1a182..b175968 100644 --- a/SDL#3/Sprite.h +++ b/SDL#3/Sprite.h @@ -24,25 +24,31 @@ class Sprite{ public: - Sprite(SDL_Rect r); - Sprite(const int rgb[], SDL_Rect r); - Sprite(const char url[], SDL_Rect r, SDL_Rect clip); + Sprite(sdltl *m); // Sprite vide + Sprite(sdltl *m, const int rgb[]); // Sprite couleur + Sprite(sdltl *m, const char *url); // Sprite image ~Sprite(); - void setImage(const char url[], int ox=0, int oy=0); + void dimensions(); // Dimensions par defaut + void dimensions(SDL_Rect r); // Dimensions sortie + void dimensions(SDL_Rect r, SDL_Rect clip); // Dimensions in/out - void appendTo(sdltl *mgr); - void removeFrom(sdltl *mgr); + void push(); // Ajoute a l'affichage + void pull(); // Retire de l'affichage + + void update(); // Fait renmonter la mise a jour du manager // GETTERS - SDL_Surface *surface(); + SDL_Texture *texture(); + sdltl *manager(); + private: - SDL_Surface *_surface; + sdltl *_manager; SDL_Texture *_texture; - SDL_Rect _rect; - SDL_Rect _origin; + SDL_Rect _dst; + SDL_Rect _src; }; @@ -55,18 +61,20 @@ void add(Sprite *s); void remove(Sprite *s); Sprite* get(int i); - void appendTo(sdltl *mgr); - void removeFrom(sdltl *mgr); - thread *animate(sdltl *mgr, int t, int flags=0); + void push(); // Ajoute les sprites a l'affichage + void pull(); // Retire les sprites de l'affichage + + void update(); // Fait renmonter la mise a jour du manager + + thread *animate(int t, int flags=0); private: - SDL_Renderer *_renderer; - vector _sprites; - thread *_animation; + vector _sprites; + thread *_animation; - friend void SpriteGroupAnimation(sdltl *mgr, SpriteGroup *sg, int t, int flags=SPRITE_ANIM_ONCE ); + friend void SpriteGroupAnimation(SpriteGroup *sg, int t, int flags=SPRITE_ANIM_ONCE ); }; diff --git a/SDL#3/exe b/SDL#3/exe index cdfd567..971ccbd 100755 Binary files a/SDL#3/exe and b/SDL#3/exe differ diff --git a/SDL#3/main.cpp b/SDL#3/main.cpp index 1fbe95b..b818052 100644 --- a/SDL#3/main.cpp +++ b/SDL#3/main.cpp @@ -9,143 +9,115 @@ static bool running = true; int main(int argc, char* argv[]) { srand(time(0)); - /* [0] Initialisation de SDL + /* [0] Initialisation du manager + Creation de la fenetre =========================================================*/ mgr = new sdltl("Ma fenetre SDL", WIN_WIDTH, WIN_HEIGHT); - /* [1] Creation de la fenetre - =========================================================*/ - if( !mgr->status() ) cout << "Erreur: " << SDL_GetError() << endl; + // Gestion erreur + if( !mgr->status() ){ + cout << "[INIT] -> " << SDL_GetError() << endl; + return -1; + } - /* [3] On definit le background color + /* [2] On definit le background color =========================================================*/ - bool bgLoaded = mgr->setBackground(255, 255, 255); - cout << "BG: " << bgLoaded << endl; - // bool imageLoaded = mgr->setImage( "src/1.bmp" ); + mgr->setBackground(255, 0, 255, 150); + // mgr->setImage( "src/1.bmp" ); /* [4] On ajoute Une animation =========================================================*/ /* (1) On cree les fonds pour couvrir les frames en arriere plan */ - int white[] = {255, 255, 255}; - Sprite *mb_background = new Sprite( - white, - (SDL_Rect){0, 0, 20, 20} - ); - - Sprite *gs_background = new Sprite( - white, - (SDL_Rect){100, 0, 20, 20} - ); - - Sprite *rs_background = new Sprite( - white, - (SDL_Rect){150, 0, 20, 20} - ); + // int white[] = {255, 255, 255}; + // Sprite *mb_background = new Sprite(mgr, white ); + // mb_background->dimensions((SDL_Rect){0, 0, 20, 20}); - /* (2) On enregistre les frames de l'animation du bloc mystere */ + // Sprite *gs_background = new Sprite(mgr, white); + // gs_background->dimensions((SDL_Rect){100, 0, 20, 20}); + + // Sprite *rs_background = new Sprite(mgr, white); + // rs_background->dimensions((SDL_Rect){150, 0, 20, 20}); + + // /* (2) On enregistre les frames de l'animation du bloc mystere */ SpriteGroup animated_mystery_bloc; for( int i = 0 ; i < 4 ; i++ ){ - animated_mystery_bloc.add( new Sprite( - "src/mario_crop.png", - (SDL_Rect){0, 0, 20, 20}, + animated_mystery_bloc.add( new Sprite(mgr, "src/mario_crop.png") ); + animated_mystery_bloc.get(i)->dimensions( + (SDL_Rect){0, 0, 100, 100}, (SDL_Rect){4*19+19*i, 2*20, 20, 20} - ) ); + ); } - /* (3) On enregistre les frames de l'animation d'une carapace verte */ + // (3) On enregistre les frames de l'animation d'une carapace verte SpriteGroup animated_green_shell; for( int i = 0 ; i < 4 ; i++ ){ - animated_green_shell.add( new Sprite( - "src/mario_crop.png", + animated_green_shell.add( new Sprite(mgr, "src/mario_crop.png") ); + animated_green_shell.get(i)->dimensions( (SDL_Rect){100, 0, 20, 20}, (SDL_Rect){4*19+19*i, 11*19, 20, 20} - ) ); + ); } - /* (4) On enregistre les frames de l'animation d'une carapace rouge */ + // /* (4) On enregistre les frames de l'animation d'une carapace rouge */ SpriteGroup animated_red_shell; for( int i = 0 ; i < 4 ; i++ ){ - animated_red_shell.add( new Sprite( - "src/mario_crop.png", - (SDL_Rect){150, 0, 20, 20}, + animated_red_shell.add( new Sprite(mgr, "src/mario_crop.png") ); + animated_red_shell.get(i)->dimensions( + (SDL_Rect){150, 0, 50, 50}, (SDL_Rect){2+19*i, 11*19, 20, 20} - ) ); + ); } - // TEST - int red[] = {255, 0, 0}; - int pink[] = {255, 0, 255}; - SpriteGroup testgroup; - - testgroup.add( new Sprite( - "src/mario_crop.png", - (SDL_Rect){150, 0, 20, 20}, - (SDL_Rect){2+19*1, 11*19, 20, 20} - ) ); - - testgroup.add( new Sprite( - pink, - (SDL_Rect){100, 0, 100, 100} - ) ); - - // testgroup.appendTo(mgr); - testgroup.get(0)->appendTo(mgr); - - - - - /* [5] On lance les animation en parallele - =========================================================*/ + // /* [5] On lance les animation en parallele + // =========================================================*/ vector animations(0); - animations.push_back( animated_mystery_bloc.animate( - mgr, // rendu a mettre a jour - 200, // delai entre-frames - SPRITE_ANIM_INFINITE // FLAGS - ) ); - delete animations[0]; // On le supprime ensuite + // animations.push_back( animated_mystery_bloc.animate( + // 200, // delai entre-frames + // SPRITE_ANIM_INFINITE // FLAGS + // ) ); + // delete animations[0]; // On le supprime ensuite - animations.push_back( animated_green_shell.animate( - mgr, // rendu a mettre a jour - 100, // delai entre-frames - SPRITE_ANIM_INFINITE // FLAGS - ) ); - delete animations[1]; // On le supprime ensuite + // animations.push_back( animated_green_shell.animate( + // 100, // delai entre-frames + // SPRITE_ANIM_INFINITE // FLAGS + // ) ); + // delete animations[1]; // On le supprime ensuite animations.push_back( animated_red_shell.animate( - mgr, // rendu a mettre a jour 100, // delai entre-frames SPRITE_ANIM_INFINITE // FLAGS ) ); - delete animations[2]; // On le supprime ensuite + delete animations[0]; // On le supprime ensuite /* [n-1] Boucle infinie =========================================================*/ + mgr->update(); mgr->manageFps(FPS); running = true; while(running){ + mgr->waitEvent(SDL_QUIT, &quitEventHandler); // cout << "Main loop" << endl; diff --git a/SDL#3/main.h b/SDL#3/main.h index 4e050b9..de4d544 100644 --- a/SDL#3/main.h +++ b/SDL#3/main.h @@ -19,8 +19,8 @@ /* [CONST] Constantes et enumerations =========================================================*/ - #define WIN_WIDTH 600 - #define WIN_HEIGHT 400 + #define WIN_WIDTH 1200 + #define WIN_HEIGHT 800 #define FPS 60 diff --git a/SDL#3/main.o b/SDL#3/main.o index fa9582f..0bbf244 100644 Binary files a/SDL#3/main.o and b/SDL#3/main.o differ diff --git a/SDL#3/sdltl.cpp b/SDL#3/sdltl.cpp index 93d387b..6283b90 100644 --- a/SDL#3/sdltl.cpp +++ b/SDL#3/sdltl.cpp @@ -32,7 +32,7 @@ sdltl::sdltl(const char *t, int w, int h){ _renderer = SDL_CreateRenderer( _window, -1, - SDL_RENDERER_ACCELERATED + SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC ); } @@ -65,38 +65,9 @@ SDL_Renderer* sdltl::renderer(){ return _renderer; } /* [SETBACKGROUND] Modifie la couleur de fond =========================================================*/ -bool sdltl::setBackground(int r, int g, int b){ - /*// On cree la surface - SDL_Surface *surf = NULL; - int win[2]; - SDL_GetWindowSize(_window, &win[0], &win[1]); +bool sdltl::setBackground(Uint8 r, Uint8 g, Uint8 b, Uint8 a){ - // On cree la surface - surf = SDL_CreateRGBSurface(0, win[0], win[1], 32, 0, 0, 0, 0); - - if( surf == NULL ) - return false; - - // On cree la couleur - Uint32 color = SDL_MapRGB(surf->format, r, g, b); - - // On colore la surface - SDL_FillRect(surf, NULL, color); - - - // On applique a la texture - _texture = SDL_CreateTextureFromSurface(_renderer, surf); - - if( _texture == NULL ) - return false; - - - // On libere la memoire - SDL_FreeSurface(surf); - surf = NULL; - */ - - SDL_SetRenderDrawColor( _renderer, 0xFF, 0xFF, 0xFF, 0x00 ); + SDL_SetRenderDrawColor( _renderer, r, g, b, a ); return true; } @@ -105,39 +76,25 @@ bool sdltl::setBackground(int r, int g, int b){ =========================================================*/ bool sdltl::setImage(const char *url){ - SDL_Surface *image = NULL; - image = SDL_LoadBMP( url ); - - // Si erreur de chargement image - if( image == NULL ) - return false; - // On cree la texture associee - _texture = SDL_CreateTextureFromSurface( - _renderer, - image - ); + _texture = IMG_LoadTexture( _renderer, url ); - // On libere la surface pour l'image - SDL_FreeSurface(image); - delete image; - - return true; + return _texture != NULL; } -/* [ADD] Ajoute une texture au rendu principal +/* [PUSH] Ajoute une texture au rendu principal =========================================================*/ -void sdltl::add(SDL_Texture *t, SDL_Rect *origin, SDL_Rect *dest){ - _sprites.push_back( t ); - _origins.push_back( origin ); - _dests.push_back( dest ); +void sdltl::push(SDL_Texture *t, SDL_Rect *src, SDL_Rect *dst){ + _sprites.push_back( t ); + _src.push_back( src ); + _dst.push_back( dst ); } -/* [REMOVE] Retire une texture du rendu principal +/* [PULL] Retire une texture du rendu principal =========================================================*/ -void sdltl::remove(SDL_Texture *t){ +void sdltl::pull(SDL_Texture *t){ // On cherche l'indice de la texture int index = -1; @@ -150,8 +107,8 @@ void sdltl::remove(SDL_Texture *t){ // On supprime la texture et ses dimensions _sprites.erase( _sprites.begin() + index ); - _origins.erase( _origins.begin() + index ); - _dests.erase( _dests.begin() + index ); + _src.erase( _src.begin() + index ); + _dst.erase( _dst.begin() + index ); } @@ -159,21 +116,32 @@ void sdltl::remove(SDL_Texture *t){ /* [UPDATE] Mise a jour du rendu =========================================================*/ void sdltl::update(){ - // On efface l'ecran + + + /* (1) On efface le rendu */ SDL_RenderClear(_renderer); - // On ajoute le rendu principal au rendu + + /* (2) On applique la couleur de fond */ + SDL_Rect dRect; // On recupere les dimensions de la fenetre + SDL_GetWindowSize(_window, &dRect.w, &dRect.h); + SDL_RenderDrawRect(_renderer, &dRect); + + + /* (3) On ajoute le rendu principal (si existe) */ if( _texture != NULL) SDL_RenderCopy(_renderer, _texture, NULL, NULL); - // On ajoute toutes les textures ajoutees - cout << "Update MAIN SPRITE +" << _sprites.size() << " added sprites.." << endl; - // for( int i = _sprites.size()-1 ; i >= 0 ; i-- ) - for( int i = 0 ; i < _sprites.size() ; i++ ) - SDL_RenderCopy(_renderer, _sprites[i], _origins[i], _dests[i]); - // On affiche le resultat + /* (4) On ajoute toutes les textures pushees */ + cout << "Update MAIN SPRITE +" << _sprites.size() << " added sprites.." << endl; + for( int i = 0 ; i < _sprites.size() ; i++ ) + SDL_RenderCopy(_renderer, _sprites[i], _src[i], _dst[i]); + + + /* (n) On affiche le resultat */ SDL_RenderPresent(_renderer); + } /* [WAITEVENT] Attends un evenement pour executer diff --git a/SDL#3/sdltl.h b/SDL#3/sdltl.h index 8641ca5..b20b4aa 100644 --- a/SDL#3/sdltl.h +++ b/SDL#3/sdltl.h @@ -5,6 +5,7 @@ /* [LIBS] Internes =========================================================*/ #include "SDL.h" + #include "SDL_image.h" #include /* [LIBS] Externes @@ -24,12 +25,13 @@ SDL_Window *window(); SDL_Renderer *renderer(); bool status(); - bool setBackground(int r=255, int g=255, int b=255); + bool setBackground(Uint8 r=0xff, Uint8 g=0xff, Uint8 b=0xff, Uint8 a=0xff); bool setImage(const char *url); void waitEvent(SDL_EventType t, void(*handler)(SDL_Event*) ); - void add(SDL_Texture *t, SDL_Rect *origin, SDL_Rect *dest); - void remove(SDL_Texture *t); + void push(SDL_Texture *t, SDL_Rect *origin, SDL_Rect *dest); + void pull(SDL_Texture *t); + void update(); void manageFps(const int fps=0); @@ -48,8 +50,8 @@ SDL_Texture *_texture; vector _sprites; - vector _origins; - vector _dests; + vector _src; + vector _dst; };