Sign in to follow this  
fmwyso

SDL_BlitSurface alternative?

Recommended Posts

Hey, I am using the template for NeHe's NEW tutorial to draw things and mess around with OpenGL / SDL to try and become more familiar with both :P. I'm trying to use SDL_BlitSurface with my SDL_Surface, but I am unable to get it working... I am not posting this in the NeHe's tutorial code because I'm just so sure there HAS to be an easier function to use that meets my requirements... - Displays SDL_Surface. - Shows the whole surface completely - Able to be drawn at programmatically controlled x, y coordinates. - My SDL_Surface is drawn by using SDL_Image to load a .png file, I need the transparent parts in the .png to be transparent in-game as well. - If possible, I'd like to be able to set an AlphaBlend value for the overall image (Not just the transparent part only). If SDL_BlitSurface is the only way to meet my requirements then can someone please help me with trying to understand the function (Most importantly, why it needs to have the screen and why it needs two SDL_Rects)? Also, I need someone to tell me how I can get the screen variable usable in the draw function in the NeHe's template code for Code::Blocks. Link: http://nehe.gamedev.net/wiki/NewLesson1.ashx Also, if SDL_BlitSurface is the only way... Could someone tell me if it is possible to make it be drawn with transparency? As in, an overall Alpha Blend value for the surface? If so, please tell me how ^_^. I am new to SDL / OpenGL and sort of new to C / C++... Please explain yourself as much as possible :D.

Share this post


Link to post
Share on other sites
If you are using SDL_OPENGL as a flag for SDL_SetVideoMode(), you cannot use any SDL functions that interact with the screen. You can use SDL to load a file and help upload it to an OpenGL texture.

You can find some examples of how to do this in the SDL tests, for example here.

Share this post


Link to post
Share on other sites
Quote:
Original post by fmwyso
Most importantly, why it needs to have the screen and why it needs two SDL_Rects

SDL_BlitSurface works by taking a source surface, a rectangle that marks which area we want to blit, the destination surface, and the rectangle that marks where we want to blit the source surface.

So for example, lets say I have an 8x8 surface but I only want to use the top left 2x2 portion of it (like if it were a sprite sheet). Thats where the first rectangle comes in, when you set its w&h to 2 and its x&y to 0, you'd be effectively selecting the 2x2 portion you wanted.
Same for the other surface and rectangle, if i want to place it in the middle of the second surface I'd make a the second rectangle w&h = 2 and x = w/2 and y = h/2 (this will be offset a little since im not taking into account the w&h of the image we're blitting).

That way, you are selecting the exact part of the original surface you want and placing it in the exact part of the destination surface you want. If you send 0 for either surface then you're selecting the whole surface:
SDL_BlitSurface( pRect1, 0, pRect2, 0); blits all the first surface on to all the second surface

You need the screen because thats the surface you want to blit to.

Hope this helps =]

Share this post


Link to post
Share on other sites
The blit thing makes more sense now and thank you, I was totally confused as to what it was and at least now I understand why it is so confusing :P.

I'm going to go ahead and make a new question in this post (I don't wanna spam too many threads ><)...

I looked up the Surface to texture code and found this which sounds like it is the most solid one for me... (I found it from here: http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL). I took off the bit checks and a few other file checks because I didn't need them because my images are all the same bits / etc.

Now, everytime it loads, it runs and then stops and traces back to whatever line first uses the surface. Atm, it always stops at the if statement to check the bitsperpixel of the surface. But before I added that in, it kept stopping at the nOfColors = surface bytesperpixel line...

I'm assuming I created it wrongly or something? The file, "cursor.png", is in the folder of the .exe and I also tried doing the full directory to the file but that didn't work either... Any ideas what I'm doing wrong? ><


