Archived

This topic is now archived and is closed to further replies.

clapton

SDL_Surface

Recommended Posts

Hi! I use SDL_Image for loading SDL_Surfaces. Unfortunately all my images seem to be 8 bit only. What''s wrong. I''ve setup the display mode correctly. Thanks for any advice! _____ ... you got me on my knees, Layla

Share this post


Link to post
Share on other sites
I'd like yo help you, but you don't provide much informations. Do you mind posting some code ? like the SDL_SetVideoMode() part and IMG_Load() part ?

Also, are you sure the files you are loading aren't 8 bit ? because if it's the case, setting the video mode to any color depth won't change a thing.

Sorry if it doesn't help you, but I can't think of anything else at the moment

Matt

edit: there was a second 'and' between SDL_SetVideoMode() and IMG_Load()

[edited by - lemurion on March 30, 2004 12:02:48 PM]

Share this post


Link to post
Share on other sites
If you specify your screen surface to only have 8 bpp then try and display a 32 bpp image then it will look extremely crappy. If your using 8 bit images then make sure your screen surface is at least 8 bbp resolution, otherwise make sure you are matching the resolution of your images to the resolution of your screen surface,.

Share this post


Link to post
Share on other sites
Thanks for your replies! It''s great to find the people willing to help me. I''ve been thinking about the problem for a long time but my lack of knowledge about SDL didn''t let me solve it...

OK. Here I post the source code for functions which initialize the display and load an image. Probably, there is a lot of SDL stuff which is actually useless. I''d be thankful if you find any bugs and finally - if you help me solve this color-depth problem.


bool Engine::InitDisplay (string title, int width, int height, int bpp, bool fullscreen) {

Uint32 flags = 0;
int rgb_size[3];

if(!m_bInitialized) { // Initialize only once
// Init all the SDL stuff
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO) < 0) {
/* LOG */ Log.Send("Error : SDL not initialized!");
m_bDone = true;
return false; //return now, nothing else should be called
}
}

m_bFullscreen = fullscreen;

if(m_bFullscreen) flags |= SDL_FULLSCREEN; // Fullscreen?

// Check if we are choosing a correct bpp
if(bpp != -1 && bpp != 8 && bpp != 16 && bpp != 24 && bpp != 32)
{
/* LOG */ Log.Send("Error : invalid BPP (%d), must be 8,16,24 or 32, trying the best BPP.", bpp);
m_bDone = true;
return false;
}
else //this choosed correct BPP
{
if(bpp == -1) bpp = SDL_GetVideoInfo()->vfmt->BitsPerPixel; //Try desktop resolution

int ok;

ok = SDL_VideoModeOK(width, height, bpp, flags);

if(!ok) {
/* LOG */ Log.Send("Error : couldn''t set video %dx%dx%d", width, height, bpp);
m_bDone = true;
return false; //return now
}
}

m_BPP = bpp;

// Buffer sizes

switch (m_BPP)
{
case 8:
rgb_size[0] = 3;
rgb_size[1] = 3;
rgb_size[2] = 2;
break;
case 16:
rgb_size[0] = 5;
rgb_size[1] = 5;
rgb_size[2] = 6;
break;
default:
rgb_size[0] = 8;
rgb_size[1] = 8;
rgb_size[2] = 8;
break;
}

// Set key GL attributes

// RGB Colors
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, rgb_size[0]);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, rgb_size[1]);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, rgb_size[2]);

SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 8); // 8 bit depth buffer

SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, 0);

flags |= SDL_OPENGLBLIT | SDL_NOFRAME | SDL_DOUBLEBUF | SDL_HWSURFACE;

// Create SDL screen and update settings based on returned screen

m_Screen = SDL_SetVideoMode(width, height, bpp, flags);

if(!m_Screen)
{
/* LOG */ Log.Send("\n........ Error : failed to create screen''s surface");

m_bDone = true;
return false; // Too bad..
}

m_Width = width;
m_Height = height;
m_Title = title;

InitOpenGL(); // Initialize OpenGL setting for the engine

if (!SDL_GetVideoInfo()) { // Check once again if everything is correct
/* LOG */ Log.Send("Error : couldn''t obtain video info.");
return false;
}

m_bInitialized = true; //If it makes it to the end it has been initialized
m_bPaused = false;
m_bDone = false;

/* LOG */ Log.Send("Video mode initialized : %dx%dx%d Fullscreen : %d", width, height, bpp, fullscreen);

return true; // Everything went pretty well! :D
}

