DEADSOFTWARE

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