GLuint Surface2Texture()
{
SDL_Surface *surface = IMG_Load("cursor.png");
GLuint texture;
GLenum texture_format;
GLint nOfColors;
if(surface->format->BitsPerPixel = 4){
}
// get the number of channels in the SDL surface
nOfColors = surface->format->BytesPerPixel;
if (nOfColors == 4) // contains an alpha channel
{
if (surface->format->Rmask == 0x000000ff)
texture_format = GL_RGBA;
else
texture_format = GL_BGRA;
}
else if (nOfColors == 3) // no alpha channel
{
if (surface->format->Rmask == 0x000000ff)
texture_format = GL_RGB;
else
texture_format = GL_BGR;
}
// Have OpenGL generate a texture object handle for us
glGenTextures( 1, &texture );

// Bind the texture object
glBindTexture( GL_TEXTURE_2D, texture );

// Set the texture's stretching properties
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

// Edit the texture object's image data using the information SDL_Surface gives us
glTexImage2D( GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0,
texture_format, GL_UNSIGNED_BYTE, surface->pixels );

return texture;
}


-- Edited the code thing to display right... I was using CODE instead of code ><.

[Edited by - fmwyso on January 17, 2009 4:12:13 PM]

Share this post


Link to post
Share on other sites
BBCode: [ code]

Quote:
Original post by fmwyso


GLuint Surface2Texture()
{
SDL_Surface *surface = IMG_Load("cursor.png");
GLuint texture;
GLenum texture_format;
GLint nOfColors;
if(surface->format->BitsPerPixel = 4){
}
// get the number of channels in the SDL surface
nOfColors = surface->format->BytesPerPixel;
if (nOfColors == 4) // contains an alpha channel
{
if (surface->format->Rmask == 0x000000ff)
texture_format = GL_RGBA;
else
texture_format = GL_BGRA;
}
else if (nOfColors == 3) // no alpha channel
{
if (surface->format->Rmask == 0x000000ff)
texture_format = GL_RGB;
else
texture_format = GL_BGR;
}
// Have OpenGL generate a texture object handle for us
glGenTextures( 1, &texture );

// Bind the texture object
glBindTexture( GL_TEXTURE_2D, texture );

// Set the texture's stretching properties
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

// Edit the texture object's image data using the information SDL_Surface gives us
glTexImage2D( GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0,
texture_format, GL_UNSIGNED_BYTE, surface->pixels );

return texture;
}

Share this post


Link to post
Share on other sites
Check for errors using code like the following:

SDL_Surface *surface = IMG_Load("cursor.png");

if(!surface)
{
// an error occurred.
// use the function SDL_GetError() to find out what went wrong.

// you could throw an exception or return an error code
}

Share this post


Link to post
Share on other sites
I added that code and it kept seeing that there was an error... I added the full path this time and then removed the if statement and now it doesn't have any errors... I'm going to work on drawing it now, thanks for the help everyone :D.

-- Another Edit --

There aren't any errors now and I can draw the image on the screen... The only problem is that the image is completely black for some reason... Does anyone know why it would make the image (texture) completely black?

By the way, I've used several different functions to try and convert it and am currently using this function that krumms "updated" from luke's code.

http://www.gamedev.net/community/forums/topic.asp?topic_id=184477

I also tried luke's code and others by the way, still makes a black texture... Also, I'm using this to draw my texture...


glBindTexture( GL_TEXTURE_2D, cursor );

glBegin( GL_QUADS );
//Top-left vertex (corner)
glTexCoord2i( 0, 0 );
glVertex2i(NeHe::Lesson::mouse_x ,NeHe::Lesson::mouse_y);

//Bottom-left vertex (corner)
glTexCoord2i( 1, 0 );
glVertex2i( NeHe::Lesson::mouse_x, NeHe::Lesson::mouse_y - 32);

//Bottom-right vertex (corner)
glTexCoord2i( 1, 1 );
glVertex2i( NeHe::Lesson::mouse_x + 32, NeHe::Lesson::mouse_y - 32);

//Top-right vertex (corner)
glTexCoord2i( 0, 1 );
glVertex2i( NeHe::Lesson::mouse_x + 32, NeHe::Lesson::mouse_y);
glEnd();


cursor is the texture by the way :P.

[Edited by - fmwyso on January 17, 2009 7:53:39 PM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this