1 (* Copyright (C) Doom 2D: Forever Developers
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.
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.
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/>.
15 {$INCLUDE ../../../shared/a_modes.inc}
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 procedure r_Draw_EnableTexture2D (enable
: Boolean);
45 procedure r_Draw_SetColor (r
, g
, b
, a
: Byte);
55 SysUtils
, Classes
, Math
,
66 sl
, st
, sr
, sb
: Integer;
67 ScreenWidth
, ScreenHeight
: Integer;
69 enableTexture2D
: Boolean;
70 curR
, curG
, curB
, curA
: Byte;
72 procedure r_Draw_EnableTexture2D (enable
: Boolean);
74 if enable
<> enableTexture2D
then
76 if enable
then glEnable(GL_TEXTURE_2D
) else glDisable(GL_TEXTURE_2D
);
77 enableTexture2D
:= enable
;
81 procedure r_Draw_SetColor (r
, g
, b
, a
: Byte);
83 if (r
<> curR
) or (g
<> curG
) or (b
<> curB
) or (curA
<> a
) then
85 glColor4ub(r
, g
, b
, a
);
93 procedure r_Draw_Setup (w
, h
: Integer);
99 glScissor(0, 0, w
, h
);
100 glViewport(0, 0, w
, h
);
101 glMatrixMode(GL_PROJECTION
);
103 glOrtho(0, w
, h
, 0, 0, 1);
104 glMatrixMode(GL_MODELVIEW
);
106 glEnable(GL_SCISSOR_TEST
);
107 r_Draw_SetRect(0, 0, w
- 1, h
- 1);
110 procedure DrawQuad (x
, y
, w
, h
: Integer);
113 glVertex2i(x
+ w
, y
);
115 glVertex2i(x
, y
+ h
);
116 glVertex2i(x
+ w
, y
+ h
);
120 procedure DrawTile (tile
: TGLAtlasNode
; x
, y
, w
, h
: Integer; flip
: Boolean; rr
, gg
, bb
, aa
: Byte; blend
: Boolean);
121 var nw
, nh
, ax
, bx
, ay
, by
: GLfloat
; l
, t
, r
, b
: Integer;
125 r_Draw_SetColor(rr
, gg
, bb
, aa
);
126 if blend
then glBlendFunc(GL_SRC_ALPHA
, GL_ONE
) else glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
127 r_Draw_EnableTexture2D(false);
129 DrawQuad(x
, y
, w
, h
);
135 ax
:= IfThen(flip
, tile
.l
, tile
.r
+ 1) / nw
;
136 bx
:= IfThen(flip
, tile
.r
+ 1, tile
.l
) / nh
;
138 by
:= (tile
.b
+ 1) / nh
;
139 l
:= x
; t
:= y
; r
:= x
+ w
; b
:= y
+ h
;
140 r_Textures_GL_Bind(tile
.id
);
141 r_Draw_SetColor(rr
, gg
, bb
, aa
);
142 r_Draw_EnableTexture2D(true);
143 if blend
then glBlendFunc(GL_SRC_ALPHA
, GL_ONE
) else glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
146 glTexCoord2f(ax
, ay
); glVertex2i(r
, t
);
147 glTexCoord2f(bx
, ay
); glVertex2i(l
, t
);
148 glTexCoord2f(bx
, by
); glVertex2i(l
, b
);
149 glTexCoord2f(ax
, by
); glVertex2i(r
, b
);
154 procedure DrawHWTexture (gltex
: GLint
; nw
, nh
, x
, y
, w
, h
: Integer; flip
: Boolean; rr
, gg
, bb
, aa
: Byte; blend
: Boolean);
155 var ax
, bx
, ay
, by
: GLfloat
; l
, t
, r
, b
: Integer;
157 ax
:= IfThen(flip
, 0, w
) / nw
;
158 bx
:= IfThen(flip
, w
, 0) / nh
;
161 l
:= x
; t
:= y
; r
:= x
+ w
; b
:= y
+ h
;
162 r_Textures_GL_Bind(gltex
);
163 r_Draw_SetColor(rr
, gg
, bb
, aa
);
164 r_Draw_EnableTexture2D(true);
165 if blend
then glBlendFunc(GL_SRC_ALPHA
, GL_ONE
) else glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
168 glTexCoord2f(ax
, ay
); glVertex2i(r
, t
);
169 glTexCoord2f(bx
, ay
); glVertex2i(l
, t
);
170 glTexCoord2f(bx
, by
); glVertex2i(l
, b
);
171 glTexCoord2f(ax
, by
); glVertex2i(r
, b
);
175 procedure r_Draw_Texture (img
: TGLTexture
; x
, y
, w
, h
: Integer; flip
: Boolean; r
, g
, b
, a
: Byte; blend
: Boolean);
176 var i
, j
, first
, last
, step
: Integer; n
: TGLAtlasNode
;
181 DrawTile(nil, x
, y
, w
, h
, flip
, NTR
, NTB
, NTG
, NTA
, blend
)
184 if flip
then first
:= img
.cols
- 1 else first
:= 0;
185 if flip
then last
:= -1 else last
:= img
.cols
;
186 if flip
then step
:= -1 else step
:= +1;
188 glTranslatef(x
, y
, 0);
189 glScalef(w
/ img
.width
, h
/ img
.height
, 1);
190 for j
:= 0 to img
.lines
- 1 do
194 n
:= img
.GetTile(i
, j
);
196 DrawTile(n
, 0, 0, n
.width
, n
.height
, flip
, r
, g
, b
, a
, blend
);
197 glTranslatef(n
.width
, 0, 0);
200 glTranslatef(-img
.width
, n
.height
, 0);
206 function r_Draw_IsHWRepeatable (img
: TGLTexture
): Boolean;
207 var n
: TGLAtlasNode
; a
: TGLAtlas
;
211 if (img
.cols
= 1) and (img
.lines
= 1) then
213 n
:= img
.GetTile(0, 0);
214 if (n
.width
= img
.width
) and (n
.height
= img
.height
) then
217 result
:= (a
.GetWidth() = img
.width
) and (a
.GetHeight() = img
.height
)
222 procedure r_Draw_TextureRepeat (img
: TGLTexture
; x
, y
, w
, h
: Integer; flip
: Boolean; r
, g
, b
, a
: Byte; blend
: Boolean);
228 r_Draw_Texture(nil, x
, y
, w
, h
, flip
, NTR
, NTG
, NTB
, NTB
, blend
)
229 else if r_Draw_IsHWRepeatable(img
) then
230 DrawHWTexture(img
.GetTile(0, 0).base
.id
, img
.width
, img
.height
, x
, y
, w
, h
, flip
, r
, g
, b
, a
, blend
)
232 for j
:= 0 to (h
- 1) div img
.height
do
233 for i
:= 0 to (w
- 1) div img
.width
do
234 r_Draw_Texture(img
, x
+ i
* img
.width
, y
+ j
* img
.height
, img
.width
, img
.height
, flip
, r
, g
, b
, a
, blend
);
237 procedure r_Draw_TextureRepeatRotate (img
: TGLTexture
; x
, y
, w
, h
: Integer; flip
: Boolean; r
, g
, b
, a
: Byte; blend
: Boolean; rx
, ry
, angle
: Integer);
244 glTranslatef(x
+ rx
, y
+ ry
, 0);
245 glRotatef(angle
, 0, 0, 1);
246 glTranslatef(-(x
+ rx
), -(y
+ ry
), 0);
247 r_Draw_TextureRepeat(img
, x
, y
, w
, h
, flip
, r
, g
, b
, a
, blend
);
251 r_Draw_TextureRepeat(img
, x
, y
, w
, h
, flip
, r
, g
, b
, a
, blend
);
254 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);
255 var img
: TGLTexture
; frame
: LongInt;
257 ASSERT(anim
.IsValid());
259 r_Draw_TextureRepeat(nil, x
, y
, w
, h
, flip
, NTR
, NTG
, NTB
, NTB
, blend
)
262 g_Anim_GetFrameFromState(anim
, backanim
, frame
);
264 ASSERT(frame
< m
.count
);
265 img
:= m
.GetTexture(frame
);
266 r_Draw_TextureRepeat(img
, x
, y
, w
, h
, flip
, r
, g
, b
, a
, blend
);
270 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);
277 glTranslatef(x
+ rx
, y
+ ry
, 0);
278 glRotatef(angle
, 0, 0, 1);
279 glTranslatef(-(x
+ rx
), -(y
+ ry
), 0);
280 r_Draw_MultiTextureRepeat(m
, anim
, backanim
, x
, y
, w
, h
, flip
, r
, g
, b
, a
, blend
);
284 r_Draw_MultiTextureRepeat(m
, anim
, backanim
, x
, y
, w
, h
, flip
, r
, g
, b
, a
, blend
);
287 procedure r_Draw_Filter (l
, t
, r
, b
: Integer; rr
, gg
, bb
, aa
: Byte);
292 glBlendFunc(GL_ZERO
, GL_SRC_COLOR
);
293 r_Draw_EnableTexture2D(false);
294 r_Draw_SetColor(rr
, gg
, bb
, aa
);
303 procedure r_Draw_Rect (l
, t
, r
, b
: Integer; rr
, gg
, bb
, aa
: Byte);
308 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
309 r_Draw_EnableTexture2D(false);
310 r_Draw_SetColor(rr
, gg
, bb
, aa
);
311 glBegin(GL_LINE_LOOP
);
318 glVertex2f(l
+ 0.5, t
+ 0.5);
319 glVertex2f(r
- 0.5, t
+ 0.5);
320 glVertex2f(r
- 0.5, b
- 0.5);
321 glVertex2f(l
+ 0.5, b
- 0.5);
325 procedure r_Draw_FillRect (l
, t
, r
, b
: Integer; rr
, gg
, bb
, aa
: Byte);
330 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
331 r_Draw_EnableTexture2D(false);
332 r_Draw_SetColor(rr
, gg
, bb
, aa
);
341 glVertex2f(l + 0.5, t + 0.5);
342 glVertex2f(r - 0.5, t + 0.5);
343 glVertex2f(r - 0.5, b - 0.5);
344 glVertex2f(l + 0.5, b - 0.5);
346 glVertex2f(l
+ 0, t
+ 0);
347 glVertex2f(r
+ 0.75, t
+ 0);
348 glVertex2f(r
+ 0.75, b
+ 0.75);
349 glVertex2f(l
+ 0, b
+ 0.75);
353 procedure r_Draw_InvertRect (l
, t
, r
, b
: Integer; rr
, gg
, bb
, aa
: Byte);
358 glBlendFunc(GL_ONE_MINUS_DST_COLOR
, GL_ZERO
);
359 r_Draw_EnableTexture2D(false);
360 r_Draw_SetColor(rr
, gg
, bb
, aa
);
369 procedure r_Draw_Text (const text: AnsiString; x
, y
: Integer; r
, g
, b
, a
: Byte; f
: TGLFont
);
370 var i
, xoff
, spc
: Integer; t
: TGLTexture
; ch
: AnsiChar;
372 xoff
:= x
; spc
:= MAX(0, f
.GetSpace());
373 for i
:= 1 to Length(text) do
378 r_Draw_Texture(t
, xoff
, y
, t
.width
, t
.height
, false, r
, g
, b
, a
, false);
379 Inc(xoff
, f
.GetWidth(ch
) + spc
);
383 procedure r_Draw_GetTextSize (const text: AnsiString; f
: TGLFont
; out w
, h
: Integer);
384 var i
, spc
, len
: Integer;
387 h
:= f
.GetMaxHeight();
391 spc
:= MAX(0, f
.GetSpace());
392 for i
:= 1 to len
- 1 do
393 Inc(w
, f
.GetWidth(text[i
]) + spc
);
394 Inc(w
, f
.GetWidth(text[len
]));
398 procedure r_Draw_SetRect (l
, t
, r
, b
: Integer);
405 glScissor(l
, ScreenHeight
- h
- t
, w
, h
);
406 sl
:= l
; st
:= t
; sr
:= r
; sb
:= b
;
409 procedure r_Draw_GetRect (out l
, t
, r
, b
: Integer);
411 l
:= sl
; t
:= st
; r
:= sr
; b
:= sb
;