# HG changeset patch # User Wolfgang Steffens # Date 1340617660 -7200 # Node ID ad4b6c2b09e8d390e50610ae14d1758f22ebb5a9 # Parent 5d0704f23a2a0697a6ed50a01d2e9400ea4ba83c retaining SDL surfaces in order to allow recreating atlases from scratch without reading back textures from the GL diff -r 5d0704f23a2a -r ad4b6c2b09e8 hedgewars/options.inc --- a/hedgewars/options.inc Mon Jun 25 10:44:27 2012 +0200 +++ b/hedgewars/options.inc Mon Jun 25 11:47:40 2012 +0200 @@ -31,6 +31,7 @@ {$DEFINE GL2} +{$DEFINE RETAIN_SURFACES} {$IFDEF ANDROID} {$DEFINE MOBILE} diff -r 5d0704f23a2a -r ad4b6c2b09e8 hedgewars/uChat.pas --- a/hedgewars/uChat.pas Mon Jun 25 10:44:27 2012 +0200 +++ b/hedgewars/uChat.pas Mon Jun 25 11:47:40 2012 +0200 @@ -96,9 +96,7 @@ SDL_FreeSurface(strSurface); cl.Time:= RealTicks + 12500; -cl.Tex:= Surface2Tex(resSurface, false); - -SDL_FreeSurface(resSurface) +cl.Tex:= Surface2Atlas(resSurface, false); end; // For uStore texture recreation diff -r 5d0704f23a2a -r ad4b6c2b09e8 hedgewars/uRenderUtils.pas --- a/hedgewars/uRenderUtils.pas Mon Jun 25 10:44:27 2012 +0200 +++ b/hedgewars/uRenderUtils.pas Mon Jun 25 11:47:40 2012 +0200 @@ -272,9 +272,7 @@ TryDo(SDL_SetColorKey(finalSurface, SDL_SRCCOLORKEY, 0) = 0, errmsgTransparentSet, true); - RenderStringTexLim:= Surface2Tex(finalSurface, false); - - SDL_FreeSurface(finalSurface); + RenderStringTexLim:= Surface2Atlas(finalSurface, false); end; @@ -459,10 +457,9 @@ inc(pos); end; - RenderSpeechBubbleTex:= Surface2Tex(finalSurface, true); + RenderSpeechBubbleTex:= Surface2Atlas(finalSurface, true); SDL_FreeSurface(rotatedEdge); - SDL_FreeSurface(finalSurface); end; end. diff -r 5d0704f23a2a -r ad4b6c2b09e8 hedgewars/uScript.pas --- a/hedgewars/uScript.pas Mon Jun 25 10:44:27 2012 +0200 +++ b/hedgewars/uScript.pas Mon Jun 25 11:47:40 2012 +0200 @@ -738,8 +738,7 @@ DrawRoundRect(@rr, clan^.Color, clan^.Color, texsurf, false); FreeTexture(team^.HealthTex); - team^.HealthTex:= Surface2Tex(texsurf, false); - SDL_FreeSurface(texsurf); + team^.HealthTex:= Surface2Atlas(texsurf, false); MakeCrossHairs end end; diff -r 5d0704f23a2a -r ad4b6c2b09e8 hedgewars/uStore.pas --- a/hedgewars/uStore.pas Mon Jun 25 10:44:27 2012 +0200 +++ b/hedgewars/uStore.pas Mon Jun 25 11:47:40 2012 +0200 @@ -155,8 +155,7 @@ SDL_UnlockSurface(texsurf); FreeTexture(CrosshairTex); - CrosshairTex:= Surface2Tex(texsurf, false); - SDL_FreeSurface(texsurf) + CrosshairTex:= Surface2Atlas(texsurf, false); end; SDL_FreeSurface(tmpsurf) @@ -189,8 +188,7 @@ rr:= r; inc(rr.x, 2); dec(rr.w, 4); inc(rr.y, 2); dec(rr.h, 4); DrawRoundRect(@rr, Clan^.Color, Clan^.Color, texsurf, false); - HealthTex:= Surface2Tex(texsurf, false); - SDL_FreeSurface(texsurf); + HealthTex:= Surface2Atlas(texsurf, false); r.x:= 0; r.y:= 0; @@ -230,8 +228,7 @@ PLongwordArray(texsurf^.pixels)^[32 * 16 + 2]:= cNearBlackColor; PLongwordArray(texsurf^.pixels)^[32 * 16 + 23]:= cNearBlackColor; - FlagTex:= Surface2Tex(texsurf, false); - SDL_FreeSurface(texsurf); + FlagTex:= Surface2Atlas(texsurf, false); texsurf:= nil; AIKillsTex := RenderStringTex(inttostr(stats.AIKills), Clan^.Color, fnt16); @@ -263,8 +260,7 @@ r.w:= 28; r.h:= 28; DrawRoundRect(@r, cWhiteColor, cNearBlackColor, iconsurf, true); - ropeIconTex:= Surface2Tex(iconsurf, false); - SDL_FreeSurface(iconsurf); + ropeIconTex:= Surface2Atlas(iconsurf, false); iconsurf:= nil; end; end; @@ -299,8 +295,7 @@ texsurf:= LoadImage(UserPathz[ptGraves] + '/Statue', ifTransparent); if texsurf = nil then texsurf:= LoadImage(Pathz[ptGraves] + '/Statue', ifCritical or ifTransparent); - GraveTex:= Surface2Tex(texsurf, false); - SDL_FreeSurface(texsurf) + GraveTex:= Surface2Atlas(texsurf, false); end end; @@ -397,12 +392,12 @@ end; if (ii in [sprSky, sprSkyL, sprSkyR, sprHorizont, sprHorizontL, sprHorizontR]) then begin - Texture:= Surface2Tex(tmpsurf, true); + Texture:= Surface2Atlas(tmpsurf, true); Texture^.Scale:= 2 end else begin - Texture:= Surface2Tex(tmpsurf, false); + Texture:= Surface2Atlas(tmpsurf, false); // HACK: We should include some sprite attribute to define the texture wrap directions if ((ii = sprWater) or (ii = sprSDWater)) and ((cReducedQuality and (rq2DWater or rqClampLess)) = 0) then glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -416,8 +411,8 @@ {$ELSE} if saveSurf then Surface:= tmpsurf - else - SDL_FreeSurface(tmpsurf) + //else + // SDL_FreeSurface(tmpsurf) released by FreeTexture {$ENDIF} end end @@ -432,8 +427,7 @@ if tmpsurf = nil then tmpsurf:= LoadImage(Pathz[ptGraphics] + '/' + cHHFileName, ifAlpha or ifCritical or ifTransparent); -HHTexture:= Surface2Tex(tmpsurf, false); -SDL_FreeSurface(tmpsurf); +HHTexture:= Surface2Atlas(tmpsurf, false); InitHealth; @@ -453,8 +447,7 @@ TryDo(tmpsurf <> nil,'Name-texture creation for ammo type #' + intToStr(ord(ai)) + ' failed!',true); tmpsurf:= doSurfaceConversion(tmpsurf); FreeTexture(NameTex); - NameTex:= Surface2Tex(tmpsurf, false); - SDL_FreeSurface(tmpsurf) + NameTex:= Surface2Atlas(tmpsurf, false); end; // number of weapons in ammo menu @@ -463,8 +456,7 @@ tmpsurf:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(IntToStr(i) + 'x'), cWhiteColorChannels); tmpsurf:= doSurfaceConversion(tmpsurf); FreeTexture(CountTexz[i]); - CountTexz[i]:= Surface2Tex(tmpsurf, false); - SDL_FreeSurface(tmpsurf) + CountTexz[i]:= Surface2Atlas(tmpsurf, false); end; if not reload then @@ -616,10 +608,7 @@ FreeTexture(HHGear^.Hedgehog^.HatTex); // assign new hat to hedgehog - HHGear^.Hedgehog^.HatTex:= Surface2Tex(texsurf, true); - - // cleanup: free temporary surface mem - SDL_FreeSurface(texsurf) + HHGear^.Hedgehog^.HatTex:= Surface2Atlas(texsurf, true); end; end; @@ -1052,11 +1041,10 @@ if texsurf = nil then texsurf:= LoadImage(Pathz[ptGraphics] + '/Progress', ifCritical or ifTransparent); - ProgrTex:= Surface2Tex(texsurf, false); + ProgrTex:= Surface2Atlas(texsurf, false); squaresize:= texsurf^.w shr 1; numsquares:= texsurf^.h div squaresize; - SDL_FreeSurface(texsurf); uMobile.GameLoading(); end; @@ -1201,8 +1189,7 @@ SDL_FillRect(tmpsurf, @r, $ffffffff); SDL_UpperBlit(iconsurf, iconrect, tmpsurf, @r); -RenderHelpWindow:= Surface2Tex(tmpsurf, true); -SDL_FreeSurface(tmpsurf) +RenderHelpWindow:= Surface2Atlas(tmpsurf, true); end; procedure RenderWeaponTooltip(atype: TAmmoType); diff -r 5d0704f23a2a -r ad4b6c2b09e8 hedgewars/uTextures.pas --- a/hedgewars/uTextures.pas Mon Jun 25 10:44:27 2012 +0200 +++ b/hedgewars/uTextures.pas Mon Jun 25 11:47:40 2012 +0200 @@ -24,7 +24,7 @@ function NewTexture(width, height: Longword; buf: Pointer): PTexture; procedure Surface2GrayScale(surf: PSDL_Surface); -function Surface2Tex(surf: PSDL_Surface; enableClamp: boolean): PTexture; +function Surface2Atlas(surf: PSDL_Surface; enableClamp: boolean): PTexture; procedure FreeTexture(tex: PTexture); procedure ComputeTexcoords(texture: PTexture; r: PSDL_Rect; tb: PVertexRect); @@ -32,7 +32,7 @@ procedure freeModule; implementation -uses GLunit, uUtils, uVariables, uConsts, uDebug, uConsole; +uses GLunit, uUtils, uVariables, uConsts, uDebug, uConsole, uAtlas; var TextureList: PTexture; @@ -159,42 +159,45 @@ end; -function Surface2Tex(surf: PSDL_Surface; enableClamp: boolean): PTexture; +function Surface2Atlas(surf: PSDL_Surface; enableClamp: boolean): PTexture; var tw, th, x, y: Longword; tmpp: pointer; fromP4, toP4: PLongWordArray; begin -new(Surface2Tex); -Surface2Tex^.PrevTexture:= nil; -Surface2Tex^.NextTexture:= nil; + if (surf^.w <= 128) and (surf^.h <= 128) then + Surface2Tex_(surf, enableClamp); // run the atlas side by side for debugging +new(Surface2Atlas); +Surface2Atlas^.PrevTexture:= nil; +Surface2Atlas^.NextTexture:= nil; if TextureList <> nil then begin - TextureList^.PrevTexture:= Surface2Tex; - Surface2Tex^.NextTexture:= TextureList + TextureList^.PrevTexture:= Surface2Atlas; + Surface2Atlas^.NextTexture:= TextureList end; -TextureList:= Surface2Tex; +TextureList:= Surface2Atlas; // Atlas allocation happens here later on. For now we just allocate one exclusive atlas per sprite -new(Surface2Tex^.atlas); +new(Surface2Atlas^.atlas); -Surface2Tex^.w:= surf^.w; -Surface2Tex^.h:= surf^.h; -Surface2Tex^.x:=0; -Surface2Tex^.y:=0; -Surface2Tex^.isRotated:=false; +Surface2Atlas^.w:= surf^.w; +Surface2Atlas^.h:= surf^.h; +Surface2Atlas^.x:=0; +Surface2Atlas^.y:=0; +Surface2Atlas^.isRotated:=false; +Surface2Atlas^.surface:= surf; if (surf^.format^.BytesPerPixel <> 4) then begin TryDo(false, 'Surface2Tex failed, expecting 32 bit surface', true); - Surface2Tex^.atlas^.id:= 0; + Surface2Atlas^.atlas^.id:= 0; exit end; -glGenTextures(1, @Surface2Tex^.atlas^.id); +glGenTextures(1, @Surface2Atlas^.atlas^.id); -glBindTexture(GL_TEXTURE_2D, Surface2Tex^.atlas^.id); +glBindTexture(GL_TEXTURE_2D, Surface2Atlas^.atlas^.id); if SDL_MustLock(surf) then SDLTry(SDL_LockSurface(surf) >= 0, true); @@ -209,8 +212,8 @@ tw:= toPowerOf2(Surf^.w); th:= toPowerOf2(Surf^.h); - Surface2Tex^.atlas^.w:=tw; - Surface2Tex^.atlas^.h:=th; + Surface2Atlas^.atlas^.w:=tw; + Surface2Atlas^.atlas^.h:=th; tmpp:= GetMem(tw * th * surf^.format^.BytesPerPixel); @@ -240,23 +243,28 @@ end else begin - Surface2Tex^.atlas^.w:=Surf^.w; - Surface2Tex^.atlas^.h:=Surf^.h; + Surface2Atlas^.atlas^.w:=Surf^.w; + Surface2Atlas^.atlas^.h:=Surf^.h; glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surf^.w, surf^.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surf^.pixels); end; -ResetVertexArrays(Surface2Tex); +ResetVertexArrays(Surface2Atlas); if SDL_MustLock(surf) then SDL_UnlockSurface(surf); SetTextureParameters(enableClamp); + + {$IFNDEF RETAIN_SURFACES} + SDL_FreeSurface(surf); + {$ENDIF} end; // deletes texture and frees the memory allocated for it. // if nil is passed nothing is done procedure FreeTexture(tex: PTexture); begin + FreeTexture_(tex); // run atlas side by side for debugging if tex <> nil then begin // Atlas cleanup happens here later on. For now we just free as each sprite has one atlas @@ -269,12 +277,18 @@ else TextureList:= tex^.NextTexture; glDeleteTextures(1, @tex^.atlas^.id); + + {$IFDEF RETAIN_SURFACES} + SDL_FreeSurface(tex^.surface); + {$ENDIF} + Dispose(tex); end end; procedure initModule; begin +uAtlas.initModule; TextureList:= nil; end; diff -r 5d0704f23a2a -r ad4b6c2b09e8 hedgewars/uTypes.pas --- a/hedgewars/uTypes.pas Mon Jun 25 10:44:27 2012 +0200 +++ b/hedgewars/uTypes.pas Mon Jun 25 11:47:40 2012 +0200 @@ -221,6 +221,8 @@ x, y: LongInt; // Offset in the texture atlas isRotated: boolean; // if true sprite is flipped in the atlas taking w pixels along the y and h pixels along the x axis + surface: PSDL_Surface; // retained in memory surface + // Cached values for texel coordinates and vertex coordinates vb, tb: TVertexRect; diff -r 5d0704f23a2a -r ad4b6c2b09e8 hedgewars/uWorld.pas --- a/hedgewars/uWorld.pas Mon Jun 25 10:44:27 2012 +0200 +++ b/hedgewars/uWorld.pas Mon Jun 25 11:47:40 2012 +0200 @@ -494,8 +494,7 @@ DrawLine2Surf(amSurface, AMRect.w+BORDERSIZE+i, BORDERSIZE, AMRect.w + BORDERSIZE+i, AMRect.h + BORDERSIZE, 160,160,160);//right end; -GetAmmoMenuTexture:= Surface2Tex(amSurface, false); -if amSurface <> nil then SDL_FreeSurface(amSurface); +GetAmmoMenuTexture:= Surface2Atlas(amSurface, false); end; procedure ShowAmmoMenu; @@ -1461,8 +1460,7 @@ tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(s), cWhiteColorChannels); tmpSurface:= doSurfaceConversion(tmpSurface); FreeTexture(timeTexture); - timeTexture:= Surface2Tex(tmpSurface, false); - SDL_FreeSurface(tmpSurface) + timeTexture:= Surface2Atlas(tmpSurface, false); end; if timeTexture <> nil then @@ -1479,8 +1477,7 @@ tmpSurface:= TTF_RenderUTF8_Blended(Fontz[fnt16].Handle, Str2PChar(s), cWhiteColorChannels); tmpSurface:= doSurfaceConversion(tmpSurface); FreeTexture(fpsTexture); - fpsTexture:= Surface2Tex(tmpSurface, false); - SDL_FreeSurface(tmpSurface) + fpsTexture:= Surface2Atlas(tmpSurface, false); end; if fpsTexture <> nil then DrawTexture((cScreenWidth shr 1) - 60 - offsetY, offsetX, fpsTexture);