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