bool tImage::OpenFromFile(string filename) {

// Function that creates an image based on a graphics file
// Formats supported : BMP, PNM, XPM, XCF, PCX, GIF, JPG, PNG, TIF, LBM

SDL_Surface *Surface;

Release(); // Clean everything up

Surface = IMG_Load(filename.c_str());

/* LOG */ Log.Send("Loading image : %s", filename.c_str() );

m_FileName = filename;

if(!Surface) {
/* LOG */ Log.Send("....Error : couldn''t load image from %s", filename.c_str);
return false;
}

bool flag;

flag = OpenFromSurface(Surface, 0, 0, Surface->w, Surface->h);

TC.FreeImage (Surface); // We don''t need that any more

return flag; // Woow! Everything OK.
}

bool tImage::OpenFromSurface(SDL_Surface *SrcSurface, int x, int y, int w, int h) {

// The function opens our beautiful image from SDL_Surface. It copies
// pixel data from a specified surface

SDL_Rect rect;
SDL_Surface *Surface;
SDL_Surface *screen;

rect.x = x;
rect.y = y;
rect.w = w;
rect.h = h;

Surface = SDL_CreateRGBSurface(SDL_HWSURFACE | SDL_SRCCOLORKEY | SDL_SRCALPHA, rect.w, rect.h, 32 /*SrcSurface->format->BitsPerPixel*/,
screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);

// Transparency
unsigned long int key = SrcSurface->format->colorkey;

SDL_SetAlpha(SrcSurface, SDL_SRCALPHA, 255);
SDL_SetColorKey(SrcSurface, SDL_SRCCOLORKEY, SDL_MapRGB(Surface->format,
m_TransparencyRGB[0], m_TransparencyRGB[1], m_TransparencyRGB[2]) );

SDL_BlitSurface(SrcSurface,&rect,Surface,NULL);

SrcSurface->format->colorkey = key;

// Surface conversion

SDL_Surface *temp = Surface;

Surface = SDL_DisplayFormatAlpha(temp);

if(Surface) {
// TC.FreeImage(temp);
} else {
// Can''t convert
/* LOG */ Log.Send("....Error : couldn''t convert image!");
Surface = temp;
}

if (Surface)
{
m_Image = Surface; // Assing the surface
ReloadTexture(); // Now let OpenGL cope with THE THING
} else {
/* LOG */ Log.Send("....Error : image''s loading failed!");
return false;
}

// We are not attached

m_pSrcImage = NULL;

// Assing class'' members

m_RegionX = 0;
m_RegionY = 0;
m_RegionWidth = m_Image->w;
m_RegionHeight = m_Image->h;

Log.Send("....Image succesfully created!");

return true;
}


Also, there is something totally messed up with transparency. You see - the rendering part is taken by OpenGL. SDL is used to load images only - not to display them. I just want to use SDL functions to create an RGBA data which is then used to create OpenGL textures.

GREEEAAT THANX!

------------------

... you got me on my knees, Layla

Share this post


Link to post
Share on other sites
If you just want to load images, why not use DevIL?

You have a small bug where you use c_str instead of c_str(), but that''s irrelevant.

I can''t see any obvious mistakes but there''s too much code for now. Are you absolutely sure your input file is in the correct format? And how do you know your images are 8 bit only - where''s the proof or symptoms of this?

[ MSVC Fixes | STL Docs | SDL | Game AI | Sockets | C++ Faq Lite | Boost
Asking Questions | Organising code files | My stuff | Tiny XML | STLPort]

Share this post


Link to post
Share on other sites
Hi! Thanks for your help. Let''s get straight into explenations...

quote:

I can''t see any obvious mistakes but there''s too much code for now. Are you absolutely sure your input file is in the correct format? And how do you know your images are 8 bit only - where''s the proof or symptoms of this?


Yeah, I am 100% sure that my images are 32 bit (some are 24). Anyway - I found something which might be helpful. A kind of a tip - do you see a line in OpenFromSurface(...) where there is a call to SDL_DisplayFormatAlpha ? I remember that once I made something somewhere around it (I know it sounds silly) and suddenlly the images became 32 bit but the colors where messed up. Doesn''t make things clearer a bit?

Bye, thanx!

-----------




... you got me on my knees, Layla

Share this post


Link to post
Share on other sites
Well, if i''m not mistaken, doing

SDL_Surface *temp = Surface;
Surface = SDL_DisplayFormatAlpha(temp);
//is the same as

Surface = SDL_DisplayFormatAlpha(Surface);
// because temp is pointing at the same memory location as Surface


// what you should do is:

SDL_Surface *temp;
temp = SDL_DisplayFormatAlpha(Surface);
// and then use temp

// or you can use temp before this line and do

SDL_Surface *Surface;
Surface = SDL_DisplayFormatAlpha(temp);


hope that helps !
Matt

PS: Yippy ! my 100th post !

Share this post


Link to post
Share on other sites
Ehh... It''s still not what I''ve been looking for. :/

Do you have any idea why do I get these 8 bit images??

Thx

----

... you got me on my knees, Layla

Share this post


Link to post
Share on other sites