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 "llglimmediate.h"
00046 #include "llrect.h"
00047 #include "llimagegl.h"
00048 //#include "llviewerimage.h"
00049 #include "lldir.h"
00050 #include "llfontgl.h"
00051 
00052 // Project includes
00053 //#include "audioengine.h"
00054 #include "llcontrol.h"
00055 //#include "llstartup.h"
00056 #include "llui.h"
00057 #include "llview.h"
00058 #include "lllineeditor.h"
00059 #include "llwindow.h"
00060 
00061 #include "llglheaders.h"
00062 
00063 //
00064 // Globals
00065 //
00066 const LLColor4 UI_VERTEX_COLOR(1.f, 1.f, 1.f, 1.f);
00067 
00068 // Used to hide the flashing text cursor when window doesn't have focus.
00069 BOOL gShowTextEditCursor = TRUE;
00070 
00071 // Language for UI construction
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 // Functions
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 // Puts GL into 2D drawing mode by turning off lighting, setting to an
00133 // orthographic projection, etc.
00134 void gl_state_for_2d(S32 width, S32 height)
00135 {
00136         stop_glerror();
00137         F32 window_width = (F32) width;//gViewerWindow->getWindowWidth();
00138         F32 window_height = (F32) height;//gViewerWindow->getWindowHeight();
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         // Counterclockwise quad will face the viewer
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                         // Work around bug in ATI driver: vertical lines are offset by (-1,-1)
00208                         gGL.begin( LLVertexBuffer::LINES );
00209 
00210                                 // Verticals 
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                                 // Horizontals
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 // Given a rectangle on the screen, draws a drop shadow _outside_
00257 // the right and bottom edges of it.  Along the right it has width "lines"
00258 // and along the bottom it has height "lines".
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         // HACK: Overlap with the rectangle by a single pixel.
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         // Right edge, CCW faces screen
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         // Bottom edge, CCW faces screen
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         // bottom left Corner
00291         gGL.color4fv(start_color.mV);
00292         gGL.vertex2i(left+lines,        bottom);
00293         gGL.color4fv(end_color.mV);
00294         gGL.vertex2i(left,              bottom);
00295         // make the bottom left corner not sharp
00296         gGL.vertex2i(left+1,            bottom-lines+1);
00297         gGL.vertex2i(left+lines,        bottom-lines);
00298 
00299         // bottom right corner
00300         gGL.color4fv(start_color.mV);
00301         gGL.vertex2i(right,             bottom);
00302         gGL.color4fv(end_color.mV);
00303         gGL.vertex2i(right,             bottom-lines);
00304         // make the rightmost corner not sharp
00305         gGL.vertex2i(right+lines-1,     bottom-lines+1);
00306         gGL.vertex2i(right+lines,       bottom);
00307 
00308         // top right corner
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         // make the corner not sharp
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         // Work around bug in ATI driver: vertical lines are offset by (-1,-1)
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         // Work around bug in ATI driver: vertical lines are offset by (-1,-1)
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         // scale screen size of borders down
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         // shrink scaling region to be proportional to clipped image region
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         // scale fixed region of image to drawn region
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                         // draw bottom left
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                         // draw bottom middle
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                         // draw bottom right
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                         // draw left 
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                         // draw middle
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                         // draw right 
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                         // draw top left
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                         // draw top middle
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                         // draw top right
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         // Stippled line
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                 // Inexact, but reasonably fast.
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                         // make sure circle is complete
00803                         steps += 1;
00804                 }
00805                 else
00806                 {
00807                         gGL.begin(LLVertexBuffer::LINE_STRIP);
00808                 }
00809 
00810                 while( steps-- )
00811                 {
00812                         // Successive rotations
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                 // Inexact, but reasonably fast.
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                         // make sure circle is complete
00842                         steps += 1;
00843                 }
00844                 else
00845                 {
00846                         gGL.begin(LLVertexBuffer::LINE_LOOP);
00847                 }
00848 
00849                 while( steps-- )
00850                 {
00851                         // Successive rotations
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 // Renders a ring with sides (tube shape)
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; // An extra step to close the circle.
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 // Draw gray and white checkerboard with black border
00905 void gl_rect_2d_checkerboard(const LLRect& rect)
00906 {
00907         // Initialize the first time this is called.
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         // ...white squares
00926         gGL.color3f( 1.f, 1.f, 1.f );
00927         gl_rect_2d(rect);
00928 
00929         // ...gray squares
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 // Draws the area between two concentric circles, like
00941 // a doughnut or washer.
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; // An extra step to close the circle.
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 // Draws the area between two concentric circles, like
00978 // a doughnut or washer.
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; // An extra step to close the circle.
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 // Draws spokes around a circle.
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                 // draw bottom left
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                 // draw bottom middle
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                 // draw bottom right
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                 // draw left 
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                 // draw middle
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                 // draw right 
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                 // draw top left
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                 // draw top middle
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                 // draw top right
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                         // draw bottom left
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                         // draw left 
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                         // draw top left
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                         // draw bottom middle
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                         // draw middle
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                         // draw top middle
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                         // draw bottom right
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                         // draw right 
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                         // draw top right
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                 // draw bottom left
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                 // draw bottom middle
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                 // draw bottom right
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                 // draw left 
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                 // draw middle
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                 // draw right 
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                 // draw top left
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                 // draw top middle
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                 // draw top right
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; // set later in startup
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 //static
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 //static
01607 void LLUI::pushMatrix()
01608 {
01609         gGL.pushMatrix();
01610         LLFontGL::sOriginStack.push_back(LLFontGL::sCurOrigin);
01611 }
01612 
01613 //static
01614 void LLUI::popMatrix()
01615 {
01616         gGL.popMatrix();
01617         LLFontGL::sCurOrigin = *LLFontGL::sOriginStack.rbegin();
01618         LLFontGL::sOriginStack.pop_back();
01619 }
01620 
01621 //static 
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 //static
01631 void LLUI::setScaleFactor(const LLVector2 &scale_factor)
01632 {
01633         sGLScaleFactor = scale_factor;
01634 }
01635 
01636 //static
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 //static 
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 //static 
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 //static
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); // Should be CUSTOM_SKINS?
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 //static
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 //static
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 //static
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 //static
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 //static
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 //static 
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 // static 
01746 void LLUI::setHtmlHelp(LLHtmlHelp* html_help)
01747 {
01748         LLUI::sHtmlHelp = html_help;
01749 }
01750 
01751 //static 
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 //static 
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 //static 
01789 void LLScreenClipRect::popClipRect()
01790 {
01791         sClipRectStack.pop();
01792 }
01793 
01794 //static
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 // LLUIImage
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 //TODO: move drawing implementation inside class
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         // return clipped dimensions of actual image area
01901         return llround((F32)mImage->getWidth(0) * mClipRegion.getWidth()); 
01902 }
01903 
01904 S32 LLUIImage::getHeight() const
01905 { 
01906         // return clipped dimensions of actual image area
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 }

Generated on Fri May 16 08:33:00 2008 for SecondLife by  doxygen 1.5.5