diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llui/llui.cpp | |
parent | README.txt (diff) | |
download | meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2 meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz |
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/llui/llui.cpp')
-rw-r--r-- | linden/indra/llui/llui.cpp | 1783 |
1 files changed, 1783 insertions, 0 deletions
diff --git a/linden/indra/llui/llui.cpp b/linden/indra/llui/llui.cpp new file mode 100644 index 0000000..c62f353 --- /dev/null +++ b/linden/indra/llui/llui.cpp | |||
@@ -0,0 +1,1783 @@ | |||
1 | /** | ||
2 | * @file llui.cpp | ||
3 | * @brief UI implementation | ||
4 | * | ||
5 | * Copyright (c) 2001-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | // Utilities functions the user interface needs | ||
29 | |||
30 | //#include "llviewerprecompiledheaders.h" | ||
31 | #include "linden_common.h" | ||
32 | |||
33 | #include <string> | ||
34 | #include <map> | ||
35 | |||
36 | // Linden library includes | ||
37 | #include "audioengine.h" | ||
38 | #include "v2math.h" | ||
39 | #include "v4color.h" | ||
40 | #include "llgl.h" | ||
41 | #include "llrect.h" | ||
42 | #include "llimagegl.h" | ||
43 | //#include "llviewerimage.h" | ||
44 | #include "lldir.h" | ||
45 | #include "llfontgl.h" | ||
46 | |||
47 | // Project includes | ||
48 | //#include "audioengine.h" | ||
49 | #include "llcontrol.h" | ||
50 | //#include "llstartup.h" | ||
51 | #include "llui.h" | ||
52 | #include "llview.h" | ||
53 | #include "llwindow.h" | ||
54 | |||
55 | #include "llglheaders.h" | ||
56 | |||
57 | // | ||
58 | // Globals | ||
59 | // | ||
60 | const LLColor4 UI_VERTEX_COLOR(1.f, 1.f, 1.f, 1.f); | ||
61 | |||
62 | // Used to hide the flashing text cursor when window doesn't have focus. | ||
63 | BOOL gShowTextEditCursor = TRUE; | ||
64 | |||
65 | // Language for UI construction | ||
66 | LLString gLanguage = "english-usa"; | ||
67 | std::map<LLString, LLString> gTranslation; | ||
68 | std::list<LLString> gUntranslated; | ||
69 | |||
70 | LLControlGroup* LLUI::sConfigGroup = NULL; | ||
71 | LLControlGroup* LLUI::sColorsGroup = NULL; | ||
72 | LLControlGroup* LLUI::sAssetsGroup = NULL; | ||
73 | LLImageProviderInterface* LLUI::sImageProvider = NULL; | ||
74 | LLUIAudioCallback LLUI::sAudioCallback = NULL; | ||
75 | LLVector2 LLUI::sGLScaleFactor(1.f, 1.f); | ||
76 | LLWindow* LLUI::sWindow = NULL; | ||
77 | BOOL LLUI::sShowXUINames = FALSE; | ||
78 | // | ||
79 | // Functions | ||
80 | // | ||
81 | void make_ui_sound(const LLString& name) | ||
82 | { | ||
83 | if (!LLUI::sConfigGroup->controlExists(name)) | ||
84 | { | ||
85 | llwarns << "tried to make ui sound for unknown sound name: " << name << llendl; | ||
86 | } | ||
87 | else | ||
88 | { | ||
89 | LLUUID uuid(LLUI::sConfigGroup->getString(name)); | ||
90 | if (uuid.isNull()) | ||
91 | { | ||
92 | if ("00000000-0000-0000-0000-000000000000" == LLUI::sConfigGroup->getString(name)) | ||
93 | { | ||
94 | if (LLUI::sConfigGroup->getBOOL("UISndDebugSpamToggle")) | ||
95 | { | ||
96 | llinfos << "ui sound name: " << name << " triggered but silent (null uuid)" << llendl; | ||
97 | } | ||
98 | } | ||
99 | else | ||
100 | { | ||
101 | llwarns << "ui sound named: " << name << " does not translate to a valid uuid" << llendl; | ||
102 | } | ||
103 | |||
104 | } | ||
105 | else if (LLUI::sAudioCallback != NULL) | ||
106 | { | ||
107 | if (LLUI::sConfigGroup->getBOOL("UISndDebugSpamToggle")) | ||
108 | { | ||
109 | llinfos << "ui sound name: " << name << llendl; | ||
110 | } | ||
111 | LLUI::sAudioCallback(uuid, LLUI::sConfigGroup->getF32("AudioLevelUI")); | ||
112 | } | ||
113 | } | ||
114 | } | ||
115 | |||
116 | BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom) | ||
117 | { | ||
118 | if (x < left || right < x) return FALSE; | ||
119 | if (y < bottom || top < y) return FALSE; | ||
120 | return TRUE; | ||
121 | } | ||
122 | |||
123 | |||
124 | // Puts GL into 2D drawing mode by turning off lighting, setting to an | ||
125 | // orthographic projection, etc. | ||
126 | void gl_state_for_2d(S32 width, S32 height) | ||
127 | { | ||
128 | stop_glerror(); | ||
129 | F32 window_width = (F32) width;//gViewerWindow->getWindowWidth(); | ||
130 | F32 window_height = (F32) height;//gViewerWindow->getWindowHeight(); | ||
131 | |||
132 | glMatrixMode(GL_PROJECTION); | ||
133 | glLoadIdentity(); | ||
134 | glOrtho(0.0f, window_width, 0.0f, window_height, -1.0f, 1.0f); | ||
135 | glMatrixMode(GL_MODELVIEW); | ||
136 | glLoadIdentity(); | ||
137 | stop_glerror(); | ||
138 | } | ||
139 | |||
140 | |||
141 | void gl_draw_x(const LLRect& rect, const LLColor4& color) | ||
142 | { | ||
143 | LLGLSNoTexture no_texture; | ||
144 | |||
145 | glColor4fv( color.mV ); | ||
146 | |||
147 | glBegin( GL_LINES ); | ||
148 | glVertex2i( rect.mLeft, rect.mTop ); | ||
149 | glVertex2i( rect.mRight, rect.mBottom ); | ||
150 | glVertex2i( rect.mLeft, rect.mBottom ); | ||
151 | glVertex2i( rect.mRight, rect.mTop ); | ||
152 | glEnd(); | ||
153 | } | ||
154 | |||
155 | |||
156 | void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset, BOOL filled) | ||
157 | { | ||
158 | glColor4fv(color.mV); | ||
159 | gl_rect_2d_offset_local(left, top, right, bottom, pixel_offset, filled); | ||
160 | } | ||
161 | |||
162 | void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset, BOOL filled) | ||
163 | { | ||
164 | glPushMatrix(); | ||
165 | left += LLFontGL::sCurOrigin.mX; | ||
166 | right += LLFontGL::sCurOrigin.mX; | ||
167 | bottom += LLFontGL::sCurOrigin.mY; | ||
168 | top += LLFontGL::sCurOrigin.mY; | ||
169 | |||
170 | glLoadIdentity(); | ||
171 | gl_rect_2d(llfloor((F32)left * LLUI::sGLScaleFactor.mV[VX]) - pixel_offset, | ||
172 | llfloor((F32)top * LLUI::sGLScaleFactor.mV[VY]) + pixel_offset, | ||
173 | llfloor((F32)right * LLUI::sGLScaleFactor.mV[VX]) + pixel_offset, | ||
174 | llfloor((F32)bottom * LLUI::sGLScaleFactor.mV[VY]) - pixel_offset, | ||
175 | filled); | ||
176 | glPopMatrix(); | ||
177 | } | ||
178 | |||
179 | |||
180 | void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled ) | ||
181 | { | ||
182 | stop_glerror(); | ||
183 | LLGLSNoTexture no_texture; | ||
184 | |||
185 | // Counterclockwise quad will face the viewer | ||
186 | if( filled ) | ||
187 | { | ||
188 | glBegin( GL_QUADS ); | ||
189 | glVertex2i(left, top); | ||
190 | glVertex2i(left, bottom); | ||
191 | glVertex2i(right, bottom); | ||
192 | glVertex2i(right, top); | ||
193 | glEnd(); | ||
194 | } | ||
195 | else | ||
196 | { | ||
197 | if( gGLManager.mATIOffsetVerticalLines ) | ||
198 | { | ||
199 | // Work around bug in ATI driver: vertical lines are offset by (-1,-1) | ||
200 | glBegin( GL_LINES ); | ||
201 | |||
202 | // Verticals | ||
203 | glVertex2i(left + 1, top); | ||
204 | glVertex2i(left + 1, bottom); | ||
205 | |||
206 | glVertex2i(right, bottom); | ||
207 | glVertex2i(right, top); | ||
208 | |||
209 | // Horizontals | ||
210 | top--; | ||
211 | right--; | ||
212 | glVertex2i(left, bottom); | ||
213 | glVertex2i(right, bottom); | ||
214 | |||
215 | glVertex2i(left, top); | ||
216 | glVertex2i(right, top); | ||
217 | glEnd(); | ||
218 | } | ||
219 | else | ||
220 | { | ||
221 | top--; | ||
222 | right--; | ||
223 | glBegin( GL_LINE_STRIP ); | ||
224 | glVertex2i(left, top); | ||
225 | glVertex2i(left, bottom); | ||
226 | glVertex2i(right, bottom); | ||
227 | glVertex2i(right, top); | ||
228 | glVertex2i(left, top); | ||
229 | glEnd(); | ||
230 | } | ||
231 | } | ||
232 | stop_glerror(); | ||
233 | } | ||
234 | |||
235 | void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled ) | ||
236 | { | ||
237 | glColor4fv( color.mV ); | ||
238 | gl_rect_2d( left, top, right, bottom, filled ); | ||
239 | } | ||
240 | |||
241 | |||
242 | void gl_rect_2d( const LLRect& rect, const LLColor4& color, BOOL filled ) | ||
243 | { | ||
244 | glColor4fv( color.mV ); | ||
245 | gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled ); | ||
246 | } | ||
247 | |||
248 | // Given a rectangle on the screen, draws a drop shadow _outside_ | ||
249 | // the right and bottom edges of it. Along the right it has width "lines" | ||
250 | // and along the bottom it has height "lines". | ||
251 | void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines) | ||
252 | { | ||
253 | stop_glerror(); | ||
254 | LLGLSNoTexture no_texture; | ||
255 | |||
256 | // HACK: Overlap with the rectangle by a single pixel. | ||
257 | right--; | ||
258 | bottom++; | ||
259 | lines++; | ||
260 | |||
261 | LLColor4 end_color = start_color; | ||
262 | end_color.mV[VALPHA] = 0.f; | ||
263 | |||
264 | glBegin(GL_QUADS); | ||
265 | |||
266 | // Right edge, CCW faces screen | ||
267 | glColor4fv(start_color.mV); | ||
268 | glVertex2i(right, top-lines); | ||
269 | glVertex2i(right, bottom); | ||
270 | glColor4fv(end_color.mV); | ||
271 | glVertex2i(right+lines, bottom); | ||
272 | glVertex2i(right+lines, top-lines); | ||
273 | |||
274 | // Bottom edge, CCW faces screen | ||
275 | glColor4fv(start_color.mV); | ||
276 | glVertex2i(right, bottom); | ||
277 | glVertex2i(left+lines, bottom); | ||
278 | glColor4fv(end_color.mV); | ||
279 | glVertex2i(left+lines, bottom-lines); | ||
280 | glVertex2i(right, bottom-lines); | ||
281 | |||
282 | // bottom left Corner | ||
283 | glColor4fv(start_color.mV); | ||
284 | glVertex2i(left+lines, bottom); | ||
285 | glColor4fv(end_color.mV); | ||
286 | glVertex2i(left, bottom); | ||
287 | // make the bottom left corner not sharp | ||
288 | glVertex2i(left+1, bottom-lines+1); | ||
289 | glVertex2i(left+lines, bottom-lines); | ||
290 | |||
291 | // bottom right corner | ||
292 | glColor4fv(start_color.mV); | ||
293 | glVertex2i(right, bottom); | ||
294 | glColor4fv(end_color.mV); | ||
295 | glVertex2i(right, bottom-lines); | ||
296 | // make the rightmost corner not sharp | ||
297 | glVertex2i(right+lines-1, bottom-lines+1); | ||
298 | glVertex2i(right+lines, bottom); | ||
299 | |||
300 | // top right corner | ||
301 | glColor4fv(start_color.mV); | ||
302 | glVertex2i( right, top-lines ); | ||
303 | glColor4fv(end_color.mV); | ||
304 | glVertex2i( right+lines, top-lines ); | ||
305 | // make the corner not sharp | ||
306 | glVertex2i( right+lines-1, top-1 ); | ||
307 | glVertex2i( right, top ); | ||
308 | |||
309 | glEnd(); | ||
310 | stop_glerror(); | ||
311 | } | ||
312 | |||
313 | void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 ) | ||
314 | { | ||
315 | // Work around bug in ATI driver: vertical lines are offset by (-1,-1) | ||
316 | if( gGLManager.mATIOffsetVerticalLines && (x1 == x2) ) | ||
317 | { | ||
318 | x1++; | ||
319 | x2++; | ||
320 | y1++; | ||
321 | y2++; | ||
322 | } | ||
323 | |||
324 | LLGLSNoTexture no_texture; | ||
325 | |||
326 | glBegin(GL_LINES); | ||
327 | glVertex2i(x1, y1); | ||
328 | glVertex2i(x2, y2); | ||
329 | glEnd(); | ||
330 | } | ||
331 | |||
332 | void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color ) | ||
333 | { | ||
334 | // Work around bug in ATI driver: vertical lines are offset by (-1,-1) | ||
335 | if( gGLManager.mATIOffsetVerticalLines && (x1 == x2) ) | ||
336 | { | ||
337 | x1++; | ||
338 | x2++; | ||
339 | y1++; | ||
340 | y2++; | ||
341 | } | ||
342 | |||
343 | LLGLSNoTexture no_texture; | ||
344 | |||
345 | glColor4fv( color.mV ); | ||
346 | |||
347 | glBegin(GL_LINES); | ||
348 | glVertex2i(x1, y1); | ||
349 | glVertex2i(x2, y2); | ||
350 | glEnd(); | ||
351 | } | ||
352 | |||
353 | void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled) | ||
354 | { | ||
355 | LLGLSNoTexture no_texture; | ||
356 | |||
357 | glColor4fv(color.mV); | ||
358 | |||
359 | if (filled) | ||
360 | { | ||
361 | glBegin(GL_TRIANGLES); | ||
362 | } | ||
363 | else | ||
364 | { | ||
365 | glBegin(GL_LINE_LOOP); | ||
366 | } | ||
367 | glVertex2i(x1, y1); | ||
368 | glVertex2i(x2, y2); | ||
369 | glVertex2i(x3, y3); | ||
370 | glEnd(); | ||
371 | } | ||
372 | |||
373 | void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac) | ||
374 | { | ||
375 | LLGLSNoTexture no_texture; | ||
376 | |||
377 | length = llmin((S32)(max_frac*(right - left)), length); | ||
378 | length = llmin((S32)(max_frac*(top - bottom)), length); | ||
379 | glBegin(GL_LINES); | ||
380 | glVertex2i(left, top); | ||
381 | glVertex2i(left + length, top); | ||
382 | |||
383 | glVertex2i(left, top); | ||
384 | glVertex2i(left, top - length); | ||
385 | |||
386 | glVertex2i(left, bottom); | ||
387 | glVertex2i(left + length, bottom); | ||
388 | |||
389 | glVertex2i(left, bottom); | ||
390 | glVertex2i(left, bottom + length); | ||
391 | |||
392 | glVertex2i(right, top); | ||
393 | glVertex2i(right - length, top); | ||
394 | |||
395 | glVertex2i(right, top); | ||
396 | glVertex2i(right, top - length); | ||
397 | |||
398 | glVertex2i(right, bottom); | ||
399 | glVertex2i(right - length, bottom); | ||
400 | |||
401 | glVertex2i(right, bottom); | ||
402 | glVertex2i(right, bottom + length); | ||
403 | glEnd(); | ||
404 | } | ||
405 | |||
406 | |||
407 | void gl_draw_image( S32 x, S32 y, LLImageGL* image, const LLColor4& color ) | ||
408 | { | ||
409 | gl_draw_scaled_rotated_image( x, y, image->getWidth(), image->getHeight(), 0.f, image, color ); | ||
410 | } | ||
411 | |||
412 | void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color) | ||
413 | { | ||
414 | gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color ); | ||
415 | } | ||
416 | |||
417 | void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLImageGL* image, const LLColor4& color, BOOL solid_color) | ||
418 | { | ||
419 | stop_glerror(); | ||
420 | F32 border_scale = 1.f; | ||
421 | |||
422 | if (border_height * 2 > height) | ||
423 | { | ||
424 | border_scale = (F32)height / ((F32)border_height * 2.f); | ||
425 | } | ||
426 | if (border_width * 2 > width) | ||
427 | { | ||
428 | border_scale = llmin(border_scale, (F32)width / ((F32)border_width * 2.f)); | ||
429 | } | ||
430 | |||
431 | // scale screen size of borders down | ||
432 | S32 scaled_border_width = llfloor(border_scale * (F32)border_width); | ||
433 | S32 scaled_border_height = llfloor(border_scale * (F32)border_height); | ||
434 | |||
435 | LLGLSUIDefault gls_ui; | ||
436 | |||
437 | if (solid_color) | ||
438 | { | ||
439 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); | ||
440 | glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE); | ||
441 | glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE); | ||
442 | |||
443 | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS); | ||
444 | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); | ||
445 | |||
446 | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); | ||
447 | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); | ||
448 | |||
449 | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PRIMARY_COLOR_ARB); | ||
450 | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA); | ||
451 | } | ||
452 | |||
453 | glPushMatrix(); | ||
454 | { | ||
455 | glTranslatef((F32)x, (F32)y, 0.f); | ||
456 | |||
457 | image->bind(); | ||
458 | |||
459 | glColor4fv(color.mV); | ||
460 | |||
461 | F32 border_width_fraction = (F32)border_width / (F32)image->getWidth(); | ||
462 | F32 border_height_fraction = (F32)border_height / (F32)image->getHeight(); | ||
463 | |||
464 | glBegin(GL_QUADS); | ||
465 | { | ||
466 | // draw bottom left | ||
467 | glTexCoord2f(0.f, 0.f); | ||
468 | glVertex2i(0, 0); | ||
469 | |||
470 | glTexCoord2f(border_width_fraction, 0.f); | ||
471 | glVertex2i(scaled_border_width, 0); | ||
472 | |||
473 | glTexCoord2f(border_width_fraction, border_height_fraction); | ||
474 | glVertex2i(scaled_border_width, scaled_border_height); | ||
475 | |||
476 | glTexCoord2f(0.f, border_height_fraction); | ||
477 | glVertex2i(0, scaled_border_height); | ||
478 | |||
479 | // draw bottom middle | ||
480 | glTexCoord2f(border_width_fraction, 0.f); | ||
481 | glVertex2i(scaled_border_width, 0); | ||
482 | |||
483 | glTexCoord2f(1.f - border_width_fraction, 0.f); | ||
484 | glVertex2i(width - scaled_border_width, 0); | ||
485 | |||
486 | glTexCoord2f(1.f - border_width_fraction, border_height_fraction); | ||
487 | glVertex2i(width - scaled_border_width, scaled_border_height); | ||
488 | |||
489 | glTexCoord2f(border_width_fraction, border_height_fraction); | ||
490 | glVertex2i(scaled_border_width, scaled_border_height); | ||
491 | |||
492 | // draw bottom right | ||
493 | glTexCoord2f(1.f - border_width_fraction, 0.f); | ||
494 | glVertex2i(width - scaled_border_width, 0); | ||
495 | |||
496 | glTexCoord2f(1.f, 0.f); | ||
497 | glVertex2i(width, 0); | ||
498 | |||
499 | glTexCoord2f(1.f, border_height_fraction); | ||
500 | glVertex2i(width, scaled_border_height); | ||
501 | |||
502 | glTexCoord2f(1.f - border_width_fraction, border_height_fraction); | ||
503 | glVertex2i(width - scaled_border_width, scaled_border_height); | ||
504 | |||
505 | // draw left | ||
506 | glTexCoord2f(0.f, border_height_fraction); | ||
507 | glVertex2i(0, scaled_border_height); | ||
508 | |||
509 | glTexCoord2f(border_width_fraction, border_height_fraction); | ||
510 | glVertex2i(scaled_border_width, scaled_border_height); | ||
511 | |||
512 | glTexCoord2f(border_width_fraction, 1.f - border_height_fraction); | ||
513 | glVertex2i(scaled_border_width, height - scaled_border_height); | ||
514 | |||
515 | glTexCoord2f(0.f, 1.f - border_height_fraction); | ||
516 | glVertex2i(0, height - scaled_border_height); | ||
517 | |||
518 | // draw middle | ||
519 | glTexCoord2f(border_width_fraction, border_height_fraction); | ||
520 | glVertex2i(scaled_border_width, scaled_border_height); | ||
521 | |||
522 | glTexCoord2f(1.f - border_width_fraction, border_height_fraction); | ||
523 | glVertex2i(width - scaled_border_width, scaled_border_height); | ||
524 | |||
525 | glTexCoord2f(1.f - border_width_fraction, 1.f - border_height_fraction); | ||
526 | glVertex2i(width - scaled_border_width, height - scaled_border_height); | ||
527 | |||
528 | glTexCoord2f(border_width_fraction, 1.f - border_height_fraction); | ||
529 | glVertex2i(scaled_border_width, height - scaled_border_height); | ||
530 | |||
531 | // draw right | ||
532 | glTexCoord2f(1.f - border_width_fraction, border_height_fraction); | ||
533 | glVertex2i(width - scaled_border_width, scaled_border_height); | ||
534 | |||
535 | glTexCoord2f(1.f, border_height_fraction); | ||
536 | glVertex2i(width, scaled_border_height); | ||
537 | |||
538 | glTexCoord2f(1.f, 1.f - border_height_fraction); | ||
539 | glVertex2i(width, height - scaled_border_height); | ||
540 | |||
541 | glTexCoord2f(1.f - border_width_fraction, 1.f - border_height_fraction); | ||
542 | glVertex2i(width - scaled_border_width, height - scaled_border_height); | ||
543 | |||
544 | // draw top left | ||
545 | glTexCoord2f(0.f, 1.f - border_height_fraction); | ||
546 | glVertex2i(0, height - scaled_border_height); | ||
547 | |||
548 | glTexCoord2f(border_width_fraction, 1.f - border_height_fraction); | ||
549 | glVertex2i(scaled_border_width, height - scaled_border_height); | ||
550 | |||
551 | glTexCoord2f(border_width_fraction, 1.f); | ||
552 | glVertex2i(scaled_border_width, height); | ||
553 | |||
554 | glTexCoord2f(0.f, 1.f); | ||
555 | glVertex2i(0, height); | ||
556 | |||
557 | // draw top middle | ||
558 | glTexCoord2f(border_width_fraction, 1.f - border_height_fraction); | ||
559 | glVertex2i(scaled_border_width, height - scaled_border_height); | ||
560 | |||
561 | glTexCoord2f(1.f - border_width_fraction, 1.f - border_height_fraction); | ||
562 | glVertex2i(width - scaled_border_width, height - scaled_border_height); | ||
563 | |||
564 | glTexCoord2f(1.f - border_width_fraction, 1.f); | ||
565 | glVertex2i(width - scaled_border_width, height); | ||
566 | |||
567 | glTexCoord2f(border_width_fraction, 1.f); | ||
568 | glVertex2i(scaled_border_width, height); | ||
569 | |||
570 | // draw top right | ||
571 | glTexCoord2f(1.f - border_width_fraction, 1.f - border_height_fraction); | ||
572 | glVertex2i(width - scaled_border_width, height - scaled_border_height); | ||
573 | |||
574 | glTexCoord2f(1.f, 1.f - border_height_fraction); | ||
575 | glVertex2i(width, height - scaled_border_height); | ||
576 | |||
577 | glTexCoord2f(1.f, 1.f); | ||
578 | glVertex2i(width, height); | ||
579 | |||
580 | glTexCoord2f(1.f - border_width_fraction, 1.f); | ||
581 | glVertex2i(width - scaled_border_width, height); | ||
582 | } | ||
583 | glEnd(); | ||
584 | } | ||
585 | glPopMatrix(); | ||
586 | |||
587 | if (solid_color) | ||
588 | { | ||
589 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | ||
590 | } | ||
591 | } | ||
592 | |||
593 | void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLImageGL* image, const LLColor4& color) | ||
594 | { | ||
595 | gl_draw_scaled_rotated_image( x, y, image->getWidth(), image->getHeight(), degrees, image, color ); | ||
596 | } | ||
597 | |||
598 | void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLImageGL* image, const LLColor4& color) | ||
599 | { | ||
600 | LLGLSUIDefault gls_ui; | ||
601 | |||
602 | glPushMatrix(); | ||
603 | { | ||
604 | glTranslatef((F32)x, (F32)y, 0.f); | ||
605 | if( degrees ) | ||
606 | { | ||
607 | F32 offset_x = F32(width/2); | ||
608 | F32 offset_y = F32(height/2); | ||
609 | glTranslatef( offset_x, offset_y, 0.f); | ||
610 | glRotatef( degrees, 0.f, 0.f, 1.f ); | ||
611 | glTranslatef( -offset_x, -offset_y, 0.f ); | ||
612 | } | ||
613 | |||
614 | image->bind(); | ||
615 | |||
616 | glColor4fv(color.mV); | ||
617 | |||
618 | glBegin(GL_QUADS); | ||
619 | { | ||
620 | glTexCoord2f(1.f, 1.f); | ||
621 | glVertex2i(width, height ); | ||
622 | |||
623 | glTexCoord2f(0.f, 1.f); | ||
624 | glVertex2i(0, height ); | ||
625 | |||
626 | glTexCoord2f(0.f, 0.f); | ||
627 | glVertex2i(0, 0); | ||
628 | |||
629 | glTexCoord2f(1.f, 0.f); | ||
630 | glVertex2i(width, 0); | ||
631 | } | ||
632 | glEnd(); | ||
633 | } | ||
634 | glPopMatrix(); | ||
635 | } | ||
636 | |||
637 | |||
638 | void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color) | ||
639 | { | ||
640 | LLGLSUIDefault gls_ui; | ||
641 | |||
642 | glPushMatrix(); | ||
643 | { | ||
644 | glTranslatef((F32)x, (F32)y, 0.f); | ||
645 | |||
646 | image->bind(); | ||
647 | |||
648 | glColor4fv(color.mV); | ||
649 | |||
650 | glBegin(GL_QUADS); | ||
651 | { | ||
652 | glTexCoord2f(1.f, 0.f); | ||
653 | glVertex2i(width, height ); | ||
654 | |||
655 | glTexCoord2f(0.f, 0.f); | ||
656 | glVertex2i(0, height ); | ||
657 | |||
658 | glTexCoord2f(0.f, 1.f); | ||
659 | glVertex2i(0, 0); | ||
660 | |||
661 | glTexCoord2f(1.f, 1.f); | ||
662 | glVertex2i(width, 0); | ||
663 | } | ||
664 | glEnd(); | ||
665 | } | ||
666 | glPopMatrix(); | ||
667 | } | ||
668 | |||
669 | |||
670 | void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase ) | ||
671 | { | ||
672 | phase = fmod(phase, 1.f); | ||
673 | |||
674 | S32 shift = S32(phase * 4.f) % 4; | ||
675 | |||
676 | // Stippled line | ||
677 | LLGLEnable stipple(GL_LINE_STIPPLE); | ||
678 | |||
679 | glColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], color.mV[VALPHA]); | ||
680 | glLineWidth(2.5f); | ||
681 | glLineStipple(2, 0x3333 << shift); | ||
682 | |||
683 | glBegin(GL_LINES); | ||
684 | { | ||
685 | glVertex3fv( start.mV ); | ||
686 | glVertex3fv( end.mV ); | ||
687 | } | ||
688 | glEnd(); | ||
689 | |||
690 | LLUI::setLineWidth(1.f); | ||
691 | } | ||
692 | |||
693 | |||
694 | void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom) | ||
695 | { | ||
696 | glColor4fv( LLColor4::white.mV ); | ||
697 | glLogicOp( GL_XOR ); | ||
698 | stop_glerror(); | ||
699 | |||
700 | glBegin(GL_QUADS); | ||
701 | glVertex2i(left, top); | ||
702 | glVertex2i(left, bottom); | ||
703 | glVertex2i(right, bottom); | ||
704 | glVertex2i(right, top); | ||
705 | glEnd(); | ||
706 | |||
707 | glLogicOp( GL_COPY ); | ||
708 | stop_glerror(); | ||
709 | } | ||
710 | |||
711 | |||
712 | void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle) | ||
713 | { | ||
714 | if (end_angle < start_angle) | ||
715 | { | ||
716 | end_angle += F_TWO_PI; | ||
717 | } | ||
718 | |||
719 | glPushMatrix(); | ||
720 | { | ||
721 | glTranslatef(center_x, center_y, 0.f); | ||
722 | |||
723 | // Inexact, but reasonably fast. | ||
724 | F32 delta = (end_angle - start_angle) / steps; | ||
725 | F32 sin_delta = sin( delta ); | ||
726 | F32 cos_delta = cos( delta ); | ||
727 | F32 x = cosf(start_angle) * radius; | ||
728 | F32 y = sinf(start_angle) * radius; | ||
729 | |||
730 | if (filled) | ||
731 | { | ||
732 | glBegin(GL_TRIANGLE_FAN); | ||
733 | glVertex2f(0.f, 0.f); | ||
734 | // make sure circle is complete | ||
735 | steps += 1; | ||
736 | } | ||
737 | else | ||
738 | { | ||
739 | glBegin(GL_LINE_STRIP); | ||
740 | } | ||
741 | |||
742 | while( steps-- ) | ||
743 | { | ||
744 | // Successive rotations | ||
745 | glVertex2f( x, y ); | ||
746 | F32 x_new = x * cos_delta - y * sin_delta; | ||
747 | y = x * sin_delta + y * cos_delta; | ||
748 | x = x_new; | ||
749 | } | ||
750 | glEnd(); | ||
751 | } | ||
752 | glPopMatrix(); | ||
753 | } | ||
754 | |||
755 | void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled) | ||
756 | { | ||
757 | glPushMatrix(); | ||
758 | { | ||
759 | LLGLSNoTexture gls_no_texture; | ||
760 | glTranslatef(center_x, center_y, 0.f); | ||
761 | |||
762 | // Inexact, but reasonably fast. | ||
763 | F32 delta = F_TWO_PI / steps; | ||
764 | F32 sin_delta = sin( delta ); | ||
765 | F32 cos_delta = cos( delta ); | ||
766 | F32 x = radius; | ||
767 | F32 y = 0.f; | ||
768 | |||
769 | if (filled) | ||
770 | { | ||
771 | glBegin(GL_TRIANGLE_FAN); | ||
772 | glVertex2f(0.f, 0.f); | ||
773 | // make sure circle is complete | ||
774 | steps += 1; | ||
775 | } | ||
776 | else | ||
777 | { | ||
778 | glBegin(GL_LINE_LOOP); | ||
779 | } | ||
780 | |||
781 | while( steps-- ) | ||
782 | { | ||
783 | // Successive rotations | ||
784 | glVertex2f( x, y ); | ||
785 | F32 x_new = x * cos_delta - y * sin_delta; | ||
786 | y = x * sin_delta + y * cos_delta; | ||
787 | x = x_new; | ||
788 | } | ||
789 | glEnd(); | ||
790 | } | ||
791 | glPopMatrix(); | ||
792 | } | ||
793 | |||
794 | // Renders a ring with sides (tube shape) | ||
795 | void gl_deep_circle( F32 radius, F32 depth, S32 steps ) | ||
796 | { | ||
797 | F32 x = radius; | ||
798 | F32 y = 0.f; | ||
799 | F32 angle_delta = F_TWO_PI / (F32)steps; | ||
800 | glBegin( GL_TRIANGLE_STRIP ); | ||
801 | { | ||
802 | S32 step = steps + 1; // An extra step to close the circle. | ||
803 | while( step-- ) | ||
804 | { | ||
805 | glVertex3f( x, y, depth ); | ||
806 | glVertex3f( x, y, 0.f ); | ||
807 | |||
808 | F32 x_new = x * cosf(angle_delta) - y * sinf(angle_delta); | ||
809 | y = x * sinf(angle_delta) + y * cosf(angle_delta); | ||
810 | x = x_new; | ||
811 | } | ||
812 | } | ||
813 | glEnd(); | ||
814 | } | ||
815 | |||
816 | void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center ) | ||
817 | { | ||
818 | glPushMatrix(); | ||
819 | { | ||
820 | glTranslatef(0.f, 0.f, -width / 2); | ||
821 | if( render_center ) | ||
822 | { | ||
823 | glColor4fv(center_color.mV); | ||
824 | gl_deep_circle( radius, width, steps ); | ||
825 | } | ||
826 | else | ||
827 | { | ||
828 | gl_washer_2d(radius, radius - width, steps, side_color, side_color); | ||
829 | glTranslatef(0.f, 0.f, width); | ||
830 | gl_washer_2d(radius - width, radius, steps, side_color, side_color); | ||
831 | } | ||
832 | } | ||
833 | glPopMatrix(); | ||
834 | } | ||
835 | |||
836 | // Draw gray and white checkerboard with black border | ||
837 | void gl_rect_2d_checkerboard(const LLRect& rect) | ||
838 | { | ||
839 | // Initialize the first time this is called. | ||
840 | const S32 PIXELS = 32; | ||
841 | static GLubyte checkerboard[PIXELS * PIXELS]; | ||
842 | static BOOL first = TRUE; | ||
843 | if( first ) | ||
844 | { | ||
845 | for( S32 i = 0; i < PIXELS; i++ ) | ||
846 | { | ||
847 | for( S32 j = 0; j < PIXELS; j++ ) | ||
848 | { | ||
849 | checkerboard[i * PIXELS + j] = ((i & 1) ^ (j & 1)) * 0xFF; | ||
850 | } | ||
851 | } | ||
852 | first = FALSE; | ||
853 | } | ||
854 | |||
855 | LLGLSNoTexture gls_no_texture; | ||
856 | |||
857 | // ...white squares | ||
858 | glColor3f( 1.f, 1.f, 1.f ); | ||
859 | gl_rect_2d(rect); | ||
860 | |||
861 | // ...gray squares | ||
862 | glColor3f( .7f, .7f, .7f ); | ||
863 | glPolygonStipple( checkerboard ); | ||
864 | |||
865 | LLGLEnable polygon_stipple(GL_POLYGON_STIPPLE); | ||
866 | gl_rect_2d(rect); | ||
867 | } | ||
868 | |||
869 | |||
870 | // Draws the area between two concentric circles, like | ||
871 | // a doughnut or washer. | ||
872 | void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color) | ||
873 | { | ||
874 | const F32 DELTA = F_TWO_PI / steps; | ||
875 | const F32 SIN_DELTA = sin( DELTA ); | ||
876 | const F32 COS_DELTA = cos( DELTA ); | ||
877 | |||
878 | F32 x1 = outer_radius; | ||
879 | F32 y1 = 0.f; | ||
880 | F32 x2 = inner_radius; | ||
881 | F32 y2 = 0.f; | ||
882 | |||
883 | LLGLSNoTexture gls_no_texture; | ||
884 | |||
885 | glBegin( GL_TRIANGLE_STRIP ); | ||
886 | { | ||
887 | steps += 1; // An extra step to close the circle. | ||
888 | while( steps-- ) | ||
889 | { | ||
890 | glColor4fv(outer_color.mV); | ||
891 | glVertex2f( x1, y1 ); | ||
892 | glColor4fv(inner_color.mV); | ||
893 | glVertex2f( x2, y2 ); | ||
894 | |||
895 | F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA; | ||
896 | y1 = x1 * SIN_DELTA + y1 * COS_DELTA; | ||
897 | x1 = x1_new; | ||
898 | |||
899 | F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA; | ||
900 | y2 = x2 * SIN_DELTA + y2 * COS_DELTA; | ||
901 | x2 = x2_new; | ||
902 | } | ||
903 | } | ||
904 | glEnd(); | ||
905 | } | ||
906 | |||
907 | // Draws the area between two concentric circles, like | ||
908 | // a doughnut or washer. | ||
909 | void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color) | ||
910 | { | ||
911 | const F32 DELTA = (end_radians - start_radians) / steps; | ||
912 | const F32 SIN_DELTA = sin( DELTA ); | ||
913 | const F32 COS_DELTA = cos( DELTA ); | ||
914 | |||
915 | F32 x1 = outer_radius * cos( start_radians ); | ||
916 | F32 y1 = outer_radius * sin( start_radians ); | ||
917 | F32 x2 = inner_radius * cos( start_radians ); | ||
918 | F32 y2 = inner_radius * sin( start_radians ); | ||
919 | |||
920 | LLGLSNoTexture gls_no_texture; | ||
921 | glBegin( GL_TRIANGLE_STRIP ); | ||
922 | { | ||
923 | steps += 1; // An extra step to close the circle. | ||
924 | while( steps-- ) | ||
925 | { | ||
926 | glColor4fv(outer_color.mV); | ||
927 | glVertex2f( x1, y1 ); | ||
928 | glColor4fv(inner_color.mV); | ||
929 | glVertex2f( x2, y2 ); | ||
930 | |||
931 | F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA; | ||
932 | y1 = x1 * SIN_DELTA + y1 * COS_DELTA; | ||
933 | x1 = x1_new; | ||
934 | |||
935 | F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA; | ||
936 | y2 = x2 * SIN_DELTA + y2 * COS_DELTA; | ||
937 | x2 = x2_new; | ||
938 | } | ||
939 | } | ||
940 | glEnd(); | ||
941 | } | ||
942 | |||
943 | // Draws spokes around a circle. | ||
944 | void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LLColor4& inner_color, const LLColor4& outer_color) | ||
945 | { | ||
946 | const F32 DELTA = F_TWO_PI / count; | ||
947 | const F32 HALF_DELTA = DELTA * 0.5f; | ||
948 | const F32 SIN_DELTA = sin( DELTA ); | ||
949 | const F32 COS_DELTA = cos( DELTA ); | ||
950 | |||
951 | F32 x1 = outer_radius * cos( HALF_DELTA ); | ||
952 | F32 y1 = outer_radius * sin( HALF_DELTA ); | ||
953 | F32 x2 = inner_radius * cos( HALF_DELTA ); | ||
954 | F32 y2 = inner_radius * sin( HALF_DELTA ); | ||
955 | |||
956 | LLGLSNoTexture gls_no_texture; | ||
957 | |||
958 | glBegin( GL_LINES ); | ||
959 | { | ||
960 | while( count-- ) | ||
961 | { | ||
962 | glColor4fv(outer_color.mV); | ||
963 | glVertex2f( x1, y1 ); | ||
964 | glColor4fv(inner_color.mV); | ||
965 | glVertex2f( x2, y2 ); | ||
966 | |||
967 | F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA; | ||
968 | y1 = x1 * SIN_DELTA + y1 * COS_DELTA; | ||
969 | x1 = x1_new; | ||
970 | |||
971 | F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA; | ||
972 | y2 = x2 * SIN_DELTA + y2 * COS_DELTA; | ||
973 | x2 = x2_new; | ||
974 | } | ||
975 | } | ||
976 | glEnd(); | ||
977 | } | ||
978 | |||
979 | void gl_rect_2d_simple_tex( S32 width, S32 height ) | ||
980 | { | ||
981 | glBegin( GL_QUADS ); | ||
982 | |||
983 | glTexCoord2f(1.f, 1.f); | ||
984 | glVertex2i(width, height); | ||
985 | |||
986 | glTexCoord2f(0.f, 1.f); | ||
987 | glVertex2i(0, height); | ||
988 | |||
989 | glTexCoord2f(0.f, 0.f); | ||
990 | glVertex2i(0, 0); | ||
991 | |||
992 | glTexCoord2f(1.f, 0.f); | ||
993 | glVertex2i(width, 0); | ||
994 | |||
995 | glEnd(); | ||
996 | } | ||
997 | |||
998 | void gl_rect_2d_simple( S32 width, S32 height ) | ||
999 | { | ||
1000 | glBegin( GL_QUADS ); | ||
1001 | glVertex2i(width, height); | ||
1002 | glVertex2i(0, height); | ||
1003 | glVertex2i(0, 0); | ||
1004 | glVertex2i(width, 0); | ||
1005 | glEnd(); | ||
1006 | } | ||
1007 | |||
1008 | void gl_segmented_rect_2d_tex(const S32 left, | ||
1009 | const S32 top, | ||
1010 | const S32 right, | ||
1011 | const S32 bottom, | ||
1012 | const S32 texture_width, | ||
1013 | const S32 texture_height, | ||
1014 | const S32 border_size, | ||
1015 | const U32 edges) | ||
1016 | { | ||
1017 | S32 width = llabs(right - left); | ||
1018 | S32 height = llabs(top - bottom); | ||
1019 | |||
1020 | glPushMatrix(); | ||
1021 | |||
1022 | glTranslatef((F32)left, (F32)bottom, 0.f); | ||
1023 | LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height); | ||
1024 | |||
1025 | if (border_uv_scale.mV[VX] > 0.5f) | ||
1026 | { | ||
1027 | border_uv_scale *= 0.5f / border_uv_scale.mV[VX]; | ||
1028 | } | ||
1029 | if (border_uv_scale.mV[VY] > 0.5f) | ||
1030 | { | ||
1031 | border_uv_scale *= 0.5f / border_uv_scale.mV[VY]; | ||
1032 | } | ||
1033 | |||
1034 | F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f); | ||
1035 | LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero; | ||
1036 | LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero; | ||
1037 | LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero; | ||
1038 | LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero; | ||
1039 | LLVector2 width_vec((F32)width, 0.f); | ||
1040 | LLVector2 height_vec(0.f, (F32)height); | ||
1041 | |||
1042 | glBegin(GL_QUADS); | ||
1043 | { | ||
1044 | // draw bottom left | ||
1045 | glTexCoord2f(0.f, 0.f); | ||
1046 | glVertex2f(0.f, 0.f); | ||
1047 | |||
1048 | glTexCoord2f(border_uv_scale.mV[VX], 0.f); | ||
1049 | glVertex2fv(border_width_left.mV); | ||
1050 | |||
1051 | glTexCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); | ||
1052 | glVertex2fv((border_width_left + border_height_bottom).mV); | ||
1053 | |||
1054 | glTexCoord2f(0.f, border_uv_scale.mV[VY]); | ||
1055 | glVertex2fv(border_height_bottom.mV); | ||
1056 | |||
1057 | // draw bottom middle | ||
1058 | glTexCoord2f(border_uv_scale.mV[VX], 0.f); | ||
1059 | glVertex2fv(border_width_left.mV); | ||
1060 | |||
1061 | glTexCoord2f(1.f - border_uv_scale.mV[VX], 0.f); | ||
1062 | glVertex2fv((width_vec - border_width_right).mV); | ||
1063 | |||
1064 | glTexCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); | ||
1065 | glVertex2fv((width_vec - border_width_right + border_height_bottom).mV); | ||
1066 | |||
1067 | glTexCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); | ||
1068 | glVertex2fv((border_width_left + border_height_bottom).mV); | ||
1069 | |||
1070 | // draw bottom right | ||
1071 | glTexCoord2f(1.f - border_uv_scale.mV[VX], 0.f); | ||
1072 | glVertex2fv((width_vec - border_width_right).mV); | ||
1073 | |||
1074 | glTexCoord2f(1.f, 0.f); | ||
1075 | glVertex2fv(width_vec.mV); | ||
1076 | |||
1077 | glTexCoord2f(1.f, border_uv_scale.mV[VY]); | ||
1078 | glVertex2fv((width_vec + border_height_bottom).mV); | ||
1079 | |||
1080 | glTexCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); | ||
1081 | glVertex2fv((width_vec - border_width_right + border_height_bottom).mV); | ||
1082 | |||
1083 | // draw left | ||
1084 | glTexCoord2f(0.f, border_uv_scale.mV[VY]); | ||
1085 | glVertex2fv(border_height_bottom.mV); | ||
1086 | |||
1087 | glTexCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); | ||
1088 | glVertex2fv((border_width_left + border_height_bottom).mV); | ||
1089 | |||
1090 | glTexCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); | ||
1091 | glVertex2fv((border_width_left + height_vec - border_height_top).mV); | ||
1092 | |||
1093 | glTexCoord2f(0.f, 1.f - border_uv_scale.mV[VY]); | ||
1094 | glVertex2fv((height_vec - border_height_top).mV); | ||
1095 | |||
1096 | // draw middle | ||
1097 | glTexCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); | ||
1098 | glVertex2fv((border_width_left + border_height_bottom).mV); | ||
1099 | |||
1100 | glTexCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); | ||
1101 | glVertex2fv((width_vec - border_width_right + border_height_bottom).mV); | ||
1102 | |||
1103 | glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); | ||
1104 | glVertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); | ||
1105 | |||
1106 | glTexCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); | ||
1107 | glVertex2fv((border_width_left + height_vec - border_height_top).mV); | ||
1108 | |||
1109 | // draw right | ||
1110 | glTexCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); | ||
1111 | glVertex2fv((width_vec - border_width_right + border_height_bottom).mV); | ||
1112 | |||
1113 | glTexCoord2f(1.f, border_uv_scale.mV[VY]); | ||
1114 | glVertex2fv((width_vec + border_height_bottom).mV); | ||
1115 | |||
1116 | glTexCoord2f(1.f, 1.f - border_uv_scale.mV[VY]); | ||
1117 | glVertex2fv((width_vec + height_vec - border_height_top).mV); | ||
1118 | |||
1119 | glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); | ||
1120 | glVertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); | ||
1121 | |||
1122 | // draw top left | ||
1123 | glTexCoord2f(0.f, 1.f - border_uv_scale.mV[VY]); | ||
1124 | glVertex2fv((height_vec - border_height_top).mV); | ||
1125 | |||
1126 | glTexCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); | ||
1127 | glVertex2fv((border_width_left + height_vec - border_height_top).mV); | ||
1128 | |||
1129 | glTexCoord2f(border_uv_scale.mV[VX], 1.f); | ||
1130 | glVertex2fv((border_width_left + height_vec).mV); | ||
1131 | |||
1132 | glTexCoord2f(0.f, 1.f); | ||
1133 | glVertex2fv((height_vec).mV); | ||
1134 | |||
1135 | // draw top middle | ||
1136 | glTexCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); | ||
1137 | glVertex2fv((border_width_left + height_vec - border_height_top).mV); | ||
1138 | |||
1139 | glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); | ||
1140 | glVertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); | ||
1141 | |||
1142 | glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f); | ||
1143 | glVertex2fv((width_vec - border_width_right + height_vec).mV); | ||
1144 | |||
1145 | glTexCoord2f(border_uv_scale.mV[VX], 1.f); | ||
1146 | glVertex2fv((border_width_left + height_vec).mV); | ||
1147 | |||
1148 | // draw top right | ||
1149 | glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); | ||
1150 | glVertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); | ||
1151 | |||
1152 | glTexCoord2f(1.f, 1.f - border_uv_scale.mV[VY]); | ||
1153 | glVertex2fv((width_vec + height_vec - border_height_top).mV); | ||
1154 | |||
1155 | glTexCoord2f(1.f, 1.f); | ||
1156 | glVertex2fv((width_vec + height_vec).mV); | ||
1157 | |||
1158 | glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f); | ||
1159 | glVertex2fv((width_vec - border_width_right + height_vec).mV); | ||
1160 | } | ||
1161 | glEnd(); | ||
1162 | |||
1163 | glPopMatrix(); | ||
1164 | } | ||
1165 | |||
1166 | void gl_segmented_rect_2d_fragment_tex(const S32 left, | ||
1167 | const S32 top, | ||
1168 | const S32 right, | ||
1169 | const S32 bottom, | ||
1170 | const S32 texture_width, | ||
1171 | const S32 texture_height, | ||
1172 | const S32 border_size, | ||
1173 | const F32 start_fragment, | ||
1174 | const F32 end_fragment, | ||
1175 | const U32 edges) | ||
1176 | { | ||
1177 | S32 width = llabs(right - left); | ||
1178 | S32 height = llabs(top - bottom); | ||
1179 | |||
1180 | glPushMatrix(); | ||
1181 | |||
1182 | glTranslatef((F32)left, (F32)bottom, 0.f); | ||
1183 | LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height); | ||
1184 | |||
1185 | if (border_uv_scale.mV[VX] > 0.5f) | ||
1186 | { | ||
1187 | border_uv_scale *= 0.5f / border_uv_scale.mV[VX]; | ||
1188 | } | ||
1189 | if (border_uv_scale.mV[VY] > 0.5f) | ||
1190 | { | ||
1191 | border_uv_scale *= 0.5f / border_uv_scale.mV[VY]; | ||
1192 | } | ||
1193 | |||
1194 | F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f); | ||
1195 | LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero; | ||
1196 | LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero; | ||
1197 | LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero; | ||
1198 | LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero; | ||
1199 | LLVector2 width_vec((F32)width, 0.f); | ||
1200 | LLVector2 height_vec(0.f, (F32)height); | ||
1201 | |||
1202 | F32 middle_start = border_scale / (F32)width; | ||
1203 | F32 middle_end = 1.f - middle_start; | ||
1204 | |||
1205 | F32 u_min; | ||
1206 | F32 u_max; | ||
1207 | LLVector2 x_min; | ||
1208 | LLVector2 x_max; | ||
1209 | |||
1210 | glBegin(GL_QUADS); | ||
1211 | { | ||
1212 | if (start_fragment < middle_start) | ||
1213 | { | ||
1214 | u_min = (start_fragment / middle_start) * border_uv_scale.mV[VX]; | ||
1215 | u_max = llmin(end_fragment / middle_start, 1.f) * border_uv_scale.mV[VX]; | ||
1216 | x_min = (start_fragment / middle_start) * border_width_left; | ||
1217 | x_max = llmin(end_fragment / middle_start, 1.f) * border_width_left; | ||
1218 | |||
1219 | // draw bottom left | ||
1220 | glTexCoord2f(u_min, 0.f); | ||
1221 | glVertex2fv(x_min.mV); | ||
1222 | |||
1223 | glTexCoord2f(border_uv_scale.mV[VX], 0.f); | ||
1224 | glVertex2fv(x_max.mV); | ||
1225 | |||
1226 | glTexCoord2f(u_max, border_uv_scale.mV[VY]); | ||
1227 | glVertex2fv((x_max + border_height_bottom).mV); | ||
1228 | |||
1229 | glTexCoord2f(u_min, border_uv_scale.mV[VY]); | ||
1230 | glVertex2fv((x_min + border_height_bottom).mV); | ||
1231 | |||
1232 | // draw left | ||
1233 | glTexCoord2f(u_min, border_uv_scale.mV[VY]); | ||
1234 | glVertex2fv((x_min + border_height_bottom).mV); | ||
1235 | |||
1236 | glTexCoord2f(u_max, border_uv_scale.mV[VY]); | ||
1237 | glVertex2fv((x_max + border_height_bottom).mV); | ||
1238 | |||
1239 | glTexCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); | ||
1240 | glVertex2fv((x_max + height_vec - border_height_top).mV); | ||
1241 | |||
1242 | glTexCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); | ||
1243 | glVertex2fv((x_min + height_vec - border_height_top).mV); | ||
1244 | |||
1245 | // draw top left | ||
1246 | glTexCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); | ||
1247 | glVertex2fv((x_min + height_vec - border_height_top).mV); | ||
1248 | |||
1249 | glTexCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); | ||
1250 | glVertex2fv((x_max + height_vec - border_height_top).mV); | ||
1251 | |||
1252 | glTexCoord2f(u_max, 1.f); | ||
1253 | glVertex2fv((x_max + height_vec).mV); | ||
1254 | |||
1255 | glTexCoord2f(u_min, 1.f); | ||
1256 | glVertex2fv((x_min + height_vec).mV); | ||
1257 | } | ||
1258 | |||
1259 | if (end_fragment > middle_start || start_fragment < middle_end) | ||
1260 | { | ||
1261 | x_min = border_width_left + ((llclamp(start_fragment, middle_start, middle_end) - middle_start)) * width_vec; | ||
1262 | x_max = border_width_left + ((llclamp(end_fragment, middle_start, middle_end) - middle_start)) * width_vec; | ||
1263 | |||
1264 | // draw bottom middle | ||
1265 | glTexCoord2f(border_uv_scale.mV[VX], 0.f); | ||
1266 | glVertex2fv(x_min.mV); | ||
1267 | |||
1268 | glTexCoord2f(1.f - border_uv_scale.mV[VX], 0.f); | ||
1269 | glVertex2fv((x_max).mV); | ||
1270 | |||
1271 | glTexCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); | ||
1272 | glVertex2fv((x_max + border_height_bottom).mV); | ||
1273 | |||
1274 | glTexCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); | ||
1275 | glVertex2fv((x_min + border_height_bottom).mV); | ||
1276 | |||
1277 | // draw middle | ||
1278 | glTexCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); | ||
1279 | glVertex2fv((x_min + border_height_bottom).mV); | ||
1280 | |||
1281 | glTexCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); | ||
1282 | glVertex2fv((x_max + border_height_bottom).mV); | ||
1283 | |||
1284 | glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); | ||
1285 | glVertex2fv((x_max + height_vec - border_height_top).mV); | ||
1286 | |||
1287 | glTexCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); | ||
1288 | glVertex2fv((x_min + height_vec - border_height_top).mV); | ||
1289 | |||
1290 | // draw top middle | ||
1291 | glTexCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); | ||
1292 | glVertex2fv((x_min + height_vec - border_height_top).mV); | ||
1293 | |||
1294 | glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); | ||
1295 | glVertex2fv((x_max + height_vec - border_height_top).mV); | ||
1296 | |||
1297 | glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f); | ||
1298 | glVertex2fv((x_max + height_vec).mV); | ||
1299 | |||
1300 | glTexCoord2f(border_uv_scale.mV[VX], 1.f); | ||
1301 | glVertex2fv((x_min + height_vec).mV); | ||
1302 | } | ||
1303 | |||
1304 | if (end_fragment > middle_end) | ||
1305 | { | ||
1306 | u_min = (1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_uv_scale.mV[VX]; | ||
1307 | u_max = (1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX]; | ||
1308 | x_min = width_vec - ((1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_width_right); | ||
1309 | x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right); | ||
1310 | |||
1311 | // draw bottom right | ||
1312 | glTexCoord2f(u_min, 0.f); | ||
1313 | glVertex2fv((x_min).mV); | ||
1314 | |||
1315 | glTexCoord2f(u_max, 0.f); | ||
1316 | glVertex2fv(x_max.mV); | ||
1317 | |||
1318 | glTexCoord2f(u_max, border_uv_scale.mV[VY]); | ||
1319 | glVertex2fv((x_max + border_height_bottom).mV); | ||
1320 | |||
1321 | glTexCoord2f(u_min, border_uv_scale.mV[VY]); | ||
1322 | glVertex2fv((x_min + border_height_bottom).mV); | ||
1323 | |||
1324 | // draw right | ||
1325 | glTexCoord2f(u_min, border_uv_scale.mV[VY]); | ||
1326 | glVertex2fv((x_min + border_height_bottom).mV); | ||
1327 | |||
1328 | glTexCoord2f(u_max, border_uv_scale.mV[VY]); | ||
1329 | glVertex2fv((x_max + border_height_bottom).mV); | ||
1330 | |||
1331 | glTexCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); | ||
1332 | glVertex2fv((x_max + height_vec - border_height_top).mV); | ||
1333 | |||
1334 | glTexCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); | ||
1335 | glVertex2fv((x_min + height_vec - border_height_top).mV); | ||
1336 | |||
1337 | // draw top right | ||
1338 | glTexCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); | ||
1339 | glVertex2fv((x_min + height_vec - border_height_top).mV); | ||
1340 | |||
1341 | glTexCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); | ||
1342 | glVertex2fv((x_max + height_vec - border_height_top).mV); | ||
1343 | |||
1344 | glTexCoord2f(u_max, 1.f); | ||
1345 | glVertex2fv((x_max + height_vec).mV); | ||
1346 | |||
1347 | glTexCoord2f(u_min, 1.f); | ||
1348 | glVertex2fv((x_min + height_vec).mV); | ||
1349 | } | ||
1350 | } | ||
1351 | glEnd(); | ||
1352 | |||
1353 | glPopMatrix(); | ||
1354 | } | ||
1355 | |||
1356 | void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, | ||
1357 | const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec, | ||
1358 | const U32 edges) | ||
1359 | { | ||
1360 | LLVector3 left_border_width = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? border_width : LLVector3::zero; | ||
1361 | LLVector3 right_border_width = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? border_width : LLVector3::zero; | ||
1362 | |||
1363 | LLVector3 top_border_height = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? border_height : LLVector3::zero; | ||
1364 | LLVector3 bottom_border_height = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? border_height : LLVector3::zero; | ||
1365 | |||
1366 | glBegin(GL_QUADS); | ||
1367 | { | ||
1368 | // draw bottom left | ||
1369 | glTexCoord2f(0.f, 0.f); | ||
1370 | glVertex3f(0.f, 0.f, 0.f); | ||
1371 | |||
1372 | glTexCoord2f(border_scale.mV[VX], 0.f); | ||
1373 | glVertex3fv(left_border_width.mV); | ||
1374 | |||
1375 | glTexCoord2f(border_scale.mV[VX], border_scale.mV[VY]); | ||
1376 | glVertex3fv((left_border_width + bottom_border_height).mV); | ||
1377 | |||
1378 | glTexCoord2f(0.f, border_scale.mV[VY]); | ||
1379 | glVertex3fv(bottom_border_height.mV); | ||
1380 | |||
1381 | // draw bottom middle | ||
1382 | glTexCoord2f(border_scale.mV[VX], 0.f); | ||
1383 | glVertex3fv(left_border_width.mV); | ||
1384 | |||
1385 | glTexCoord2f(1.f - border_scale.mV[VX], 0.f); | ||
1386 | glVertex3fv((width_vec - right_border_width).mV); | ||
1387 | |||
1388 | glTexCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); | ||
1389 | glVertex3fv((width_vec - right_border_width + bottom_border_height).mV); | ||
1390 | |||
1391 | glTexCoord2f(border_scale.mV[VX], border_scale.mV[VY]); | ||
1392 | glVertex3fv((left_border_width + bottom_border_height).mV); | ||
1393 | |||
1394 | // draw bottom right | ||
1395 | glTexCoord2f(1.f - border_scale.mV[VX], 0.f); | ||
1396 | glVertex3fv((width_vec - right_border_width).mV); | ||
1397 | |||
1398 | glTexCoord2f(1.f, 0.f); | ||
1399 | glVertex3fv(width_vec.mV); | ||
1400 | |||
1401 | glTexCoord2f(1.f, border_scale.mV[VY]); | ||
1402 | glVertex3fv((width_vec + bottom_border_height).mV); | ||
1403 | |||
1404 | glTexCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); | ||
1405 | glVertex3fv((width_vec - right_border_width + bottom_border_height).mV); | ||
1406 | |||
1407 | // draw left | ||
1408 | glTexCoord2f(0.f, border_scale.mV[VY]); | ||
1409 | glVertex3fv(bottom_border_height.mV); | ||
1410 | |||
1411 | glTexCoord2f(border_scale.mV[VX], border_scale.mV[VY]); | ||
1412 | glVertex3fv((left_border_width + bottom_border_height).mV); | ||
1413 | |||
1414 | glTexCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); | ||
1415 | glVertex3fv((left_border_width + height_vec - top_border_height).mV); | ||
1416 | |||
1417 | glTexCoord2f(0.f, 1.f - border_scale.mV[VY]); | ||
1418 | glVertex3fv((height_vec - top_border_height).mV); | ||
1419 | |||
1420 | // draw middle | ||
1421 | glTexCoord2f(border_scale.mV[VX], border_scale.mV[VY]); | ||
1422 | glVertex3fv((left_border_width + bottom_border_height).mV); | ||
1423 | |||
1424 | glTexCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); | ||
1425 | glVertex3fv((width_vec - right_border_width + bottom_border_height).mV); | ||
1426 | |||
1427 | glTexCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); | ||
1428 | glVertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); | ||
1429 | |||
1430 | glTexCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); | ||
1431 | glVertex3fv((left_border_width + height_vec - top_border_height).mV); | ||
1432 | |||
1433 | // draw right | ||
1434 | glTexCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); | ||
1435 | glVertex3fv((width_vec - right_border_width + bottom_border_height).mV); | ||
1436 | |||
1437 | glTexCoord2f(1.f, border_scale.mV[VY]); | ||
1438 | glVertex3fv((width_vec + bottom_border_height).mV); | ||
1439 | |||
1440 | glTexCoord2f(1.f, 1.f - border_scale.mV[VY]); | ||
1441 | glVertex3fv((width_vec + height_vec - top_border_height).mV); | ||
1442 | |||
1443 | glTexCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); | ||
1444 | glVertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); | ||
1445 | |||
1446 | // draw top left | ||
1447 | glTexCoord2f(0.f, 1.f - border_scale.mV[VY]); | ||
1448 | glVertex3fv((height_vec - top_border_height).mV); | ||
1449 | |||
1450 | glTexCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); | ||
1451 | glVertex3fv((left_border_width + height_vec - top_border_height).mV); | ||
1452 | |||
1453 | glTexCoord2f(border_scale.mV[VX], 1.f); | ||
1454 | glVertex3fv((left_border_width + height_vec).mV); | ||
1455 | |||
1456 | glTexCoord2f(0.f, 1.f); | ||
1457 | glVertex3fv((height_vec).mV); | ||
1458 | |||
1459 | // draw top middle | ||
1460 | glTexCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); | ||
1461 | glVertex3fv((left_border_width + height_vec - top_border_height).mV); | ||
1462 | |||
1463 | glTexCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); | ||
1464 | glVertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); | ||
1465 | |||
1466 | glTexCoord2f(1.f - border_scale.mV[VX], 1.f); | ||
1467 | glVertex3fv((width_vec - right_border_width + height_vec).mV); | ||
1468 | |||
1469 | glTexCoord2f(border_scale.mV[VX], 1.f); | ||
1470 | glVertex3fv((left_border_width + height_vec).mV); | ||
1471 | |||
1472 | // draw top right | ||
1473 | glTexCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); | ||
1474 | glVertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); | ||
1475 | |||
1476 | glTexCoord2f(1.f, 1.f - border_scale.mV[VY]); | ||
1477 | glVertex3fv((width_vec + height_vec - top_border_height).mV); | ||
1478 | |||
1479 | glTexCoord2f(1.f, 1.f); | ||
1480 | glVertex3fv((width_vec + height_vec).mV); | ||
1481 | |||
1482 | glTexCoord2f(1.f - border_scale.mV[VX], 1.f); | ||
1483 | glVertex3fv((width_vec - right_border_width + height_vec).mV); | ||
1484 | } | ||
1485 | glEnd(); | ||
1486 | } | ||
1487 | |||
1488 | void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec) | ||
1489 | { | ||
1490 | gl_segmented_rect_3d_tex(border_scale, border_width, border_height, width_vec, height_vec, ROUNDED_RECT_TOP); | ||
1491 | } | ||
1492 | |||
1493 | #if 0 // No longer used | ||
1494 | void load_tr(const LLString& lang) | ||
1495 | { | ||
1496 | LLString inname = "words." + lang + ".txt"; | ||
1497 | LLString filename = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, inname.c_str()); | ||
1498 | |||
1499 | llifstream file; | ||
1500 | file.open(filename.c_str(), std::ios_base::binary); | ||
1501 | if (!file) | ||
1502 | { | ||
1503 | llinfos << "No translation dictionary for: " << filename << llendl; | ||
1504 | return; | ||
1505 | } | ||
1506 | |||
1507 | llinfos << "Reading language translation dictionary: " << filename << llendl; | ||
1508 | |||
1509 | gTranslation.clear(); | ||
1510 | gUntranslated.clear(); | ||
1511 | |||
1512 | const S32 MAX_LINE_LEN = 1024; | ||
1513 | char buffer[MAX_LINE_LEN]; | ||
1514 | while (!file.eof()) | ||
1515 | { | ||
1516 | file.getline(buffer, MAX_LINE_LEN); | ||
1517 | LLString line(buffer); | ||
1518 | S32 commentpos = line.find("//"); | ||
1519 | if (commentpos != LLString::npos) | ||
1520 | { | ||
1521 | line = line.substr(0, commentpos); | ||
1522 | } | ||
1523 | S32 offset = line.find('\t'); | ||
1524 | if (offset != LLString::npos) | ||
1525 | { | ||
1526 | LLString english = line.substr(0,offset); | ||
1527 | LLString translation = line.substr(offset+1); | ||
1528 | //llinfos << "TR: " << english << " = " << translation << llendl; | ||
1529 | gTranslation[english] = translation; | ||
1530 | } | ||
1531 | } | ||
1532 | |||
1533 | file.close(); | ||
1534 | } | ||
1535 | |||
1536 | void init_tr(const LLString& language) | ||
1537 | { | ||
1538 | if (!language.empty()) | ||
1539 | { | ||
1540 | gLanguage = language; | ||
1541 | } | ||
1542 | load_tr(gLanguage); | ||
1543 | } | ||
1544 | |||
1545 | void cleanup_tr() | ||
1546 | { | ||
1547 | // Dump untranslated phrases to help with translation | ||
1548 | if (gUntranslated.size() > 0) | ||
1549 | { | ||
1550 | LLString outname = "untranslated_" + gLanguage + ".txt"; | ||
1551 | LLString outfilename = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, outname.c_str()); | ||
1552 | llofstream outfile; | ||
1553 | outfile.open(outfilename.c_str()); | ||
1554 | if (!outfile) | ||
1555 | { | ||
1556 | return; | ||
1557 | } | ||
1558 | llinfos << "Writing untranslated words to: " << outfilename << llendl; | ||
1559 | LLString outtext; | ||
1560 | for (std::list<LLString>::iterator iter = gUntranslated.begin(); | ||
1561 | iter != gUntranslated.end(); ++iter) | ||
1562 | { | ||
1563 | // output: english_phrase english_phrase | ||
1564 | outtext += *iter; | ||
1565 | outtext += "\t"; | ||
1566 | outtext += *iter; | ||
1567 | outtext += "\n"; | ||
1568 | } | ||
1569 | outfile << outtext.c_str(); | ||
1570 | outfile.close(); | ||
1571 | } | ||
1572 | } | ||
1573 | |||
1574 | LLString tr(const LLString& english_string) | ||
1575 | { | ||
1576 | std::map<LLString, LLString>::iterator it = gTranslation.find(english_string); | ||
1577 | if (it != gTranslation.end()) | ||
1578 | { | ||
1579 | return it->second; | ||
1580 | } | ||
1581 | else | ||
1582 | { | ||
1583 | gUntranslated.push_back(english_string); | ||
1584 | return english_string; | ||
1585 | } | ||
1586 | } | ||
1587 | |||
1588 | #endif | ||
1589 | |||
1590 | |||
1591 | class LLShowXUINamesListener: public LLSimpleListener | ||
1592 | { | ||
1593 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | ||
1594 | { | ||
1595 | LLUI::sShowXUINames = (BOOL) event->getValue().asBoolean(); | ||
1596 | return true; | ||
1597 | } | ||
1598 | }; | ||
1599 | static LLShowXUINamesListener show_xui_names_listener; | ||
1600 | |||
1601 | |||
1602 | void LLUI::initClass(LLControlGroup* config, | ||
1603 | LLControlGroup* colors, | ||
1604 | LLControlGroup* assets, | ||
1605 | LLImageProviderInterface* image_provider, | ||
1606 | LLUIAudioCallback audio_callback, | ||
1607 | const LLVector2* scale_factor, | ||
1608 | const LLString& language) | ||
1609 | { | ||
1610 | sConfigGroup = config; | ||
1611 | sColorsGroup = colors; | ||
1612 | sAssetsGroup = assets; | ||
1613 | sImageProvider = image_provider; | ||
1614 | sAudioCallback = audio_callback; | ||
1615 | sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor; | ||
1616 | sWindow = NULL; // set later in startup | ||
1617 | LLFontGL::sShadowColor = colors->getColor("ColorDropShadow"); | ||
1618 | |||
1619 | LLUI::sShowXUINames = LLUI::sConfigGroup->getBOOL("ShowXUINames"); | ||
1620 | LLUI::sConfigGroup->getControl("ShowXUINames")->addListener(&show_xui_names_listener); | ||
1621 | // init_tr(language); | ||
1622 | } | ||
1623 | |||
1624 | void LLUI::cleanupClass() | ||
1625 | { | ||
1626 | // cleanup_tr(); | ||
1627 | } | ||
1628 | |||
1629 | |||
1630 | //static | ||
1631 | void LLUI::translate(F32 x, F32 y, F32 z) | ||
1632 | { | ||
1633 | glTranslatef(x,y,z); | ||
1634 | LLFontGL::sCurOrigin.mX += (S32) x; | ||
1635 | LLFontGL::sCurOrigin.mY += (S32) y; | ||
1636 | LLFontGL::sCurOrigin.mZ += z; | ||
1637 | } | ||
1638 | |||
1639 | //static | ||
1640 | void LLUI::pushMatrix() | ||
1641 | { | ||
1642 | glPushMatrix(); | ||
1643 | LLFontGL::sOriginStack.push_back(LLFontGL::sCurOrigin); | ||
1644 | } | ||
1645 | |||
1646 | //static | ||
1647 | void LLUI::popMatrix() | ||
1648 | { | ||
1649 | glPopMatrix(); | ||
1650 | LLFontGL::sCurOrigin = *LLFontGL::sOriginStack.rbegin(); | ||
1651 | LLFontGL::sOriginStack.pop_back(); | ||
1652 | } | ||
1653 | |||
1654 | //static | ||
1655 | void LLUI::loadIdentity() | ||
1656 | { | ||
1657 | glLoadIdentity(); | ||
1658 | LLFontGL::sCurOrigin.mX = 0; | ||
1659 | LLFontGL::sCurOrigin.mY = 0; | ||
1660 | LLFontGL::sCurOrigin.mZ = 0; | ||
1661 | } | ||
1662 | |||
1663 | //static | ||
1664 | void LLUI::setScissorRegionScreen(const LLRect& rect) | ||
1665 | { | ||
1666 | stop_glerror(); | ||
1667 | S32 x,y,w,h; | ||
1668 | x = llround(rect.mLeft * LLUI::sGLScaleFactor.mV[VX]); | ||
1669 | y = llround(rect.mBottom * LLUI::sGLScaleFactor.mV[VY]); | ||
1670 | w = llround(rect.getWidth() * LLUI::sGLScaleFactor.mV[VX]); | ||
1671 | h = llround(rect.getHeight() * LLUI::sGLScaleFactor.mV[VY]); | ||
1672 | glScissor( x,y,w,h ); | ||
1673 | stop_glerror(); | ||
1674 | } | ||
1675 | |||
1676 | //static | ||
1677 | void LLUI::setScissorRegionLocal(const LLRect& rect) | ||
1678 | { | ||
1679 | stop_glerror(); | ||
1680 | S32 screen_left = LLFontGL::sCurOrigin.mX + rect.mLeft; | ||
1681 | S32 screen_bottom = LLFontGL::sCurOrigin.mY + rect.mBottom; | ||
1682 | |||
1683 | S32 x,y,w,h; | ||
1684 | |||
1685 | x = llround((F32)screen_left * LLUI::sGLScaleFactor.mV[VX]); | ||
1686 | y = llround((F32)screen_bottom * LLUI::sGLScaleFactor.mV[VY]); | ||
1687 | w = llround((F32)rect.getWidth() * LLUI::sGLScaleFactor.mV[VX]); | ||
1688 | h = llround((F32)rect.getHeight() * LLUI::sGLScaleFactor.mV[VY]); | ||
1689 | |||
1690 | w = llmax(0,w); | ||
1691 | h = llmax(0,h); | ||
1692 | |||
1693 | glScissor(x,y,w,h); | ||
1694 | stop_glerror(); | ||
1695 | } | ||
1696 | |||
1697 | //static | ||
1698 | void LLUI::setScaleFactor(const LLVector2 &scale_factor) | ||
1699 | { | ||
1700 | sGLScaleFactor = scale_factor; | ||
1701 | } | ||
1702 | |||
1703 | //static | ||
1704 | void LLUI::setLineWidth(F32 width) | ||
1705 | { | ||
1706 | glLineWidth(width * lerp(sGLScaleFactor.mV[VX], sGLScaleFactor.mV[VY], 0.5f)); | ||
1707 | } | ||
1708 | |||
1709 | //static | ||
1710 | void LLUI::setCursorPositionScreen(S32 x, S32 y) | ||
1711 | { | ||
1712 | S32 screen_x, screen_y; | ||
1713 | screen_x = llround((F32)x * sGLScaleFactor.mV[VX]); | ||
1714 | screen_y = llround((F32)y * sGLScaleFactor.mV[VY]); | ||
1715 | |||
1716 | LLCoordWindow window_point; | ||
1717 | LLView::getWindow()->convertCoords(LLCoordGL(screen_x, screen_y), &window_point); | ||
1718 | |||
1719 | LLView::getWindow()->setCursorPosition(window_point); | ||
1720 | } | ||
1721 | |||
1722 | //static | ||
1723 | void LLUI::setCursorPositionLocal(LLView* viewp, S32 x, S32 y) | ||
1724 | { | ||
1725 | S32 screen_x, screen_y; | ||
1726 | viewp->localPointToScreen(x, y, &screen_x, &screen_y); | ||
1727 | |||
1728 | setCursorPositionScreen(screen_x, screen_y); | ||
1729 | } | ||
1730 | |||
1731 | //static | ||
1732 | LLString LLUI::locateSkin(const LLString& filename) | ||
1733 | { | ||
1734 | LLString slash = gDirUtilp->getDirDelimiter(); | ||
1735 | LLString found_file = filename; | ||
1736 | if (!gDirUtilp->fileExists(found_file)) | ||
1737 | { | ||
1738 | found_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename); // Should be CUSTOM_SKINS? | ||
1739 | } | ||
1740 | if (sConfigGroup && sConfigGroup->controlExists("Language")) | ||
1741 | { | ||
1742 | if (!gDirUtilp->fileExists(found_file)) | ||
1743 | { | ||
1744 | LLString localization(sConfigGroup->getString("Language")); | ||
1745 | LLString local_skin = "xui" + slash + localization + slash + filename; | ||
1746 | found_file = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, local_skin); | ||
1747 | } | ||
1748 | } | ||
1749 | if (!gDirUtilp->fileExists(found_file)) | ||
1750 | { | ||
1751 | LLString local_skin = "xui" + slash + "en-us" + slash + filename; | ||
1752 | found_file = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, local_skin); | ||
1753 | } | ||
1754 | if (!gDirUtilp->fileExists(found_file)) | ||
1755 | { | ||
1756 | found_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, filename); | ||
1757 | } | ||
1758 | return found_file; | ||
1759 | } | ||
1760 | |||
1761 | //static | ||
1762 | LLVector2 LLUI::getWindowSize() | ||
1763 | { | ||
1764 | LLCoordWindow window_rect; | ||
1765 | sWindow->getSize(&window_rect); | ||
1766 | |||
1767 | return LLVector2(window_rect.mX / sGLScaleFactor.mV[VX], window_rect.mY / sGLScaleFactor.mV[VY]); | ||
1768 | } | ||
1769 | |||
1770 | //static | ||
1771 | LLUUID LLUI::findAssetUUIDByName(const LLString &asset_name) | ||
1772 | { | ||
1773 | if(asset_name == LLString::null) return LLUUID::null; | ||
1774 | LLString foundValue = LLUI::sConfigGroup->findString(asset_name); | ||
1775 | if(foundValue==LLString::null) | ||
1776 | { | ||
1777 | foundValue = LLUI::sAssetsGroup->findString(asset_name); | ||
1778 | } | ||
1779 | if(foundValue == LLString::null){ | ||
1780 | return LLUUID::null; | ||
1781 | } | ||
1782 | return LLUUID( foundValue ); | ||
1783 | } | ||