DEADSOFTWARE

gl: draw server list
[d2df-sdl.git] / src / game / renders / opengl / r_draw.pas
1 (* Copyright (C) Doom 2D: Forever Developers
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, version 3 of the License ONLY.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 *)
15 {$INCLUDE ../../../shared/a_modes.inc}
16 unit r_draw;
18 interface
20 uses
21 g_animations,
22 r_textures
23 ;
25 procedure r_Draw_Texture (img: TGLTexture; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean);
26 procedure r_Draw_TextureRepeat (img: TGLTexture; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean);
27 procedure r_Draw_TextureRepeatRotate (img: TGLTexture; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean; rx, ry, angle: Integer);
29 procedure r_Draw_MultiTextureRepeat (m: TGLMultiTexture; const anim: TAnimState; backanim: Boolean; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean);
30 procedure r_Draw_MultiTextureRepeatRotate (m: TGLMultiTexture; const anim: TAnimState; backanim: Boolean; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean; rx, ry, angle: Integer);
32 procedure r_Draw_Filter (l, t, r, b: Integer; rr, gg, bb, aa: Byte);
33 procedure r_Draw_Rect (l, t, r, b: Integer; rr, gg, bb, aa: Byte);
34 procedure r_Draw_FillRect (l, t, r, b: Integer; rr, gg, bb, aa: Byte);
35 procedure r_Draw_InvertRect (l, t, r, b: Integer; rr, gg, bb, aa: Byte);
37 procedure r_Draw_Text (const text: AnsiString; x, y: Integer; r, g, b, a: Byte; f: TGLFont);
38 procedure r_Draw_GetTextSize (const text: AnsiString; f: TGLFont; out w, h: Integer);
40 procedure r_Draw_Setup (w, h: Integer);
41 procedure r_Draw_SetRect (l, t, r, b: Integer);
42 procedure r_Draw_GetRect (out l, t, r, b: Integer);
44 implementation
46 uses
47 {$IFDEF USE_GLES1}
48 GLES11,
49 {$ELSE}
50 GL, GLEXT,
51 {$ENDIF}
52 SysUtils, Classes, Math,
53 e_log, utils
54 ;
56 const
57 NTR = $FF;
58 NTG = $00;
59 NTB = $00;
60 NTA = $FF;
62 var
63 sl, st, sr, sb: Integer;
64 ScreenWidth, ScreenHeight: Integer;
66 procedure r_Draw_Setup (w, h: Integer);
67 begin
68 ASSERT(w >= 0);
69 ASSERT(h >= 0);
70 ScreenWidth := w;
71 ScreenHeight := h;
72 glScissor(0, 0, w, h);
73 glViewport(0, 0, w, h);
74 glMatrixMode(GL_PROJECTION);
75 glLoadIdentity;
76 glOrtho(0, w, h, 0, 0, 1);
77 glMatrixMode(GL_MODELVIEW);
78 glLoadIdentity;
79 // glTranslatef(0.5, 0.5, 0);
80 end;
82 procedure DrawQuad (x, y, w, h: Integer);
83 begin
84 glBegin(GL_QUADS);
85 glVertex2i(x + w, y);
86 glVertex2i(x, y);
87 glVertex2i(x, y + h);
88 glVertex2i(x + w, y + h);
89 glEnd();
90 end;
92 procedure DrawTile (tile: TGLAtlasNode; x, y, w, h: Integer; flip: Boolean; rr, gg, bb, aa: Byte; blend: Boolean);
93 var nw, nh, ax, bx, ay, by: GLfloat; l, t, r, b: Integer;
94 begin
95 if tile = nil then
96 begin
97 glColor4ub(rr, gg, bb, aa);
98 if blend then glBlendFunc(GL_SRC_ALPHA, GL_ONE) else glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
99 glDisable(GL_TEXTURE_2D);
100 glEnable(GL_BLEND);
101 DrawQuad(x, y, w, h);
102 end
103 else
104 begin
105 nw := tile.base.w;
106 nh := tile.base.h;
107 ax := IfThen(flip, tile.l, tile.r + 1) / nw;
108 bx := IfThen(flip, tile.r + 1, tile.l) / nh;
109 ay := (tile.t) / nw;
110 by := (tile.b + 1) / nh;
111 l := x; t := y; r := x + w; b := y + h;
112 glBindTexture(GL_TEXTURE_2D, tile.id);
113 glColor4ub(rr, gg, bb, aa);
114 if blend then glBlendFunc(GL_SRC_ALPHA, GL_ONE) else glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
115 glEnable(GL_TEXTURE_2D);
116 glEnable(GL_BLEND);
117 glBegin(GL_QUADS);
118 glTexCoord2f(ax, ay); glVertex2i(r, t);
119 glTexCoord2f(bx, ay); glVertex2i(l, t);
120 glTexCoord2f(bx, by); glVertex2i(l, b);
121 glTexCoord2f(ax, by); glVertex2i(r, b);
122 glEnd();
123 glDisable(GL_TEXTURE_2D);
124 glBindTexture(GL_TEXTURE_2D, 0);
125 end
126 end;
128 procedure r_Draw_Texture (img: TGLTexture; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean);
129 var i, j, offx, offy: Integer; n: TGLAtlasNode;
130 begin
131 ASSERT(w >= 0);
132 ASSERT(h >= 0);
133 if img = nil then
134 DrawTile(nil, x, y, w, h, flip, NTR, NTB, NTG, NTA, blend)
135 else
136 begin
137 offx := 0;
138 offy := 0;
139 for j := 0 to img.lines - 1 do
140 begin
141 for i := 0 to img.cols - 1 do
142 begin
143 n := img.GetTile(i, j);
144 ASSERT(n <> nil);
145 glPushMatrix;
146 glTranslatef(x + offx, y + offy, 0);
147 glScalef(w / img.width, h / img.height, 1);
148 DrawTile(n, 0, 0, n.width, n.height, flip, r, g, b, a, blend);
149 glPopMatrix;
150 offx := offx + n.width;
151 end;
152 offx := 0;
153 offy := offy + n.height;
154 end;
155 end
156 end;
158 procedure r_Draw_TextureRepeat (img: TGLTexture; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean);
159 var i, j: Integer;
160 begin
161 ASSERT(w >= 0);
162 ASSERT(h >= 0);
163 if img = nil then
164 r_Draw_Texture(nil, x, y, w, h, flip, NTR, NTG, NTB, NTB, blend)
165 else
166 for j := 0 to (h - 1) div img.height do
167 for i := 0 to (w - 1) div img.width do
168 r_Draw_Texture(img, x + i * img.width, y + j * img.height, img.width, img.height, flip, r, g, b, a, blend);
169 end;
171 procedure r_Draw_TextureRepeatRotate (img: TGLTexture; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean; rx, ry, angle: Integer);
172 begin
173 ASSERT(w >= 0);
174 ASSERT(h >= 0);
175 if a <> 0 then
176 begin
177 glPushMatrix;
178 glTranslatef(x + rx, y + ry, 0);
179 glRotatef(angle, 0, 0, 1);
180 glTranslatef(-(x + rx), -(y + ry), 0);
181 r_Draw_TextureRepeat(img, x, y, w, h, flip, r, g, b, a, blend);
182 glPopMatrix;
183 end
184 else
185 r_Draw_TextureRepeat(img, x, y, w, h, flip, r, g, b, a, blend);
186 end;
188 procedure r_Draw_MultiTextureRepeat (m: TGLMultiTexture; const anim: TAnimState; backanim: Boolean; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean);
189 var img: TGLTexture; frame: LongInt;
190 begin
191 ASSERT(anim.IsValid());
192 if m = nil then
193 r_Draw_TextureRepeat(nil, x, y, w, h, flip, NTR, NTG, NTB, NTB, blend)
194 else
195 begin
196 g_Anim_GetFrameFromState(anim, backanim, frame);
197 ASSERT(frame >= 0);
198 ASSERT(frame < m.count);
199 img := m.GetTexture(frame);
200 r_Draw_TextureRepeat(img, x, y, w, h, flip, r, g, b, a, blend);
201 end
202 end;
204 procedure r_Draw_MultiTextureRepeatRotate (m: TGLMultiTexture; const anim: TAnimState; backanim: Boolean; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean; rx, ry, angle: Integer);
205 begin
206 ASSERT(w >= 0);
207 ASSERT(h >= 0);
208 if a <> 0 then
209 begin
210 glPushMatrix;
211 glTranslatef(x + rx, y + ry, 0);
212 glRotatef(angle, 0, 0, 1);
213 glTranslatef(-(x + rx), -(y + ry), 0);
214 r_Draw_MultiTextureRepeat(m, anim, backanim, x, y, w, h, flip, r, g, b, a, blend);
215 glPopMatrix;
216 end
217 else
218 r_Draw_MultiTextureRepeat(m, anim, backanim, x, y, w, h, flip, r, g, b, a, blend);
219 end;
221 procedure r_Draw_Filter (l, t, r, b: Integer; rr, gg, bb, aa: Byte);
222 begin
223 ASSERT(r >= l);
224 ASSERT(b >= t);
225 glEnable(GL_BLEND);
226 glBlendFunc(GL_ZERO, GL_SRC_COLOR);
227 glDisable(GL_TEXTURE_2D);
228 glColor4ub(rr, gg, bb, aa);
229 glBegin(GL_QUADS);
230 glVertex2i(l, t);
231 glVertex2i(r, t);
232 glVertex2i(r, b);
233 glVertex2i(l, b);
234 glEnd;
235 end;
237 procedure r_Draw_Rect (l, t, r, b: Integer; rr, gg, bb, aa: Byte);
238 begin
239 ASSERT(r >= l);
240 ASSERT(b >= t);
241 glEnable(GL_BLEND);
242 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
243 glDisable(GL_TEXTURE_2D);
244 glColor4ub(rr, gg, bb, aa);
245 glBegin(GL_LINE_LOOP);
247 glVertex2i(l, t);
248 glVertex2i(r, t);
249 glVertex2i(r, b);
250 glVertex2i(l, b);
252 glVertex2f(l + 0.5, t + 0.5);
253 glVertex2f(r - 0.5, t + 0.5);
254 glVertex2f(r - 0.5, b - 0.5);
255 glVertex2f(l + 0.5, b - 0.5);
256 glEnd;
257 end;
259 procedure r_Draw_FillRect (l, t, r, b: Integer; rr, gg, bb, aa: Byte);
260 begin
261 ASSERT(r >= l);
262 ASSERT(b >= t);
263 glEnable(GL_BLEND);
264 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
265 glDisable(GL_TEXTURE_2D);
266 glColor4ub(rr, gg, bb, aa);
267 glBegin(GL_QUADS);
269 glVertex2i(l, t);
270 glVertex2i(r, t);
271 glVertex2i(r, b);
272 glVertex2i(l, b);
274 glVertex2f(l + 0.5, t + 0.5);
275 glVertex2f(r - 0.5, t + 0.5);
276 glVertex2f(r - 0.5, b - 0.5);
277 glVertex2f(l + 0.5, b - 0.5);
278 glEnd;
279 end;
281 procedure r_Draw_InvertRect (l, t, r, b: Integer; rr, gg, bb, aa: Byte);
282 begin
283 ASSERT(r >= l);
284 ASSERT(b >= t);
285 glEnable(GL_BLEND);
286 glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO);
287 glDisable(GL_TEXTURE_2D);
288 glColor4ub(rr, gg, bb, aa);
289 glBegin(GL_QUADS);
290 glVertex2i(l, t);
291 glVertex2i(r, t);
292 glVertex2i(r, b);
293 glVertex2i(l, b);
294 glEnd;
295 end;
297 procedure r_Draw_Text (const text: AnsiString; x, y: Integer; r, g, b, a: Byte; f: TGLFont);
298 var i, xoff, spc: Integer; t: TGLTexture; ch: AnsiChar;
299 begin
300 xoff := x; spc := MAX(0, f.GetSpace());
301 for i := 1 to Length(text) do
302 begin
303 ch := text[i];
304 t := f.GetChar(ch);
305 if t <> nil then
306 r_Draw_Texture(t, xoff, y, t.width, t.height, false, r, g, b, a, false);
307 Inc(xoff, f.GetWidth(ch) + spc);
308 end;
309 end;
311 procedure r_Draw_GetTextSize (const text: AnsiString; f: TGLFont; out w, h: Integer);
312 var i, spc, len: Integer;
313 begin
314 w := 0;
315 h := f.GetMaxHeight();
316 len := Length(text);
317 if len > 0 then
318 begin
319 spc := MAX(0, f.GetSpace());
320 for i := 1 to len - 1 do
321 Inc(w, f.GetWidth(text[i]) + spc);
322 Inc(w, f.GetWidth(text[len]));
323 end;
324 end;
326 procedure r_Draw_SetRect (l, t, r, b: Integer);
327 var w, h: Integer;
328 begin
329 ASSERT(l <= r);
330 ASSERT(t <= b);
331 w := r - l + 1;
332 h := b - t + 1;
333 glScissor(l, ScreenHeight - h - t, w, h);
334 sl := l; st := t; sr := r; sb := b;
335 end;
337 procedure r_Draw_GetRect (out l, t, r, b: Integer);
338 begin
339 l := sl; t := st; r := sr; b := sb;
340 end;
342 end.