Skip to main content
GameDev.net gamedev.net
🔒 Locked

Sending a SDL_Surface*

Started by ixuz Feb 8, 2010 at 7:01 PM 7 replies 3.2k views
Original Post
ixuz
ixuz
Hi, I'm having problem with sending a SDL_Surface through winsock. This works fine.

// Load an image to a surface
SDL_Surface* image = sdl.loadImage("image.png");

// Convert the SDL_Surface* to char*
char* data = (char*)image;

// Convert the char back to SDL_Surface*
SDL_Surface* image2 = (SDL_Surface*)data;

// Draw the image to screen
sdl.drawImage(image2,0,0);
But when I'm trying the send the char* over the network and convert it back to SDL_Surface* it just won't work. :S What am I doing wrong? // ixuz
Servant of the Lord
Servant of the Lord
Here's the definition of SDL_Surface from the SDL documentation:
typedef struct SDL_Surface {   2     Uint32 flags;                           /* Read-only */   3     SDL_PixelFormat *format;                /* Read-only */   4     int w, h;                               /* Read-only */   5     Uint16 pitch;                           /* Read-only */   6     void *pixels;                           /* Read-write */   7     SDL_Rect clip_rect;                     /* Read-only */   8     int refcount;                           /* Read-mostly */   9   10   /* This structure also contains private fields not shown here */  11 } SDL_Surface;
A pointer points to a location in memory, right? A point to a location in your computer's memory. So sending a pointer to another computer, doesn't make the data at that point on that computer, the same as the data in your computer.

Even if you send the SDL_Surface (and not just the SDL_Surface pointer) over the 'net, the SDL_Surface itself contains pointers (format, which itself contains even more pointers, and also pixels). You have to get the data from the individual pointers in the struct (and member structs (meaning format)) yourself, and then send them over, and then put them back together (Easy enough to do).

However, it'd be better if you just sent the pixels and width/height/pitch over (and anything else you need), and have SDL create a new surface from that same data on the other side, using SDL_CreateRGBSurfaceFrom, because some parts of the SDL_Surface is used by SDL to manage the surface on your computer, and would need to change the information for another computer.
ixuz
ixuz
Okay, then I'll try that!
Thank you for your extremly fast reply!!!
ixuz
ixuz
Nice it worked out, I can now transfer SDL_Surfaces.

But there is another problem that occured. I'm having problem allocating memory for all the pixels I'm going to send. I tried to allocate:
unsigned int pixels[640*480]

But my program crashes, I guess I can't allocate that much memory so I tried a lower resolution:

unsigned int pixels[320*240]

Which worked well.

Is it possible to allocate an array with the size: unsigned int pixels[640*480]?
Thanks for all the help I've gotten so far! <3
// ixuz
Deranged
Deranged
Try allocating the memory on the heap with unsigned int * pixels = new unsigned int[640 * 480];. But don't forget to clean up after yourself with delete.
hplus0603
hplus0603
640*480*4 bytes isn't that much. Many programs do much more than that.

However, if "your program crashes," what you should do is bring it up in the debugger, and step through it to figure out *why* it crashes. That will probably teach you more than just trying to make the image smaller.

Finally, why are you transferring the decompressed data? Wouldn't it be more efficient to transfer the PNG data itself, and decompress it on the other end? Or, even better, pre-install the necessary images as part of an installer, and just transfer the name of the image?
enum Bool { True, False, FileNotFound };
ixuz
ixuz
Well, I'm trying to make a stream for a little project.

I'm not that sure how to send the whole .png, thank you for the information about allocating more than 320*240 arrayspots.

About the sending of the image, I use SDL to read the .png into my c++ program. When I tried to send the loaded png in the form of a SDL_Surface* I ran into problems. The SDL_Surface* uses pointers to memory locations at my own computer, so that's why I copied the neccessary data from the SDL_Surface* and sent over the network.

But how do I use the debugger to find out why it crashes and tips on how I send the .png directly?

And a little off topic, is there a way to get the pixel data from a "PBITMAPINFO pBitmapInfo"?

thanks in advance
// ixuz

[Edited by - ixuz on February 10, 2010 4:11:57 PM]
Antheus
Antheus
Quote:
Original post by ixuz

I'm not that sure how to send the whole .png


Load the png into buffer, into something like this:
char * ibuffer;size_t filesize;


Send this over network.

On other side, after receiving the data, make a new surface from memory source:
SDL_RWops * rw = SDL_RWFromMem(buffer, filesize);SDL_Surface * sfc = SDL_LoadPNG_RW(rw, 0);
hplus0603
hplus0603
Quote:
But how do I use the debugger to find out why it crashes and tips on how I send the .png directly?


By reading the manual and tutorials that came with your development environment.
Here's an example.
enum Bool { True, False, FileNotFound };

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.