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( 1, @FGLImage );
glGenTextures(1, @FGLImage);
glBindTexture(GL_TEXTURE_2D, FGLImage);
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, SDL_Image^.w, SDL_Image^.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, SDL_Image^.pixels );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
if SDL_MustLock(SDL_Image) then
SDL_UnlockSurface(SDL_Image);
end;
OpenGL Drawing code:
procedure SDL_GL_BlitSurface(SrcRect, DstRect: PSDL_Rect; imgWidth, imgHeight : Integer; Texture: GluInt);
var
textTop, textLeft, textBottom, textRight, scaleX, scaleY : Single;
begin
textTop := SrcRect^.Y/imgHeight;
textLeft := SrcRect^.X/imgWidth;
textBottom := (SrcRect^.Y+SrcRect^.H)/imgHeight;
textRight := (SrcRect^.X+SrcRect^.W)/imgWidth;
scaleX := DstRect^.w / SrcRect^.w;
scaleY := DstRect^.h / SrcRect^.h;
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
glBindTexture(GL_TEXTURE_2D, Texture);
glEnable(GL_DEPTH_TEST); // Enable Depth Testing
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Enable Alpha Blending (disable alpha testing)
glEnable(GL_BLEND); // Enable Blending (disable alpha testing)
glColor3f(1, 1, 1);
BeginOrtho;
glPushMatrix;
// Move to the destination
glTranslatef(DstRect^.X, DstRect^.Y, 0);
// Get the actual tile
glBegin(GL_QUADS);
// Top-left vertex (corner)
glTexCoord2f( textLeft, textTop );
glVertex2f( 0, 0 );
// Bottom-left vertex (corner)
glTexCoord2f( textLeft, textBottom );
glVertex2f( 0, DstRect^.H*scaleY );
// Bottom-right vertex (corner)
glTexCoord2f( textRight, textBottom );
glVertex2f( DstRect^.W*scaleX, DstRect^.H*scaleY );
// Top-right vertex (corner)
glTexCoord2f( textRight, textTop );
glVertex2f( DstRect^.W*scaleX, 0 );
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?
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( 1, @FGLImage );
glGenTextures(1, @FGLImage);
glBindTexture(GL_TEXTURE_2D, FGLImage);
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, SDL_Image^.w, SDL_Image^.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, SDL_Image^.pixels );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
if SDL_MustLock(SDL_Image) then
SDL_UnlockSurface(SDL_Image);
end;
OpenGL Drawing code:
procedure SDL_GL_BlitSurface(SrcRect, DstRect: PSDL_Rect; imgWidth, imgHeight : Integer; Texture: GluInt);
var
textTop, textLeft, textBottom, textRight, scaleX, scaleY : Single;
begin
textTop := SrcRect^.Y/imgHeight;
textLeft := SrcRect^.X/imgWidth;
textBottom := (SrcRect^.Y+SrcRect^.H)/imgHeight;
textRight := (SrcRect^.X+SrcRect^.W)/imgWidth;
scaleX := DstRect^.w / SrcRect^.w;
scaleY := DstRect^.h / SrcRect^.h;
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
glBindTexture(GL_TEXTURE_2D, Texture);
glEnable(GL_DEPTH_TEST); // Enable Depth Testing
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Enable Alpha Blending (disable alpha testing)
glEnable(GL_BLEND); // Enable Blending (disable alpha testing)
glColor3f(1, 1, 1);
BeginOrtho;
glPushMatrix;
// Move to the destination
glTranslatef(DstRect^.X, DstRect^.Y, 0);
// Get the actual tile
glBegin(GL_QUADS);
// Top-left vertex (corner)
glTexCoord2f( textLeft, textTop );
glVertex2f( 0, 0 );
// Bottom-left vertex (corner)
glTexCoord2f( textLeft, textBottom );
glVertex2f( 0, DstRect^.H*scaleY );
// Bottom-right vertex (corner)
glTexCoord2f( textRight, textBottom );
glVertex2f( DstRect^.W*scaleX, DstRect^.H*scaleY );
// Top-right vertex (corner)
glTexCoord2f( textRight, textTop );
glVertex2f( DstRect^.W*scaleX, 0 );
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?