hedgewars/uTextures.pas
changeset 7291 ad4b6c2b09e8
parent 7186 013deb83086b
child 7292 18430abfbcd2
equal deleted inserted replaced
7288:5d0704f23a2a 7291:ad4b6c2b09e8
    22 interface
    22 interface
    23 uses SDLh, uTypes;
    23 uses SDLh, uTypes;
    24 
    24 
    25 function  NewTexture(width, height: Longword; buf: Pointer): PTexture;
    25 function  NewTexture(width, height: Longword; buf: Pointer): PTexture;
    26 procedure Surface2GrayScale(surf: PSDL_Surface);
    26 procedure Surface2GrayScale(surf: PSDL_Surface);
    27 function  Surface2Tex(surf: PSDL_Surface; enableClamp: boolean): PTexture;
    27 function  Surface2Atlas(surf: PSDL_Surface; enableClamp: boolean): PTexture;
    28 procedure FreeTexture(tex: PTexture);
    28 procedure FreeTexture(tex: PTexture);
    29 procedure ComputeTexcoords(texture: PTexture; r: PSDL_Rect; tb: PVertexRect);
    29 procedure ComputeTexcoords(texture: PTexture; r: PSDL_Rect; tb: PVertexRect);
    30 
    30 
    31 procedure initModule;
    31 procedure initModule;
    32 procedure freeModule;
    32 procedure freeModule;
    33 
    33 
    34 implementation
    34 implementation
    35 uses GLunit, uUtils, uVariables, uConsts, uDebug, uConsole;
    35 uses GLunit, uUtils, uVariables, uConsts, uDebug, uConsole, uAtlas;
    36 
    36 
    37 var TextureList: PTexture;
    37 var TextureList: PTexture;
    38 
    38 
    39 
    39 
    40 procedure SetTextureParameters(enableClamp: Boolean);
    40 procedure SetTextureParameters(enableClamp: Boolean);
   157     fromP4:= @(fromP4^[Surf^.pitch div 4])
   157     fromP4:= @(fromP4^[Surf^.pitch div 4])
   158     end;
   158     end;
   159 end;
   159 end;
   160 
   160 
   161 
   161 
   162 function Surface2Tex(surf: PSDL_Surface; enableClamp: boolean): PTexture;
   162 function Surface2Atlas(surf: PSDL_Surface; enableClamp: boolean): PTexture;
   163 var tw, th, x, y: Longword;
   163 var tw, th, x, y: Longword;
   164     tmpp: pointer;
   164     tmpp: pointer;
   165     fromP4, toP4: PLongWordArray;
   165     fromP4, toP4: PLongWordArray;
   166 begin
   166 begin
   167 new(Surface2Tex);
   167     if (surf^.w <= 128) and (surf^.h <= 128) then
   168 Surface2Tex^.PrevTexture:= nil;
   168         Surface2Tex_(surf, enableClamp); // run the atlas side by side for debugging
   169 Surface2Tex^.NextTexture:= nil;
   169 new(Surface2Atlas);
       
   170 Surface2Atlas^.PrevTexture:= nil;
       
   171 Surface2Atlas^.NextTexture:= nil;
   170 if TextureList <> nil then
   172 if TextureList <> nil then
   171     begin
   173     begin
   172     TextureList^.PrevTexture:= Surface2Tex;
   174     TextureList^.PrevTexture:= Surface2Atlas;
   173     Surface2Tex^.NextTexture:= TextureList
   175     Surface2Atlas^.NextTexture:= TextureList
   174     end;
   176     end;
   175 TextureList:= Surface2Tex;
   177 TextureList:= Surface2Atlas;
   176 
   178 
   177 // Atlas allocation happens here later on. For now we just allocate one exclusive atlas per sprite
   179 // Atlas allocation happens here later on. For now we just allocate one exclusive atlas per sprite
   178 new(Surface2Tex^.atlas);
   180 new(Surface2Atlas^.atlas);
   179 
   181 
   180 Surface2Tex^.w:= surf^.w;
   182 Surface2Atlas^.w:= surf^.w;
   181 Surface2Tex^.h:= surf^.h;
   183 Surface2Atlas^.h:= surf^.h;
   182 Surface2Tex^.x:=0;
   184 Surface2Atlas^.x:=0;
   183 Surface2Tex^.y:=0;
   185 Surface2Atlas^.y:=0;
   184 Surface2Tex^.isRotated:=false;
   186 Surface2Atlas^.isRotated:=false;
       
   187 Surface2Atlas^.surface:= surf;
   185 
   188 
   186 
   189 
   187 if (surf^.format^.BytesPerPixel <> 4) then
   190 if (surf^.format^.BytesPerPixel <> 4) then
   188     begin
   191     begin
   189     TryDo(false, 'Surface2Tex failed, expecting 32 bit surface', true);
   192     TryDo(false, 'Surface2Tex failed, expecting 32 bit surface', true);
   190     Surface2Tex^.atlas^.id:= 0;
   193     Surface2Atlas^.atlas^.id:= 0;
   191     exit
   194     exit
   192     end;
   195     end;
   193 
   196 
   194 
   197 
   195 glGenTextures(1, @Surface2Tex^.atlas^.id);
   198 glGenTextures(1, @Surface2Atlas^.atlas^.id);
   196 
   199 
   197 glBindTexture(GL_TEXTURE_2D, Surface2Tex^.atlas^.id);
   200 glBindTexture(GL_TEXTURE_2D, Surface2Atlas^.atlas^.id);
   198 
   201 
   199 if SDL_MustLock(surf) then
   202 if SDL_MustLock(surf) then
   200     SDLTry(SDL_LockSurface(surf) >= 0, true);
   203     SDLTry(SDL_LockSurface(surf) >= 0, true);
   201 
   204 
   202 fromP4:= Surf^.pixels;
   205 fromP4:= Surf^.pixels;
   207 if (not SupportNPOTT) and (not (isPowerOf2(Surf^.w) and isPowerOf2(Surf^.h))) then
   210 if (not SupportNPOTT) and (not (isPowerOf2(Surf^.w) and isPowerOf2(Surf^.h))) then
   208     begin
   211     begin
   209     tw:= toPowerOf2(Surf^.w);
   212     tw:= toPowerOf2(Surf^.w);
   210     th:= toPowerOf2(Surf^.h);
   213     th:= toPowerOf2(Surf^.h);
   211 
   214 
   212     Surface2Tex^.atlas^.w:=tw;
   215     Surface2Atlas^.atlas^.w:=tw;
   213     Surface2Tex^.atlas^.h:=th;
   216     Surface2Atlas^.atlas^.h:=th;
   214 
   217 
   215     tmpp:= GetMem(tw * th * surf^.format^.BytesPerPixel);
   218     tmpp:= GetMem(tw * th * surf^.format^.BytesPerPixel);
   216 
   219 
   217     fromP4:= Surf^.pixels;
   220     fromP4:= Surf^.pixels;
   218     toP4:= tmpp;
   221     toP4:= tmpp;
   238 
   241 
   239     FreeMem(tmpp, tw * th * surf^.format^.BytesPerPixel)
   242     FreeMem(tmpp, tw * th * surf^.format^.BytesPerPixel)
   240     end
   243     end
   241 else
   244 else
   242     begin
   245     begin
   243     Surface2Tex^.atlas^.w:=Surf^.w;
   246     Surface2Atlas^.atlas^.w:=Surf^.w;
   244     Surface2Tex^.atlas^.h:=Surf^.h;
   247     Surface2Atlas^.atlas^.h:=Surf^.h;
   245     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surf^.w, surf^.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surf^.pixels);
   248     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surf^.w, surf^.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surf^.pixels);
   246     end;
   249     end;
   247 
   250 
   248 ResetVertexArrays(Surface2Tex);
   251 ResetVertexArrays(Surface2Atlas);
   249 
   252 
   250 if SDL_MustLock(surf) then
   253 if SDL_MustLock(surf) then
   251     SDL_UnlockSurface(surf);
   254     SDL_UnlockSurface(surf);
   252 
   255 
   253 SetTextureParameters(enableClamp);
   256 SetTextureParameters(enableClamp);
       
   257 
       
   258     {$IFNDEF RETAIN_SURFACES}
       
   259     SDL_FreeSurface(surf);
       
   260     {$ENDIF}
   254 end;
   261 end;
   255 
   262 
   256 // deletes texture and frees the memory allocated for it.
   263 // deletes texture and frees the memory allocated for it.
   257 // if nil is passed nothing is done
   264 // if nil is passed nothing is done
   258 procedure FreeTexture(tex: PTexture);
   265 procedure FreeTexture(tex: PTexture);
   259 begin
   266 begin
       
   267     FreeTexture_(tex); // run atlas side by side for debugging
   260 if tex <> nil then
   268 if tex <> nil then
   261     begin
   269     begin
   262     // Atlas cleanup happens here later on. For now we just free as each sprite has one atlas
   270     // Atlas cleanup happens here later on. For now we just free as each sprite has one atlas
   263     Dispose(tex^.atlas);
   271     Dispose(tex^.atlas);
   264 
   272 
   267     if tex^.PrevTexture <> nil then
   275     if tex^.PrevTexture <> nil then
   268         tex^.PrevTexture^.NextTexture:= tex^.NextTexture
   276         tex^.PrevTexture^.NextTexture:= tex^.NextTexture
   269     else
   277     else
   270         TextureList:= tex^.NextTexture;
   278         TextureList:= tex^.NextTexture;
   271     glDeleteTextures(1, @tex^.atlas^.id);
   279     glDeleteTextures(1, @tex^.atlas^.id);
       
   280 
       
   281     {$IFDEF RETAIN_SURFACES}
       
   282     SDL_FreeSurface(tex^.surface);
       
   283     {$ENDIF}
       
   284 
   272     Dispose(tex);
   285     Dispose(tex);
   273     end
   286     end
   274 end;
   287 end;
   275 
   288 
   276 procedure initModule;
   289 procedure initModule;
   277 begin
   290 begin
       
   291 uAtlas.initModule;
   278 TextureList:= nil;
   292 TextureList:= nil;
   279 end;
   293 end;
   280 
   294 
   281 procedure freeModule;
   295 procedure freeModule;
   282 begin
   296 begin