llui.cpp

Go to the documentation of this file.
00001 
00032 // Utilities functions the user interface needs
00033 
00034 //#include "llviewerprecompiledheaders.h"
00035 #include "linden_common.h"
00036 
00037 #include <string>
00038 #include <map>
00039 
00040 // Linden library includes
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 //#include "llviewerimage.h"
00048 #include "lldir.h"
00049 #include "llfontgl.h"
00050 
00051 // Project includes
00052 //#include "audioengine.h"
00053 #include "llcontrol.h"
00054 //#include "llstartup.h"
00055 #include "llui.h"
00056 #include "llview.h"
00057 #include "llwindow.h"
00058 
00059 #include "llglheaders.h"
00060 
00061 //
00062 // Globals
00063 //
00064 const LLColor4 UI_VERTEX_COLOR(1.f, 1.f, 1.f, 1.f);
00065 
00066 // Used to hide the flashing text cursor when window doesn't have focus.
00067 BOOL gShowTextEditCursor = TRUE;
00068 
00069 // Language for UI construction
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 // Functions
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 // Puts GL into 2D drawing mode by turning off lighting, setting to an
00131 // orthographic projection, etc.
00132 void gl_state_for_2d(S32 width, S32 height)
00133 {
00134         stop_glerror();
00135         F32 window_width = (F32) width;//gViewerWindow->getWindowWidth();
00136         F32 window_height = (F32) height;//gViewerWindow->getWindowHeight();
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         // Counterclockwise quad will face the viewer
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                         // Work around bug in ATI driver: vertical lines are offset by (-1,-1)
00206                         glBegin( GL_LINES );
00207 
00208                                 // Verticals 
00209                                 glVertex2i(left + 1, top);
00210                                 glVertex2i(left + 1, bottom);
00211 
00212                                 glVertex2i(right, bottom);
00213                                 glVertex2i(right, top);
00214 
00215                                 // Horizontals
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 // Given a rectangle on the screen, draws a drop shadow _outside_
00255 // the right and bottom edges of it.  Along the right it has width "lines"
00256 // and along the bottom it has height "lines".
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         // HACK: Overlap with the rectangle by a single pixel.
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         // Right edge, CCW faces screen
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         // Bottom edge, CCW faces screen
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         // bottom left Corner
00289         glColor4fv(start_color.mV);
00290         glVertex2i(left+lines,  bottom);
00291         glColor4fv(end_color.mV);
00292         glVertex2i(left,                bottom);
00293         // make the bottom left corner not sharp
00294         glVertex2i(left+1,              bottom-lines+1);
00295         glVertex2i(left+lines,  bottom-lines);
00296 
00297         // bottom right corner
00298         glColor4fv(start_color.mV);
00299         glVertex2i(right,               bottom);
00300         glColor4fv(end_color.mV);
00301         glVertex2i(right,               bottom-lines);
00302         // make the rightmost corner not sharp
00303         glVertex2i(right+lines-1,       bottom-lines+1);
00304         glVertex2i(right+lines, bottom);
00305 
00306         // top right corner
00307         glColor4fv(start_color.mV);
00308         glVertex2i( right,                      top-lines );
00309         glColor4fv(end_color.mV);
00310         glVertex2i( right+lines,        top-lines );
00311         // make the corner not sharp
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         // Work around bug in ATI driver: vertical lines are offset by (-1,-1)
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         // Work around bug in ATI driver: vertical lines are offset by (-1,-1)
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         // scale screen size of borders down
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                         // draw bottom left
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                         // draw bottom middle
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                         // draw bottom right
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                         // draw left 
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                         // draw middle
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                         // draw right 
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                         // draw top left
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                         // draw top middle
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                         // draw top right
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         // Stippled line
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                 // Inexact, but reasonably fast.
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                         // make sure circle is complete
00759                         steps += 1;
00760                 }
00761                 else
00762                 {
00763                         glBegin(GL_LINE_STRIP);
00764                 }
00765 
00766                 while( steps-- )
00767                 {
00768                         // Successive rotations
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                 // Inexact, but reasonably fast.
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                         // make sure circle is complete
00798                         steps += 1;
00799                 }
00800                 else
00801                 {
00802                         glBegin(GL_LINE_LOOP);
00803                 }
00804 
00805                 while( steps-- )
00806                 {
00807                         // Successive rotations
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 // Renders a ring with sides (tube shape)
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; // An extra step to close the circle.
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 // Draw gray and white checkerboard with black border
00861 void gl_rect_2d_checkerboard(const LLRect& rect)
00862 {
00863         // Initialize the first time this is called.
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         // ...white squares
00882         glColor3f( 1.f, 1.f, 1.f );
00883         gl_rect_2d(rect);
00884 
00885         // ...gray squares
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 // Draws the area between two concentric circles, like
00895 // a doughnut or washer.
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; // An extra step to close the circle.
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 // Draws the area between two concentric circles, like
00932 // a doughnut or washer.
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; // An extra step to close the circle.
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 // Draws spokes around a circle.
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                 // draw bottom left
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                 // draw bottom middle
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                 // draw bottom right
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                 // draw left 
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                 // draw middle
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                 // draw right 
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                 // draw top left
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                 // draw top middle
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                 // draw top right
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                         // draw bottom left
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                         // draw left 
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                         // draw top left
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                         // draw bottom middle
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                         // draw middle
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                         // draw top middle
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                         // draw bottom right
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                         // draw right 
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                         // draw top right
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                 // draw bottom left
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                 // draw bottom middle
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                 // draw bottom right
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                 // draw left 
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                 // draw middle
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                 // draw right 
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                 // draw top left
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                 // draw top middle
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                 // draw top right
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; // set later in startup
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 //static
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 //static
01564 void LLUI::pushMatrix()
01565 {
01566         glPushMatrix();
01567         LLFontGL::sOriginStack.push_back(LLFontGL::sCurOrigin);
01568 }
01569 
01570 //static
01571 void LLUI::popMatrix()
01572 {
01573         glPopMatrix();
01574         LLFontGL::sCurOrigin = *LLFontGL::sOriginStack.rbegin();
01575         LLFontGL::sOriginStack.pop_back();
01576 }
01577 
01578 //static 
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 //static 
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 //static
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 //static
01622 void LLUI::setScaleFactor(const LLVector2 &scale_factor)
01623 {
01624         sGLScaleFactor = scale_factor;
01625 }
01626 
01627 //static
01628 void LLUI::setLineWidth(F32 width)
01629 {
01630         glLineWidth(width * lerp(sGLScaleFactor.mV[VX], sGLScaleFactor.mV[VY], 0.5f));
01631 }
01632 
01633 //static 
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 //static 
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 //static
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); // Should be CUSTOM_SKINS?
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 //static
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 //static
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 // static 
01714 void LLUI::setHtmlHelp(LLHtmlHelp* html_help)
01715 {
01716         LLUI::sHtmlHelp = html_help;
01717 }
01718 
01719 //static 
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 //static 
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 }

Generated on Thu Jul 1 06:09:23 2010 for Second Life Viewer by  doxygen 1.4.7