PDA

View Full Version : Drawing part of SDL surface to OpenGL texture?



Christian Knudsen
25-06-2009, 06:45 PM
The standard SDL blitting has become too slow for the game I'm currently programming, so I've looked into using OpenGL for drawing to the screen. I've managed to make a texture out of an SDL surface (a .png sprite map) and I've also figured out how to draw this texture to the screen with alpha channel and everything. However, as the SDL surface is a sprite map, I don't want to draw the entire texture to the screen. How do I draw only the part of it that contains the relevant sprite?

I'm using this to draw the texture to the screen:



glBegin( GL_QUADS );
//Top-left vertex (corner)
glTexCoord2i( 0, 0 );
glVertex3f( 0, 0, 0.0 );

//Bottom-left vertex (corner)
glTexCoord2i( 1, 0 );
glVertex3f( 512, 0, 0 );

//Bottom-right vertex (corner)
glTexCoord2i( 1, 1 );
glVertex3f( 512, 512, 0 );

//Top-right vertex (corner)
glTexCoord2i( 0, 1 );
glVertex3f( 0, 512, 0 );
glEnd();
SDL_GL_SwapBuffers();


If I change any of these values, it just magnifies or shrinks the texture, which makes sense. I was thinking that I can just load the SDL surface spritemap into multiple textures, each holding a separate sprite, but then the textures wouldn't be a power of 2 size. So, how do I go about using my spritmap?

chronozphere
25-06-2009, 09:14 PM
Try using glTexCoord2f() instead of glTexCoord2i() and give them value's between 0.0 and 1.0. Like this:


glBegin( GL_QUADS );
//Top-left vertex (corner)
glTexCoord2f( 0, 0 );
glVertex3f( 0, 0, 0.0 );

//Bottom-left vertex (corner)
glTexCoord2f( 0.25, 0 );
glVertex3f( 512, 0, 0 );

//Bottom-right vertex (corner)
glTexCoord2f( 0.25, 0.25 );
glVertex3f( 512, 512, 0 );

//Top-right vertex (corner)
glTexCoord2f( 0, 0.25 );
glVertex3f( 0, 512, 0 );
glEnd();
SDL_GL_SwapBuffers();


This should display 1/4th of the texture. Hope this helps. :)

Christian Knudsen
25-06-2009, 09:54 PM
That certainly makes it possible for spritemaps with only a few sprites and where the pixel coordinates of the sprites can be converted to simple decimal points. But I have spritemaps with lots of sprites of various sizes on them and it would be a mess to calculate the decimal values for their positions. Isn't it possible to use the exact pixel coordinates instead, like it is when blitting with SDL? It would definitely make things a lot easier...

WILL
26-06-2009, 01:35 AM
I use JEDI-SDL with OpenGL for my graphics myself and what I do is make a small function to do these calculations for me. Then I make individual functions for grabbing my segment of texture using simple x,y co-ordinates.

The trick is to make functions that will do all the labour intensive stuff for you. ;)

chronozphere
26-06-2009, 06:18 AM
It's just:


TTextureTile = record
u1, v1, u2, v2: Single;
end;

TSpriteTile = record
x, y, width, height: Integer;
end;

function SpriteTileToTextureTile(ST: TSpriteTile; fTexWidth, fTexHeight: Integer): TTextureTile;
begin
Result.u1 := ST.x / fTexWidth;
Result.v1 := ST.y / fTexHeight;
Result.u2 := (ST.x + ST.width) / fTexWidth;
Result.v2 := (ST.y + ST.height) / fTexHeight;
end;


Then just pass the data in TTextureTile to openGL and you're done.


var TT: TTextureTile;

....

glTexCoord2f( TT.u1, TT.v1 );
glVertex3f( 0, 0, 0.0 );

glTexCoord2f( TT.u2, TT.v1 );
glVertex3f( 512, 0, 0 );

glTexCoord2f( TT.u2, TT.v2 );
glVertex3f( 512, 512, 0 );

glTexCoord2f( TT.u1, TT.v2 );
glVertex3f( 0, 512, 0 );


Hope this helps. :)

Christian Knudsen
26-06-2009, 08:17 AM
It sure did. I'll try it out. Thanks to both of you! :)