llviewerdisplay.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "llagent.h"
00035 #include "llviewercontrol.h"
00036 #include "llcoord.h"
00037 #include "llcriticaldamp.h"
00038 #include "lldir.h"
00039 #include "lldynamictexture.h"
00040 #include "lldrawpoolalpha.h"
00041 #include "llfeaturemanager.h"
00042 #include "llframestats.h"
00043 #include "llgl.h"
00044 #include "llglheaders.h"
00045 #include "llhudmanager.h"
00046 #include "llimagebmp.h"
00047 #include "llimagegl.h"
00048 #include "llselectmgr.h"
00049 #include "llsky.h"
00050 #include "llstartup.h"
00051 #include "lltoolfocus.h"
00052 #include "lltoolmgr.h"
00053 #include "lltooldraganddrop.h"
00054 #include "lltoolpie.h"
00055 #include "lltracker.h"
00056 #include "llui.h"
00057 #include "llviewercamera.h"
00058 #include "llviewerobjectlist.h"
00059 #include "llviewerparcelmgr.h"
00060 #include "llviewerwindow.h"
00061 #include "llvoavatar.h"
00062 #include "llvograss.h"
00063 #include "llworld.h"
00064 #include "pipeline.h"
00065 #include "viewer.h"
00066 #include "llstartup.h"
00067 #include "llfasttimer.h"
00068 #include "llfloatertools.h"
00069 #include "llviewerimagelist.h"
00070 #include "llfocusmgr.h"
00071 #include "llcubemap.h"
00072 #include "llviewerregion.h"
00073 #include "lldrawpoolwater.h"
00074 #include "llwindow.h"
00075 
00076 extern U32 gFrameCount;
00077 extern LLPointer<LLImageGL> gStartImageGL;
00078 extern LLPointer<LLImageGL> gDisconnectedImagep;
00079 extern BOOL gLogoutRequestSent;
00080 extern LLTimer gLogoutTimer;
00081 extern BOOL gHaveSavedSnapshot;
00082 extern BOOL gDisplaySwapBuffers;
00083 
00084 // used to toggle renderer back on after teleport
00085 const F32 TELEPORT_RENDER_DELAY = 20.f; // Max time a teleport is allowed to take before we raise the curtain
00086 const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived.
00087 BOOL             gTeleportDisplay = FALSE;
00088 LLFrameTimer gTeleportDisplayTimer;
00089 LLFrameTimer gTeleportArrivalTimer;
00090 const F32               RESTORE_GL_TIME = 5.f;  // Wait this long while reloading textures before we raise the curtain
00091 
00092 BOOL gForceRenderLandFence = FALSE;
00093 BOOL gDisplaySwapBuffers = FALSE;
00094 
00095 // Rendering stuff
00096 void pre_show_depth_buffer();
00097 void post_show_depth_buffer();
00098 void render_ui_and_swap();
00099 void render_ui_3d();
00100 void render_ui_2d();
00101 void render_disconnected_background();
00102 
00103 void process_keystrokes_async(); // in viewer.cpp
00104 
00105 void display_startup()
00106 {
00107         if (   !gViewerWindow->getActive()
00108                 || !gViewerWindow->mWindow->getVisible() 
00109                 || gViewerWindow->mWindow->getMinimized()
00110                 || gNoRender )
00111         {
00112                 return; 
00113         }
00114 
00115         // Required for HTML update in login screen
00116         static S32 frame_count = 0;
00117         if (frame_count++ > 1) // make sure we have rendered a frame first
00118         {
00119                 LLDynamicTexture::updateAllInstances();
00120         }
00121         glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
00122         LLGLSDefault gls_default;
00123         LLGLSUIDefault gls_ui;
00124         gPipeline.disableLights();
00125 
00126         gViewerWindow->setup2DRender();
00127         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00128 
00129         gViewerWindow->draw();
00130         gViewerWindow->mWindow->swapBuffers();
00131 }
00132 
00133 
00134 void display_update_camera()
00135 {
00136         // TODO: cut draw distance down if customizing avatar?
00137         // TODO: cut draw distance on per-parcel basis?
00138 
00139         // Cut draw distance in half when customizing avatar,
00140         // but on the viewer only.
00141         F32 final_far = gAgent.mDrawDistance;
00142         if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode())
00143         {
00144                 final_far *= 0.5f;
00145         }
00146         gCamera->setFar(final_far);
00147         gViewerWindow->setup3DRender();
00148 
00149         // Update land visibility too
00150         if (gWorldp)
00151         {
00152                 gWorldp->setLandFarClip(final_far);
00153         }
00154 }
00155 
00156 
00157 // Paint the display!
00158 void display(BOOL rebuild, F32 zoom_factor, int subfield)
00159 {
00160         LLFastTimer t(LLFastTimer::FTM_RENDER);
00161 
00162         LLGLSDefault gls_default;
00163         LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL);
00164 
00165         // No clue where this is getting unset, but safe enough to reset it here.
00166         LLGLState::resetTextureStates();
00167         
00168 #ifndef LL_RELEASE_FOR_DOWNLOAD
00169         LLGLState::checkStates();
00170         LLGLState::checkTextureChannels();
00171 #endif
00172         
00173         gPipeline.disableLights();
00174 
00175         // Don't draw if the window is hidden or minimized.
00176         // In fact, must explicitly check the minimized state before drawing.
00177         // Attempting to draw into a minimized window causes a GL error. JC
00178         if (   !gViewerWindow->getActive()
00179                 || !gViewerWindow->mWindow->getVisible() 
00180                 || gViewerWindow->mWindow->getMinimized() )
00181         {
00182                 // Clean up memory the pools may have allocated
00183                 if (rebuild)
00184                 {
00185                         gFrameStats.start(LLFrameStats::REBUILD);
00186                         gPipeline.rebuildPools();
00187                 }
00188                 return; 
00189         }
00190 
00191         gViewerWindow->checkSettings();
00192         gViewerWindow->performPick();
00193 
00194 #ifndef LL_RELEASE_FOR_DOWNLOAD
00195         LLGLState::checkStates();
00196         LLGLState::checkTextureChannels();
00197 #endif
00198         
00200         //
00201         // Logic for forcing window updates if we're in drone mode.
00202         //
00203 
00204         if (gNoRender) 
00205         {
00206 #if LL_WINDOWS
00207                 static F32 last_update_time = 0.f;
00208                 if ((gFrameTimeSeconds - last_update_time) > 1.f)
00209                 {
00210                         InvalidateRect((HWND)gViewerWindow->getPlatformWindow(), NULL, FALSE);
00211                         last_update_time = gFrameTimeSeconds;
00212                 }
00213 #elif LL_DARWIN
00214                 // MBW -- Do something clever here.
00215 #endif
00216                 // Not actually rendering, don't bother.
00217                 return;
00218         }
00219 
00220 
00221         //
00222         // Bail out if we're in the startup state and don't want to try to
00223         // render the world.
00224         //
00225         if (LLStartUp::getStartupState() < STATE_STARTED)
00226         {
00227                 display_startup();
00228                 return;
00229         }
00230 
00231         //LLGLState::verify(FALSE);
00232 
00234         //
00235         // Update GL Texture statistics (used for discard logic?)
00236         //
00237 
00238         gFrameStats.start(LLFrameStats::UPDATE_TEX_STATS);
00239         stop_glerror();
00240 
00241         LLImageGL::updateStats(gFrameTimeSeconds);
00242 
00243         LLVOAvatar::sRenderName = gSavedSettings.getS32("RenderName");
00244         LLVOAvatar::sRenderGroupTitles = gSavedSettings.getBOOL("RenderGroupTitleAll");
00245         gPipeline.mBackfaceCull = TRUE;
00246         gFrameCount++;
00247         if (gFocusMgr.getAppHasFocus())
00248         {
00249                 gForegroundFrameCount++;
00250         }
00251 
00253         //
00254         // Display start screen if we're teleporting, and skip render
00255         //
00256 
00257         if (gTeleportDisplay)
00258         {
00259                 const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived.
00260 
00261                 S32 attach_count = 0;
00262                 if (gAgent.getAvatarObject())
00263                 {
00264                         attach_count = gAgent.getAvatarObject()->getAttachmentCount();
00265                 }
00266                 F32 teleport_save_time = TELEPORT_EXPIRY + TELEPORT_EXPIRY_PER_ATTACHMENT * attach_count;
00267                 F32 teleport_elapsed = gTeleportDisplayTimer.getElapsedTimeF32();
00268                 F32 teleport_percent = teleport_elapsed * (100.f / teleport_save_time);
00269                 if( (gAgent.getTeleportState() != LLAgent::TELEPORT_START) && (teleport_percent > 100.f) )
00270                 {
00271                         // Give up.  Don't keep the UI locked forever.
00272                         gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
00273                         gAgent.setTeleportMessage("");
00274                 }
00275 
00276                 const LLString& message = gAgent.getTeleportMessage();
00277                 switch( gAgent.getTeleportState() )
00278                 {
00279                 case LLAgent::TELEPORT_START:
00280                         // Transition to REQUESTED.  Viewer has sent some kind
00281                         // of TeleportRequest to the source simulator
00282                         gTeleportDisplayTimer.reset();
00283                         gViewerWindow->setShowProgress(TRUE);
00284                         gViewerWindow->setProgressPercent(0);
00285                         gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED );
00286                         gAgent.setTeleportMessage(
00287                                 LLAgent::sTeleportProgressMessages["requesting"]);
00288                         break;
00289 
00290                 case LLAgent::TELEPORT_REQUESTED:
00291                         // Waiting for source simulator to respond
00292                         gViewerWindow->setProgressPercent( llmin(teleport_percent, 37.5f) );
00293                         gViewerWindow->setProgressString(message);
00294                         break;
00295 
00296                 case LLAgent::TELEPORT_MOVING:
00297                         // Viewer has received destination location from source simulator
00298                         gViewerWindow->setProgressPercent( llmin(teleport_percent, 75.f) );
00299                         gViewerWindow->setProgressString(message);
00300                         break;
00301 
00302                 case LLAgent::TELEPORT_START_ARRIVAL:
00303                         // Transition to ARRIVING.  Viewer has received avatar update, etc., from destination simulator
00304                         gTeleportArrivalTimer.reset();
00305                         gViewerWindow->setProgressCancelButtonVisible(FALSE, "Cancel");
00306                         gViewerWindow->setProgressPercent(75.f);
00307                         gAgent.setTeleportState( LLAgent::TELEPORT_ARRIVING );
00308                         gAgent.setTeleportMessage(
00309                                 LLAgent::sTeleportProgressMessages["arriving"]);
00310                         gImageList.mForceResetTextureStats = TRUE;
00311                         break;
00312 
00313                 case LLAgent::TELEPORT_ARRIVING:
00314                         // Make the user wait while content "pre-caches"
00315                         {
00316                                 F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / TELEPORT_ARRIVAL_DELAY);
00317                                 if( arrival_fraction > 1.f )
00318                                 {
00319                                         arrival_fraction = 1.f;
00320                                         gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
00321                                 }
00322                                 gViewerWindow->setProgressCancelButtonVisible(FALSE, "Cancel");
00323                                 gViewerWindow->setProgressPercent(  arrival_fraction * 25.f + 75.f);
00324                                 gViewerWindow->setProgressString(message);
00325                         }
00326                         break;
00327 
00328                 case LLAgent::TELEPORT_NONE:
00329                         // No teleport in progress
00330                         gViewerWindow->setShowProgress(FALSE);
00331                         gTeleportDisplay = FALSE;
00332                         break;
00333                 }
00334         }
00335         else if(gLogoutRequestSent)
00336         {
00337                 F32 percent_done = gLogoutTimer.getElapsedTimeF32() * 100.f / gLogoutMaxTime;
00338                 if (percent_done > 100.f)
00339                 {
00340                         percent_done = 100.f;
00341                 }
00342 
00343                 if( gQuit )
00344                 {
00345                         percent_done = 100.f;
00346                 }
00347                 
00348                 gViewerWindow->setProgressPercent( percent_done );
00349         }
00350         else
00351         if (gRestoreGL)
00352         {
00353                 F32 percent_done = gRestoreGLTimer.getElapsedTimeF32() * 100.f / RESTORE_GL_TIME;
00354                 if( percent_done > 100.f )
00355                 {
00356                         gViewerWindow->setShowProgress(FALSE);
00357                         gRestoreGL = FALSE;
00358                 }
00359                 else
00360                 {
00361 
00362                         if( gQuit )
00363                         {
00364                                 percent_done = 100.f;
00365                         }
00366                         
00367                         gViewerWindow->setProgressPercent( percent_done );
00368                 }
00369         }
00370 
00372         //
00373         // Prepare for the next frame
00374         //
00375 
00376         // Hmm...  Should this be moved elsewhere? - djs 09/09/02
00377         // do render-to-texture stuff here
00378         if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES))
00379         {
00380 //              LLFastTimer t(LLFastTimer::FTM_UPDATE_TEXTURES);
00381                 if (LLDynamicTexture::updateAllInstances())
00382                 {
00383                         glClear(GL_COLOR_BUFFER_BIT);
00384                 }
00385         }
00386 
00387 
00389         //
00390         // Update the camera
00391         //
00392         //
00393         gCamera->setZoomParameters(zoom_factor, subfield);
00394         gCamera->setNear(MIN_NEAR_PLANE);
00395 
00397         //
00398         // clear the next buffer
00399         // (must follow dynamic texture writing since that uses the frame buffer)
00400         //
00401         if (gDisconnected)
00402         {
00403                 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
00404                 render_disconnected_background();
00405         }
00406         else if (!gViewerWindow->isPickPending())
00407         {
00408                 glClear( GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
00409                 //DEBUG TEMPORARY
00410                 glClear(GL_COLOR_BUFFER_BIT);
00411         }
00412         gViewerWindow->setupViewport();
00413 
00414 
00415         //************ UMICH 3D LAB ****************
00416         if (gSavedSettings.getS32("StereoMode") > 0)
00417         {
00418                 //*** RIGHT EYE ***
00419                 if (gSavedSettings.getS32("StereoMode") == STEREO_MODE_ACTIVE)
00420                 {
00421                         // Draw to the right buffer (right eye)
00422                         glDrawBuffer(GL_BACK_RIGHT);
00423                         glClear( GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
00424                 }
00425                 else
00426                 {
00427                         // setup our color mask for anaglyph
00428                         glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);
00429                 }
00430                 
00431                 // Rotate the camera to simulate the right eye
00432                 gCamera->updateStereoValues();
00433                 gCamera->rotateToRightEye();
00434         }
00435         //************ UMICH 3D LAB ****************
00436 
00437 
00439         //
00440         // Set rendering options
00441         //
00442         //
00443         stop_glerror();
00444         if (gSavedSettings.getBOOL("ShowDepthBuffer"))
00445         {
00446                 pre_show_depth_buffer();
00447         }
00448 
00449         if(gUseWireframe)//gSavedSettings.getBOOL("UseWireframe"))
00450         {
00451                 glClearColor(0.5f, 0.5f, 0.5f, 0.f);
00452                 glClear(GL_COLOR_BUFFER_BIT);
00453                 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00454                 LLPipeline::sUseOcclusion = FALSE;
00455         }
00456         else
00457         {
00458                 LLPipeline::sUseOcclusion = gSavedSettings.getBOOL("UseOcclusion") && gGLManager.mHasOcclusionQuery && gFeatureManagerp->isFeatureAvailable("UseOcclusion");
00459         }
00460 
00461         stop_glerror();
00462 
00464         //
00465         // Slam lighting parameters back to our defaults.
00466         // Note that these are not the same as GL defaults...
00467 
00468         stop_glerror();
00469         F32 one[4] =    {1.f, 1.f, 1.f, 1.f};
00470         glLightModelfv (GL_LIGHT_MODEL_AMBIENT,one);
00471         stop_glerror();
00472         
00473         //Increment drawable frame counter
00474         LLDrawable::incrementVisible();
00475 
00477         //
00478         // Render
00479         //
00480         // Actually push all of our triangles to the screen.
00481         //
00482         if (!gDisconnected)
00483         {
00484                 if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
00485                 { //don't draw hud objects in this frame
00486                         gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
00487                 }
00488                 
00489                 LLFastTimer t(LLFastTimer::FTM_WORLD_UPDATE);
00490                 stop_glerror();
00491                 display_update_camera();
00492                 stop_glerror();
00493                 
00494                 // *TODO: merge these two methods
00495                 gHUDManager->updateEffects();
00496                 LLHUDObject::updateAll();
00497                 stop_glerror();
00498                 
00499                 gFrameStats.start(LLFrameStats::UPDATE_GEOM);
00500                 const F32 max_geom_update_time = 0.005f; // 5 ms update time
00501                 gPipeline.updateGeom(max_geom_update_time);
00502                 stop_glerror();
00503                 
00504                 LLSpatialPartition* part = gPipeline.getSpatialPartition(LLPipeline::PARTITION_VOLUME);
00505                 part->processImagery(gCamera);
00506 
00507                 display_update_camera();
00508 
00509                 gFrameStats.start(LLFrameStats::UPDATE_CULL);
00510                 gPipeline.updateCull(*gCamera);
00511                 stop_glerror();
00512                 
00514                 //
00515                 // StateSort
00516                 //
00517                 // Responsible for taking visible objects, and adding them to the appropriate draw orders.
00518                 // In the case of alpha objects, z-sorts them first.
00519                 // Also creates special lists for outlines and selected face rendering.
00520                 //
00521                 {
00522                         LLFastTimer t(LLFastTimer::FTM_REBUILD);
00523                         
00524                         gFrameStats.start(LLFrameStats::STATE_SORT);
00525                         gPipeline.stateSort(*gCamera);
00526                         stop_glerror();
00527                                 
00528                         if (rebuild)
00529                         {
00531                                 //
00532                                 // rebuildPools
00533                                 //
00534                                 //
00535                                 gFrameStats.start(LLFrameStats::REBUILD);
00536                                 gPipeline.rebuildPools();
00537                                 stop_glerror();
00538                         }
00539                 }
00540         }
00541 
00543         //LLFloater* frontmost_floaterp = gFloaterView->getFrontmost();
00545         //if (frontmost_floaterp && gFocusMgr.childHasKeyboardFocus(frontmost_floaterp))
00546         //{
00547         //      glMatrixMode(GL_MODELVIEW);
00548         //      glPushMatrix();
00549         //      {
00550         //              LLGLSNoTexture gls_no_texture;
00551 
00552         //              glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
00553         //              glLoadIdentity();
00554 
00555         //              LLRect floater_rect = frontmost_floaterp->getScreenRect();
00556         //              // deflate by one pixel so rounding errors don't occlude outside of floater extents
00557         //              floater_rect.stretch(-1);
00558         //              LLRectf floater_3d_rect((F32)floater_rect.mLeft / (F32)gViewerWindow->getWindowWidth(), 
00559         //                                                              (F32)floater_rect.mTop / (F32)gViewerWindow->getWindowHeight(),
00560         //                                                              (F32)floater_rect.mRight / (F32)gViewerWindow->getWindowWidth(),
00561         //                                                              (F32)floater_rect.mBottom / (F32)gViewerWindow->getWindowHeight());
00562         //              floater_3d_rect.translate(-0.5f, -0.5f);
00563         //              glTranslatef(0.f, 0.f, -gCamera->getNear());
00564         //              glScalef(gCamera->getNear() * gCamera->getAspect() / sinf(gCamera->getView()), gCamera->getNear() / sinf(gCamera->getView()), 1.f);
00565         //              glColor4fv(LLColor4::white.mV);
00566         //              glBegin(GL_QUADS);
00567         //              {
00568         //                      glVertex3f(floater_3d_rect.mLeft, floater_3d_rect.mBottom, 0.f);
00569         //                      glVertex3f(floater_3d_rect.mLeft, floater_3d_rect.mTop, 0.f);
00570         //                      glVertex3f(floater_3d_rect.mRight, floater_3d_rect.mTop, 0.f);
00571         //                      glVertex3f(floater_3d_rect.mRight, floater_3d_rect.mBottom, 0.f);
00572         //              }
00573         //              glEnd();
00574         //              glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
00575         //      }
00576         //      glPopMatrix();
00577         //}
00578 
00579         if (!(gLogoutRequestSent && gHaveSavedSnapshot) 
00580                         && !gRestoreGL
00581                         && !gDisconnected)
00582         {
00583                 gPipeline.renderGeom(*gCamera);
00584                 stop_glerror();
00585         }
00586 
00587         //render hud attachments
00588         glMatrixMode(GL_PROJECTION);
00589         glPushMatrix();
00590         glMatrixMode(GL_MODELVIEW);
00591         glPushMatrix();
00592         
00593         if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices(FALSE))
00594         {
00595                 LLCamera hud_cam = *gCamera;
00596                 glClear(GL_DEPTH_BUFFER_BIT);
00597                 LLVector3 origin = hud_cam.getOrigin();
00598                 hud_cam.setOrigin(-1.f,0,0);
00599                 hud_cam.setAxes(LLVector3(1,0,0), LLVector3(0,1,0), LLVector3(0,0,1));
00600                 LLViewerCamera::updateFrustumPlanes(hud_cam, TRUE);
00601                 //only render hud objects
00602                 U32 mask = gPipeline.getRenderTypeMask();
00603                 gPipeline.setRenderTypeMask(0);
00604                 gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
00605 
00606                 BOOL has_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
00607                 if (has_ui)
00608                 {
00609                         gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI);
00610                 }
00611 
00612                 BOOL use_occlusion = gSavedSettings.getBOOL("UseOcclusion");
00613                 gSavedSettings.setBOOL("UseOcclusion", FALSE);
00614 
00615                 //cull, sort, and render hud objects
00616                 gPipeline.updateCull(hud_cam);
00617 
00618                 gPipeline.toggleRenderType(LLDrawPool::POOL_ALPHA_POST_WATER);
00619                 gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_BUMP);
00620                 gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_SIMPLE);
00621                 gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME);
00622                 
00623                 {
00624                         LLFastTimer ftm(LLFastTimer::FTM_REBUILD);
00625                         gPipeline.stateSort(hud_cam);
00626                 }
00627                                 
00628                 gPipeline.renderGeom(hud_cam);
00629 
00630                 //restore type mask
00631                 gPipeline.setRenderTypeMask(mask);
00632                 if (has_ui)
00633                 {
00634                         gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI);
00635                 }
00636                 gSavedSettings.setBOOL("UseOcclusion", use_occlusion);
00637         }
00638         glMatrixMode(GL_PROJECTION);
00639         glPopMatrix();
00640         glMatrixMode(GL_MODELVIEW);
00641         glPopMatrix();
00642 
00643 
00644 
00645 //************ UMICH 3D LAB ****************
00646         // Render for second eye
00647         if (gSavedSettings.getS32("StereoMode") > 0)
00648         {
00649 
00651                 //
00652                 // Update the camera
00653                 //
00654                 //
00655                 gCamera->setZoomParameters(zoom_factor, subfield);
00656                 gCamera->setNear(MIN_NEAR_PLANE);
00657 
00659                 //
00660                 // clear the next buffer
00661                 // (must follow dynamic texture writing since that uses the frame buffer)
00662                 //
00663                 gViewerWindow->setupViewport();
00664 
00665                 //*** LEFT EYE ***
00666                 if (gSavedSettings.getS32("StereoMode")==STEREO_MODE_ACTIVE)
00667                 {
00668                         // Draw to the left buffer (left eye)
00669                         glDrawBuffer(GL_BACK_LEFT);
00670                         glClear( GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
00671                 }
00672                 else
00673                 {
00674                         glClear(GL_DEPTH_BUFFER_BIT);
00675                         glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE);
00676                 }
00677                                                 
00678                 // Rotate the camera to simulate the left eye
00679                 gCamera->rotateToLeftEye();
00680 
00681 
00683                 //
00684                 // Set rendering options
00685                 //
00686                 //
00687                 stop_glerror();
00688                 if (gSavedSettings.getBOOL("ShowDepthBuffer"))
00689                 {
00690                         pre_show_depth_buffer();
00691                 }
00692 
00693                 if(gUseWireframe)//gSavedSettings.getBOOL("UseWireframe"))
00694                 {
00695                         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00696                         LLPipeline::sUseOcclusion = FALSE;
00697                 }
00698                 else
00699                 {
00700                         LLPipeline::sUseOcclusion = gSavedSettings.getBOOL("UseOcclusion") && gGLManager.mHasOcclusionQuery;
00701                 }
00702 
00703                 stop_glerror();
00704 
00705 
00707                 //
00708                 // Slam lighting parameters back to our defaults.
00709                 // Note that these are not the same as GL defaults...
00710 
00711                 stop_glerror();
00712 //              F32 one[4] =    {1.f, 1.f, 1.f, 1.f};
00713                 glLightModelfv (GL_LIGHT_MODEL_AMBIENT,one);
00714                 stop_glerror();
00715                 
00716                 //Increment drawable frame counter
00717                 LLDrawable::incrementVisible();
00718 
00720                 //
00721                 // Render
00722                 //
00723                 // Actually push all of our triangles to the screen.
00724                 //
00725                 if (!gDisconnected)
00726                 {
00727                         if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
00728                         { //don't draw hud objects in this frame
00729                                 gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
00730                         }
00731                         
00732                         LLFastTimer t(LLFastTimer::FTM_WORLD_UPDATE);
00733                         stop_glerror();
00734                         display_update_camera();
00735                         stop_glerror();
00736                         
00737                         // *TODO: merge these two methods
00738                         gHUDManager->updateEffects();
00739                         LLHUDObject::updateAll();
00740                         stop_glerror();
00741                         
00742                         gFrameStats.start(LLFrameStats::UPDATE_GEOM);
00743                         const F32 max_geom_update_time = 0.005f; // 5 ms update time
00744                         gPipeline.updateGeom(max_geom_update_time);
00745                         stop_glerror();
00746                         
00747                         LLSpatialPartition* part = gPipeline.getSpatialPartition(LLPipeline::PARTITION_VOLUME);
00748                         part->processImagery(gCamera);
00749 
00750                         display_update_camera();
00751 
00752                         gFrameStats.start(LLFrameStats::UPDATE_CULL);
00753                         gPipeline.updateCull(*gCamera);
00754                         stop_glerror();
00755                         
00757                         //
00758                         // StateSort
00759                         //
00760                         // Responsible for taking visible objects, and adding them to the appropriate draw orders.
00761                         // In the case of alpha objects, z-sorts them first.
00762                         // Also creates special lists for outlines and selected face rendering.
00763                         //
00764                         {
00765                                 LLFastTimer t(LLFastTimer::FTM_REBUILD);
00766                                 
00767                                 gFrameStats.start(LLFrameStats::STATE_SORT);
00768                                 gPipeline.stateSort(*gCamera);
00769                                 stop_glerror();
00770                                         
00771                                 if (rebuild)
00772                                 {
00774                                         //
00775                                         // rebuildPools
00776                                         //
00777                                         //
00778                                         gFrameStats.start(LLFrameStats::REBUILD);
00779                                         gPipeline.rebuildPools();
00780                                         stop_glerror();
00781                                 }
00782                         }
00783                 }
00784 
00785                 if (!(gLogoutRequestSent && gHaveSavedSnapshot) 
00786                                 && !gRestoreGL
00787                                 && !gDisconnected)
00788                 {
00789                         gPipeline.renderGeom(*gCamera);
00790                         stop_glerror();
00791                 }
00792 
00793                 //render hud attachments
00794                 glMatrixMode(GL_PROJECTION);
00795                 glPushMatrix();
00796                 glMatrixMode(GL_MODELVIEW);
00797                 glPushMatrix();
00798                 if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices(FALSE))
00799                 {
00800                         LLCamera hud_cam = *gCamera;
00801                         glClear(GL_DEPTH_BUFFER_BIT);
00802                         LLVector3 origin = hud_cam.getOrigin();
00803                         hud_cam.setOrigin(-1.f,0,0);
00804                         hud_cam.setAxes(LLVector3(1,0,0), LLVector3(0,1,0), LLVector3(0,0,1));
00805                         LLViewerCamera::updateFrustumPlanes(hud_cam, TRUE);
00806                         //only render hud objects
00807                         U32 mask = gPipeline.getRenderTypeMask();
00808                         gPipeline.setRenderTypeMask(0);
00809                         gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
00810 
00811                         BOOL has_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
00812                         if (has_ui)
00813                         {
00814                                 gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI);
00815                         }
00816 
00817                         BOOL use_occlusion = gSavedSettings.getBOOL("UseOcclusion");
00818                         gSavedSettings.setBOOL("UseOcclusion", FALSE);
00819 
00820                         //cull, sort, and render hud objects
00821                         gPipeline.updateCull(hud_cam);
00822 
00823                         gPipeline.toggleRenderType(LLDrawPool::POOL_ALPHA_POST_WATER);
00824                         gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_BUMP);
00825                         gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_SIMPLE);
00826                         gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME);
00827                         
00828                         {
00829                                 LLFastTimer ftm(LLFastTimer::FTM_REBUILD);
00830                                 gPipeline.stateSort(hud_cam);
00831                         }
00832                         
00833                         gPipeline.renderGeom(hud_cam);
00834 
00835                         //restore type mask
00836                         gPipeline.setRenderTypeMask(mask);
00837                         if (has_ui)
00838                         {
00839                                 gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI);
00840                         }
00841                         gSavedSettings.setBOOL("UseOcclusion", use_occlusion);
00842                 }
00843                 glMatrixMode(GL_PROJECTION);
00844                 glPopMatrix();
00845                 glMatrixMode(GL_MODELVIEW);
00846                 glPopMatrix();
00847 
00848                 // standard rendering for UI
00849                 if (gSavedSettings.getS32("StereoMode")==STEREO_MODE_ACTIVE)
00850                 {
00851                         glDrawBuffer(GL_BACK);
00852                 }
00853                 else
00854                 {
00855                         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
00856                 }
00857         }
00858         //************ UMICH 3D LAB ****************
00859 
00860         gFrameStats.start(LLFrameStats::RENDER_UI);
00861 
00862         if (gHandleKeysAsync)
00863         {
00864                 process_keystrokes_async();
00865                 stop_glerror();
00866         }
00867 
00868         
00869 #ifndef LL_RELEASE_FOR_DOWNLOAD
00870         LLGLState::checkStates();
00871 #endif
00872         render_ui_and_swap();
00873 #ifndef LL_RELEASE_FOR_DOWNLOAD
00874         LLGLState::checkStates();
00875 #endif
00876 
00877         gFrameStats.start(LLFrameStats::MISC_END);
00878         stop_glerror();
00879 
00880 }
00881 
00882 BOOL setup_hud_matrices(BOOL for_select)
00883 {
00884         LLVOAvatar* my_avatarp = gAgent.getAvatarObject();
00885         if (my_avatarp && my_avatarp->hasHUDAttachment())
00886         {
00887                 if (!for_select)
00888                 {
00889                         // clamp target zoom level to reasonable values
00890                         my_avatarp->mHUDTargetZoom = llclamp(my_avatarp->mHUDTargetZoom, 0.1f, 1.f);
00891                         // smoothly interpolate current zoom level
00892                         my_avatarp->mHUDCurZoom = lerp(my_avatarp->mHUDCurZoom, my_avatarp->mHUDTargetZoom, LLCriticalDamp::getInterpolant(0.03f));
00893                 }
00894 
00895                 F32 zoom_level = my_avatarp->mHUDCurZoom;
00896                 // clear z buffer and set up transform for hud
00897                 if (!for_select)
00898                 {
00899                         glClear(GL_DEPTH_BUFFER_BIT);
00900                 }
00901                 LLBBox hud_bbox = my_avatarp->getHUDBBox();
00902 
00903                 
00904                 // set up transform to encompass bounding box of HUD
00905                 glMatrixMode(GL_PROJECTION);
00906                 glLoadIdentity();
00907                 F32 hud_depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f);
00908                 if (for_select)
00909                 {
00910                         //RN: reset viewport to window extents so ortho screen is calculated with proper reference frame
00911                         gViewerWindow->setupViewport();
00912                 }
00913                 glOrtho(-0.5f * gCamera->getAspect(), 0.5f * gCamera->getAspect(), -0.5f, 0.5f, 0.f, hud_depth);
00914 
00915                 // apply camera zoom transform (for high res screenshots)
00916                 F32 zoom_factor = gCamera->getZoomFactor();
00917                 S16 sub_region = gCamera->getZoomSubRegion();
00918                 if (zoom_factor > 1.f)
00919                 {
00920                         float offset = zoom_factor - 1.f;
00921                         int pos_y = sub_region / llceil(zoom_factor);
00922                         int pos_x = sub_region - (pos_y*llceil(zoom_factor));
00923                         glTranslatef(gCamera->getAspect() * 0.5f * (offset - (F32)pos_x * 2.f), 0.5f * (offset - (F32)pos_y * 2.f), 0.f);
00924                         glScalef(zoom_factor, zoom_factor, 1.f);
00925                 }
00926 
00927                 glMatrixMode(GL_MODELVIEW);
00928                 glLoadIdentity();
00929                 glLoadMatrixf(OGL_TO_CFR_ROTATION);             // Load Cory's favorite reference frame
00930                 glTranslatef(-hud_bbox.getCenterLocal().mV[VX] + (hud_depth * 0.5f), 0.f, 0.f);
00931                 glScalef(zoom_level, zoom_level, zoom_level);
00932                 
00933                 return TRUE;
00934         }
00935         else
00936         {
00937                 return FALSE;
00938         }
00939 }
00940 
00941 
00942 void render_ui_and_swap()
00943 {
00944 #ifndef LL_RELEASE_FOR_DOWNLOAD
00945         LLGLState::checkStates();
00946 #endif
00947 
00948         LLGLSDefault gls_default;
00949         {
00950                 LLGLSUIDefault gls_ui;
00951                 gPipeline.disableLights();
00952                 LLVertexBuffer::startRender();
00953                 if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
00954                 {
00955                         LLFastTimer t(LLFastTimer::FTM_RENDER_UI);
00956                         if (!gDisconnected)
00957                         {
00958                                 render_ui_3d();
00959 #ifndef LL_RELEASE_FOR_DOWNLOAD
00960                                 LLGLState::checkStates();
00961 #endif
00962                         }
00963 
00964                         render_ui_2d();
00965 #ifndef LL_RELEASE_FOR_DOWNLOAD
00966                         LLGLState::checkStates();
00967 #endif
00968                 }
00969                 LLVertexBuffer::stopRender();
00970                 glFlush();
00971 
00972                 // now do the swap buffer
00973                 if (gDisplaySwapBuffers)
00974                 {
00975                         LLFastTimer t(LLFastTimer::FTM_SWAP);
00976                         gViewerWindow->mWindow->swapBuffers();
00977                 }
00978 
00979                 {
00980                         LLFastTimer ftm(LLFastTimer::FTM_CLIENT_COPY);
00981                         LLVertexBuffer::clientCopy(0.016);
00982                 }
00983 
00984         }
00985 }
00986 
00987 void render_ui_3d()
00988 {
00989         LLGLSPipeline gls_pipeline;
00990 
00992         //
00993         // Render 3D UI elements
00994         // NOTE: zbuffer is cleared before we get here by LLDrawPoolHUD,
00995         //               so 3d elements requiring Z buffer are moved to LLDrawPoolHUD
00996         //
00997 
00998         // Render selections
00999         glDisableClientState(GL_COLOR_ARRAY);
01000         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
01001         glDisableClientState(GL_NORMAL_ARRAY);
01002 
01004         //
01005         // Render 2.5D elements (2D elements in the world)
01006         // Stuff without z writes
01007         //
01008 
01009         // Debugging stuff goes before the UI.
01010 
01011         if (gSavedSettings.getBOOL("ShowDepthBuffer"))
01012         {
01013                 post_show_depth_buffer();
01014         }
01015 
01016         // Coordinate axes
01017         if (gSavedSettings.getBOOL("ShowAxes"))
01018         {
01019                 draw_axes();
01020         }
01021 
01022         stop_glerror();
01023                 
01024         gViewerWindow->renderSelections(FALSE, FALSE, TRUE); // Non HUD call in render_hud_elements
01025         stop_glerror();
01026 }
01027 
01028 void render_ui_2d()
01029 {
01030         LLGLSUIDefault gls_ui;
01031 
01033         //
01034         // Render 2D UI elements that overlay the world (no z compare)
01035 
01036         //  Disable wireframe mode below here, as this is HUD/menus
01037         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
01038 
01039         //  Menu overlays, HUD, etc
01040         gViewerWindow->setup2DRender();
01041 
01042         F32 zoom_factor = gCamera->getZoomFactor();
01043         S16 sub_region = gCamera->getZoomSubRegion();
01044 
01045         if (zoom_factor > 1.f)
01046         {
01047                 //decompose subregion number to x and y values
01048                 int pos_y = sub_region / llceil(zoom_factor);
01049                 int pos_x = sub_region - (pos_y*llceil(zoom_factor));
01050                 // offset for this tile
01051                 LLFontGL::sCurOrigin.mX -= llround((F32)gViewerWindow->getWindowWidth() * (F32)pos_x / zoom_factor);
01052                 LLFontGL::sCurOrigin.mY -= llround((F32)gViewerWindow->getWindowHeight() * (F32)pos_y / zoom_factor);
01053         }
01054 
01055         stop_glerror();
01056         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
01057 
01058         // render outline for HUD
01059         if (gAgent.getAvatarObject() && gAgent.getAvatarObject()->mHUDCurZoom < 0.98f)
01060         {
01061                 glPushMatrix();
01062                 S32 half_width = (gViewerWindow->getWindowWidth() / 2);
01063                 S32 half_height = (gViewerWindow->getWindowHeight() / 2);
01064                 glScalef(LLUI::sGLScaleFactor.mV[0], LLUI::sGLScaleFactor.mV[1], 1.f);
01065                 glTranslatef((F32)half_width, (F32)half_height, 0.f);
01066                 F32 zoom = gAgent.getAvatarObject()->mHUDCurZoom;
01067                 glScalef(zoom,zoom,1.f);
01068                 glColor4fv(LLColor4::white.mV);
01069                 gl_rect_2d(-half_width, half_height, half_width, -half_height, FALSE);
01070                 glPopMatrix();
01071                 stop_glerror();
01072         }
01073         gViewerWindow->draw();
01074         if (gDebugSelect)
01075         {
01076                 gViewerWindow->drawPickBuffer();
01077         }
01078 
01079         // reset current origin for font rendering, in case of tiling render
01080         LLFontGL::sCurOrigin.set(0, 0);
01081 }
01082 
01083 void renderCoordinateAxes()
01084 {
01085         LLGLSNoTexture gls_no_texture;
01086         glBegin(GL_LINES);
01087                 glColor3f(1.0f, 0.0f, 0.0f);   // i direction = X-Axis = red
01088                 glVertex3f(0.0f, 0.0f, 0.0f);
01089                 glVertex3f(2.0f, 0.0f, 0.0f);
01090                 glVertex3f(3.0f, 0.0f, 0.0f);
01091                 glVertex3f(5.0f, 0.0f, 0.0f);
01092                 glVertex3f(6.0f, 0.0f, 0.0f);
01093                 glVertex3f(8.0f, 0.0f, 0.0f);
01094                 // Make an X
01095                 glVertex3f(11.0f, 1.0f, 1.0f);
01096                 glVertex3f(11.0f, -1.0f, -1.0f);
01097                 glVertex3f(11.0f, 1.0f, -1.0f);
01098                 glVertex3f(11.0f, -1.0f, 1.0f);
01099 
01100                 glColor3f(0.0f, 1.0f, 0.0f);   // j direction = Y-Axis = green
01101                 glVertex3f(0.0f, 0.0f, 0.0f);
01102                 glVertex3f(0.0f, 2.0f, 0.0f);
01103                 glVertex3f(0.0f, 3.0f, 0.0f);
01104                 glVertex3f(0.0f, 5.0f, 0.0f);
01105                 glVertex3f(0.0f, 6.0f, 0.0f);
01106                 glVertex3f(0.0f, 8.0f, 0.0f);
01107                 // Make a Y
01108                 glVertex3f(1.0f, 11.0f, 1.0f);
01109                 glVertex3f(0.0f, 11.0f, 0.0f);
01110                 glVertex3f(-1.0f, 11.0f, 1.0f);
01111                 glVertex3f(0.0f, 11.0f, 0.0f);
01112                 glVertex3f(0.0f, 11.0f, 0.0f);
01113                 glVertex3f(0.0f, 11.0f, -1.0f);
01114 
01115                 glColor3f(0.0f, 0.0f, 1.0f);   // Z-Axis = blue
01116                 glVertex3f(0.0f, 0.0f, 0.0f);
01117                 glVertex3f(0.0f, 0.0f, 2.0f);
01118                 glVertex3f(0.0f, 0.0f, 3.0f);
01119                 glVertex3f(0.0f, 0.0f, 5.0f);
01120                 glVertex3f(0.0f, 0.0f, 6.0f);
01121                 glVertex3f(0.0f, 0.0f, 8.0f);
01122                 // Make a Z
01123                 glVertex3f(-1.0f, 1.0f, 11.0f);
01124                 glVertex3f(1.0f, 1.0f, 11.0f);
01125                 glVertex3f(1.0f, 1.0f, 11.0f);
01126                 glVertex3f(-1.0f, -1.0f, 11.0f);
01127                 glVertex3f(-1.0f, -1.0f, 11.0f);
01128                 glVertex3f(1.0f, -1.0f, 11.0f);
01129         glEnd();
01130 }
01131 
01132 void draw_axes() 
01133 {
01134         LLGLSUIDefault gls_ui;
01135         LLGLSNoTexture gls_no_texture;
01136         // A vertical white line at origin
01137         LLVector3 v = gAgent.getPositionAgent();
01138         glBegin(GL_LINES);
01139                 glColor3f(1.0f, 1.0f, 1.0f); 
01140                 glVertex3f(0.0f, 0.0f, 0.0f);
01141                 glVertex3f(0.0f, 0.0f, 40.0f);
01142         glEnd();
01143         // Some coordinate axes
01144         glPushMatrix();
01145                 glTranslatef( v.mV[VX], v.mV[VY], v.mV[VZ] );
01146                 renderCoordinateAxes();
01147         glPopMatrix();
01148 }
01149 
01150 
01151 void render_disconnected_background()
01152 {
01153         if (!gDisconnectedImagep && gDisconnected)
01154         {
01155                 llinfos << "Loading last bitmap..." << llendl;
01156 
01157                 char temp_str[MAX_PATH];                /* Flawfinder: ignore */
01158                 strncpy(temp_str, gDirUtilp->getLindenUserDir().c_str(), MAX_PATH -1);          /* Flawfinder: ignore */
01159                 temp_str[MAX_PATH -1] = '\0';
01160                 strncat(temp_str, gDirUtilp->getDirDelimiter().c_str(), MAX_PATH - strlen(temp_str) -1);                /* Flawfinder: ignore */
01161 
01162                 strcat(temp_str, SCREEN_LAST_FILENAME);         /* Flawfinder: ignore */
01163 
01164                 LLPointer<LLImageBMP> image_bmp = new LLImageBMP;
01165                 if( !image_bmp->load(temp_str) )
01166                 {
01167                         //llinfos << "Bitmap load failed" << llendl;
01168                         return;
01169                 }
01170 
01171                 gDisconnectedImagep = new LLImageGL( FALSE );
01172                 LLPointer<LLImageRaw> raw = new LLImageRaw;
01173                 if (!image_bmp->decode(raw))
01174                 {
01175                         llinfos << "Bitmap decode failed" << llendl;
01176                         gDisconnectedImagep = NULL;
01177                         return;
01178                 }
01179 
01180                 U8 *rawp = raw->getData();
01181                 S32 npixels = (S32)image_bmp->getWidth()*(S32)image_bmp->getHeight();
01182                 for (S32 i = 0; i < npixels; i++)
01183                 {
01184                         S32 sum = 0;
01185                         sum = *rawp + *(rawp+1) + *(rawp+2);
01186                         sum /= 3;
01187                         *rawp = ((S32)sum*6 + *rawp)/7;
01188                         rawp++;
01189                         *rawp = ((S32)sum*6 + *rawp)/7;
01190                         rawp++;
01191                         *rawp = ((S32)sum*6 + *rawp)/7;
01192                         rawp++;
01193                 }
01194 
01195 
01196                 raw->expandToPowerOfTwo();
01197                 gDisconnectedImagep->createGLTexture(0, raw);
01198                 gStartImageGL = gDisconnectedImagep;
01199                 LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
01200         }
01201 
01202         // Make sure the progress view always fills the entire window.
01203         S32 width = gViewerWindow->getWindowWidth();
01204         S32 height = gViewerWindow->getWindowHeight();
01205 
01206         if (gDisconnectedImagep)
01207         {
01208                 LLGLSUIDefault gls_ui;
01209                 gViewerWindow->setup2DRender();
01210                 glPushMatrix();
01211                 {
01212                         // scale ui to reflect UIScaleFactor
01213                         // this can't be done in setup2DRender because it requires a
01214                         // pushMatrix/popMatrix pair
01215                         const LLVector2& display_scale = gViewerWindow->getDisplayScale();
01216                         glScalef(display_scale.mV[VX], display_scale.mV[VY], 1.f);
01217 
01218                         LLViewerImage::bindTexture(gDisconnectedImagep);
01219                         glColor4f(1.f, 1.f, 1.f, 1.f);
01220                         gl_rect_2d_simple_tex(width, height);
01221                         LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
01222                 }
01223                 glPopMatrix();
01224         }
01225 }

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