20 |
20 |
21 unit uRender; |
21 unit uRender; |
22 |
22 |
23 interface |
23 interface |
24 |
24 |
25 uses SDLh, uTypes, GLunit, uConsts; |
25 uses SDLh, uTypes, GLunit, uConsts, uTextures; |
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); |
28 procedure DrawSprite (Sprite: TSprite; X, Y, FrameX, FrameY: LongInt); |
29 procedure DrawSpriteFromRect (Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); |
29 procedure DrawSpriteFromRect (Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); |
30 procedure DrawSpriteClipped (Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt); |
30 procedure DrawSpriteClipped (Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt); |
69 DrawTextureFromRect(X, Y, r^.w, r^.h, r, SourceTexture) |
69 DrawTextureFromRect(X, Y, r^.w, r^.h, r, SourceTexture) |
70 end; |
70 end; |
71 |
71 |
72 procedure DrawTextureFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture); |
72 procedure DrawTextureFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture); |
73 var rr: TSDL_Rect; |
73 var rr: TSDL_Rect; |
74 _l, _r, _t, _b: real; |
74 VertexBuffer, TextureBuffer: TVertexRect; |
75 VertexBuffer, TextureBuffer: array [0..3] of TVertex2f; |
|
76 begin |
75 begin |
77 if (SourceTexture^.h = 0) or (SourceTexture^.w = 0) then |
76 if (SourceTexture^.h = 0) or (SourceTexture^.w = 0) then |
78 exit; |
77 exit; |
79 |
78 |
80 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
79 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
86 rr.x:= X; |
85 rr.x:= X; |
87 rr.y:= Y; |
86 rr.y:= Y; |
88 rr.w:= W; |
87 rr.w:= W; |
89 rr.h:= H; |
88 rr.h:= H; |
90 |
89 |
91 _l:= r^.x / SourceTexture^.w * SourceTexture^.rx; |
90 glBindTexture(GL_TEXTURE_2D, SourceTexture^.atlas^.id); |
92 _r:= (r^.x + r^.w) / SourceTexture^.w * SourceTexture^.rx; |
91 |
93 _t:= r^.y / SourceTexture^.h * SourceTexture^.ry; |
92 ComputeTexcoords(SourceTexture, r, @TextureBuffer); |
94 _b:= (r^.y + r^.h) / SourceTexture^.h * SourceTexture^.ry; |
|
95 |
|
96 glBindTexture(GL_TEXTURE_2D, SourceTexture^.id); |
|
97 |
93 |
98 VertexBuffer[0].X:= X; |
94 VertexBuffer[0].X:= X; |
99 VertexBuffer[0].Y:= Y; |
95 VertexBuffer[0].Y:= Y; |
100 VertexBuffer[1].X:= rr.w + X; |
96 VertexBuffer[1].X:= rr.w + X; |
101 VertexBuffer[1].Y:= Y; |
97 VertexBuffer[1].Y:= Y; |
102 VertexBuffer[2].X:= rr.w + X; |
98 VertexBuffer[2].X:= rr.w + X; |
103 VertexBuffer[2].Y:= rr.h + Y; |
99 VertexBuffer[2].Y:= rr.h + Y; |
104 VertexBuffer[3].X:= X; |
100 VertexBuffer[3].X:= X; |
105 VertexBuffer[3].Y:= rr.h + Y; |
101 VertexBuffer[3].Y:= rr.h + Y; |
106 |
102 |
107 TextureBuffer[0].X:= _l; |
|
108 TextureBuffer[0].Y:= _t; |
|
109 TextureBuffer[1].X:= _r; |
|
110 TextureBuffer[1].Y:= _t; |
|
111 TextureBuffer[2].X:= _r; |
|
112 TextureBuffer[2].Y:= _b; |
|
113 TextureBuffer[3].X:= _l; |
|
114 TextureBuffer[3].Y:= _b; |
|
115 |
|
116 glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); |
103 glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); |
117 glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]); |
104 glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]); |
118 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
105 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
119 end; |
106 end; |
120 |
107 |
128 |
115 |
129 glPushMatrix; |
116 glPushMatrix; |
130 glTranslatef(X, Y, 0); |
117 glTranslatef(X, Y, 0); |
131 glScalef(Scale, Scale, 1); |
118 glScalef(Scale, Scale, 1); |
132 |
119 |
133 glBindTexture(GL_TEXTURE_2D, Texture^.id); |
120 glBindTexture(GL_TEXTURE_2D, Texture^.atlas^.id); |
134 |
121 |
135 glVertexPointer(2, GL_FLOAT, 0, @Texture^.vb); |
122 glVertexPointer(2, GL_FLOAT, 0, @Texture^.vb); |
136 glTexCoordPointer(2, GL_FLOAT, 0, @Texture^.tb); |
123 glTexCoordPointer(2, GL_FLOAT, 0, @Texture^.tb); |
137 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(Texture^.vb)); |
124 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(Texture^.vb)); |
138 |
125 |
143 begin |
130 begin |
144 DrawTextureRotatedF(Texture, Scale, 0, 0, X, Y, Frame, Dir, w, h, 0) |
131 DrawTextureRotatedF(Texture, Scale, 0, 0, X, Y, Frame, Dir, w, h, 0) |
145 end; |
132 end; |
146 |
133 |
147 procedure DrawTextureRotatedF(Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real); |
134 procedure DrawTextureRotatedF(Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real); |
148 var ft, fb, fl, fr: GLfloat; |
135 var hw, nx, ny: LongInt; |
149 hw, nx, ny: LongInt; |
136 r: TSDL_Rect; |
150 VertexBuffer, TextureBuffer: array [0..3] of TVertex2f; |
137 VertexBuffer, TextureBuffer: array [0..3] of TVertex2f; |
151 begin |
138 begin |
152 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
139 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
153 if (abs(X) > W) and ((abs(X + dir * OffsetX) - W / 2) * cScaleFactor > cScreenWidth) then |
140 if (abs(X) > W) and ((abs(X + dir * OffsetX) - W / 2) * cScaleFactor > cScreenWidth) then |
154 exit; |
141 exit; |
170 hw:= w div (2 div Dir); |
157 hw:= w div (2 div Dir); |
171 |
158 |
172 nx:= round(Texture^.w / w); // number of horizontal frames |
159 nx:= round(Texture^.w / w); // number of horizontal frames |
173 ny:= round(Texture^.h / h); // number of vertical frames |
160 ny:= round(Texture^.h / h); // number of vertical frames |
174 |
161 |
175 ft:= (Frame mod ny) * Texture^.ry / ny; |
162 r.y:=(Frame mod ny) * h; |
176 fb:= ((Frame mod ny) + 1) * Texture^.ry / ny; |
163 r.x:=(Frame div ny) * w; |
177 fl:= (Frame div ny) * Texture^.rx / nx; |
164 r.w:=w; |
178 fr:= ((Frame div ny) + 1) * Texture^.rx / nx; |
165 r.h:=h; |
179 |
166 ComputeTexcoords(Texture, @r, @TextureBuffer); |
180 glBindTexture(GL_TEXTURE_2D, Texture^.id); |
167 |
|
168 glBindTexture(GL_TEXTURE_2D, Texture^.atlas^.id); |
181 |
169 |
182 VertexBuffer[0].X:= -hw; |
170 VertexBuffer[0].X:= -hw; |
183 VertexBuffer[0].Y:= w / -2; |
171 VertexBuffer[0].Y:= w / -2; |
184 VertexBuffer[1].X:= hw; |
172 VertexBuffer[1].X:= hw; |
185 VertexBuffer[1].Y:= w / -2; |
173 VertexBuffer[1].Y:= w / -2; |
186 VertexBuffer[2].X:= hw; |
174 VertexBuffer[2].X:= hw; |
187 VertexBuffer[2].Y:= w / 2; |
175 VertexBuffer[2].Y:= w / 2; |
188 VertexBuffer[3].X:= -hw; |
176 VertexBuffer[3].X:= -hw; |
189 VertexBuffer[3].Y:= w / 2; |
177 VertexBuffer[3].Y:= w / 2; |
190 |
178 |
191 TextureBuffer[0].X:= fl; |
|
192 TextureBuffer[0].Y:= ft; |
|
193 TextureBuffer[1].X:= fr; |
|
194 TextureBuffer[1].Y:= ft; |
|
195 TextureBuffer[2].X:= fr; |
|
196 TextureBuffer[2].Y:= fb; |
|
197 TextureBuffer[3].X:= fl; |
|
198 TextureBuffer[3].Y:= fb; |
|
199 |
|
200 glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); |
179 glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); |
201 glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]); |
180 glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]); |
202 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
181 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
203 |
182 |
204 glPopMatrix |
183 glPopMatrix |
248 end |
227 end |
249 else |
228 else |
250 glRotatef(Angle, 0, 0, 1); |
229 glRotatef(Angle, 0, 0, 1); |
251 |
230 |
252 |
231 |
253 glBindTexture(GL_TEXTURE_2D, Texture^.id); |
232 glBindTexture(GL_TEXTURE_2D, Texture^.atlas^.id); |
254 |
233 |
255 VertexBuffer[0].X:= -hw; |
234 VertexBuffer[0].X:= -hw; |
256 VertexBuffer[0].Y:= -hh; |
235 VertexBuffer[0].Y:= -hh; |
257 VertexBuffer[1].X:= hw; |
236 VertexBuffer[1].X:= hw; |
258 VertexBuffer[1].Y:= -hh; |
237 VertexBuffer[1].Y:= -hh; |
405 glDisable(GL_LINE_SMOOTH); |
384 glDisable(GL_LINE_SMOOTH); |
406 end; |
385 end; |
407 |
386 |
408 |
387 |
409 procedure DrawHedgehog(X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real); |
388 procedure DrawHedgehog(X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real); |
410 const VertexBuffer: array [0..3] of TVertex2f = ( |
389 const VertexBuffers: array[0..1] of TVertexRect = ( |
411 (X: -16; Y: -16), |
390 ((x: -16; y: -16), |
412 (X: 16; Y: -16), |
391 (x: 16; y: -16), |
413 (X: 16; Y: 16), |
392 (x: 16; y: 16), |
414 (X: -16; Y: 16)); |
393 (x: -16; y: 16)), |
415 var l, r, t, b: real; |
394 ((x: 16; y: -16), |
|
395 (x: -16; y: -16), |
|
396 (x: -16; y: 16), |
|
397 (x: 16; y: 16))); |
|
398 var r: TSDL_Rect; |
416 TextureBuffer: array [0..3] of TVertex2f; |
399 TextureBuffer: array [0..3] of TVertex2f; |
417 begin |
400 begin |
418 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
401 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
419 if (abs(X) > 32) and ((abs(X) - 16) * cScaleFactor > cScreenWidth) then |
402 if (abs(X) > 32) and ((abs(X) - 16) * cScaleFactor > cScreenWidth) then |
420 exit; |
403 exit; |
421 if (abs(Y) > 32) and ((abs(Y - 0.5 * cScreenHeight) - 16) * cScaleFactor > cScreenHeight) then |
404 if (abs(Y) > 32) and ((abs(Y - 0.5 * cScreenHeight) - 16) * cScaleFactor > cScreenHeight) then |
422 exit; |
405 exit; |
423 |
406 |
424 t:= Pos * 32 / HHTexture^.h; |
407 r.x:=Step * 32; |
425 b:= (Pos + 1) * 32 / HHTexture^.h; |
408 r.y:=Pos * 32; |
426 |
409 r.w:=32; |
427 if Dir = -1 then |
410 r.h:=32; |
428 begin |
411 ComputeTexcoords(HHTexture, @r, @TextureBuffer); |
429 l:= (Step + 1) * 32 / HHTexture^.w; |
|
430 r:= Step * 32 / HHTexture^.w |
|
431 end |
|
432 else |
|
433 begin |
|
434 l:= Step * 32 / HHTexture^.w; |
|
435 r:= (Step + 1) * 32 / HHTexture^.w |
|
436 end; |
|
437 |
|
438 |
412 |
439 glPushMatrix(); |
413 glPushMatrix(); |
440 glTranslatef(X, Y, 0); |
414 glTranslatef(X, Y, 0); |
441 glRotatef(Angle, 0, 0, 1); |
415 glRotatef(Angle, 0, 0, 1); |
442 |
416 |
443 glBindTexture(GL_TEXTURE_2D, HHTexture^.id); |
417 glBindTexture(GL_TEXTURE_2D, HHTexture^.atlas^.id); |
444 |
418 if Dir = -1 then |
445 TextureBuffer[0].X:= l; |
419 glVertexPointer(2, GL_FLOAT, 0, @VertexBuffers[1][0]) |
446 TextureBuffer[0].Y:= t; |
420 else |
447 TextureBuffer[1].X:= r; |
421 glVertexPointer(2, GL_FLOAT, 0, @VertexBuffers[0][0]); |
448 TextureBuffer[1].Y:= t; |
|
449 TextureBuffer[2].X:= r; |
|
450 TextureBuffer[2].Y:= b; |
|
451 TextureBuffer[3].X:= l; |
|
452 TextureBuffer[3].Y:= b; |
|
453 |
|
454 glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]); |
|
455 glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]); |
422 glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]); |
456 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
423 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
457 |
424 |
458 glPopMatrix |
425 glPopMatrix |
459 end; |
426 end; |
460 |
427 |
461 procedure DrawScreenWidget(widget: POnScreenWidget); |
428 procedure DrawScreenWidget(widget: POnScreenWidget); |