Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
draw.qc
Go to the documentation of this file.
1#include "draw.qh"
2
3#include <client/hud/hud.qh>
4
5void drawborderlines(float thickness, vector pos, vector dim, vector color, float theAlpha, float drawflag)
6{
7 vector line_dim = '0 0 0';
8
9 // left and right lines
10 pos.x -= thickness;
11 line_dim.x = thickness;
12 line_dim.y = dim.y;
13 drawfill(pos, line_dim, color, theAlpha, drawflag);
14 drawfill(pos + (dim.x + thickness) * '1 0 0', line_dim, color, theAlpha, drawflag);
15
16 // upper and lower lines
17 pos.y -= thickness;
18 line_dim.x = dim.x + thickness * 2; // make upper and lower lines longer
19 line_dim.y = thickness;
20 drawfill(pos, line_dim, color, theAlpha, drawflag);
21 drawfill(pos + (dim.y + thickness) * '0 1 0', line_dim, color, theAlpha, drawflag);
22}
23
24void drawpic_tiled(vector pos, string pic, vector sz, vector area, vector color, float theAlpha, float drawflag)
25{
26 pos = HUD_Shift(pos);
27 sz = HUD_Scale(sz);
28 area = HUD_Scale(area);
29
30 vector current_pos = '0 0 0', end_pos, new_size = '0 0 0', ratio = '0 0 0';
31 end_pos = pos + area;
32
33 current_pos.y = pos.y;
34 while (current_pos.y < end_pos.y)
35 {
36 current_pos.x = pos.x;
37 while (current_pos.x < end_pos.x)
38 {
39 new_size.x = min(sz.x, end_pos.x - current_pos.x);
40 new_size.y = min(sz.y, end_pos.y - current_pos.y);
41 ratio.x = new_size.x / sz.x;
42 ratio.y = new_size.y / sz.y;
43 drawsubpic(current_pos, new_size, pic, '0 0 0', ratio, color, theAlpha, drawflag);
44 current_pos.x += sz.x;
45 }
46 current_pos.y += sz.y;
47 }
48}
49
51{
52 return 1.2 / (1.2 - fadelerp);
53}
54
55vector expandingbox_resize_centered_box_offset(float sz, vector boxsize, float boxxsizefactor)
56{
57 boxsize.x *= boxxsizefactor; // easier interface for text
58 return boxsize * (0.5 * (1 - sz));
59}
60
61void drawpic_aspect_skin_expanding(vector position, string pic, vector theScale, vector rgb, float theAlpha, float flag, float fadelerp)
62{
63 float sz = expandingbox_sizefactor_from_fadelerp(fadelerp);
64
65 drawpic_aspect_skin(position + expandingbox_resize_centered_box_offset(sz, theScale, 1), pic, theScale * sz, rgb, theAlpha * (1 - fadelerp), flag);
66}
67
68void drawpic_aspect_skin_expanding_two(vector position, string pic, vector theScale, vector rgb, float theAlpha, float flag, float fadelerp)
69{
70 drawpic_aspect_skin_expanding(position, pic, theScale, rgb, theAlpha, flag, fadelerp);
71 drawpic_skin(position, pic, theScale, rgb, theAlpha * fadelerp, flag);
72}
73
74float stringwidth(string text, float handleColors, vector sz)
75{
77 drawfontscale = '1 1 0';
78 float r = stringwidth_builtin(text, handleColors, sz);
79 drawfontscale = dfs;
80 return r;
81}
82
83// it scales text up to box width
84// NOTE it doesn't work perfectly because r_font_size_snapping 4 (default value)
85// may render text with a slightly different size making text bigger or smaller
86// NOTE this is implemented as a macro to reduce number of function calls per frame
87#define DRAWSTRING_ASPECT_SCALE(pos, text, sz, allow_colors) MACRO_BEGIN \
88 float textaspect, oldsz; \
89 vector dfs = drawfontscale; \
90 drawfontscale = '1 1 0'; \
91 textaspect = stringwidth(text, allow_colors, '1 1 1' * sz.y) / sz.y; \
92 if(sz.x/sz.y > textaspect) { \
93 oldsz = sz.x; \
94 sz.x = sz.y * textaspect; \
95 pos.x += (oldsz - sz.x) * 0.5; \
96 } else { \
97 oldsz = sz.y; \
98 sz.y = sz.x / textaspect; \
99 pos.y += (oldsz - sz.y) * 0.5; \
100 /* in case text is rendered with a different size, at least recenter it horizontally */ \
101 /* unfortunately there is no way to correctly recenter it vertically */ \
102 float new_textwidth = stringwidth(text, allow_colors, '1 1 1' * sz.y); \
103 pos.x += (sz.x - new_textwidth) * 0.5; \
104 } \
105 drawfontscale = dfs; \
106MACRO_END
107
108// drawstring wrapper to draw a string as large as possible with preserved aspect ratio into a box
109void drawstring_aspect(vector pos, string text, vector sz, vector color, float theAlpha, float drawflag) {
110 DRAWSTRING_ASPECT_SCALE(pos, text, sz, false);
111 drawstring(pos, text, '1 1 0' * sz.y, color, theAlpha, drawflag);
112}
113
114// drawstring wrapper to draw a colorcodedstring as large as possible with preserved aspect ratio into a box
115void drawcolorcodedstring_aspect(vector pos, string text, vector sz, float theAlpha, float drawflag) {
116 DRAWSTRING_ASPECT_SCALE(pos, text, sz, true);
117 drawcolorcodedstring(pos, text, '1 1 0' * sz.y, theAlpha, drawflag);
118}
119
120void drawstring_expanding(vector position, string text, vector theScale, vector rgb, float theAlpha, float flag, float fadelerp)
121{
122 float sz = expandingbox_sizefactor_from_fadelerp(fadelerp);
123
125 vector dfs = drawfontscale;
126 drawfontscale = sz * '1 1 0';
127 float textaspect = stringwidth_builtin(text, false, theScale * (sz / drawfontscale.x)) / (theScale.x * sz);
128 drawfontscale = dfs;
129 drawstring(position + expandingbox_resize_centered_box_offset(sz, theScale, textaspect), text, HUD_Scale(theScale * (sz / drawfontscale.x)), rgb, theAlpha * (1 - fadelerp), flag);
130 // width parameter:
131 // (scale_x * sz / drawfontscale.x) * drawfontscale.x * SIZE1 / (scale_x * sz)
132 // SIZE1
134}
135
136// drawstring wrapper to draw a string as large as possible with preserved aspect ratio into a box
137void drawstring_aspect_expanding(vector pos, string text, vector sz, vector color, float theAlpha, float drawflag, float fadelerp) {
138 DRAWSTRING_ASPECT_SCALE(pos, text, sz, false);
139 drawstring_expanding(pos, text, '1 1 0' * sz.y, color, theAlpha, drawflag, fadelerp);
140}
141
142void drawcolorcodedstring_expanding(vector position, string text, vector theScale, float theAlpha, float flag, float fadelerp)
143{
144 float sz = expandingbox_sizefactor_from_fadelerp(fadelerp);
145
147 // eventually replace with drawcolorcodedstring
148 drawcolorcodedstring(position + expandingbox_resize_centered_box_offset(sz, theScale, stringwidth_builtin(text, true, theScale * (sz / drawfontscale.x)) / (theScale.x * sz)), text, theScale * (sz / drawfontscale.x), theAlpha * (1 - fadelerp), flag);
150}
151
152void drawcolorcodedstring_aspect_expanding(vector pos, string text, vector sz, float theAlpha, float drawflag, float fadelerp) {
153 DRAWSTRING_ASPECT_SCALE(pos, text, sz, true);
154 drawcolorcodedstring_expanding(pos, text, '1 1 0' * sz.y, theAlpha, drawflag, fadelerp);
155}
156
157// this draws the triangles of a model DIRECTLY. Don't expect high performance, really...
158float PolyDrawModelSurface(entity e, float i_s)
159{
160 string tex = getsurfacetexture(e, i_s);
161 if (!tex)
162 return 0; // this is beyond the last one
163 vector tri;
164 float n_t = getsurfacenumtriangles(e, i_s);
165 for(int i_t = 0; i_t < n_t; ++i_t)
166 {
167 tri = getsurfacetriangle(e, i_s, i_t);
168 R_BeginPolygon(tex, 0, false);
169 R_PolygonVertex(getsurfacepoint(e, i_s, tri.x), getsurfacepointattribute(e, i_s, tri.x, SPA_TEXCOORDS0), '1 1 1', 1);
170 R_PolygonVertex(getsurfacepoint(e, i_s, tri.y), getsurfacepointattribute(e, i_s, tri.y, SPA_TEXCOORDS0), '1 1 1', 1);
171 R_PolygonVertex(getsurfacepoint(e, i_s, tri.z), getsurfacepointattribute(e, i_s, tri.z, SPA_TEXCOORDS0), '1 1 1', 1);
172 R_EndPolygon();
173 }
174 return 1;
175}
177{
178 for(int i_s = 0; ; ++i_s)
179 if(!PolyDrawModelSurface(e, i_s))
180 break;
181}
182
183void DrawCircleClippedPic(vector centre, float radi, string pic, float f, vector rgb, float a, float drawflag)
184{
185 vector ringsize, v, t;
186 ringsize = radi * '1 1 0';
187 centre = HUD_Shift(centre);
188 ringsize = HUD_Scale(ringsize);
189
190 if(f >= 1)
191 {
192 // draw full rectangle
193 R_BeginPolygon(pic, drawflag, true);
194 v = centre; t = '0.5 0.5 0';
195 v.x += 0.5 * ringsize.x; t += '0.5 0.5 0';
196 R_PolygonVertex(v, t, rgb, a);
197
198 v = centre; t = '0.5 0.5 0';
199 v.y += 0.5 * ringsize.y; t += '0.5 -0.5 0';
200 R_PolygonVertex(v, t, rgb, a);
201
202 v = centre; t = '0.5 0.5 0';
203 v.x -= 0.5 * ringsize.x; t -= '0.5 0.5 0';
204 R_PolygonVertex(v, t, rgb, a);
205
206 v = centre; t = '0.5 0.5 0';
207 v.y -= 0.5 * ringsize.y; t -= '0.5 -0.5 0';
208 R_PolygonVertex(v, t, rgb, a);
209 R_EndPolygon();
210 return; // Complete rectangle, nothing more needed.
211 }
212
213 float co = cos(f * (2 * M_PI));
214 float si = sin(f * (2 * M_PI));
215 float q = fabs(co) + fabs(si);
216 co /= q;
217 si /= q;
218
219 if(f > 0.75)
220 {
221 // draw upper half in full
222 R_BeginPolygon(pic, drawflag, true);
223 v = centre; t = '0.5 0.5 0';
224 v.x += 0.5 * ringsize.x; t += '0.5 0.5 0';
225 R_PolygonVertex(v, t, rgb, a);
226
227 v = centre; t = '0.5 0.5 0';
228 v.y += 0.5 * ringsize.y; t += '0.5 -0.5 0';
229 R_PolygonVertex(v, t, rgb, a);
230
231 v = centre; t = '0.5 0.5 0';
232 v.x -= 0.5 * ringsize.x; t -= '0.5 0.5 0';
233 R_PolygonVertex(v, t, rgb, a);
234 R_EndPolygon();
235 // draw clipped lower half as a quad
236 R_BeginPolygon(pic, drawflag, true);
237 v = centre; t = '0.5 0.5 0';
238 R_PolygonVertex(v, t, rgb, a);
239
240 v = centre; t = '0.5 0.5 0';
241 v.x -= 0.5 * ringsize.x; t -= '0.5 0.5 0';
242 R_PolygonVertex(v, t, rgb, a);
243
244 v = centre; t = '0.5 0.5 0';
245 v.y -= 0.5 * ringsize.y; t -= '0.5 -0.5 0';
246 R_PolygonVertex(v, t, rgb, a);
247 }
248 else if(f > 0.5)
249 {
250 // draw upper half in full
251 R_BeginPolygon(pic, drawflag, true);
252 v = centre; t = '0.5 0.5 0';
253 v.x += 0.5 * ringsize.x; t += '0.5 0.5 0';
254 R_PolygonVertex(v, t, rgb, a);
255
256 v = centre; t = '0.5 0.5 0';
257 v.y += 0.5 * ringsize.y; t += '0.5 -0.5 0';
258 R_PolygonVertex(v, t, rgb, a);
259
260 v = centre; t = '0.5 0.5 0';
261 v.x -= 0.5 * ringsize.x; t -= '0.5 0.5 0';
262 R_PolygonVertex(v, t, rgb, a);
263 R_EndPolygon();
264 // draw clipped lower half as a triangle
265 R_BeginPolygon(pic, drawflag, true);
266 v = centre; t = '0.5 0.5 0';
267 R_PolygonVertex(v, t, rgb, a);
268
269 v = centre; t = '0.5 0.5 0';
270 v.x -= 0.5 * ringsize.x; t -= '0.5 0.5 0';
271 R_PolygonVertex(v, t, rgb, a);
272 }
273 else if(f > 0.25)
274 {
275 // draw clipped lower half as a quad
276 R_BeginPolygon(pic, drawflag, true);
277 v = centre; t = '0.5 0.5 0';
278 R_PolygonVertex(v, t, rgb, a);
279
280 v = centre; t = '0.5 0.5 0';
281 v.x += 0.5 * ringsize.x; t += '0.5 0.5 0';
282 R_PolygonVertex(v, t, rgb, a);
283
284 v = centre; t = '0.5 0.5 0';
285 v.y += 0.5 * ringsize.y; t += '0.5 -0.5 0';
286 R_PolygonVertex(v, t, rgb, a);
287 }
288 else if (f > 0)
289 {
290 // draw clipped lower half as a triangle
291 R_BeginPolygon(pic, drawflag, true);
292 v = centre; t = '0.5 0.5 0';
293 R_PolygonVertex(v, t, rgb, a);
294
295 v = centre; t = '0.5 0.5 0';
296 v.x += 0.5 * ringsize.x; t += '0.5 0.5 0';
297 R_PolygonVertex(v, t, rgb, a);
298 }
299 else
300 {
301 // Nothing to draw.
302 return;
303 }
304
305 // The last, moving vertex.
306 v = centre; t = '0.5 0.5 0';
307 v.x += co * 0.5 * ringsize.x; t += co * '0.5 0.5 0';
308 v.y += si * 0.5 * ringsize.y; t += si * '0.5 -0.5 0';
309 R_PolygonVertex(v, t, rgb, a);
310 R_EndPolygon();
311}
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
float expandingbox_sizefactor_from_fadelerp(float fadelerp)
Definition draw.qc:50
void drawstring_aspect(vector pos, string text, vector sz, vector color, float theAlpha, float drawflag)
Definition draw.qc:109
void drawcolorcodedstring_expanding(vector position, string text, vector theScale, float theAlpha, float flag, float fadelerp)
Definition draw.qc:142
void PolyDrawModel(entity e)
Definition draw.qc:176
void drawpic_aspect_skin_expanding(vector position, string pic, vector theScale, vector rgb, float theAlpha, float flag, float fadelerp)
Definition draw.qc:61
void drawpic_tiled(vector pos, string pic, vector sz, vector area, vector color, float theAlpha, float drawflag)
Definition draw.qc:24
void drawcolorcodedstring_aspect(vector pos, string text, vector sz, float theAlpha, float drawflag)
Definition draw.qc:115
void drawborderlines(float thickness, vector pos, vector dim, vector color, float theAlpha, float drawflag)
Definition draw.qc:5
#define DRAWSTRING_ASPECT_SCALE(pos, text, sz, allow_colors)
Definition draw.qc:87
void drawcolorcodedstring_aspect_expanding(vector pos, string text, vector sz, float theAlpha, float drawflag, float fadelerp)
Definition draw.qc:152
vector expandingbox_resize_centered_box_offset(float sz, vector boxsize, float boxxsizefactor)
Definition draw.qc:55
void drawstring_aspect_expanding(vector pos, string text, vector sz, vector color, float theAlpha, float drawflag, float fadelerp)
Definition draw.qc:137
void DrawCircleClippedPic(vector centre, float radi, string pic, float f, vector rgb, float a, float drawflag)
Definition draw.qc:183
void drawstring_expanding(vector position, string text, vector theScale, vector rgb, float theAlpha, float flag, float fadelerp)
Definition draw.qc:120
float PolyDrawModelSurface(entity e, float i_s)
Definition draw.qc:158
void drawpic_aspect_skin_expanding_two(vector position, string pic, vector theScale, vector rgb, float theAlpha, float flag, float fadelerp)
Definition draw.qc:68
#define drawcolorcodedstring(position, text, scale, alpha, flag)
Definition draw.qh:30
#define drawstring(position, text, scale, rgb, alpha, flag)
Definition draw.qh:27
#define drawpic_aspect_skin(pos, pic, sz, color, theAlpha, drawflag)
Definition draw.qh:78
#define drawpic_skin(pos, pic, sz, color, theAlpha, drawflag)
Definition draw.qh:88
vector drawfontscale
Definition draw.qh:3
#define drawfill(position, size, rgb, alpha, flag)
Definition draw.qh:36
float drawsubpic(vector position, vector size, string pic, vector srcPosition, vector srcSize, vector rgb, float alpha, float flag)
#define SPA_TEXCOORDS0
#define stringwidth
vector color
Definition dynlight.qc:15
vector HUD_Shift(vector v)
Definition hud.qc:105
vector HUD_Scale(vector v)
Definition hud.qc:98
vector hud_scale
Definition hud.qh:221
#define M_PI
Definition mathlib.qh:108
float cos(float f)
float sin(float f)
float min(float f,...)
float fabs(float f)
vector
Definition self.qh:92