llviewerdisplay.cpp

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

Generated on Fri May 16 08:34:09 2008 for SecondLife by  doxygen 1.5.5