Jump to content

View more

Image of the Day

雑魚は多めにして、爽快感重視にしつつ・・・(´・ω・`)
早いとこ、ベースを作って、完成にもっていかないとね。
タイトルもまだ迷ってるだよなぁ。 
#indiedev  #indiegame #screenshotsaturday https://t.co/IwVbswGrhe
IOTD | Top Screenshots

The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.


Sign up now

[SDL] How to copy the screen to another surface?

4: Adsense

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.


  • You cannot reply to this topic
14 replies to this topic

#1 Rafael Toledo   Members   

100
Like
0Likes
Like

Posted 22 August 2011 - 07:25 AM

Hello!

I'm trying to make a copy of the actual screen to another SDL_Surface. I tried to use SDL_BlitSurface and SDL_DisplayFormat, rounded and non-rounded by callings of SDL_LockSurface and SDL_UnlockSurface, but I can't get the copy. I only get an empty surface.

Anyone can help me?

#2 rip-off   Moderators   

10891
Like
0Likes
Like

Posted 22 August 2011 - 07:26 AM

SDL_BlitSurface() should work, without SDL_LockSurface(). How are you allocating the destination surface? Have you tried checking the return value of SDL_BlitSurface(), and the value of SDL_GetError()?

#3 Rafael Toledo   Members   

100
Like
0Likes
Like

Posted 22 August 2011 - 07:44 AM

I did the following:

SDL_Surface *mySurface, *temp;
SDL_Rect rect;

temp = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, screen->w, screen->h, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);

if (temp) {
   mySurface = SDL_DisplayFormat(temp);
   SDL_FreeSurface(temp);
}

rect.x = 0;
rect.y = 0;

SDL_BlitSurface(screen, NULL, mySurface, &rect);

I tried to use SDL_GetError() but it didn't returned anything.

#4 Wooh   Members   

1088
Like
0Likes
Like

Posted 22 August 2011 - 07:57 AM

SDL_CreateRGBSurface takes 8 arguments but you only pass 7 arguments. How is that possible?

SDL_DisplayFormat creates a copy so all you should have to do to create a copy of the screen surface is
mySurface = SDL_DisplayFormat(screen);


#5 Rafael Toledo   Members   

100
Like
0Likes
Like

Posted 22 August 2011 - 08:04 AM

Sorry, I mistyped that line:

temp = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, screen->w, screen->h, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);

I tried to use SDL_DisplayFormat, but no result and no error... Posted Image

#6 rip-off   Moderators   

10891
Like
0Likes
Like

Posted 22 August 2011 - 08:15 AM

You aren't checking for errors in that code.

#7 Rafael Toledo   Members   

100
Like
0Likes
Like

Posted 22 August 2011 - 08:21 AM

Sorry, I just put a fragment of the code, just a explanation of what I'm doing...

SDL_Surface *mySurface, *temp;
SDL_Rect rect;

temp = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, screen->w, screen->h, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);

if (temp) {
   mySurface = SDL_DisplayFormat(temp);
   SDL_FreeSurface(temp);
}

rect.x = 0;
rect.y = 0;

SDL_BlitSurface(screen, NULL, mySurface, &rect);

if (!mySurface) {
   cerr << string(SDL_GetError()) << endl;
   exit(-1);
}

It pass through the 'if'... there's no error, but it gives me a black surface.

#8 Wooh   Members   

1088
Like
0Likes
Like

Posted 22 August 2011 - 08:22 AM

When you say no result, do you mean that SDL_DisplayFormat returns NULL?

#9 Rafael Toledo   Members   

100
Like
0Likes
Like

Posted 22 August 2011 - 08:28 AM

No... it returns a black surface with the size of the screen...

#10 rip-off   Moderators   

10891
Like
0Likes
Like

Posted 22 August 2011 - 08:40 AM

You still aren't checking the return value of SDL_BlitSurface().

#11 Wooh   Members   

1088
Like
0Likes
Like

Posted 22 August 2011 - 08:45 AM

In your code SDL_DisplayFormat should return a blank surface because you haven't copied the screen surface yet.

#12 Rafael Toledo   Members   

100
Like
0Likes
Like

Posted 22 August 2011 - 08:46 AM

SDL_BlitSurface is returning 0 (success)...

#13 Wooh   Members   

1088
Like
0Likes
Like

Posted 22 August 2011 - 09:00 AM

It is probably easier if you make a testcase: A small program that compiles and have the same problem you want to show. Because now we are only guessing.

#14 rip-off   Moderators   

10891
Like
1Likes
Like

Posted 22 August 2011 - 09:09 AM

Here is such a reasonably minimal example:
#include "SDL.h"
#include <iostream>
#include <cstdlib>
#include <ctime>

int main(int, char **)
{
    std::srand(static_cast<unsigned>(std::time(0)));

    if(SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        std::cerr << "Failed to initialise SDL: " << SDL_GetError() << '\n';
        return 1;
    }
    
    std::atexit(&SDL_Quit);
    
    SDL_Surface *screen = SDL_SetVideoMode(400, 400, 0, 0);
    if(!screen)
    {
        std::cerr << "Failed to initialise SDL: " << SDL_GetError() << '\n';
        return 1;
    }
    
    bool running = true;
    while(running)
    {
        SDL_Event event;
        if(SDL_WaitEvent(&event))
        {
            if(event.type == SDL_QUIT)
            {
                running = false;
            }
            else if((event.type == SDL_KEYUP) && (event.key.keysym.sym == SDLK_ESCAPE))
            {
                running = false;
            }
        }
        
        SDL_FillRect(screen, NULL, 0);
        
        for(int i = 0 ; i < 10 ; ++i)
        {
            SDL_Rect r;
            r.w = ((std::rand() % 5) + 1) * 10;
            r.h = ((std::rand() % 5) + 1) * 10;
            r.x = std::rand() % (screen->w - r.w);
            r.y = std::rand() % (screen->h - r.h);
            SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 0xff * ((i % 3) == 0), 0xff * ((i % 3) == 1), 0xff * ((i % 3) == 2)));
        }
        
        SDL_Flip(screen);
    }

    SDL_Surface *copy = SDL_DisplayFormat(screen);
    if(!copy)
    {
        std::cerr << "Failed to copy surface: " << SDL_GetError() << '\n';
        return 1; 
    }
    
    if(SDL_SaveBMP(copy, "out.bmp") != 0)
    {
        std::cerr << "Failed to save output: " << SDL_GetError() << '\n';
        return 1;
    }
    
    std::cout << "Success!\n";
    return 0;
}
Works for meTM.

#15 Rafael Toledo   Members   

100
Like
0Likes
Like

Posted 22 August 2011 - 11:13 AM

I deleted all my code, and started again. It worked... Posted Image
I used SDL_DisplayFormat to convert the screen to another surface.

Thanks guys




Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.