DEADSOFTWARE

gl: draw hud
[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_textures,
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; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean);
30 procedure r_Draw_MultiTextureRepeatRotate (m: TGLMultiTexture; const anim: TAnimState; 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_FillRect (l, t, r, b: Integer; rr, gg, bb, aa: Byte);
34 procedure r_Draw_InvertRect (l, t, r, b: Integer; rr, gg, bb, aa: Byte);
36 procedure r_Draw_Text (const text: AnsiString; x, y: Integer; r, g, b, a: Byte; f: TGLFont);
38 implementation
40 uses
41 {$IFDEF USE_GLES1}
42 GLES11,
43 {$ELSE}
44 GL, GLEXT,
45 {$ENDIF}
46 SysUtils, Classes, Math,
47 e_log, utils,
48 g_game // gScreenWidth, gScreenHeight
49 ;
51 const
52 NTR = $FF;
53 NTG = $00;
54 NTB = $00;
55 NTA = $FF;
57 procedure SetupMatrix;
58 begin
59 glScissor(0, 0, gScreenWidth, gScreenHeight);
60 glViewport(0, 0, gScreenWidth, gScreenHeight);
61 glMatrixMode(GL_PROJECTION);
62 glLoadIdentity;
63 glOrtho(0, gScreenWidth, gScreenHeight, 0, 0, 1);
64 glMatrixMode(GL_MODELVIEW);
65 glLoadIdentity;
66 end;
68 procedure DrawQuad (x, y, w, h: Integer);
69 begin
70 glBegin(GL_QUADS);
71 glVertex2i(x + w, y);
72 glVertex2i(x, y);
73 glVertex2i(x, y + h);
74 glVertex2i(x + w, y + h);
75 glEnd();
76 end;
78 procedure DrawTile (tile: TGLAtlasNode; x, y, w, h: Integer; flip: Boolean; rr, gg, bb, aa: Byte; blend: Boolean);
79 var nw, nh, ax, bx, ay, by: GLfloat; l, t, r, b: Integer;
80 begin
81 if tile = nil then
82 begin
83 glColor4ub(rr, gg, bb, aa);
84 if blend then glBlendFunc(GL_SRC_ALPHA, GL_ONE) else glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
85 glDisable(GL_TEXTURE_2D);
86 glEnable(GL_BLEND);
87 DrawQuad(x, y, w, h);
88 end
89 else
90 begin
91 nw := tile.base.w;
92 nh := tile.base.h;
93 ax := IfThen(flip, tile.l, tile.r + 1) / nw;
94 bx := IfThen(flip, tile.r + 1, tile.l) / nh;
95 ay := (tile.t) / nw;
96 by := (tile.b + 1) / nh;
97 l := x; t := y; r := x + w; b := y + h;
98 glBindTexture(GL_TEXTURE_2D, tile.id);
99 glColor4ub(rr, gg, bb, aa);
100 if blend then glBlendFunc(GL_SRC_ALPHA, GL_ONE) else glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
101 glEnable(GL_TEXTURE_2D);
102 glEnable(GL_BLEND);
103 glBegin(GL_QUADS);
104 glTexCoord2f(ax, ay); glVertex2i(r, t);
105 glTexCoord2f(bx, ay); glVertex2i(l, t);
106 glTexCoord2f(bx, by); glVertex2i(l, b);
107 glTexCoord2f(ax, by); glVertex2i(r, b);
108 glEnd();
109 glDisable(GL_TEXTURE_2D);
110 glBindTexture(GL_TEXTURE_2D, 0);
111 end
112 end;
114 procedure r_Draw_Texture (img: TGLTexture; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean);
115 var i, j, offx, offy: Integer; n: TGLAtlasNode;
116 begin
117 ASSERT(w >= 0);
118 ASSERT(h >= 0);
119 if img = nil then
120 DrawTile(nil, x, y, w, h, flip, NTR, NTB, NTG, NTA, blend)
121 else
122 begin
123 offx := 0;
124 offy := 0;
125 for j := 0 to img.lines - 1 do
126 begin
127 for i := 0 to img.cols - 1 do
128 begin
129 n := img.GetTile(i, j);
130 ASSERT(n <> nil);
131 glPushMatrix;
132 glTranslatef(x + offx, y + offy, 0);
133 glScalef(w / img.width, h / img.height, 1);
134 DrawTile(n, 0, 0, n.width, n.height, flip, r, g, b, a, blend);
135 glPopMatrix;
136 offx := offx + n.width;
137 end;
138 offx := 0;
139 offy := offy + n.height;
140 end;
141 end
142 end;
144 procedure r_Draw_TextureRepeat (img: TGLTexture; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean);
145 var i, j: Integer;
146 begin
147 ASSERT(w >= 0);
148 ASSERT(h >= 0);
149 if img = nil then
150 r_Draw_Texture(nil, x, y, w, h, flip, NTR, NTG, NTB, NTB, blend)
151 else
152 for j := 0 to (h - 1) div img.height do
153 for i := 0 to (w - 1) div img.width do
154 r_Draw_Texture(img, x + i * img.width, y + j * img.height, img.width, img.height, flip, r, g, b, a, blend);
155 end;
157 procedure r_Draw_TextureRepeatRotate (img: TGLTexture; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean; rx, ry, angle: Integer);
158 begin
159 ASSERT(w >= 0);
160 ASSERT(h >= 0);
161 if a <> 0 then
162 begin
163 glPushMatrix;
164 glTranslatef(x + rx, y + ry, 0);
165 glRotatef(angle, 0, 0, 1);
166 glTranslatef(-(x + rx), -(y + ry), 0);
167 r_Draw_TextureRepeat(img, x, y, w, h, flip, r, g, b, a, blend);
168 glPopMatrix;
169 end
170 else
171 r_Draw_TextureRepeat(img, x, y, w, h, flip, r, g, b, a, blend);
172 end;
174 procedure r_Draw_MultiTextureRepeat (m: TGLMultiTexture; const anim: TAnimState; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean);
175 var img: TGLTexture; cur, total, i: Integer;
176 begin
177 ASSERT(anim.IsValid());
178 if m = nil then
179 r_Draw_TextureRepeat(nil, x, y, w, h, flip, NTR, NTG, NTB, NTB, blend)
180 else
181 begin
182 if m.BackAnim then
183 begin
184 total := m.count * 2 - 1;
185 cur := anim.CurrentFrame mod total;
186 if cur < m.count then i := cur else i := total - cur - 1;
187 end
188 else
189 i := anim.CurrentFrame mod m.count;
190 img := m.GetTexture(i);
191 r_Draw_TextureRepeat(img, x, y, w, h, flip, r, g, b, a, blend);
192 end
193 end;
195 procedure r_Draw_MultiTextureRepeatRotate (m: TGLMultiTexture; const anim: TAnimState; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean; rx, ry, angle: Integer);
196 begin
197 ASSERT(w >= 0);
198 ASSERT(h >= 0);
199 if a <> 0 then
200 begin
201 glPushMatrix;
202 glTranslatef(x + rx, y + ry, 0);
203 glRotatef(angle, 0, 0, 1);
204 glTranslatef(-(x + rx), -(y + ry), 0);
205 r_Draw_MultiTextureRepeat(m, anim, x, y, w, h, flip, r, g, b, a, blend);
206 glPopMatrix;
207 end
208 else
209 r_Draw_MultiTextureRepeat(m, anim, x, y, w, h, flip, r, g, b, a, blend);
210 end;
212 procedure r_Draw_Filter (l, t, r, b: Integer; rr, gg, bb, aa: Byte);
213 begin
214 ASSERT(r >= l);
215 ASSERT(b >= t);
216 glEnable(GL_BLEND);
217 glBlendFunc(GL_ZERO, GL_SRC_COLOR);
218 glDisable(GL_TEXTURE_2D);
219 glColor4ub(rr, gg, bb, aa);
220 glBegin(GL_QUADS);
221 glVertex2i(l, t);
222 glVertex2i(r, t);
223 glVertex2i(r, b);
224 glVertex2i(l, b);
225 glEnd;
226 end;
228 procedure r_Draw_FillRect (l, t, r, b: Integer; rr, gg, bb, aa: Byte);
229 begin
230 ASSERT(r >= l);
231 ASSERT(b >= t);
232 glEnable(GL_BLEND);
233 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
234 glDisable(GL_TEXTURE_2D);
235 glColor4ub(rr, gg, bb, aa);
236 glBegin(GL_QUADS);
237 glVertex2i(l, t);
238 glVertex2i(r, t);
239 glVertex2i(r, b);
240 glVertex2i(l, b);
241 glEnd;
242 end;
244 procedure r_Draw_InvertRect (l, t, r, b: Integer; rr, gg, bb, aa: Byte);
245 begin
246 ASSERT(r >= l);
247 ASSERT(b >= t);
248 glEnable(GL_BLEND);
249 glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO);
250 glDisable(GL_TEXTURE_2D);
251 glColor4ub(rr, gg, bb, aa);
252 glBegin(GL_QUADS);
253 glVertex2i(l, t);
254 glVertex2i(r, t);
255 glVertex2i(r, b);
256 glVertex2i(l, b);
257 glEnd;
258 end;
260 procedure r_Draw_Text (const text: AnsiString; x, y: Integer; r, g, b, a: Byte; f: TGLFont);
261 var i, xoff: Integer; t: TGLTexture; ch: AnsiChar;
262 begin
263 xoff := x;
264 for i := 1 to Length(text) do
265 begin
266 ch := text[i];
267 t := f.GetChar(ch);
268 if t <> nil then
269 r_Draw_Texture(t, xoff, y, t.width, t.height, false, r, g, b, a, false);
270 Inc(xoff, f.GetWidth(ch) + f.GetSpace());
271 end;
272 end;
274 end.