diff options
author | James Cook <james@lindenlab.com> | 2007-01-02 08:33:20 +0000 |
---|---|---|
committer | James Cook <james@lindenlab.com> | 2007-01-02 08:33:20 +0000 |
commit | 420b91db29485df39fd6e724e782c449158811cb (patch) | |
tree | b471a94563af914d3ed3edd3e856d21cb1b69945 /indra/newview/llviewerdisplay.cpp |
Print done when done.
Diffstat (limited to 'indra/newview/llviewerdisplay.cpp')
-rw-r--r-- | indra/newview/llviewerdisplay.cpp | 832 |
1 files changed, 832 insertions, 0 deletions
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp new file mode 100644 index 0000000000..d027f7dd54 --- /dev/null +++ b/indra/newview/llviewerdisplay.cpp @@ -0,0 +1,832 @@ +/** + * @file llviewerdisplay.cpp + * @brief LLViewerDisplay class implementation + * + * Copyright (c) 2004-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llagent.h" +#include "llviewercontrol.h" +#include "llcoord.h" +#include "llcriticaldamp.h" +#include "lldir.h" +#include "lldynamictexture.h" +#include "lldrawpoolalpha.h" +#include "llframestats.h" +#include "llgl.h" +#include "llglheaders.h" +#include "llhudmanager.h" +#include "llimagebmp.h" +#include "llimagegl.h" +#include "llselectmgr.h" +#include "llsky.h" +#include "llstartup.h" +#include "lltoolfocus.h" +#include "lltoolmgr.h" +#include "lltooldraganddrop.h" +#include "lltoolpie.h" +#include "lltracker.h" +#include "llui.h" +#include "llviewercamera.h" +#include "llviewerobjectlist.h" +#include "llviewerparcelmgr.h" +#include "llviewerwindow.h" +#include "llvoavatar.h" +#include "llvograss.h" +#include "llworld.h" +#include "pipeline.h" +#include "viewer.h" +#include "llstartup.h" +#include "llfasttimer.h" +#include "llfloatertools.h" +#include "llviewerimagelist.h" +#include "llfocusmgr.h" + +extern U32 gFrameCount; +extern LLPointer<LLImageGL> gStartImageGL; +extern LLPointer<LLImageGL> gDisconnectedImagep; +extern BOOL gLogoutRequestSent; +extern LLTimer gLogoutTimer; +extern BOOL gHaveSavedSnapshot; +extern BOOL gDisplaySwapBuffers; + +// used to toggle renderer back on after teleport +const F32 TELEPORT_RENDER_DELAY = 20.f; // Max time a teleport is allowed to take before we raise the curtain +const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived. +BOOL gTeleportDisplay = FALSE; +LLFrameTimer gTeleportDisplayTimer; +LLFrameTimer gTeleportArrivalTimer; +const F32 RESTORE_GL_TIME = 5.f; // Wait this long while reloading textures before we raise the curtain + +BOOL gForceRenderLandFence = FALSE; +BOOL gDisplaySwapBuffers = FALSE; + +// Rendering stuff +void pre_show_depth_buffer(); +void post_show_depth_buffer(); +void render_ui_and_swap(); +void render_ui_3d(); +void render_ui_2d(); +void render_disconnected_background(); + +void process_keystrokes_async(); // in viewer.cpp + +void display_startup() +{ + if ( !gViewerWindow->getActive() + || !gViewerWindow->mWindow->getVisible() + || gViewerWindow->mWindow->getMinimized() + || gNoRender ) + { + return; + } + + LLDynamicTexture::updateAllInstances(); + + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + LLGLSDefault gls_default; + LLGLSUIDefault gls_ui; + gPipeline.disableLights(); + + gViewerWindow->setup2DRender(); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + gViewerWindow->draw(); + gViewerWindow->mWindow->swapBuffers(); +} + + +void display_update_camera() +{ + // TODO: cut draw distance down if customizing avatar? + // TODO: cut draw distance on per-parcel basis? + + // Cut draw distance in half when customizing avatar, + // but on the viewer only. + F32 final_far = gAgent.mDrawDistance; + if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode()) + { + final_far *= 0.5f; + } + gCamera->setFar(final_far); + gViewerWindow->setup3DRender(); + + // Update land visibility too + if (gWorldp) + { + gWorldp->setLandFarClip(final_far); + } +} + + +// Paint the display! +void display(BOOL rebuild, F32 zoom_factor, int subfield) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER); + + LLGLSDefault gls_default; + LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL); + + // No clue where this is getting unset, but safe enough to reset it here. + for (S32 j = 7; j >=0; j--) + { + glActiveTextureARB(GL_TEXTURE0_ARB+j); + glClientActiveTextureARB(GL_TEXTURE0_ARB+j); + j == 0 ? glEnable(GL_TEXTURE_2D) : glDisable(GL_TEXTURE_2D); + } + +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); +#endif + + gPipeline.disableLights(); + + // Don't draw if the window is hidden or minimized. + // In fact, must explicitly check the minimized state before drawing. + // Attempting to draw into a minimized window causes a GL error. JC + if ( !gViewerWindow->getActive() + || !gViewerWindow->mWindow->getVisible() + || gViewerWindow->mWindow->getMinimized() ) + { + // Clean up memory the pools may have allocated + if (rebuild) + { + if (!gViewerWindow->renderingFastFrame()) + { + gFrameStats.start(LLFrameStats::REBUILD); + gPipeline.rebuildPools(); + } + } + return; + } + + gViewerWindow->checkSettings(); + gViewerWindow->performPick(); + +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); +#endif + + ////////////////////////////////////////////////////////// + // + // Logic for forcing window updates if we're in drone mode. + // + + if (gNoRender) + { +#if LL_WINDOWS + static F32 last_update_time = 0.f; + if ((gFrameTimeSeconds - last_update_time) > 1.f) + { + InvalidateRect(llwindow_get_hwnd(gViewerWindow->getWindow()), NULL, FALSE); + last_update_time = gFrameTimeSeconds; + } +#elif LL_DARWIN + // MBW -- Do something clever here. +#endif + // Not actually rendering, don't bother. + return; + } + + + // + // Bail out if we're in the startup state and don't want to try to + // render the world. + // + if (gStartupState < STATE_STARTED) + { + display_startup(); + return; + } + + //LLGLState::verify(FALSE); + + ///////////////////////////////////////////////// + // + // Update GL Texture statistics (used for discard logic?) + // + + gFrameStats.start(LLFrameStats::UPDATE_TEX_STATS); + stop_glerror(); + + LLImageGL::updateStats(gFrameTimeSeconds); + + LLVOAvatar::sRenderName = gSavedSettings.getS32("RenderName"); + gPipeline.mBackfaceCull = TRUE; + gFrameCount++; + + ////////////////////////////////////////////////////////// + // + // Display start screen if we're teleporting, and skip render + // + + if (gTeleportDisplay) + { + const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived. + + S32 attach_count = 0; + if (gAgent.getAvatarObject()) + { + attach_count = gAgent.getAvatarObject()->getAttachmentCount(); + } + F32 teleport_save_time = TELEPORT_EXPIRY + TELEPORT_EXPIRY_PER_ATTACHMENT * attach_count; + F32 teleport_elapsed = gTeleportDisplayTimer.getElapsedTimeF32(); + F32 teleport_percent = teleport_elapsed * (100.f / teleport_save_time); + if( (gAgent.getTeleportState() != LLAgent::TELEPORT_START) && (teleport_percent > 100.f) ) + { + // Give up. Don't keep the UI locked forever. + gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); + gAgent.setTeleportMessage(""); + } + + const LLString& message = gAgent.getTeleportMessage(); + switch( gAgent.getTeleportState() ) + { + case LLAgent::TELEPORT_START: + // Transition to REQUESTED. Viewer has sent some kind + // of TeleportRequest to the source simulator + gTeleportDisplayTimer.reset(); + gViewerWindow->setShowProgress(TRUE); + gViewerWindow->setProgressPercent(0); + gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED ); + gAgent.setTeleportMessage("Requesting Teleport..."); + break; + + case LLAgent::TELEPORT_REQUESTED: + // Waiting for source simulator to respond + gViewerWindow->setProgressPercent( llmin(teleport_percent, 37.5f) ); + gViewerWindow->setProgressString(message); + break; + + case LLAgent::TELEPORT_MOVING: + // Viewer has received destination location from source simulator + gViewerWindow->setProgressPercent( llmin(teleport_percent, 75.f) ); + gViewerWindow->setProgressString(message); + break; + + case LLAgent::TELEPORT_START_ARRIVAL: + // Transition to ARRIVING. Viewer has received avatar update, etc., from destination simulator + gTeleportArrivalTimer.reset(); + gViewerWindow->setProgressCancelButtonVisible(FALSE, "Cancel"); + gViewerWindow->setProgressPercent(75.f); + gAgent.setTeleportState( LLAgent::TELEPORT_ARRIVING ); + gAgent.setTeleportMessage("Arriving..."); + gImageList.mForceResetTextureStats = TRUE; + break; + + case LLAgent::TELEPORT_ARRIVING: + // Make the user wait while content "pre-caches" + { + F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / TELEPORT_ARRIVAL_DELAY); + if( arrival_fraction > 1.f ) + { + arrival_fraction = 1.f; + gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); + } + gViewerWindow->setProgressCancelButtonVisible(FALSE, "Cancel"); + gViewerWindow->setProgressPercent( arrival_fraction * 25.f + 75.f); + gViewerWindow->setProgressString(message); + } + break; + + case LLAgent::TELEPORT_CANCELLING: + gViewerWindow->setProgressCancelButtonVisible(FALSE, "Cancel"); + gViewerWindow->setProgressPercent( 100.f ); + gViewerWindow->setProgressString("Canceling..."); + break; + + case LLAgent::TELEPORT_NONE: + // No teleport in progress + gViewerWindow->setShowProgress(FALSE); + gTeleportDisplay = FALSE; + break; + } + } + else if(gLogoutRequestSent) + { + F32 percent_done = gLogoutTimer.getElapsedTimeF32() * 100.f / gLogoutMaxTime; + if (percent_done > 100.f) + { + percent_done = 100.f; + } + + if( gQuit ) + { + percent_done = 100.f; + } + + gViewerWindow->setProgressPercent( percent_done ); + } + else + if (gRestoreGL) + { + F32 percent_done = gRestoreGLTimer.getElapsedTimeF32() * 100.f / RESTORE_GL_TIME; + if( percent_done > 100.f ) + { + gViewerWindow->setShowProgress(FALSE); + gRestoreGL = FALSE; + } + else + { + + if( gQuit ) + { + percent_done = 100.f; + } + + gViewerWindow->setProgressPercent( percent_done ); + } + } + + ////////////////////////// + // + // Prepare for the next frame + // + + // Hmm... Should this be moved elsewhere? - djs 09/09/02 + // do render-to-texture stuff here + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES)) + { +// LLFastTimer t(LLFastTimer::FTM_UPDATE_TEXTURES); + if (LLDynamicTexture::updateAllInstances()) + { + glClear(GL_COLOR_BUFFER_BIT); + } + } + + if (rebuild) + { + if (gViewerWindow->renderingFastFrame()) + { + gFrameStats.start(LLFrameStats::STATE_SORT); + gFrameStats.start(LLFrameStats::REBUILD); + } + } + + ///////////////////////////// + // + // Update the camera + // + // + + gCamera->setZoomParameters(zoom_factor, subfield); + + ////////////////////////// + // + // clear the next buffer + // (must follow dynamic texture writing since that uses the frame buffer) + // + + if (gDisconnected) + { + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + render_disconnected_background(); + } + else if (!gViewerWindow->isPickPending()) + { + glClear( GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); + } + gViewerWindow->setupViewport(); + + + ////////////////////////// + // + // Set rendering options + // + // + stop_glerror(); + if (gSavedSettings.getBOOL("ShowDepthBuffer")) + { + pre_show_depth_buffer(); + } + + if(gUseWireframe)//gSavedSettings.getBOOL("UseWireframe")) + { + glClearColor(0.5f, 0.5f, 0.5f, 0.f); + glClear(GL_COLOR_BUFFER_BIT); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + } + stop_glerror(); + + /////////////////////////////////////// + // + // Slam lighting parameters back to our defaults. + // Note that these are not the same as GL defaults... + + stop_glerror(); + F32 one[4] = {1.f, 1.f, 1.f, 1.f}; + glLightModelfv (GL_LIGHT_MODEL_AMBIENT,one); + stop_glerror(); + + //LLGLState::verify(); + + ///////////////////////////////////// + // + // Render + // + // Actually push all of our triangles to the screen. + // + if (!gDisconnected) + { + LLFastTimer t(LLFastTimer::FTM_WORLD_UPDATE); + stop_glerror(); + display_update_camera(); + stop_glerror(); + + //FIXME: merge these two methods + gHUDManager->updateEffects(); + LLHUDObject::updateAll(); + stop_glerror(); + + gFrameStats.start(LLFrameStats::UPDATE_GEOM); + const F32 max_geom_update_time = 0.005f; // 5 ms update time + gPipeline.updateGeom(max_geom_update_time); + stop_glerror(); + + gFrameStats.start(LLFrameStats::UPDATE_CULL); + gPipeline.updateCull(); + stop_glerror(); + + if (rebuild && !gViewerWindow->renderingFastFrame()) + { + LLFastTimer t(LLFastTimer::FTM_REBUILD); + + /////////////////////////////////// + // + // StateSort + // + // Responsible for taking visible objects, and adding them to the appropriate draw orders. + // In the case of alpha objects, z-sorts them first. + // Also creates special lists for outlines and selected face rendering. + // + gFrameStats.start(LLFrameStats::STATE_SORT); + gPipeline.stateSort(); + stop_glerror(); + + ////////////////////////////////////// + // + // rebuildPools + // + // + gFrameStats.start(LLFrameStats::REBUILD); + gPipeline.rebuildPools(); + stop_glerror(); + } + } + + //// render frontmost floater opaque for occlusion culling purposes + //LLFloater* frontmost_floaterp = gFloaterView->getFrontmost(); + //// assumes frontmost floater with focus is opaque + //if (frontmost_floaterp && gFocusMgr.childHasKeyboardFocus(frontmost_floaterp)) + //{ + // glMatrixMode(GL_MODELVIEW); + // glPushMatrix(); + // { + // LLGLSNoTexture gls_no_texture; + + // glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); + // glLoadIdentity(); + + // LLRect floater_rect = frontmost_floaterp->getScreenRect(); + // // deflate by one pixel so rounding errors don't occlude outside of floater extents + // floater_rect.stretch(-1); + // LLRectf floater_3d_rect((F32)floater_rect.mLeft / (F32)gViewerWindow->getWindowWidth(), + // (F32)floater_rect.mTop / (F32)gViewerWindow->getWindowHeight(), + // (F32)floater_rect.mRight / (F32)gViewerWindow->getWindowWidth(), + // (F32)floater_rect.mBottom / (F32)gViewerWindow->getWindowHeight()); + // floater_3d_rect.translate(-0.5f, -0.5f); + // glTranslatef(0.f, 0.f, -gCamera->getNear()); + // glScalef(gCamera->getNear() * gCamera->getAspect() / sinf(gCamera->getView()), gCamera->getNear() / sinf(gCamera->getView()), 1.f); + // glColor4fv(LLColor4::white.mV); + // glBegin(GL_QUADS); + // { + // glVertex3f(floater_3d_rect.mLeft, floater_3d_rect.mBottom, 0.f); + // glVertex3f(floater_3d_rect.mLeft, floater_3d_rect.mTop, 0.f); + // glVertex3f(floater_3d_rect.mRight, floater_3d_rect.mTop, 0.f); + // glVertex3f(floater_3d_rect.mRight, floater_3d_rect.mBottom, 0.f); + // } + // glEnd(); + // glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + // } + // glPopMatrix(); + //} + + if (gViewerWindow->renderingFastFrame()) + { + gFrameStats.start(LLFrameStats::RENDER_SYNC); + gFrameStats.start(LLFrameStats::RENDER_GEOM); + } + else if (!(gLogoutRequestSent && gHaveSavedSnapshot) + && !gRestoreGL + && !gDisconnected) + { + gPipeline.renderGeom(); + stop_glerror(); + } + + gFrameStats.start(LLFrameStats::RENDER_UI); + + if (gHandleKeysAsync) + { + process_keystrokes_async(); + stop_glerror(); + } + + +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkStates(); +#endif + render_ui_and_swap(); +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkStates(); +#endif + + gFrameStats.start(LLFrameStats::MISC_END); + stop_glerror(); + +} + + +void render_ui_and_swap() +{ +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkStates(); +#endif + + LLGLSDefault gls_default; + { + LLGLSUIDefault gls_ui; + gPipeline.disableLights(); + + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + { + LLFastTimer t(LLFastTimer::FTM_RENDER_UI); + if (!gViewerWindow->renderingFastFrame() && !gDisconnected) + { + render_ui_3d(); +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkStates(); +#endif + } + + render_ui_2d(); +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkStates(); +#endif + } + + // now do the swap buffer + if (gDisplaySwapBuffers) + { + LLFastTimer t(LLFastTimer::FTM_SWAP); + gViewerWindow->mWindow->swapBuffers(); + } + } + + gViewerWindow->finishFirstFastFrame(); +} + +void render_ui_3d() +{ + LLGLSPipeline gls_pipeline; + + ////////////////////////////////////// + // + // Render 3D UI elements + // NOTE: zbuffer is cleared before we get here by LLDrawPoolHUD, + // so 3d elements requiring Z buffer are moved to LLDrawPoolHUD + // + + // Render selections + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + + ///////////////////////////////////////////////////////////// + // + // Render 2.5D elements (2D elements in the world) + // Stuff without z writes + // + + // Debugging stuff goes before the UI. + + if (gSavedSettings.getBOOL("ShowDepthBuffer")) + { + post_show_depth_buffer(); + } + + // Coordinate axes + if (gSavedSettings.getBOOL("ShowAxes")) + { + draw_axes(); + } + + stop_glerror(); + + gViewerWindow->renderSelections(FALSE, FALSE, TRUE); // Non HUD call in render_hud_elements + stop_glerror(); +} + +void render_ui_2d() +{ + LLGLSUIDefault gls_ui; + + ///////////////////////////////////////////////////////////// + // + // Render 2D UI elements that overlay the world (no z compare) + + // Disable wireframe mode below here, as this is HUD/menus + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + // Menu overlays, HUD, etc + gViewerWindow->setup2DRender(); + + F32 zoom_factor = gCamera->getZoomFactor(); + S16 sub_region = gCamera->getZoomSubRegion(); + + if (zoom_factor > 1.f) + { + //decompose subregion number to x and y values + int pos_y = sub_region / llceil(zoom_factor); + int pos_x = sub_region - (pos_y*llceil(zoom_factor)); + // offset for this tile + LLFontGL::sCurOrigin.mX -= llround((F32)gViewerWindow->getWindowWidth() * (F32)pos_x / zoom_factor); + LLFontGL::sCurOrigin.mY -= llround((F32)gViewerWindow->getWindowHeight() * (F32)pos_y / zoom_factor); + } + + + stop_glerror(); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + // render outline for HUD + if (gAgent.getAvatarObject() && gAgent.getAvatarObject()->mHUDCurZoom < 0.98f) + { + glPushMatrix(); + S32 half_width = (gViewerWindow->getWindowWidth() / 2); + S32 half_height = (gViewerWindow->getWindowHeight() / 2); + glTranslatef((F32)half_width, (F32)half_height, 0.f); + glScalef(gAgent.getAvatarObject()->mHUDCurZoom, gAgent.getAvatarObject()->mHUDCurZoom, gAgent.getAvatarObject()->mHUDCurZoom); + glColor4fv(LLColor4::white.mV); + gl_rect_2d(-half_width, half_height, half_width, -half_height, FALSE); + glPopMatrix(); + stop_glerror(); + } + gViewerWindow->draw(); + if (gDebugSelect) + { + gViewerWindow->drawPickBuffer(); + } + + // reset current origin for font rendering, in case of tiling render + LLFontGL::sCurOrigin.set(0, 0); +} + +void renderCoordinateAxes() +{ + LLGLSNoTexture gls_no_texture; + glBegin(GL_LINES); + glColor3f(1.0f, 0.0f, 0.0f); // i direction = X-Axis = red + glVertex3f(0.0f, 0.0f, 0.0f); + glVertex3f(2.0f, 0.0f, 0.0f); + glVertex3f(3.0f, 0.0f, 0.0f); + glVertex3f(5.0f, 0.0f, 0.0f); + glVertex3f(6.0f, 0.0f, 0.0f); + glVertex3f(8.0f, 0.0f, 0.0f); + // Make an X + glVertex3f(11.0f, 1.0f, 1.0f); + glVertex3f(11.0f, -1.0f, -1.0f); + glVertex3f(11.0f, 1.0f, -1.0f); + glVertex3f(11.0f, -1.0f, 1.0f); + + glColor3f(0.0f, 1.0f, 0.0f); // j direction = Y-Axis = green + glVertex3f(0.0f, 0.0f, 0.0f); + glVertex3f(0.0f, 2.0f, 0.0f); + glVertex3f(0.0f, 3.0f, 0.0f); + glVertex3f(0.0f, 5.0f, 0.0f); + glVertex3f(0.0f, 6.0f, 0.0f); + glVertex3f(0.0f, 8.0f, 0.0f); + // Make a Y + glVertex3f(1.0f, 11.0f, 1.0f); + glVertex3f(0.0f, 11.0f, 0.0f); + glVertex3f(-1.0f, 11.0f, 1.0f); + glVertex3f(0.0f, 11.0f, 0.0f); + glVertex3f(0.0f, 11.0f, 0.0f); + glVertex3f(0.0f, 11.0f, -1.0f); + + glColor3f(0.0f, 0.0f, 1.0f); // Z-Axis = blue + glVertex3f(0.0f, 0.0f, 0.0f); + glVertex3f(0.0f, 0.0f, 2.0f); + glVertex3f(0.0f, 0.0f, 3.0f); + glVertex3f(0.0f, 0.0f, 5.0f); + glVertex3f(0.0f, 0.0f, 6.0f); + glVertex3f(0.0f, 0.0f, 8.0f); + // Make a Z + glVertex3f(-1.0f, 1.0f, 11.0f); + glVertex3f(1.0f, 1.0f, 11.0f); + glVertex3f(1.0f, 1.0f, 11.0f); + glVertex3f(-1.0f, -1.0f, 11.0f); + glVertex3f(-1.0f, -1.0f, 11.0f); + glVertex3f(1.0f, -1.0f, 11.0f); + glEnd(); +} + +void draw_axes() +{ + LLGLSUIDefault gls_ui; + LLGLSNoTexture gls_no_texture; + // A vertical white line at origin + LLVector3 v = gAgent.getPositionAgent(); + glBegin(GL_LINES); + glColor3f(1.0f, 1.0f, 1.0f); + glVertex3f(0.0f, 0.0f, 0.0f); + glVertex3f(0.0f, 0.0f, 40.0f); + glEnd(); + // Some coordinate axes + glPushMatrix(); + glTranslatef( v.mV[VX], v.mV[VY], v.mV[VZ] ); + renderCoordinateAxes(); + glPopMatrix(); +} + + +void render_disconnected_background() +{ + if (!gDisconnectedImagep && gDisconnected) + { + llinfos << "Loading last bitmap..." << llendl; + + char temp_str[MAX_PATH]; + strcpy(temp_str, gDirUtilp->getLindenUserDir().c_str()); + strcat(temp_str, gDirUtilp->getDirDelimiter().c_str()); + + strcat(temp_str, SCREEN_LAST_FILENAME); + + LLPointer<LLImageBMP> image_bmp = new LLImageBMP; + if( !image_bmp->load(temp_str) ) + { + //llinfos << "Bitmap load failed" << llendl; + return; + } + + gDisconnectedImagep = new LLImageGL( FALSE ); + LLPointer<LLImageRaw> raw = new LLImageRaw; + if (!image_bmp->decode(raw)) + { + llinfos << "Bitmap decode failed" << llendl; + gDisconnectedImagep = NULL; + return; + } + + U8 *rawp = raw->getData(); + S32 npixels = (S32)image_bmp->getWidth()*(S32)image_bmp->getHeight(); + for (S32 i = 0; i < npixels; i++) + { + S32 sum = 0; + sum = *rawp + *(rawp+1) + *(rawp+2); + sum /= 3; + *rawp = ((S32)sum*6 + *rawp)/7; + rawp++; + *rawp = ((S32)sum*6 + *rawp)/7; + rawp++; + *rawp = ((S32)sum*6 + *rawp)/7; + rawp++; + } + + + raw->expandToPowerOfTwo(); + gDisconnectedImagep->createGLTexture(0, raw); + gStartImageGL = gDisconnectedImagep; + LLImageGL::unbindTexture(0, GL_TEXTURE_2D); + } + + // Make sure the progress view always fills the entire window. + S32 width = gViewerWindow->getWindowWidth(); + S32 height = gViewerWindow->getWindowHeight(); + + if (gDisconnectedImagep) + { + LLGLSUIDefault gls_ui; + gViewerWindow->setup2DRender(); + glPushMatrix(); + { + // scale ui to reflect UIScaleFactor + // this can't be done in setup2DRender because it requires a + // pushMatrix/popMatrix pair + const LLVector2& display_scale = gViewerWindow->getDisplayScale(); + glScalef(display_scale.mV[VX], display_scale.mV[VY], 1.f); + + LLViewerImage::bindTexture(gDisconnectedImagep); + glColor4f(1.f, 1.f, 1.f, 1.f); + gl_rect_2d_simple_tex(width, height); + LLImageGL::unbindTexture(0, GL_TEXTURE_2D); + } + glPopMatrix(); + } +} |