summaryrefslogtreecommitdiff
path: root/indra/newview/llviewerdisplay.cpp
diff options
context:
space:
mode:
authorJames Cook <james@lindenlab.com>2007-01-02 08:33:20 +0000
committerJames Cook <james@lindenlab.com>2007-01-02 08:33:20 +0000
commit420b91db29485df39fd6e724e782c449158811cb (patch)
treeb471a94563af914d3ed3edd3e856d21cb1b69945 /indra/newview/llviewerdisplay.cpp
Print done when done.
Diffstat (limited to 'indra/newview/llviewerdisplay.cpp')
-rw-r--r--indra/newview/llviewerdisplay.cpp832
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();
+ }
+}