View Full Version : [SOLVED] SDL surfaces...
pjpdev
14-11-2009, 01:05 PM
For PJPlib's graphics core I need to be able to get various data from the surfaces. But PSDL_Surface can't give me stuff like width, height and format. I need to use TSDL_Surface instead, but then I can't load images into it because the loading routines of JEDI-SDL return pointers.
For PJPlib I've decided to use OpenGL for graphics rendering, so I need to be able to convert the PSDL_Surface data to OpenGL textures.
Can any pointer-guru help me out here please?
Thanks in advance.
Stoney
14-11-2009, 08:30 PM
For PJPlib's graphics core I need to be able to get various data from the surfaces. But PSDL_Surface can't give me stuff like width, height and format. I need to use TSDL_Surface instead, but then I can't load images into it because the loading routines of JEDI-SDL return pointers.
After you've called a loading routine and assuming that the image has been loaded correctly, you can get the width of the surface with MySDL_Surface^.w and the height with MySDL_Surface^.h. (var MySDL_Surface: PSDL_Surface should be declared somewhere in your code.) As far as I know w and h are read-only, so don't try to change the values.
For PJPlib I've decided to use OpenGL for graphics rendering, so I need to be able to convert the PSDL_Surface data to OpenGL textures.
Basically you just need to write your own texture loader or use an existing one. :)
For example to convert a SDL_Surface into a texture to be used with OpenGL, you can use this little function (it also scales the surfaces that are not power of 2):
function CreateTexture(SDL_Surface: PSDL_Surface): Integer;
var Texture: TGLuInt;
Begin
Result := -1;
if Assigned(SDL_Surface) then
begin
glGenTextures(1, @Texture);
glBindTexture(GL_TEXTURE_2D, Texture);
if SDL_Surface.format.BytesPerPixel > 3 then glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SDL_Surface^.w, SDL_Surface^.h,0, GL_RGBA, GL_UNSIGNED_BYTE, SDL_Surface^.pixels)
else glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SDL_Surface^.w, SDL_Surface^.h,0, GL_RGB, GL_UNSIGNED_BYTE, SDL_Surface^.pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if SDL_Surface.format.BytesPerPixel > 3 then gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, SDL_Surface^.w, SDL_Surface^.h, GL_RGBA, GL_UNSIGNED_BYTE, SDL_Surface^.pixels)
else gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, SDL_Surface^.w, SDL_Surface^.h, GL_RGB, GL_UNSIGNED_BYTE, SDL_Surface^.pixels);
SDL_FreeSurface(SDL_Surface);
Result := Texture;
end;
End;
...
var
MyTexture: GLuInt;
MySDL_Surface: PSDL_Surface;
begin
// SDL init and OpenGL init
glEnable(GL_TEXTURE_2D);
MySDL_Surface := IMG_Load(...);
MyTexture := CreateTexture(MySDL_Surface);
// Game Loop
while ... do
begin
glBindTexture(GL_TEXTURE_2D, Texture);
// Draw quad here
end;
end.
Alternatively, you can the easySDL texture loader from DelphiGL:
http://svn.delphigl.com/websvn/filedetails.php?repname=dglsdk_linux&path=%2Ftrunk%2Fheader%2FeasySDLTextures.pas&rev=174
pjpdev
15-11-2009, 08:43 AM
Thanks Stoney, it helped a lot.
pjpdev
15-11-2009, 11:44 AM
Now I just get a blank quad... I tried figuring it out, but it just won't work.
Here's my image loading code:
function TPJPImage.LoadImage(filename: PChar): Boolean;
var
surface: PSDL_Surface;
nOfColors: GLint;
begin
//Load the texture into memory
surface := IMG_Load(filename);
if (surface = nil) then
begin
Result := False;
Exit;
end;
//Process the surface
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glGenTextures(1, @texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R, GL_NEAREST);
nOfColors := surface^.format^.BitsPerPixel;
if (nOfColors = 4) then //Texture has alpha channel
begin
glTexImage2D(GL_TEXTURE_2D, 0, 4, surface^.w, surface^.h, 0, GL_RGBA,
GL_UNSIGNED_BYTE, surface^.pixels);
gluBuild2DMipmaps(GL_TEXTURE_2D, 4, surface^.w, surface^.h, GL_RGBA,
GL_UNSIGNED_BYTE, surface^.pixels);
end
else if (nOfColors = 3) then //No alpha channel
begin
glTexImage2D(GL_TEXTURE_2D, 0, 3, surface^.w, surface^.h, 0, GL_RGB,
GL_UNSIGNED_BYTE, surface^.pixels);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, surface^.w, surface^.h, GL_RGB,
GL_UNSIGNED_BYTE, surface^.pixels);
end;
fWidth := surface^.w;
fHeight := surface^.h;
SDL_FreeSurface(surface);
Result := True;
end;
The texture variable belongs to the TPJPImage class and is a GLuint.
pjpdev
15-11-2009, 11:49 AM
Oh... never mind. I used BitsPerPixel instead of BytesPerPixel :-[
Problem solved.
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.