DEADSOFTWARE

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