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 |