Jump to content

  • Log In with Google      Sign In   
  • Create Account


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


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   -  Reputation: 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?

Sponsor:

#2 rip-off   Moderators   -  Reputation: 7651

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   -  Reputation: 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   -  Reputation: 552

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   -  Reputation: 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   -  Reputation: 7651

Like
0Likes
Like

Posted 22 August 2011 - 08:15 AM

You aren't checking for errors in that code.

#7 Rafael Toledo   Members   -  Reputation: 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   -  Reputation: 552

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   -  Reputation: 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   -  Reputation: 7651

Like
0Likes
Like

Posted 22 August 2011 - 08:40 AM

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

#11 Wooh   Members   -  Reputation: 552

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   -  Reputation: 100

Like
0Likes
Like

Posted 22 August 2011 - 08:46 AM

SDL_BlitSurface is returning 0 (success)...

#13 Wooh   Members   -  Reputation: 552

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   -  Reputation: 7651

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   -  Reputation: 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.



PARTNERS