D1X
D1X

Reputation: 5444

How to insert image in a part of the screen?

My board game is using a matrix. I created a board using rectangles. gimprimir() takes the matrix and translates it creating different types of rectangles.

I need to insert an image on a part of the screen. This tutorial teaches how to put an image on screen, but not how to load it in a part of the screen. Whenever I try to modify it, I get a segmentation fault. I want to keep it simple. The image format is .bmp.

My code:

bool loadMedia();                               
void close();                                  
SDL_Texture* loadTexture( std::string path );   
SDL_Window* gWindow = NULL;                     
SDL_Renderer* gRenderer = NULL;

const int SCREEN_WIDTH = 1200;
const int SCREEN_HEIGHT = 680;

int main(int argc, char* args[]){
  nodo a;
 if( !init() ){
        cout << "Failed to initialize!\n" ;
 }
 else{
        if(!loadMedia()){
                cout << "Failed to load media!\n";
        }
        else{
                bool quit = false;      // flag ciclo principal
                SDL_Event e;            // variables manejo de eventos
                SDL_Event t;
                gimprimir(a);
        }
}

}

Function gimprimir() prints a board using struct a:

struct nodo {
 array<array<int,19>,19> tablero;       // Estado tablero
 array<int,2> p1,p2;                    // Posiciones
 int d1,d2;                             // Distancias mínimas
 int paredes1;
 int paredes2;
} a;

gimprimir() uses empty and filled rectangles:

    void gimprimir(nodo aa){
 
 //Clear screen
 SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );
 SDL_RenderClear( gRenderer );
 int i,j;
 for (i=1; i<=17; i++){
    if (i%2==1){
        for (j=1; j<=17 ; j++){
            if (j%2==1){
                if (aa.p1[0]==i && aa.p1[1]==j){  // FICHA 1
                    SDL_Rect fillRect = {(50+SCREEN_WIDTH/11)+(SCREEN_WIDTH/11)*(j-1)/2+34, (SCREEN_HEIGHT/11)+(SCREEN_HEIGHT/11)*(i-1)/2+34, SCREEN_WIDTH/12, SCREEN_HEIGHT/12};
                                    SDL_SetRenderDrawColor( gRenderer, 0xff, 0xcc, 0x66, 0xFF );
                                SDL_RenderFillRect( gRenderer, &fillRect );
                }
                else{
                                if (aa.p2[0]==i && aa.p2[1]==j){   // FICHA 2
                                        SDL_Rect fillRect = {(50+SCREEN_WIDTH/11)+(SCREEN_WIDTH/11)*(j-1)/2+34, (SCREEN_HEIGHT/11)+(SCREEN_HEIGHT/11)*(i-1)/2+34, SCREEN_WIDTH/12, SCREEN_HEIGHT/12};
                                        SDL_SetRenderDrawColor( gRenderer, 0x6E, 0x2C, 0x67, 0xFF );
                                        SDL_RenderFillRect( gRenderer, &fillRect );
                                }
                    else{                   // CASILLA VACÍA
                        SDL_Rect fillRect = {(50+SCREEN_WIDTH/11)+(SCREEN_WIDTH/11)*(j-1)/2+34, (SCREEN_HEIGHT/11)+(SCREEN_HEIGHT/11)*(i-1)/2+34, SCREEN_WIDTH/12, SCREEN_HEIGHT/12};
                                        SDL_SetRenderDrawColor( gRenderer, 0x8B, 0x45, 0x13, 0xFF);
                                        SDL_RenderFillRect( gRenderer, &fillRect );
                    }
                }
            }
        }
    }
}
                SDL_RenderPresent( gRenderer );

}

loadMedia():

bool loadMedia()
{
        //Loading success flag
        bool success = true;

        //Nothing to load
        return success;
}

I want to have both on screen. To load the image to be left in a part of the screen forever and then update the rectangles generated with gimprimir().

Upvotes: 1

Views: 1150

Answers (2)

i-am-wells
i-am-wells

Reputation: 61

SDL_BlitSurface() will work, but since you're using SDL2 you're probably working mostly with SDL_Textures and not SDL_Surfaces. If this is the case the easiest way to copy one texture onto another texture or onto the screen is using SDL_RenderCopy() as keltar mentioned. The advantages of using SDL_Texture are explained here: http://wiki.libsdl.org/MigrationGuide#Video

As documented here, SDL_RenderCopy() takes four arguments: a pointer to the SDL_Renderer, a pointer to your source texture, a pointer to the source rectangle, and a pointer to the destination rectangle. By default the texture will be copied onto the screen but you can copy onto other textures by setting a target texture with SDL_SetRenderTarget().

Everything about source and destination rectangles carries over from SDL_BlitSurface.

Upvotes: 0

Alex
Alex

Reputation: 3454

SDL_BlitSurface is the SDL function used to blit (copy) from a surface to another, it takes two SDL_Rect arguments, srcrect for source and dstrect for destination.

SDL_BlitSurface isn't changed much from SDL1.2 to SDL2, so, old examples which use it should still work.

In the getting_an_image_on_the_screen example you propose a NULL pointer is used for both src and dst rect, a NULL rect mean copy the whole src surface into the destination at top, left = 0, 0 with a maximum size equal to the destination size (if the source is bigger should be cropped).

To blit a partial image just specify src and dst rect:

        SDL_Rect srcrect = { 0, 0, 100, 100 };
        SDL_Rect dstrect = { 50, 50, 100, 100 };

        //Apply the image
        SDL_BlitSurface( gHelloWorld, &srcrect, gScreenSurface, &dstrect );

In this case top, left = 0, 0 with width, height = 100, 100 from source surface (gHelloWorld) is blit to top, left = 50, 50 of dest surface (gScreenSurface).

how to load it with other types of objects

Sorry but is not clear to me what you mean by other types of objects

Upvotes: 2

Related Questions