DEADSOFTWARE

gl: draw gibs
[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 glPushMatrix;
120 glScalef(w / img.width, h / img.height, 1);
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 DrawTile(n, x + offx, y + offy, n.width, n.height, flip, r, g, b, a, blend);
130 offx := offx + n.width;
131 end;
132 offx := 0;
133 offy := offy + n.height;
134 end;
135 glPopMatrix;
136 end
137 end;
139 procedure r_Draw_TextureRepeat (img: TGLTexture; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean);
140 var i, j: Integer;
141 begin
142 ASSERT(w >= 0);
143 ASSERT(h >= 0);
144 if img = nil then
145 r_Draw_Texture(nil, x, y, w, h, flip, NTR, NTG, NTB, NTB, blend)
146 else
147 for j := 0 to h div img.height - 1 do
148 for i := 0 to w div img.width - 1 do
149 r_Draw_Texture(img, x + i * img.width, y + j * img.height, img.width, img.height, flip, r, g, b, a, blend);
150 end;
152 procedure r_Draw_TextureRepeatRotate (img: TGLTexture; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean; rx, ry, angle: Integer);
153 begin
154 ASSERT(w >= 0);
155 ASSERT(h >= 0);
156 if a <> 0 then
157 begin
158 glPushMatrix;
159 glTranslatef(x + rx, y + ry, 0);
160 glRotatef(angle, 0, 0, 1);
161 glTranslatef(-(x + rx), -(y + ry), 0);
162 r_Draw_TextureRepeat(img, x, y, w, h, flip, r, g, b, a, blend);
163 glPopMatrix;
164 end
165 else
166 r_Draw_TextureRepeat(img, x, y, w, h, flip, r, g, b, a, blend);
167 end;
169 procedure r_Draw_MultiTextureRepeat (m: TGLMultiTexture; const anim: TAnimState; x, y, w, h: Integer; flip: Boolean; r, g, b, a: Byte; blend: Boolean);
170 var img: TGLTexture; cur, total, i: Integer;
171 begin
172 ASSERT(anim.IsValid());
173 if m = nil then
174 r_Draw_TextureRepeat(nil, x, y, w, h, flip, NTR, NTG, NTB, NTB, blend)
175 else
176 begin
177 if m.BackAnim then
178 begin
179 total := m.count * 2 - 1;
180 cur := anim.CurrentFrame mod total;
181 if cur < m.count then i := cur else i := total - cur - 1;
182 end
183 else
184 i := anim.CurrentFrame mod m.count;
185 img := m.GetTexture(i);
186 r_Draw_TextureRepeat(img, x, y, w, h, flip, r, g, b, a, blend);
187 end
188 end;
190 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);
191 begin
192 ASSERT(w >= 0);
193 ASSERT(h >= 0);
194 if a <> 0 then
195 begin
196 glPushMatrix;
197 glTranslatef(x + rx, y + ry, 0);
198 glRotatef(angle, 0, 0, 1);
199 glTranslatef(-(x + rx), -(y + ry), 0);
200 r_Draw_MultiTextureRepeat(m, anim, x, y, w, h, flip, r, g, b, a, blend);
201 glPopMatrix;
202 end
203 else
204 r_Draw_MultiTextureRepeat(m, anim, x, y, w, h, flip, r, g, b, a, blend);
205 end;
207 procedure r_Draw_Filter (l, t, r, b: Integer; rr, gg, bb, aa: Byte);
208 begin
209 ASSERT(r >= l);
210 ASSERT(b >= t);
211 glEnable(GL_BLEND);
212 glBlendFunc(GL_ZERO, GL_SRC_COLOR);
213 glDisable(GL_TEXTURE_2D);
214 glColor4ub(rr, gg, bb, aa);
215 glBegin(GL_QUADS);
216 glVertex2i(l, t);
217 glVertex2i(r, t);
218 glVertex2i(r, b);
219 glVertex2i(l, b);
220 glEnd;
221 end;
223 end.