00001
00032
00033
00034
00035 #include "linden_common.h"
00036
00037 #include <string>
00038 #include <map>
00039
00040
00041 #include "audioengine.h"
00042 #include "v2math.h"
00043 #include "v4color.h"
00044 #include "llgl.h"
00045 #include "llrect.h"
00046 #include "llimagegl.h"
00047
00048 #include "lldir.h"
00049 #include "llfontgl.h"
00050
00051
00052
00053 #include "llcontrol.h"
00054
00055 #include "llui.h"
00056 #include "llview.h"
00057 #include "llwindow.h"
00058
00059 #include "llglheaders.h"
00060
00061
00062
00063
00064 const LLColor4 UI_VERTEX_COLOR(1.f, 1.f, 1.f, 1.f);
00065
00066
00067 BOOL gShowTextEditCursor = TRUE;
00068
00069
00070 std::map<LLString, LLString> gTranslation;
00071 std::list<LLString> gUntranslated;
00072
00073 LLControlGroup* LLUI::sConfigGroup = NULL;
00074 LLControlGroup* LLUI::sColorsGroup = NULL;
00075 LLControlGroup* LLUI::sAssetsGroup = NULL;
00076 LLImageProviderInterface* LLUI::sImageProvider = NULL;
00077 LLUIAudioCallback LLUI::sAudioCallback = NULL;
00078 LLVector2 LLUI::sGLScaleFactor(1.f, 1.f);
00079 LLWindow* LLUI::sWindow = NULL;
00080 LLHtmlHelp* LLUI::sHtmlHelp = NULL;
00081 BOOL LLUI::sShowXUINames = FALSE;
00082 std::stack<LLRect> LLUI::sClipRectStack;
00083
00084
00085
00086
00087 void make_ui_sound(const LLString& name)
00088 {
00089 if (!LLUI::sConfigGroup->controlExists(name))
00090 {
00091 llwarns << "tried to make ui sound for unknown sound name: " << name << llendl;
00092 }
00093 else
00094 {
00095 LLUUID uuid(LLUI::sConfigGroup->getString(name));
00096 if (uuid.isNull())
00097 {
00098 if ("00000000-0000-0000-0000-000000000000" == LLUI::sConfigGroup->getString(name))
00099 {
00100 if (LLUI::sConfigGroup->getBOOL("UISndDebugSpamToggle"))
00101 {
00102 llinfos << "ui sound name: " << name << " triggered but silent (null uuid)" << llendl;
00103 }
00104 }
00105 else
00106 {
00107 llwarns << "ui sound named: " << name << " does not translate to a valid uuid" << llendl;
00108 }
00109
00110 }
00111 else if (LLUI::sAudioCallback != NULL)
00112 {
00113 if (LLUI::sConfigGroup->getBOOL("UISndDebugSpamToggle"))
00114 {
00115 llinfos << "ui sound name: " << name << llendl;
00116 }
00117 LLUI::sAudioCallback(uuid);
00118 }
00119 }
00120 }
00121
00122 BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom)
00123 {
00124 if (x < left || right < x) return FALSE;
00125 if (y < bottom || top < y) return FALSE;
00126 return TRUE;
00127 }
00128
00129
00130
00131
00132 void gl_state_for_2d(S32 width, S32 height)
00133 {
00134 stop_glerror();
00135 F32 window_width = (F32) width;
00136 F32 window_height = (F32) height;
00137
00138 glMatrixMode(GL_PROJECTION);
00139 glLoadIdentity();
00140 glOrtho(0.0f, window_width, 0.0f, window_height, -1.0f, 1.0f);
00141 glMatrixMode(GL_MODELVIEW);
00142 glLoadIdentity();
00143 stop_glerror();
00144 }
00145
00146
00147 void gl_draw_x(const LLRect& rect, const LLColor4& color)
00148 {
00149 LLGLSNoTexture no_texture;
00150
00151 glColor4fv( color.mV );
00152
00153 glBegin( GL_LINES );
00154 glVertex2i( rect.mLeft, rect.mTop );
00155 glVertex2i( rect.mRight, rect.mBottom );
00156 glVertex2i( rect.mLeft, rect.mBottom );
00157 glVertex2i( rect.mRight, rect.mTop );
00158 glEnd();
00159 }
00160
00161
00162 void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset, BOOL filled)
00163 {
00164 glColor4fv(color.mV);
00165 gl_rect_2d_offset_local(left, top, right, bottom, pixel_offset, filled);
00166 }
00167
00168 void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset, BOOL filled)
00169 {
00170 glPushMatrix();
00171 left += LLFontGL::sCurOrigin.mX;
00172 right += LLFontGL::sCurOrigin.mX;
00173 bottom += LLFontGL::sCurOrigin.mY;
00174 top += LLFontGL::sCurOrigin.mY;
00175
00176 glLoadIdentity();
00177 gl_rect_2d(llfloor((F32)left * LLUI::sGLScaleFactor.mV[VX]) - pixel_offset,
00178 llfloor((F32)top * LLUI::sGLScaleFactor.mV[VY]) + pixel_offset,
00179 llfloor((F32)right * LLUI::sGLScaleFactor.mV[VX]) + pixel_offset,
00180 llfloor((F32)bottom * LLUI::sGLScaleFactor.mV[VY]) - pixel_offset,
00181 filled);
00182 glPopMatrix();
00183 }
00184
00185
00186 void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled )
00187 {
00188 stop_glerror();
00189 LLGLSNoTexture no_texture;
00190
00191
00192 if( filled )
00193 {
00194 glBegin( GL_QUADS );
00195 glVertex2i(left, top);
00196 glVertex2i(left, bottom);
00197 glVertex2i(right, bottom);
00198 glVertex2i(right, top);
00199 glEnd();
00200 }
00201 else
00202 {
00203 if( gGLManager.mATIOffsetVerticalLines )
00204 {
00205
00206 glBegin( GL_LINES );
00207
00208
00209 glVertex2i(left + 1, top);
00210 glVertex2i(left + 1, bottom);
00211
00212 glVertex2i(right, bottom);
00213 glVertex2i(right, top);
00214
00215
00216 top--;
00217 right--;
00218 glVertex2i(left, bottom);
00219 glVertex2i(right, bottom);
00220
00221 glVertex2i(left, top);
00222 glVertex2i(right, top);
00223 glEnd();
00224 }
00225 else
00226 {
00227 top--;
00228 right--;
00229 glBegin( GL_LINE_STRIP );
00230 glVertex2i(left, top);
00231 glVertex2i(left, bottom);
00232 glVertex2i(right, bottom);
00233 glVertex2i(right, top);
00234 glVertex2i(left, top);
00235 glEnd();
00236 }
00237 }
00238 stop_glerror();
00239 }
00240
00241 void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled )
00242 {
00243 glColor4fv( color.mV );
00244 gl_rect_2d( left, top, right, bottom, filled );
00245 }
00246
00247
00248 void gl_rect_2d( const LLRect& rect, const LLColor4& color, BOOL filled )
00249 {
00250 glColor4fv( color.mV );
00251 gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
00252 }
00253
00254
00255
00256
00257 void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines)
00258 {
00259 stop_glerror();
00260 LLGLSNoTexture no_texture;
00261
00262
00263 right--;
00264 bottom++;
00265 lines++;
00266
00267 LLColor4 end_color = start_color;
00268 end_color.mV[VALPHA] = 0.f;
00269
00270 glBegin(GL_QUADS);
00271
00272
00273 glColor4fv(start_color.mV);
00274 glVertex2i(right, top-lines);
00275 glVertex2i(right, bottom);
00276 glColor4fv(end_color.mV);
00277 glVertex2i(right+lines, bottom);
00278 glVertex2i(right+lines, top-lines);
00279
00280
00281 glColor4fv(start_color.mV);
00282 glVertex2i(right, bottom);
00283 glVertex2i(left+lines, bottom);
00284 glColor4fv(end_color.mV);
00285 glVertex2i(left+lines, bottom-lines);
00286 glVertex2i(right, bottom-lines);
00287
00288
00289 glColor4fv(start_color.mV);
00290 glVertex2i(left+lines, bottom);
00291 glColor4fv(end_color.mV);
00292 glVertex2i(left, bottom);
00293
00294 glVertex2i(left+1, bottom-lines+1);
00295 glVertex2i(left+lines, bottom-lines);
00296
00297
00298 glColor4fv(start_color.mV);
00299 glVertex2i(right, bottom);
00300 glColor4fv(end_color.mV);
00301 glVertex2i(right, bottom-lines);
00302
00303 glVertex2i(right+lines-1, bottom-lines+1);
00304 glVertex2i(right+lines, bottom);
00305
00306
00307 glColor4fv(start_color.mV);
00308 glVertex2i( right, top-lines );
00309 glColor4fv(end_color.mV);
00310 glVertex2i( right+lines, top-lines );
00311
00312 glVertex2i( right+lines-1, top-1 );
00313 glVertex2i( right, top );
00314
00315 glEnd();
00316 stop_glerror();
00317 }
00318
00319 void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 )
00320 {
00321
00322 if( gGLManager.mATIOffsetVerticalLines && (x1 == x2) )
00323 {
00324 x1++;
00325 x2++;
00326 y1++;
00327 y2++;
00328 }
00329
00330 LLGLSNoTexture no_texture;
00331
00332 glBegin(GL_LINES);
00333 glVertex2i(x1, y1);
00334 glVertex2i(x2, y2);
00335 glEnd();
00336 }
00337
00338 void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color )
00339 {
00340
00341 if( gGLManager.mATIOffsetVerticalLines && (x1 == x2) )
00342 {
00343 x1++;
00344 x2++;
00345 y1++;
00346 y2++;
00347 }
00348
00349 LLGLSNoTexture no_texture;
00350
00351 glColor4fv( color.mV );
00352
00353 glBegin(GL_LINES);
00354 glVertex2i(x1, y1);
00355 glVertex2i(x2, y2);
00356 glEnd();
00357 }
00358
00359 void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled)
00360 {
00361 LLGLSNoTexture no_texture;
00362
00363 glColor4fv(color.mV);
00364
00365 if (filled)
00366 {
00367 glBegin(GL_TRIANGLES);
00368 }
00369 else
00370 {
00371 glBegin(GL_LINE_LOOP);
00372 }
00373 glVertex2i(x1, y1);
00374 glVertex2i(x2, y2);
00375 glVertex2i(x3, y3);
00376 glEnd();
00377 }
00378
00379 void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac)
00380 {
00381 LLGLSNoTexture no_texture;
00382
00383 length = llmin((S32)(max_frac*(right - left)), length);
00384 length = llmin((S32)(max_frac*(top - bottom)), length);
00385 glBegin(GL_LINES);
00386 glVertex2i(left, top);
00387 glVertex2i(left + length, top);
00388
00389 glVertex2i(left, top);
00390 glVertex2i(left, top - length);
00391
00392 glVertex2i(left, bottom);
00393 glVertex2i(left + length, bottom);
00394
00395 glVertex2i(left, bottom);
00396 glVertex2i(left, bottom + length);
00397
00398 glVertex2i(right, top);
00399 glVertex2i(right - length, top);
00400
00401 glVertex2i(right, top);
00402 glVertex2i(right, top - length);
00403
00404 glVertex2i(right, bottom);
00405 glVertex2i(right - length, bottom);
00406
00407 glVertex2i(right, bottom);
00408 glVertex2i(right, bottom + length);
00409 glEnd();
00410 }
00411
00412
00413 void gl_draw_image( S32 x, S32 y, LLImageGL* image, const LLColor4& color )
00414 {
00415 gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color );
00416 }
00417
00418 void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color)
00419 {
00420 gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color );
00421 }
00422
00423 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)
00424 {
00425 stop_glerror();
00426 F32 border_scale = 1.f;
00427
00428 if (NULL == image)
00429 {
00430 llwarns << "image == NULL; aborting function" << llendl;
00431 return;
00432 }
00433
00434 if (border_height * 2 > height)
00435 {
00436 border_scale = (F32)height / ((F32)border_height * 2.f);
00437 }
00438 if (border_width * 2 > width)
00439 {
00440 border_scale = llmin(border_scale, (F32)width / ((F32)border_width * 2.f));
00441 }
00442
00443
00444 S32 scaled_border_width = llfloor(border_scale * (F32)border_width);
00445 S32 scaled_border_height = llfloor(border_scale * (F32)border_height);
00446
00447 LLGLSUIDefault gls_ui;
00448
00449 if (solid_color)
00450 {
00451 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
00452 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
00453 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
00454
00455 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS);
00456 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
00457
00458 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
00459 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
00460
00461 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
00462 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);
00463 }
00464
00465 glPushMatrix();
00466 {
00467 glTranslatef((F32)x, (F32)y, 0.f);
00468
00469 image->bind();
00470
00471 glColor4fv(color.mV);
00472
00473 F32 border_width_fraction = (F32)border_width / (F32)image->getWidth(0);
00474 F32 border_height_fraction = (F32)border_height / (F32)image->getHeight(0);
00475
00476 glBegin(GL_QUADS);
00477 {
00478
00479 glTexCoord2f(0.f, 0.f);
00480 glVertex2i(0, 0);
00481
00482 glTexCoord2f(border_width_fraction, 0.f);
00483 glVertex2i(scaled_border_width, 0);
00484
00485 glTexCoord2f(border_width_fraction, border_height_fraction);
00486 glVertex2i(scaled_border_width, scaled_border_height);
00487
00488 glTexCoord2f(0.f, border_height_fraction);
00489 glVertex2i(0, scaled_border_height);
00490
00491
00492 glTexCoord2f(border_width_fraction, 0.f);
00493 glVertex2i(scaled_border_width, 0);
00494
00495 glTexCoord2f(1.f - border_width_fraction, 0.f);
00496 glVertex2i(width - scaled_border_width, 0);
00497
00498 glTexCoord2f(1.f - border_width_fraction, border_height_fraction);
00499 glVertex2i(width - scaled_border_width, scaled_border_height);
00500
00501 glTexCoord2f(border_width_fraction, border_height_fraction);
00502 glVertex2i(scaled_border_width, scaled_border_height);
00503
00504
00505 glTexCoord2f(1.f - border_width_fraction, 0.f);
00506 glVertex2i(width - scaled_border_width, 0);
00507
00508 glTexCoord2f(1.f, 0.f);
00509 glVertex2i(width, 0);
00510
00511 glTexCoord2f(1.f, border_height_fraction);
00512 glVertex2i(width, scaled_border_height);
00513
00514 glTexCoord2f(1.f - border_width_fraction, border_height_fraction);
00515 glVertex2i(width - scaled_border_width, scaled_border_height);
00516
00517
00518 glTexCoord2f(0.f, border_height_fraction);
00519 glVertex2i(0, scaled_border_height);
00520
00521 glTexCoord2f(border_width_fraction, border_height_fraction);
00522 glVertex2i(scaled_border_width, scaled_border_height);
00523
00524 glTexCoord2f(border_width_fraction, 1.f - border_height_fraction);
00525 glVertex2i(scaled_border_width, height - scaled_border_height);
00526
00527 glTexCoord2f(0.f, 1.f - border_height_fraction);
00528 glVertex2i(0, height - scaled_border_height);
00529
00530
00531 glTexCoord2f(border_width_fraction, border_height_fraction);
00532 glVertex2i(scaled_border_width, scaled_border_height);
00533
00534 glTexCoord2f(1.f - border_width_fraction, border_height_fraction);
00535 glVertex2i(width - scaled_border_width, scaled_border_height);
00536
00537 glTexCoord2f(1.f - border_width_fraction, 1.f - border_height_fraction);
00538 glVertex2i(width - scaled_border_width, height - scaled_border_height);
00539
00540 glTexCoord2f(border_width_fraction, 1.f - border_height_fraction);
00541 glVertex2i(scaled_border_width, height - scaled_border_height);
00542
00543
00544 glTexCoord2f(1.f - border_width_fraction, border_height_fraction);
00545 glVertex2i(width - scaled_border_width, scaled_border_height);
00546
00547 glTexCoord2f(1.f, border_height_fraction);
00548 glVertex2i(width, scaled_border_height);
00549
00550 glTexCoord2f(1.f, 1.f - border_height_fraction);
00551 glVertex2i(width, height - scaled_border_height);
00552
00553 glTexCoord2f(1.f - border_width_fraction, 1.f - border_height_fraction);
00554 glVertex2i(width - scaled_border_width, height - scaled_border_height);
00555
00556
00557 glTexCoord2f(0.f, 1.f - border_height_fraction);
00558 glVertex2i(0, height - scaled_border_height);
00559
00560 glTexCoord2f(border_width_fraction, 1.f - border_height_fraction);
00561 glVertex2i(scaled_border_width, height - scaled_border_height);
00562
00563 glTexCoord2f(border_width_fraction, 1.f);
00564 glVertex2i(scaled_border_width, height);
00565
00566 glTexCoord2f(0.f, 1.f);
00567 glVertex2i(0, height);
00568
00569
00570 glTexCoord2f(border_width_fraction, 1.f - border_height_fraction);
00571 glVertex2i(scaled_border_width, height - scaled_border_height);
00572
00573 glTexCoord2f(1.f - border_width_fraction, 1.f - border_height_fraction);
00574 glVertex2i(width - scaled_border_width, height - scaled_border_height);
00575
00576 glTexCoord2f(1.f - border_width_fraction, 1.f);
00577 glVertex2i(width - scaled_border_width, height);
00578
00579 glTexCoord2f(border_width_fraction, 1.f);
00580 glVertex2i(scaled_border_width, height);
00581
00582
00583 glTexCoord2f(1.f - border_width_fraction, 1.f - border_height_fraction);
00584 glVertex2i(width - scaled_border_width, height - scaled_border_height);
00585
00586 glTexCoord2f(1.f, 1.f - border_height_fraction);
00587 glVertex2i(width, height - scaled_border_height);
00588
00589 glTexCoord2f(1.f, 1.f);
00590 glVertex2i(width, height);
00591
00592 glTexCoord2f(1.f - border_width_fraction, 1.f);
00593 glVertex2i(width - scaled_border_width, height);
00594 }
00595 glEnd();
00596 }
00597 glPopMatrix();
00598
00599 if (solid_color)
00600 {
00601 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00602 }
00603 }
00604
00605 void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLImageGL* image, const LLColor4& color)
00606 {
00607 gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color );
00608 }
00609
00610 void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLImageGL* image, const LLColor4& color)
00611 {
00612 if (NULL == image)
00613 {
00614 llwarns << "image == NULL; aborting function" << llendl;
00615 return;
00616 }
00617
00618 LLGLSUIDefault gls_ui;
00619
00620 glPushMatrix();
00621 {
00622 glTranslatef((F32)x, (F32)y, 0.f);
00623 if( degrees )
00624 {
00625 F32 offset_x = F32(width/2);
00626 F32 offset_y = F32(height/2);
00627 glTranslatef( offset_x, offset_y, 0.f);
00628 glRotatef( degrees, 0.f, 0.f, 1.f );
00629 glTranslatef( -offset_x, -offset_y, 0.f );
00630 }
00631
00632 image->bind();
00633
00634 glColor4fv(color.mV);
00635
00636 glBegin(GL_QUADS);
00637 {
00638 glTexCoord2f(1.f, 1.f);
00639 glVertex2i(width, height );
00640
00641 glTexCoord2f(0.f, 1.f);
00642 glVertex2i(0, height );
00643
00644 glTexCoord2f(0.f, 0.f);
00645 glVertex2i(0, 0);
00646
00647 glTexCoord2f(1.f, 0.f);
00648 glVertex2i(width, 0);
00649 }
00650 glEnd();
00651 }
00652 glPopMatrix();
00653 }
00654
00655
00656 void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLImageGL* image, const LLColor4& color)
00657 {
00658 if (NULL == image)
00659 {
00660 llwarns << "image == NULL; aborting function" << llendl;
00661 return;
00662 }
00663
00664 LLGLSUIDefault gls_ui;
00665
00666 glPushMatrix();
00667 {
00668 glTranslatef((F32)x, (F32)y, 0.f);
00669
00670 image->bind();
00671
00672 glColor4fv(color.mV);
00673
00674 glBegin(GL_QUADS);
00675 {
00676 glTexCoord2f(1.f, 0.f);
00677 glVertex2i(width, height );
00678
00679 glTexCoord2f(0.f, 0.f);
00680 glVertex2i(0, height );
00681
00682 glTexCoord2f(0.f, 1.f);
00683 glVertex2i(0, 0);
00684
00685 glTexCoord2f(1.f, 1.f);
00686 glVertex2i(width, 0);
00687 }
00688 glEnd();
00689 }
00690 glPopMatrix();
00691 }
00692
00693
00694 void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase )
00695 {
00696 phase = fmod(phase, 1.f);
00697
00698 S32 shift = S32(phase * 4.f) % 4;
00699
00700
00701 LLGLEnable stipple(GL_LINE_STIPPLE);
00702
00703 glColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], color.mV[VALPHA]);
00704 glLineWidth(2.5f);
00705 glLineStipple(2, 0x3333 << shift);
00706
00707 glBegin(GL_LINES);
00708 {
00709 glVertex3fv( start.mV );
00710 glVertex3fv( end.mV );
00711 }
00712 glEnd();
00713
00714 LLUI::setLineWidth(1.f);
00715 }
00716
00717
00718 void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom)
00719 {
00720 glColor4fv( LLColor4::white.mV );
00721 glLogicOp( GL_XOR );
00722 stop_glerror();
00723
00724 glBegin(GL_QUADS);
00725 glVertex2i(left, top);
00726 glVertex2i(left, bottom);
00727 glVertex2i(right, bottom);
00728 glVertex2i(right, top);
00729 glEnd();
00730
00731 glLogicOp( GL_COPY );
00732 stop_glerror();
00733 }
00734
00735
00736 void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle)
00737 {
00738 if (end_angle < start_angle)
00739 {
00740 end_angle += F_TWO_PI;
00741 }
00742
00743 glPushMatrix();
00744 {
00745 glTranslatef(center_x, center_y, 0.f);
00746
00747
00748 F32 delta = (end_angle - start_angle) / steps;
00749 F32 sin_delta = sin( delta );
00750 F32 cos_delta = cos( delta );
00751 F32 x = cosf(start_angle) * radius;
00752 F32 y = sinf(start_angle) * radius;
00753
00754 if (filled)
00755 {
00756 glBegin(GL_TRIANGLE_FAN);
00757 glVertex2f(0.f, 0.f);
00758
00759 steps += 1;
00760 }
00761 else
00762 {
00763 glBegin(GL_LINE_STRIP);
00764 }
00765
00766 while( steps-- )
00767 {
00768
00769 glVertex2f( x, y );
00770 F32 x_new = x * cos_delta - y * sin_delta;
00771 y = x * sin_delta + y * cos_delta;
00772 x = x_new;
00773 }
00774 glEnd();
00775 }
00776 glPopMatrix();
00777 }
00778
00779 void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled)
00780 {
00781 glPushMatrix();
00782 {
00783 LLGLSNoTexture gls_no_texture;
00784 glTranslatef(center_x, center_y, 0.f);
00785
00786
00787 F32 delta = F_TWO_PI / steps;
00788 F32 sin_delta = sin( delta );
00789 F32 cos_delta = cos( delta );
00790 F32 x = radius;
00791 F32 y = 0.f;
00792
00793 if (filled)
00794 {
00795 glBegin(GL_TRIANGLE_FAN);
00796 glVertex2f(0.f, 0.f);
00797
00798 steps += 1;
00799 }
00800 else
00801 {
00802 glBegin(GL_LINE_LOOP);
00803 }
00804
00805 while( steps-- )
00806 {
00807
00808 glVertex2f( x, y );
00809 F32 x_new = x * cos_delta - y * sin_delta;
00810 y = x * sin_delta + y * cos_delta;
00811 x = x_new;
00812 }
00813 glEnd();
00814 }
00815 glPopMatrix();
00816 }
00817
00818
00819 void gl_deep_circle( F32 radius, F32 depth, S32 steps )
00820 {
00821 F32 x = radius;
00822 F32 y = 0.f;
00823 F32 angle_delta = F_TWO_PI / (F32)steps;
00824 glBegin( GL_TRIANGLE_STRIP );
00825 {
00826 S32 step = steps + 1;
00827 while( step-- )
00828 {
00829 glVertex3f( x, y, depth );
00830 glVertex3f( x, y, 0.f );
00831
00832 F32 x_new = x * cosf(angle_delta) - y * sinf(angle_delta);
00833 y = x * sinf(angle_delta) + y * cosf(angle_delta);
00834 x = x_new;
00835 }
00836 }
00837 glEnd();
00838 }
00839
00840 void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center )
00841 {
00842 glPushMatrix();
00843 {
00844 glTranslatef(0.f, 0.f, -width / 2);
00845 if( render_center )
00846 {
00847 glColor4fv(center_color.mV);
00848 gl_deep_circle( radius, width, steps );
00849 }
00850 else
00851 {
00852 gl_washer_2d(radius, radius - width, steps, side_color, side_color);
00853 glTranslatef(0.f, 0.f, width);
00854 gl_washer_2d(radius - width, radius, steps, side_color, side_color);
00855 }
00856 }
00857 glPopMatrix();
00858 }
00859
00860
00861 void gl_rect_2d_checkerboard(const LLRect& rect)
00862 {
00863
00864 const S32 PIXELS = 32;
00865 static GLubyte checkerboard[PIXELS * PIXELS];
00866 static BOOL first = TRUE;
00867 if( first )
00868 {
00869 for( S32 i = 0; i < PIXELS; i++ )
00870 {
00871 for( S32 j = 0; j < PIXELS; j++ )
00872 {
00873 checkerboard[i * PIXELS + j] = ((i & 1) ^ (j & 1)) * 0xFF;
00874 }
00875 }
00876 first = FALSE;
00877 }
00878
00879 LLGLSNoTexture gls_no_texture;
00880
00881
00882 glColor3f( 1.f, 1.f, 1.f );
00883 gl_rect_2d(rect);
00884
00885
00886 glColor3f( .7f, .7f, .7f );
00887 glPolygonStipple( checkerboard );
00888
00889 LLGLEnable polygon_stipple(GL_POLYGON_STIPPLE);
00890 gl_rect_2d(rect);
00891 }
00892
00893
00894
00895
00896 void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color)
00897 {
00898 const F32 DELTA = F_TWO_PI / steps;
00899 const F32 SIN_DELTA = sin( DELTA );
00900 const F32 COS_DELTA = cos( DELTA );
00901
00902 F32 x1 = outer_radius;
00903 F32 y1 = 0.f;
00904 F32 x2 = inner_radius;
00905 F32 y2 = 0.f;
00906
00907 LLGLSNoTexture gls_no_texture;
00908
00909 glBegin( GL_TRIANGLE_STRIP );
00910 {
00911 steps += 1;
00912 while( steps-- )
00913 {
00914 glColor4fv(outer_color.mV);
00915 glVertex2f( x1, y1 );
00916 glColor4fv(inner_color.mV);
00917 glVertex2f( x2, y2 );
00918
00919 F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
00920 y1 = x1 * SIN_DELTA + y1 * COS_DELTA;
00921 x1 = x1_new;
00922
00923 F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
00924 y2 = x2 * SIN_DELTA + y2 * COS_DELTA;
00925 x2 = x2_new;
00926 }
00927 }
00928 glEnd();
00929 }
00930
00931
00932
00933 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)
00934 {
00935 const F32 DELTA = (end_radians - start_radians) / steps;
00936 const F32 SIN_DELTA = sin( DELTA );
00937 const F32 COS_DELTA = cos( DELTA );
00938
00939 F32 x1 = outer_radius * cos( start_radians );
00940 F32 y1 = outer_radius * sin( start_radians );
00941 F32 x2 = inner_radius * cos( start_radians );
00942 F32 y2 = inner_radius * sin( start_radians );
00943
00944 LLGLSNoTexture gls_no_texture;
00945 glBegin( GL_TRIANGLE_STRIP );
00946 {
00947 steps += 1;
00948 while( steps-- )
00949 {
00950 glColor4fv(outer_color.mV);
00951 glVertex2f( x1, y1 );
00952 glColor4fv(inner_color.mV);
00953 glVertex2f( x2, y2 );
00954
00955 F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
00956 y1 = x1 * SIN_DELTA + y1 * COS_DELTA;
00957 x1 = x1_new;
00958
00959 F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
00960 y2 = x2 * SIN_DELTA + y2 * COS_DELTA;
00961 x2 = x2_new;
00962 }
00963 }
00964 glEnd();
00965 }
00966
00967
00968 void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LLColor4& inner_color, const LLColor4& outer_color)
00969 {
00970 const F32 DELTA = F_TWO_PI / count;
00971 const F32 HALF_DELTA = DELTA * 0.5f;
00972 const F32 SIN_DELTA = sin( DELTA );
00973 const F32 COS_DELTA = cos( DELTA );
00974
00975 F32 x1 = outer_radius * cos( HALF_DELTA );
00976 F32 y1 = outer_radius * sin( HALF_DELTA );
00977 F32 x2 = inner_radius * cos( HALF_DELTA );
00978 F32 y2 = inner_radius * sin( HALF_DELTA );
00979
00980 LLGLSNoTexture gls_no_texture;
00981
00982 glBegin( GL_LINES );
00983 {
00984 while( count-- )
00985 {
00986 glColor4fv(outer_color.mV);
00987 glVertex2f( x1, y1 );
00988 glColor4fv(inner_color.mV);
00989 glVertex2f( x2, y2 );
00990
00991 F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
00992 y1 = x1 * SIN_DELTA + y1 * COS_DELTA;
00993 x1 = x1_new;
00994
00995 F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
00996 y2 = x2 * SIN_DELTA + y2 * COS_DELTA;
00997 x2 = x2_new;
00998 }
00999 }
01000 glEnd();
01001 }
01002
01003 void gl_rect_2d_simple_tex( S32 width, S32 height )
01004 {
01005 glBegin( GL_QUADS );
01006
01007 glTexCoord2f(1.f, 1.f);
01008 glVertex2i(width, height);
01009
01010 glTexCoord2f(0.f, 1.f);
01011 glVertex2i(0, height);
01012
01013 glTexCoord2f(0.f, 0.f);
01014 glVertex2i(0, 0);
01015
01016 glTexCoord2f(1.f, 0.f);
01017 glVertex2i(width, 0);
01018
01019 glEnd();
01020 }
01021
01022 void gl_rect_2d_simple( S32 width, S32 height )
01023 {
01024 glBegin( GL_QUADS );
01025 glVertex2i(width, height);
01026 glVertex2i(0, height);
01027 glVertex2i(0, 0);
01028 glVertex2i(width, 0);
01029 glEnd();
01030 }
01031
01032 void gl_segmented_rect_2d_tex(const S32 left,
01033 const S32 top,
01034 const S32 right,
01035 const S32 bottom,
01036 const S32 texture_width,
01037 const S32 texture_height,
01038 const S32 border_size,
01039 const U32 edges)
01040 {
01041 S32 width = llabs(right - left);
01042 S32 height = llabs(top - bottom);
01043
01044 glPushMatrix();
01045
01046 glTranslatef((F32)left, (F32)bottom, 0.f);
01047 LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
01048
01049 if (border_uv_scale.mV[VX] > 0.5f)
01050 {
01051 border_uv_scale *= 0.5f / border_uv_scale.mV[VX];
01052 }
01053 if (border_uv_scale.mV[VY] > 0.5f)
01054 {
01055 border_uv_scale *= 0.5f / border_uv_scale.mV[VY];
01056 }
01057
01058 F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f);
01059 LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
01060 LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
01061 LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
01062 LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
01063 LLVector2 width_vec((F32)width, 0.f);
01064 LLVector2 height_vec(0.f, (F32)height);
01065
01066 glBegin(GL_QUADS);
01067 {
01068
01069 glTexCoord2f(0.f, 0.f);
01070 glVertex2f(0.f, 0.f);
01071
01072 glTexCoord2f(border_uv_scale.mV[VX], 0.f);
01073 glVertex2fv(border_width_left.mV);
01074
01075 glTexCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
01076 glVertex2fv((border_width_left + border_height_bottom).mV);
01077
01078 glTexCoord2f(0.f, border_uv_scale.mV[VY]);
01079 glVertex2fv(border_height_bottom.mV);
01080
01081
01082 glTexCoord2f(border_uv_scale.mV[VX], 0.f);
01083 glVertex2fv(border_width_left.mV);
01084
01085 glTexCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
01086 glVertex2fv((width_vec - border_width_right).mV);
01087
01088 glTexCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
01089 glVertex2fv((width_vec - border_width_right + border_height_bottom).mV);
01090
01091 glTexCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
01092 glVertex2fv((border_width_left + border_height_bottom).mV);
01093
01094
01095 glTexCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
01096 glVertex2fv((width_vec - border_width_right).mV);
01097
01098 glTexCoord2f(1.f, 0.f);
01099 glVertex2fv(width_vec.mV);
01100
01101 glTexCoord2f(1.f, border_uv_scale.mV[VY]);
01102 glVertex2fv((width_vec + border_height_bottom).mV);
01103
01104 glTexCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
01105 glVertex2fv((width_vec - border_width_right + border_height_bottom).mV);
01106
01107
01108 glTexCoord2f(0.f, border_uv_scale.mV[VY]);
01109 glVertex2fv(border_height_bottom.mV);
01110
01111 glTexCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
01112 glVertex2fv((border_width_left + border_height_bottom).mV);
01113
01114 glTexCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
01115 glVertex2fv((border_width_left + height_vec - border_height_top).mV);
01116
01117 glTexCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
01118 glVertex2fv((height_vec - border_height_top).mV);
01119
01120
01121 glTexCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
01122 glVertex2fv((border_width_left + border_height_bottom).mV);
01123
01124 glTexCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
01125 glVertex2fv((width_vec - border_width_right + border_height_bottom).mV);
01126
01127 glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
01128 glVertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
01129
01130 glTexCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
01131 glVertex2fv((border_width_left + height_vec - border_height_top).mV);
01132
01133
01134 glTexCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
01135 glVertex2fv((width_vec - border_width_right + border_height_bottom).mV);
01136
01137 glTexCoord2f(1.f, border_uv_scale.mV[VY]);
01138 glVertex2fv((width_vec + border_height_bottom).mV);
01139
01140 glTexCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
01141 glVertex2fv((width_vec + height_vec - border_height_top).mV);
01142
01143 glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
01144 glVertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
01145
01146
01147 glTexCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
01148 glVertex2fv((height_vec - border_height_top).mV);
01149
01150 glTexCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
01151 glVertex2fv((border_width_left + height_vec - border_height_top).mV);
01152
01153 glTexCoord2f(border_uv_scale.mV[VX], 1.f);
01154 glVertex2fv((border_width_left + height_vec).mV);
01155
01156 glTexCoord2f(0.f, 1.f);
01157 glVertex2fv((height_vec).mV);
01158
01159
01160 glTexCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
01161 glVertex2fv((border_width_left + height_vec - border_height_top).mV);
01162
01163 glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
01164 glVertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
01165
01166 glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
01167 glVertex2fv((width_vec - border_width_right + height_vec).mV);
01168
01169 glTexCoord2f(border_uv_scale.mV[VX], 1.f);
01170 glVertex2fv((border_width_left + height_vec).mV);
01171
01172
01173 glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
01174 glVertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
01175
01176 glTexCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
01177 glVertex2fv((width_vec + height_vec - border_height_top).mV);
01178
01179 glTexCoord2f(1.f, 1.f);
01180 glVertex2fv((width_vec + height_vec).mV);
01181
01182 glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
01183 glVertex2fv((width_vec - border_width_right + height_vec).mV);
01184 }
01185 glEnd();
01186
01187 glPopMatrix();
01188 }
01189
01190 void gl_segmented_rect_2d_fragment_tex(const S32 left,
01191 const S32 top,
01192 const S32 right,
01193 const S32 bottom,
01194 const S32 texture_width,
01195 const S32 texture_height,
01196 const S32 border_size,
01197 const F32 start_fragment,
01198 const F32 end_fragment,
01199 const U32 edges)
01200 {
01201 S32 width = llabs(right - left);
01202 S32 height = llabs(top - bottom);
01203
01204 glPushMatrix();
01205
01206 glTranslatef((F32)left, (F32)bottom, 0.f);
01207 LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
01208
01209 if (border_uv_scale.mV[VX] > 0.5f)
01210 {
01211 border_uv_scale *= 0.5f / border_uv_scale.mV[VX];
01212 }
01213 if (border_uv_scale.mV[VY] > 0.5f)
01214 {
01215 border_uv_scale *= 0.5f / border_uv_scale.mV[VY];
01216 }
01217
01218 F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f);
01219 LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
01220 LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
01221 LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
01222 LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
01223 LLVector2 width_vec((F32)width, 0.f);
01224 LLVector2 height_vec(0.f, (F32)height);
01225
01226 F32 middle_start = border_scale / (F32)width;
01227 F32 middle_end = 1.f - middle_start;
01228
01229 F32 u_min;
01230 F32 u_max;
01231 LLVector2 x_min;
01232 LLVector2 x_max;
01233
01234 glBegin(GL_QUADS);
01235 {
01236 if (start_fragment < middle_start)
01237 {
01238 u_min = (start_fragment / middle_start) * border_uv_scale.mV[VX];
01239 u_max = llmin(end_fragment / middle_start, 1.f) * border_uv_scale.mV[VX];
01240 x_min = (start_fragment / middle_start) * border_width_left;
01241 x_max = llmin(end_fragment / middle_start, 1.f) * border_width_left;
01242
01243
01244 glTexCoord2f(u_min, 0.f);
01245 glVertex2fv(x_min.mV);
01246
01247 glTexCoord2f(border_uv_scale.mV[VX], 0.f);
01248 glVertex2fv(x_max.mV);
01249
01250 glTexCoord2f(u_max, border_uv_scale.mV[VY]);
01251 glVertex2fv((x_max + border_height_bottom).mV);
01252
01253 glTexCoord2f(u_min, border_uv_scale.mV[VY]);
01254 glVertex2fv((x_min + border_height_bottom).mV);
01255
01256
01257 glTexCoord2f(u_min, border_uv_scale.mV[VY]);
01258 glVertex2fv((x_min + border_height_bottom).mV);
01259
01260 glTexCoord2f(u_max, border_uv_scale.mV[VY]);
01261 glVertex2fv((x_max + border_height_bottom).mV);
01262
01263 glTexCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
01264 glVertex2fv((x_max + height_vec - border_height_top).mV);
01265
01266 glTexCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
01267 glVertex2fv((x_min + height_vec - border_height_top).mV);
01268
01269
01270 glTexCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
01271 glVertex2fv((x_min + height_vec - border_height_top).mV);
01272
01273 glTexCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
01274 glVertex2fv((x_max + height_vec - border_height_top).mV);
01275
01276 glTexCoord2f(u_max, 1.f);
01277 glVertex2fv((x_max + height_vec).mV);
01278
01279 glTexCoord2f(u_min, 1.f);
01280 glVertex2fv((x_min + height_vec).mV);
01281 }
01282
01283 if (end_fragment > middle_start || start_fragment < middle_end)
01284 {
01285 x_min = border_width_left + ((llclamp(start_fragment, middle_start, middle_end) - middle_start)) * width_vec;
01286 x_max = border_width_left + ((llclamp(end_fragment, middle_start, middle_end) - middle_start)) * width_vec;
01287
01288
01289 glTexCoord2f(border_uv_scale.mV[VX], 0.f);
01290 glVertex2fv(x_min.mV);
01291
01292 glTexCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
01293 glVertex2fv((x_max).mV);
01294
01295 glTexCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
01296 glVertex2fv((x_max + border_height_bottom).mV);
01297
01298 glTexCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
01299 glVertex2fv((x_min + border_height_bottom).mV);
01300
01301
01302 glTexCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
01303 glVertex2fv((x_min + border_height_bottom).mV);
01304
01305 glTexCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
01306 glVertex2fv((x_max + border_height_bottom).mV);
01307
01308 glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
01309 glVertex2fv((x_max + height_vec - border_height_top).mV);
01310
01311 glTexCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
01312 glVertex2fv((x_min + height_vec - border_height_top).mV);
01313
01314
01315 glTexCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
01316 glVertex2fv((x_min + height_vec - border_height_top).mV);
01317
01318 glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
01319 glVertex2fv((x_max + height_vec - border_height_top).mV);
01320
01321 glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
01322 glVertex2fv((x_max + height_vec).mV);
01323
01324 glTexCoord2f(border_uv_scale.mV[VX], 1.f);
01325 glVertex2fv((x_min + height_vec).mV);
01326 }
01327
01328 if (end_fragment > middle_end)
01329 {
01330 u_min = (1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_uv_scale.mV[VX];
01331 u_max = (1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX];
01332 x_min = width_vec - ((1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_width_right);
01333 x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right);
01334
01335
01336 glTexCoord2f(u_min, 0.f);
01337 glVertex2fv((x_min).mV);
01338
01339 glTexCoord2f(u_max, 0.f);
01340 glVertex2fv(x_max.mV);
01341
01342 glTexCoord2f(u_max, border_uv_scale.mV[VY]);
01343 glVertex2fv((x_max + border_height_bottom).mV);
01344
01345 glTexCoord2f(u_min, border_uv_scale.mV[VY]);
01346 glVertex2fv((x_min + border_height_bottom).mV);
01347
01348
01349 glTexCoord2f(u_min, border_uv_scale.mV[VY]);
01350 glVertex2fv((x_min + border_height_bottom).mV);
01351
01352 glTexCoord2f(u_max, border_uv_scale.mV[VY]);
01353 glVertex2fv((x_max + border_height_bottom).mV);
01354
01355 glTexCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
01356 glVertex2fv((x_max + height_vec - border_height_top).mV);
01357
01358 glTexCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
01359 glVertex2fv((x_min + height_vec - border_height_top).mV);
01360
01361
01362 glTexCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
01363 glVertex2fv((x_min + height_vec - border_height_top).mV);
01364
01365 glTexCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
01366 glVertex2fv((x_max + height_vec - border_height_top).mV);
01367
01368 glTexCoord2f(u_max, 1.f);
01369 glVertex2fv((x_max + height_vec).mV);
01370
01371 glTexCoord2f(u_min, 1.f);
01372 glVertex2fv((x_min + height_vec).mV);
01373 }
01374 }
01375 glEnd();
01376
01377 glPopMatrix();
01378 }
01379
01380 void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width,
01381 const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec,
01382 const U32 edges)
01383 {
01384 LLVector3 left_border_width = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? border_width : LLVector3::zero;
01385 LLVector3 right_border_width = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? border_width : LLVector3::zero;
01386
01387 LLVector3 top_border_height = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? border_height : LLVector3::zero;
01388 LLVector3 bottom_border_height = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? border_height : LLVector3::zero;
01389
01390 glBegin(GL_QUADS);
01391 {
01392
01393 glTexCoord2f(0.f, 0.f);
01394 glVertex3f(0.f, 0.f, 0.f);
01395
01396 glTexCoord2f(border_scale.mV[VX], 0.f);
01397 glVertex3fv(left_border_width.mV);
01398
01399 glTexCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
01400 glVertex3fv((left_border_width + bottom_border_height).mV);
01401
01402 glTexCoord2f(0.f, border_scale.mV[VY]);
01403 glVertex3fv(bottom_border_height.mV);
01404
01405
01406 glTexCoord2f(border_scale.mV[VX], 0.f);
01407 glVertex3fv(left_border_width.mV);
01408
01409 glTexCoord2f(1.f - border_scale.mV[VX], 0.f);
01410 glVertex3fv((width_vec - right_border_width).mV);
01411
01412 glTexCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
01413 glVertex3fv((width_vec - right_border_width + bottom_border_height).mV);
01414
01415 glTexCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
01416 glVertex3fv((left_border_width + bottom_border_height).mV);
01417
01418
01419 glTexCoord2f(1.f - border_scale.mV[VX], 0.f);
01420 glVertex3fv((width_vec - right_border_width).mV);
01421
01422 glTexCoord2f(1.f, 0.f);
01423 glVertex3fv(width_vec.mV);
01424
01425 glTexCoord2f(1.f, border_scale.mV[VY]);
01426 glVertex3fv((width_vec + bottom_border_height).mV);
01427
01428 glTexCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
01429 glVertex3fv((width_vec - right_border_width + bottom_border_height).mV);
01430
01431
01432 glTexCoord2f(0.f, border_scale.mV[VY]);
01433 glVertex3fv(bottom_border_height.mV);
01434
01435 glTexCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
01436 glVertex3fv((left_border_width + bottom_border_height).mV);
01437
01438 glTexCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
01439 glVertex3fv((left_border_width + height_vec - top_border_height).mV);
01440
01441 glTexCoord2f(0.f, 1.f - border_scale.mV[VY]);
01442 glVertex3fv((height_vec - top_border_height).mV);
01443
01444
01445 glTexCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
01446 glVertex3fv((left_border_width + bottom_border_height).mV);
01447
01448 glTexCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
01449 glVertex3fv((width_vec - right_border_width + bottom_border_height).mV);
01450
01451 glTexCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
01452 glVertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
01453
01454 glTexCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
01455 glVertex3fv((left_border_width + height_vec - top_border_height).mV);
01456
01457
01458 glTexCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
01459 glVertex3fv((width_vec - right_border_width + bottom_border_height).mV);
01460
01461 glTexCoord2f(1.f, border_scale.mV[VY]);
01462 glVertex3fv((width_vec + bottom_border_height).mV);
01463
01464 glTexCoord2f(1.f, 1.f - border_scale.mV[VY]);
01465 glVertex3fv((width_vec + height_vec - top_border_height).mV);
01466
01467 glTexCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
01468 glVertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
01469
01470
01471 glTexCoord2f(0.f, 1.f - border_scale.mV[VY]);
01472 glVertex3fv((height_vec - top_border_height).mV);
01473
01474 glTexCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
01475 glVertex3fv((left_border_width + height_vec - top_border_height).mV);
01476
01477 glTexCoord2f(border_scale.mV[VX], 1.f);
01478 glVertex3fv((left_border_width + height_vec).mV);
01479
01480 glTexCoord2f(0.f, 1.f);
01481 glVertex3fv((height_vec).mV);
01482
01483
01484 glTexCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
01485 glVertex3fv((left_border_width + height_vec - top_border_height).mV);
01486
01487 glTexCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
01488 glVertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
01489
01490 glTexCoord2f(1.f - border_scale.mV[VX], 1.f);
01491 glVertex3fv((width_vec - right_border_width + height_vec).mV);
01492
01493 glTexCoord2f(border_scale.mV[VX], 1.f);
01494 glVertex3fv((left_border_width + height_vec).mV);
01495
01496
01497 glTexCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
01498 glVertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
01499
01500 glTexCoord2f(1.f, 1.f - border_scale.mV[VY]);
01501 glVertex3fv((width_vec + height_vec - top_border_height).mV);
01502
01503 glTexCoord2f(1.f, 1.f);
01504 glVertex3fv((width_vec + height_vec).mV);
01505
01506 glTexCoord2f(1.f - border_scale.mV[VX], 1.f);
01507 glVertex3fv((width_vec - right_border_width + height_vec).mV);
01508 }
01509 glEnd();
01510 }
01511
01512 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)
01513 {
01514 gl_segmented_rect_3d_tex(border_scale, border_width, border_height, width_vec, height_vec, ROUNDED_RECT_TOP);
01515 }
01516
01517 class LLShowXUINamesListener: public LLSimpleListener
01518 {
01519 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
01520 {
01521 LLUI::sShowXUINames = (BOOL) event->getValue().asBoolean();
01522 return true;
01523 }
01524 };
01525 static LLShowXUINamesListener show_xui_names_listener;
01526
01527
01528 void LLUI::initClass(LLControlGroup* config,
01529 LLControlGroup* colors,
01530 LLControlGroup* assets,
01531 LLImageProviderInterface* image_provider,
01532 LLUIAudioCallback audio_callback,
01533 const LLVector2* scale_factor,
01534 const LLString& language)
01535 {
01536 sConfigGroup = config;
01537 sColorsGroup = colors;
01538 sAssetsGroup = assets;
01539 sImageProvider = image_provider;
01540 sAudioCallback = audio_callback;
01541 sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor;
01542 sWindow = NULL;
01543 LLFontGL::sShadowColor = colors->getColor("ColorDropShadow");
01544
01545 LLUI::sShowXUINames = LLUI::sConfigGroup->getBOOL("ShowXUINames");
01546 LLUI::sConfigGroup->getControl("ShowXUINames")->addListener(&show_xui_names_listener);
01547 }
01548
01549 void LLUI::cleanupClass()
01550 {
01551 }
01552
01553
01554
01555 void LLUI::translate(F32 x, F32 y, F32 z)
01556 {
01557 glTranslatef(x,y,z);
01558 LLFontGL::sCurOrigin.mX += (S32) x;
01559 LLFontGL::sCurOrigin.mY += (S32) y;
01560 LLFontGL::sCurOrigin.mZ += z;
01561 }
01562
01563
01564 void LLUI::pushMatrix()
01565 {
01566 glPushMatrix();
01567 LLFontGL::sOriginStack.push_back(LLFontGL::sCurOrigin);
01568 }
01569
01570
01571 void LLUI::popMatrix()
01572 {
01573 glPopMatrix();
01574 LLFontGL::sCurOrigin = *LLFontGL::sOriginStack.rbegin();
01575 LLFontGL::sOriginStack.pop_back();
01576 }
01577
01578
01579 void LLUI::loadIdentity()
01580 {
01581 glLoadIdentity();
01582 LLFontGL::sCurOrigin.mX = 0;
01583 LLFontGL::sCurOrigin.mY = 0;
01584 LLFontGL::sCurOrigin.mZ = 0;
01585 }
01586
01587
01588 void LLUI::setScissorRegionScreen(const LLRect& rect)
01589 {
01590 stop_glerror();
01591 S32 x,y,w,h;
01592 x = llround(rect.mLeft * LLUI::sGLScaleFactor.mV[VX]);
01593 y = llround(rect.mBottom * LLUI::sGLScaleFactor.mV[VY]);
01594 w = llround(rect.getWidth() * LLUI::sGLScaleFactor.mV[VX]);
01595 h = llround(rect.getHeight() * LLUI::sGLScaleFactor.mV[VY]);
01596 glScissor( x,y,w,h );
01597 stop_glerror();
01598 }
01599
01600
01601 void LLUI::setScissorRegionLocal(const LLRect& rect)
01602 {
01603 stop_glerror();
01604 S32 screen_left = LLFontGL::sCurOrigin.mX + rect.mLeft;
01605 S32 screen_bottom = LLFontGL::sCurOrigin.mY + rect.mBottom;
01606
01607 S32 x,y,w,h;
01608
01609 x = llround((F32)screen_left * LLUI::sGLScaleFactor.mV[VX]);
01610 y = llround((F32)screen_bottom * LLUI::sGLScaleFactor.mV[VY]);
01611 w = llround((F32)rect.getWidth() * LLUI::sGLScaleFactor.mV[VX]);
01612 h = llround((F32)rect.getHeight() * LLUI::sGLScaleFactor.mV[VY]);
01613
01614 w = llmax(0,w);
01615 h = llmax(0,h);
01616
01617 glScissor(x,y,w,h);
01618 stop_glerror();
01619 }
01620
01621
01622 void LLUI::setScaleFactor(const LLVector2 &scale_factor)
01623 {
01624 sGLScaleFactor = scale_factor;
01625 }
01626
01627
01628 void LLUI::setLineWidth(F32 width)
01629 {
01630 glLineWidth(width * lerp(sGLScaleFactor.mV[VX], sGLScaleFactor.mV[VY], 0.5f));
01631 }
01632
01633
01634 void LLUI::setCursorPositionScreen(S32 x, S32 y)
01635 {
01636 S32 screen_x, screen_y;
01637 screen_x = llround((F32)x * sGLScaleFactor.mV[VX]);
01638 screen_y = llround((F32)y * sGLScaleFactor.mV[VY]);
01639
01640 LLCoordWindow window_point;
01641 LLView::getWindow()->convertCoords(LLCoordGL(screen_x, screen_y), &window_point);
01642
01643 LLView::getWindow()->setCursorPosition(window_point);
01644 }
01645
01646
01647 void LLUI::setCursorPositionLocal(LLView* viewp, S32 x, S32 y)
01648 {
01649 S32 screen_x, screen_y;
01650 viewp->localPointToScreen(x, y, &screen_x, &screen_y);
01651
01652 setCursorPositionScreen(screen_x, screen_y);
01653 }
01654
01655
01656 LLString LLUI::locateSkin(const LLString& filename)
01657 {
01658 LLString slash = gDirUtilp->getDirDelimiter();
01659 LLString found_file = filename;
01660 if (!gDirUtilp->fileExists(found_file))
01661 {
01662 found_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename);
01663 }
01664 if (sConfigGroup && sConfigGroup->controlExists("Language"))
01665 {
01666 if (!gDirUtilp->fileExists(found_file))
01667 {
01668 LLString localization(sConfigGroup->getString("Language"));
01669 if(localization == "default")
01670 {
01671 localization = sConfigGroup->getString("SystemLanguage");
01672 }
01673 LLString local_skin = "xui" + slash + localization + slash + filename;
01674 found_file = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, local_skin);
01675 }
01676 }
01677 if (!gDirUtilp->fileExists(found_file))
01678 {
01679 LLString local_skin = "xui" + slash + "en-us" + slash + filename;
01680 found_file = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, local_skin);
01681 }
01682 if (!gDirUtilp->fileExists(found_file))
01683 {
01684 found_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, filename);
01685 }
01686 return found_file;
01687 }
01688
01689
01690 LLVector2 LLUI::getWindowSize()
01691 {
01692 LLCoordWindow window_rect;
01693 sWindow->getSize(&window_rect);
01694
01695 return LLVector2(window_rect.mX / sGLScaleFactor.mV[VX], window_rect.mY / sGLScaleFactor.mV[VY]);
01696 }
01697
01698
01699 LLUUID LLUI::findAssetUUIDByName(const LLString &asset_name)
01700 {
01701 if(asset_name == LLString::null) return LLUUID::null;
01702 LLString foundValue = LLUI::sConfigGroup->findString(asset_name);
01703 if(foundValue==LLString::null)
01704 {
01705 foundValue = LLUI::sAssetsGroup->findString(asset_name);
01706 }
01707 if(foundValue == LLString::null){
01708 return LLUUID::null;
01709 }
01710 return LLUUID( foundValue );
01711 }
01712
01713
01714 void LLUI::setHtmlHelp(LLHtmlHelp* html_help)
01715 {
01716 LLUI::sHtmlHelp = html_help;
01717 }
01718
01719
01720 void LLUI::pushClipRect(const LLRect& rect)
01721 {
01722 LLRect combined_clip_rect = rect;
01723 if (!sClipRectStack.empty())
01724 {
01725 combined_clip_rect.intersectWith(sClipRectStack.top());
01726 }
01727 sClipRectStack.push(combined_clip_rect);
01728 setScissorRegionScreen(combined_clip_rect);
01729 }
01730
01731
01732 void LLUI::popClipRect()
01733 {
01734 sClipRectStack.pop();
01735 if (!sClipRectStack.empty())
01736 {
01737 setScissorRegionScreen(sClipRectStack.top());
01738 }
01739 }
01740
01741 LLClipRect::LLClipRect(const LLRect& rect, BOOL enabled) : mScissorState(GL_SCISSOR_TEST, enabled), mEnabled(enabled)
01742 {
01743 if (mEnabled)
01744 {
01745 LLUI::pushClipRect(rect);
01746 }
01747 }
01748
01749 LLClipRect::~LLClipRect()
01750 {
01751 if (mEnabled)
01752 {
01753 LLUI::popClipRect();
01754 }
01755 }
01756
01757 LLLocalClipRect::LLLocalClipRect(const LLRect &rect, BOOL enabled) : mScissorState(GL_SCISSOR_TEST, enabled), mEnabled(enabled)
01758 {
01759 if (mEnabled)
01760 {
01761 LLRect scissor_rect = rect;
01762 scissor_rect.translate(LLFontGL::sCurOrigin.mX, LLFontGL::sCurOrigin.mY);
01763 LLUI::pushClipRect(scissor_rect);
01764 }
01765 }
01766
01767 LLLocalClipRect::~LLLocalClipRect()
01768 {
01769 if (mEnabled)
01770 {
01771 LLUI::popClipRect();
01772 }
01773 }