PDA

View Full Version : SDL_AllocSurface and OpenGL textures



jdarling
25-01-2007, 07:17 PM
I'm having a problem with using SDL_AllocSurface and OpenGL at the same time. Basically, I create a blank image with SDL_AllocSurface, then draw another SDL surface to it, finally I convert my new surface to an OpenGL texture. The use that texture from here out to draw with. Problem is, the new OpenGL texture doesn't render.

I'm copy/pasting between multiple functions to get the idea, so hopefully I didn't make any major mistakes.

Loading Code:


procedure TImage.LoadFromFile(AFileName : AnsiString);
var
tmp : PSDL_Surface;
r : TSDL_Rect;
begin
if assigned(SDL_Image) then
SDL_FreeSurface(SDL_Image);
tmp := IMG_Load(PChar(AFileName));
SDL_Image := SDL_AllocSurface( SDL_SWSURFACE, NextPow2(tmp^.w), NextPow2(tmp^.h),
Screen^.format^.BitsPerPixel,
Screen^.format^.RMask, Screen^.format^.GMask,
Screen^.format^.BMask, Screen^.format^.AMask);
r.x := 0;
r.y := 0;
r.h := tmp^.h;
r.w := tmp^.w;
SDL_BlitSurface( tmp, @r, SDL_Image, @r);
SDL_FreeSurface(tmp);
if SDL_MustLock(SDL_Image) then
SDL_LockSurface(SDL_Image);
if FGLImage <> 0 then
glDeleteTextures&#40; 1, @FGLImage &#41;;
glGenTextures&#40;1, @FGLImage&#41;;
glBindTexture&#40;GL_TEXTURE_2D, FGLImage&#41;;
glTexImage2D&#40; GL_TEXTURE_2D, 0, GL_RGBA, SDL_Image^.w, SDL_Image^.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, SDL_Image^.pixels &#41;;
glTexParameteri&#40; GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP &#41;;
glTexParameteri&#40; GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP &#41;;
glTexParameteri&#40; GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR &#41;;
glTexParameteri&#40; GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR &#41;;
if SDL_MustLock&#40;SDL_Image&#41; then
SDL_UnlockSurface&#40;SDL_Image&#41;;
end;


OpenGL Drawing code:


procedure SDL_GL_BlitSurface&#40;SrcRect, DstRect&#58; PSDL_Rect; imgWidth, imgHeight &#58; Integer; Texture&#58; GluInt&#41;;
var
textTop, textLeft, textBottom, textRight, scaleX, scaleY &#58; Single;
begin
textTop &#58;= SrcRect^.Y/imgHeight;
textLeft &#58;= SrcRect^.X/imgWidth;
textBottom &#58;= &#40;SrcRect^.Y+SrcRect^.H&#41;/imgHeight;
textRight &#58;= &#40;SrcRect^.X+SrcRect^.W&#41;/imgWidth;

scaleX &#58;= DstRect^.w / SrcRect^.w;
scaleY &#58;= DstRect^.h / SrcRect^.h;

glEnable&#40;GL_TEXTURE_2D&#41;; // Enable Texture Mapping
glBindTexture&#40;GL_TEXTURE_2D, Texture&#41;;
glEnable&#40;GL_DEPTH_TEST&#41;; // Enable Depth Testing
glBlendFunc&#40;GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA&#41;; // Enable Alpha Blending &#40;disable alpha testing&#41;
glEnable&#40;GL_BLEND&#41;; // Enable Blending &#40;disable alpha testing&#41;

glColor3f&#40;1, 1, 1&#41;;

BeginOrtho;
glPushMatrix;
// Move to the destination
glTranslatef&#40;DstRect^.X, DstRect^.Y, 0&#41;;

// Get the actual tile
glBegin&#40;GL_QUADS&#41;;
// Top-left vertex &#40;corner&#41;
glTexCoord2f&#40; textLeft, textTop &#41;;
glVertex2f&#40; 0, 0 &#41;;

// Bottom-left vertex &#40;corner&#41;
glTexCoord2f&#40; textLeft, textBottom &#41;;
glVertex2f&#40; 0, DstRect^.H*scaleY &#41;;

// Bottom-right vertex &#40;corner&#41;
glTexCoord2f&#40; textRight, textBottom &#41;;
glVertex2f&#40; DstRect^.W*scaleX, DstRect^.H*scaleY &#41;;

// Top-right vertex &#40;corner&#41;
glTexCoord2f&#40; textRight, textTop &#41;;
glVertex2f&#40; DstRect^.W*scaleX, 0 &#41;;
glEnd;
glPopMatrix;
EndOrtho;
end;


As I said, everything works, until I try and use the new OpenGL texture. In fact, if I do an SDL_SaveBMP(SDL_Image) it looks fine. I can also render the surface in pure SDL mode w/o any problems. Any ideas what I'm doing wrong?

grudzio
25-01-2007, 08:36 PM
Three things that come to my mind:
1. Before calling glTexImage convert surface to RGBA format.
2. Disable depth test in SDL_GL_Blit procedure.
3. The (0, 0) texture coordinate corresponds to bottom left corner of the texture. So textTop and textBottom should be


textTop &#58;= &#40;imgHeight - SrcRect^.Y&#41;/imgHeight;
textBottom &#58;= &#40;imgHeight - SrcRect^.Y+SrcRect^.H&#41;/imgHeight;