23 interface |
23 interface |
24 |
24 |
25 uses SDLh, uTypes, GLunit, uConsts, uTextures, math; |
25 uses SDLh, uTypes, GLunit, uConsts, uTextures, math; |
26 |
26 |
27 procedure DrawSprite (Sprite: TSprite; X, Y, Frame: LongInt); |
27 procedure DrawSprite (Sprite: TSprite; X, Y, Frame: LongInt); |
28 procedure DrawSprite (Sprite: TSprite; X, Y, FrameX, FrameY: LongInt); |
|
29 procedure DrawSpriteFromRect (Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); |
28 procedure DrawSpriteFromRect (Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); |
30 procedure DrawSpriteClipped (Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt); |
29 procedure DrawSpriteClipped (Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt); |
31 procedure DrawSpriteRotated (Sprite: TSprite; X, Y, Dir: LongInt; Angle: real); |
30 procedure DrawSpriteRotated (Sprite: TSprite; X, Y, Dir: LongInt; Angle: real); |
32 procedure DrawSpriteRotatedF (Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real); |
31 procedure DrawSpriteRotatedF (Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real); |
33 |
32 |
132 begin |
131 begin |
133 DrawTextureFromRect(X, Y, r^.w, r^.h, r, SourceTexture) |
132 DrawTextureFromRect(X, Y, r^.w, r^.h, r, SourceTexture) |
134 end; |
133 end; |
135 |
134 |
136 procedure DrawTextureFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture); |
135 procedure DrawTextureFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture); |
137 var rr: TSDL_Rect; |
136 var |
|
137 rr: TSDL_Rect; |
138 VertexBuffer, TextureBuffer: TVertexRect; |
138 VertexBuffer, TextureBuffer: TVertexRect; |
139 begin |
139 _l, _r, _t, _b: GLfloat; |
140 if (SourceTexture^.h = 0) or (SourceTexture^.w = 0) then |
140 begin |
141 exit; |
141 if (SourceTexture^.h = 0) or (SourceTexture^.w = 0) then |
142 |
142 exit; |
143 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
143 |
144 if (abs(X) > W) and ((abs(X + W / 2) - W / 2) > cScreenWidth / cScaleFactor) then |
144 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
145 exit; |
145 if (abs(X) > W) and ((abs(X + W / 2) - W / 2) > cScreenWidth / cScaleFactor) then |
146 if (abs(Y) > H) and ((abs(Y + H / 2 - (0.5 * cScreenHeight)) - H / 2) > cScreenHeight / cScaleFactor) then |
146 exit; |
147 exit; |
147 if (abs(Y) > H) and ((abs(Y + H / 2 - (0.5 * cScreenHeight)) - H / 2) > cScreenHeight / cScaleFactor) then |
148 |
148 exit; |
149 rr.x:= X; |
149 |
150 rr.y:= Y; |
150 rr.x:= X; |
151 rr.w:= W; |
151 rr.y:= Y; |
152 rr.h:= H; |
152 rr.w:= W; |
153 |
153 rr.h:= H; |
154 glBindTexture(GL_TEXTURE_2D, SourceTexture^.atlas^.id); |
154 |
155 |
155 glBindTexture(GL_TEXTURE_2D, SourceTexture^.atlas^.id); |
156 ComputeTexcoords(SourceTexture, r, @TextureBuffer); |
156 |
157 |
157 ComputeTexcoords(SourceTexture, r, @TextureBuffer); |
158 VertexBuffer[0].X:= X; |
158 |
159 VertexBuffer[0].Y:= Y; |
159 _l:= X + SourceTexture^.cropInfo.l; |
160 VertexBuffer[1].X:= rr.w + X; |
160 _r:= X + rr.w - SourceTexture^.cropInfo.l - SourceTexture^.cropInfo.r; |
161 VertexBuffer[1].Y:= Y; |
161 _t:= Y + SourceTexture^.cropInfo.t; |
162 VertexBuffer[2].X:= rr.w + X; |
162 _b:= Y + rr.h - SourceTexture^.cropInfo.t - SourceTexture^.cropInfo.b; |
163 VertexBuffer[2].Y:= rr.h + Y; |
163 |
164 VertexBuffer[3].X:= X; |
164 |
165 VertexBuffer[3].Y:= rr.h + Y; |
165 VertexBuffer[0].X:= _l; |
166 |
166 VertexBuffer[0].Y:= _t; |
167 SetVertexPointer(@VertexBuffer[0]); |
167 VertexBuffer[1].X:= _r; |
168 SetTexCoordPointer(@TextureBuffer[0]); |
168 VertexBuffer[1].Y:= _t; |
169 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
169 VertexBuffer[2].X:= _r; |
|
170 VertexBuffer[2].Y:= _b; |
|
171 VertexBuffer[3].X:= _l; |
|
172 VertexBuffer[3].Y:= _b; |
|
173 |
|
174 SetVertexPointer(@VertexBuffer[0]); |
|
175 //SetTexCoordPointer(@TextureBuffer[0]); |
|
176 SetTexCoordPointer(@SourceTexture^.tb[0]); |
|
177 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
170 end; |
178 end; |
171 |
179 |
172 procedure DrawTexture(X, Y: LongInt; Texture: PTexture); inline; |
180 procedure DrawTexture(X, Y: LongInt; Texture: PTexture); inline; |
173 begin |
181 begin |
174 DrawTexture(X, Y, Texture, 1.0); |
182 DrawTexture(X, Y, Texture, 1.0); |
196 |
204 |
197 procedure DrawTextureRotatedF(Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real); |
205 procedure DrawTextureRotatedF(Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real); |
198 var hw, nx, ny: LongInt; |
206 var hw, nx, ny: LongInt; |
199 r: TSDL_Rect; |
207 r: TSDL_Rect; |
200 VertexBuffer, TextureBuffer: array [0..3] of TVertex2f; |
208 VertexBuffer, TextureBuffer: array [0..3] of TVertex2f; |
201 begin |
209 _l, _r, _t, _b: GLfloat; |
|
210 begin |
|
211 |
|
212 while (Frame > 0) and (Texture <> nil) do |
|
213 begin |
|
214 Texture:= Texture^.nextFrame; |
|
215 dec(Frame); |
|
216 end; |
|
217 |
|
218 if Texture = nil then |
|
219 exit; |
|
220 |
202 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
221 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
203 if (abs(X) > W) and ((abs(X + dir * OffsetX) - W / 2) * cScaleFactor > cScreenWidth) then |
222 if (abs(X) > W) and ((abs(X + dir * OffsetX) - W / 2) * cScaleFactor > cScreenWidth) then |
204 exit; |
223 exit; |
205 if (abs(Y) > H) and ((abs(Y + OffsetY - (0.5 * cScreenHeight)) - W / 2) * cScaleFactor > cScreenHeight) then |
224 if (abs(Y) > H) and ((abs(Y + OffsetY - (0.5 * cScreenHeight)) - W / 2) * cScaleFactor > cScreenHeight) then |
206 exit; |
225 exit; |
216 // Any reason for this call? And why only in t direction, not s? |
235 // Any reason for this call? And why only in t direction, not s? |
217 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
236 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
218 |
237 |
219 hw:= w div (2 div Dir); |
238 hw:= w div (2 div Dir); |
220 |
239 |
221 nx:= round(Texture^.w / w); // number of horizontal frames |
240 r.y:=0; |
222 ny:= round(Texture^.h / h); // number of vertical frames |
241 r.x:=0; |
223 |
|
224 r.y:=(Frame mod ny) * h; |
|
225 r.x:=(Frame div ny) * w; |
|
226 r.w:=w; |
242 r.w:=w; |
227 r.h:=h; |
243 r.h:=h; |
228 ComputeTexcoords(Texture, @r, @TextureBuffer); |
244 ComputeTexcoords(Texture, @r, @TextureBuffer); |
229 |
245 |
230 glBindTexture(GL_TEXTURE_2D, Texture^.atlas^.id); |
246 glBindTexture(GL_TEXTURE_2D, Texture^.atlas^.id); |
231 |
247 |
232 VertexBuffer[0].X:= -hw; |
248 _l:= -hw + Texture^.cropInfo.l; |
233 VertexBuffer[0].Y:= w / -2; |
249 _t:= w/-2 + Texture^.cropInfo.t; |
234 VertexBuffer[1].X:= hw; |
250 _r:= hw - Texture^.cropInfo.l - Texture^.cropInfo.r; |
235 VertexBuffer[1].Y:= w / -2; |
251 _b:= w/2 - Texture^.cropInfo.t - Texture^.cropInfo.b; |
236 VertexBuffer[2].X:= hw; |
252 |
237 VertexBuffer[2].Y:= w / 2; |
253 VertexBuffer[0].X:= _l; |
238 VertexBuffer[3].X:= -hw; |
254 VertexBuffer[0].Y:= _t; |
239 VertexBuffer[3].Y:= w / 2; |
255 VertexBuffer[1].X:= _r; |
|
256 VertexBuffer[1].Y:= _t; |
|
257 VertexBuffer[2].X:= _r; |
|
258 VertexBuffer[2].Y:= _b; |
|
259 VertexBuffer[3].X:= _l; |
|
260 VertexBuffer[3].Y:= _b; |
240 |
261 |
241 SetVertexPointer(@VertexBuffer[0]); |
262 SetVertexPointer(@VertexBuffer[0]); |
242 SetTexCoordPointer(@TextureBuffer[0]); |
263 //SetTexCoordPointer(@TextureBuffer[0]); |
|
264 SetTexCoordPointer(@Texture^.tb[0]); |
243 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
265 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
244 |
266 |
245 ResetModelview; |
267 ResetModelview; |
246 end; |
268 end; |
247 |
269 |
269 ResetModelview; |
291 ResetModelview; |
270 end; |
292 end; |
271 |
293 |
272 procedure DrawTextureRotated(Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real); |
294 procedure DrawTextureRotated(Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real); |
273 var VertexBuffer: array [0..3] of TVertex2f; |
295 var VertexBuffer: array [0..3] of TVertex2f; |
|
296 _l, _r, _t, _b: GLfloat; |
274 begin |
297 begin |
275 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
298 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
276 if (abs(X) > 2 * hw) and ((abs(X) - hw) > cScreenWidth / cScaleFactor) then |
299 if (abs(X) > 2 * hw) and ((abs(X) - hw) > cScreenWidth / cScaleFactor) then |
277 exit; |
300 exit; |
278 if (abs(Y) > 2 * hh) and ((abs(Y - 0.5 * cScreenHeight) - hh) > cScreenHeight / cScaleFactor) then |
301 if (abs(Y) > 2 * hh) and ((abs(Y - 0.5 * cScreenHeight) - hh) > cScreenHeight / cScaleFactor) then |
289 SetRotation(Angle, 1.0); |
312 SetRotation(Angle, 1.0); |
290 UpdateModelview; |
313 UpdateModelview; |
291 |
314 |
292 glBindTexture(GL_TEXTURE_2D, Texture^.atlas^.id); |
315 glBindTexture(GL_TEXTURE_2D, Texture^.atlas^.id); |
293 |
316 |
294 VertexBuffer[0].X:= -hw; |
317 _l:= -hw + Texture^.cropInfo.l; |
295 VertexBuffer[0].Y:= -hh; |
318 _t:= -hh + Texture^.cropInfo.t; |
296 VertexBuffer[1].X:= hw; |
319 _r:= hw - Texture^.cropInfo.l - Texture^.cropInfo.r; |
297 VertexBuffer[1].Y:= -hh; |
320 _b:= hh - Texture^.cropInfo.t - Texture^.cropInfo.b; |
298 VertexBuffer[2].X:= hw; |
321 |
299 VertexBuffer[2].Y:= hh; |
322 VertexBuffer[0].X:= _l; |
300 VertexBuffer[3].X:= -hw; |
323 VertexBuffer[0].Y:= _t; |
301 VertexBuffer[3].Y:= hh; |
324 VertexBuffer[1].X:= _r; |
|
325 VertexBuffer[1].Y:= _t; |
|
326 VertexBuffer[2].X:= _r; |
|
327 VertexBuffer[2].Y:= _b; |
|
328 VertexBuffer[3].X:= _l; |
|
329 VertexBuffer[3].Y:= _b; |
302 |
330 |
303 SetVertexPointer(@VertexBuffer[0]); |
331 SetVertexPointer(@VertexBuffer[0]); |
304 SetTexCoordPointer(@Texture^.tb); |
332 SetTexCoordPointer(@Texture^.tb); |
305 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
333 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
306 |
334 |
307 ResetModelview; |
335 ResetModelview; |
308 end; |
336 end; |
309 |
337 |
310 procedure DrawSprite(Sprite: TSprite; X, Y, Frame: LongInt); |
338 procedure DrawSprite(Sprite: TSprite; X, Y, Frame: LongInt); |
311 var row, col, numFramesFirstCol: LongInt; |
339 var |
|
340 r: TSDL_Rect; |
|
341 tex: PTexture; |
312 begin |
342 begin |
313 if SpritesData[Sprite].imageHeight = 0 then |
343 if SpritesData[Sprite].imageHeight = 0 then |
314 exit; |
344 exit; |
315 numFramesFirstCol:= SpritesData[Sprite].imageHeight div SpritesData[Sprite].Height; |
345 |
316 row:= Frame mod numFramesFirstCol; |
346 tex:= SpritesData[Sprite].Texture; |
317 col:= Frame div numFramesFirstCol; |
347 |
318 DrawSprite(Sprite, X, Y, col, row); |
348 while (Frame > 0) and (tex <> nil) do |
319 end; |
349 begin |
320 |
350 tex:= tex^.nextFrame; |
321 procedure DrawSprite(Sprite: TSprite; X, Y, FrameX, FrameY: LongInt); |
351 dec(Frame); |
322 var r: TSDL_Rect; |
352 end; |
323 begin |
353 |
324 r.x:= FrameX * SpritesData[Sprite].Width; |
354 if (tex = nil) or (tex^.w = 0) or (tex^.h = 0) then |
|
355 exit; |
|
356 |
|
357 r.x:= 0; |
325 r.w:= SpritesData[Sprite].Width; |
358 r.w:= SpritesData[Sprite].Width; |
326 r.y:= FrameY * SpritesData[Sprite].Height; |
359 r.y:= 0; |
327 r.h:= SpritesData[Sprite].Height; |
360 r.h:= SpritesData[Sprite].Height; |
328 DrawTextureFromRect(X, Y, @r, SpritesData[Sprite].Texture) |
361 DrawTextureFromRect(X, Y, @r, tex) |
329 end; |
362 end; |
330 |
363 |
331 procedure DrawSpriteClipped(Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt); |
364 procedure DrawSpriteClipped(Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt); |
332 var r: TSDL_Rect; |
365 var r: TSDL_Rect; |
333 begin |
366 begin |