aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llviewerdisplay.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llviewerdisplay.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/newview/llviewerdisplay.cpp')
-rw-r--r--linden/indra/newview/llviewerdisplay.cpp851
1 files changed, 851 insertions, 0 deletions
diff --git a/linden/indra/newview/llviewerdisplay.cpp b/linden/indra/newview/llviewerdisplay.cpp
new file mode 100644
index 0000000..f09e34c
--- /dev/null
+++ b/linden/indra/newview/llviewerdisplay.cpp
@@ -0,0 +1,851 @@
1/**
2 * @file llviewerdisplay.cpp
3 * @brief LLViewerDisplay class implementation
4 *
5 * Copyright (c) 2004-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "llviewerprecompiledheaders.h"
29
30#include "llagent.h"
31#include "llviewercontrol.h"
32#include "llcoord.h"
33#include "llcriticaldamp.h"
34#include "lldir.h"
35#include "lldynamictexture.h"
36#include "lldrawpoolalpha.h"
37#include "llframestats.h"
38#include "llgl.h"
39#include "llglheaders.h"
40#include "llhudmanager.h"
41#include "llimagebmp.h"
42#include "llimagegl.h"
43#include "llselectmgr.h"
44#include "llsky.h"
45#include "llstartup.h"
46#include "lltoolfocus.h"
47#include "lltoolmgr.h"
48#include "lltooldraganddrop.h"
49#include "lltoolpie.h"
50#include "lltracker.h"
51#include "llui.h"
52#include "llviewercamera.h"
53#include "llviewerobjectlist.h"
54#include "llviewerparcelmgr.h"
55#include "llviewerwindow.h"
56#include "llvoavatar.h"
57#include "llvograss.h"
58#include "llworld.h"
59#include "pipeline.h"
60#include "viewer.h"
61#include "llstartup.h"
62#include "llfasttimer.h"
63#include "llfloatertools.h"
64#include "llviewerimagelist.h"
65#include "llfocusmgr.h"
66
67extern U32 gFrameCount;
68extern LLPointer<LLImageGL> gStartImageGL;
69extern LLPointer<LLImageGL> gDisconnectedImagep;
70extern BOOL gLogoutRequestSent;
71extern LLTimer gLogoutTimer;
72extern BOOL gHaveSavedSnapshot;
73extern BOOL gDisplaySwapBuffers;
74
75// used to toggle renderer back on after teleport
76const F32 TELEPORT_RENDER_DELAY = 20.f; // Max time a teleport is allowed to take before we raise the curtain
77const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived.
78BOOL gTeleportDisplay = FALSE;
79LLFrameTimer gTeleportDisplayTimer;
80LLFrameTimer gTeleportArrivalTimer;
81const F32 RESTORE_GL_TIME = 5.f; // Wait this long while reloading textures before we raise the curtain
82
83BOOL gForceRenderLandFence = FALSE;
84BOOL gDisplaySwapBuffers = FALSE;
85
86// Rendering stuff
87void pre_show_depth_buffer();
88void post_show_depth_buffer();
89void render_ui_and_swap();
90void render_ui_3d();
91void render_ui_2d();
92void render_disconnected_background();
93
94void process_keystrokes_async(); // in viewer.cpp
95
96void display_startup()
97{
98 if ( !gViewerWindow->getActive()
99 || !gViewerWindow->mWindow->getVisible()
100 || gViewerWindow->mWindow->getMinimized()
101 || gNoRender )
102 {
103 return;
104 }
105
106 LLDynamicTexture::updateAllInstances();
107
108 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
109 LLGLSDefault gls_default;
110 LLGLSUIDefault gls_ui;
111 gPipeline.disableLights();
112
113 gViewerWindow->setup2DRender();
114 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
115
116 gViewerWindow->draw();
117 gViewerWindow->mWindow->swapBuffers();
118}
119
120
121void display_update_camera()
122{
123 // TODO: cut draw distance down if customizing avatar?
124 // TODO: cut draw distance on per-parcel basis?
125
126 // Cut draw distance in half when customizing avatar,
127 // but on the viewer only.
128 F32 final_far = gAgent.mDrawDistance;
129 if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode())
130 {
131 final_far *= 0.5f;
132 }
133 gCamera->setFar(final_far);
134 gViewerWindow->setup3DRender();
135
136 // Update land visibility too
137 if (gWorldp)
138 {
139 gWorldp->setLandFarClip(final_far);
140 }
141}
142
143
144// Paint the display!
145void display(BOOL rebuild, F32 zoom_factor, int subfield)
146{
147 LLFastTimer t(LLFastTimer::FTM_RENDER);
148
149 LLGLSDefault gls_default;
150 LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL);
151
152 // No clue where this is getting unset, but safe enough to reset it here.
153 for (S32 j = 7; j >=0; j--)
154 {
155 glActiveTextureARB(GL_TEXTURE0_ARB+j);
156 glClientActiveTextureARB(GL_TEXTURE0_ARB+j);
157 j == 0 ? glEnable(GL_TEXTURE_2D) : glDisable(GL_TEXTURE_2D);
158 }
159
160#ifndef LL_RELEASE_FOR_DOWNLOAD
161 LLGLState::checkStates();
162 LLGLState::checkTextureChannels();
163#endif
164
165 gPipeline.disableLights();
166
167 // Don't draw if the window is hidden or minimized.
168 // In fact, must explicitly check the minimized state before drawing.
169 // Attempting to draw into a minimized window causes a GL error. JC
170 if ( !gViewerWindow->getActive()
171 || !gViewerWindow->mWindow->getVisible()
172 || gViewerWindow->mWindow->getMinimized() )
173 {
174 // Clean up memory the pools may have allocated
175 if (rebuild)
176 {
177 if (!gViewerWindow->renderingFastFrame())
178 {
179 gFrameStats.start(LLFrameStats::REBUILD);
180 gPipeline.rebuildPools();
181 }
182 }
183 return;
184 }
185
186 gViewerWindow->checkSettings();
187 gViewerWindow->performPick();
188
189#ifndef LL_RELEASE_FOR_DOWNLOAD
190 LLGLState::checkStates();
191 LLGLState::checkTextureChannels();
192#endif
193
194 //////////////////////////////////////////////////////////
195 //
196 // Logic for forcing window updates if we're in drone mode.
197 //
198
199 if (gNoRender)
200 {
201#if LL_WINDOWS
202 static F32 last_update_time = 0.f;
203 if ((gFrameTimeSeconds - last_update_time) > 1.f)
204 {
205 InvalidateRect((HWND)gViewerWindow->getPlatformWindow(), NULL, FALSE);
206 last_update_time = gFrameTimeSeconds;
207 }
208#elif LL_DARWIN
209 // MBW -- Do something clever here.
210#endif
211 // Not actually rendering, don't bother.
212 return;
213 }
214
215
216 //
217 // Bail out if we're in the startup state and don't want to try to
218 // render the world.
219 //
220 if (gStartupState < STATE_STARTED)
221 {
222 display_startup();
223 return;
224 }
225
226 //LLGLState::verify(FALSE);
227
228 /////////////////////////////////////////////////
229 //
230 // Update GL Texture statistics (used for discard logic?)
231 //
232
233 gFrameStats.start(LLFrameStats::UPDATE_TEX_STATS);
234 stop_glerror();
235
236 LLImageGL::updateStats(gFrameTimeSeconds);
237
238 LLVOAvatar::sRenderName = gSavedSettings.getS32("RenderName");
239 gPipeline.mBackfaceCull = TRUE;
240 gFrameCount++;
241
242 //////////////////////////////////////////////////////////
243 //
244 // Display start screen if we're teleporting, and skip render
245 //
246
247 if (gTeleportDisplay)
248 {
249 const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived.
250
251 S32 attach_count = 0;
252 if (gAgent.getAvatarObject())
253 {
254 attach_count = gAgent.getAvatarObject()->getAttachmentCount();
255 }
256 F32 teleport_save_time = TELEPORT_EXPIRY + TELEPORT_EXPIRY_PER_ATTACHMENT * attach_count;
257 F32 teleport_elapsed = gTeleportDisplayTimer.getElapsedTimeF32();
258 F32 teleport_percent = teleport_elapsed * (100.f / teleport_save_time);
259 if( (gAgent.getTeleportState() != LLAgent::TELEPORT_START) && (teleport_percent > 100.f) )
260 {
261 // Give up. Don't keep the UI locked forever.
262 gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
263 gAgent.setTeleportMessage("");
264 }
265
266 const LLString& message = gAgent.getTeleportMessage();
267 switch( gAgent.getTeleportState() )
268 {
269 case LLAgent::TELEPORT_START:
270 // Transition to REQUESTED. Viewer has sent some kind
271 // of TeleportRequest to the source simulator
272 gTeleportDisplayTimer.reset();
273 gViewerWindow->setShowProgress(TRUE);
274 gViewerWindow->setProgressPercent(0);
275 gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED );
276 gAgent.setTeleportMessage("Requesting Teleport...");
277 break;
278
279 case LLAgent::TELEPORT_REQUESTED:
280 // Waiting for source simulator to respond
281 gViewerWindow->setProgressPercent( llmin(teleport_percent, 37.5f) );
282 gViewerWindow->setProgressString(message);
283 break;
284
285 case LLAgent::TELEPORT_MOVING:
286 // Viewer has received destination location from source simulator
287 gViewerWindow->setProgressPercent( llmin(teleport_percent, 75.f) );
288 gViewerWindow->setProgressString(message);
289 break;
290
291 case LLAgent::TELEPORT_START_ARRIVAL:
292 // Transition to ARRIVING. Viewer has received avatar update, etc., from destination simulator
293 gTeleportArrivalTimer.reset();
294 gViewerWindow->setProgressCancelButtonVisible(FALSE, "Cancel");
295 gViewerWindow->setProgressPercent(75.f);
296 gAgent.setTeleportState( LLAgent::TELEPORT_ARRIVING );
297 gAgent.setTeleportMessage("Arriving...");
298 gImageList.mForceResetTextureStats = TRUE;
299 break;
300
301 case LLAgent::TELEPORT_ARRIVING:
302 // Make the user wait while content "pre-caches"
303 {
304 F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / TELEPORT_ARRIVAL_DELAY);
305 if( arrival_fraction > 1.f )
306 {
307 arrival_fraction = 1.f;
308 gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
309 }
310 gViewerWindow->setProgressCancelButtonVisible(FALSE, "Cancel");
311 gViewerWindow->setProgressPercent( arrival_fraction * 25.f + 75.f);
312 gViewerWindow->setProgressString(message);
313 }
314 break;
315
316 case LLAgent::TELEPORT_CANCELLING:
317 gViewerWindow->setProgressCancelButtonVisible(FALSE, "Cancel");
318 gViewerWindow->setProgressPercent( 100.f );
319 gViewerWindow->setProgressString("Canceling...");
320 break;
321
322 case LLAgent::TELEPORT_NONE:
323 // No teleport in progress
324 gViewerWindow->setShowProgress(FALSE);
325 gTeleportDisplay = FALSE;
326 break;
327 }
328 }
329 else if(gLogoutRequestSent)
330 {
331 F32 percent_done = gLogoutTimer.getElapsedTimeF32() * 100.f / gLogoutMaxTime;
332 if (percent_done > 100.f)
333 {
334 percent_done = 100.f;
335 }
336
337 if( gQuit )
338 {
339 percent_done = 100.f;
340 }
341
342 gViewerWindow->setProgressPercent( percent_done );
343 }
344 else
345 if (gRestoreGL)
346 {
347 F32 percent_done = gRestoreGLTimer.getElapsedTimeF32() * 100.f / RESTORE_GL_TIME;
348 if( percent_done > 100.f )
349 {
350 gViewerWindow->setShowProgress(FALSE);
351 gRestoreGL = FALSE;
352 }
353 else
354 {
355
356 if( gQuit )
357 {
358 percent_done = 100.f;
359 }
360
361 gViewerWindow->setProgressPercent( percent_done );
362 }
363 }
364
365 //////////////////////////
366 //
367 // Prepare for the next frame
368 //
369
370 // Hmm... Should this be moved elsewhere? - djs 09/09/02
371 // do render-to-texture stuff here
372 if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES))
373 {
374// LLFastTimer t(LLFastTimer::FTM_UPDATE_TEXTURES);
375 if (LLDynamicTexture::updateAllInstances())
376 {
377 glClear(GL_COLOR_BUFFER_BIT);
378 }
379 }
380
381 if (rebuild)
382 {
383 if (gViewerWindow->renderingFastFrame())
384 {
385 gFrameStats.start(LLFrameStats::STATE_SORT);
386 gFrameStats.start(LLFrameStats::REBUILD);
387 }
388 }
389
390 /////////////////////////////
391 //
392 // Update the camera
393 //
394 //
395
396 gCamera->setZoomParameters(zoom_factor, subfield);
397
398 //////////////////////////
399 //
400 // clear the next buffer
401 // (must follow dynamic texture writing since that uses the frame buffer)
402 //
403
404 if (gDisconnected)
405 {
406 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
407 render_disconnected_background();
408 }
409 else if (!gViewerWindow->isPickPending())
410 {
411 glClear( GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
412 }
413 gViewerWindow->setupViewport();
414
415
416 //////////////////////////
417 //
418 // Set rendering options
419 //
420 //
421 stop_glerror();
422 if (gSavedSettings.getBOOL("ShowDepthBuffer"))
423 {
424 pre_show_depth_buffer();
425 }
426
427 if(gUseWireframe)//gSavedSettings.getBOOL("UseWireframe"))
428 {
429 glClearColor(0.5f, 0.5f, 0.5f, 0.f);
430 glClear(GL_COLOR_BUFFER_BIT);
431 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
432 }
433 stop_glerror();
434
435 ///////////////////////////////////////
436 //
437 // Slam lighting parameters back to our defaults.
438 // Note that these are not the same as GL defaults...
439
440 stop_glerror();
441 F32 one[4] = {1.f, 1.f, 1.f, 1.f};
442 glLightModelfv (GL_LIGHT_MODEL_AMBIENT,one);
443 stop_glerror();
444
445 //LLGLState::verify();
446
447 /////////////////////////////////////
448 //
449 // Render
450 //
451 // Actually push all of our triangles to the screen.
452 //
453 if (!gDisconnected)
454 {
455 LLFastTimer t(LLFastTimer::FTM_WORLD_UPDATE);
456 stop_glerror();
457 display_update_camera();
458 stop_glerror();
459
460 // *TODO: merge these two methods
461 gHUDManager->updateEffects();
462 LLHUDObject::updateAll();
463 stop_glerror();
464
465 gFrameStats.start(LLFrameStats::UPDATE_GEOM);
466 const F32 max_geom_update_time = 0.005f; // 5 ms update time
467 gPipeline.updateGeom(max_geom_update_time);
468 stop_glerror();
469
470 gFrameStats.start(LLFrameStats::UPDATE_CULL);
471 gPipeline.updateCull();
472 stop_glerror();
473
474 if (rebuild && !gViewerWindow->renderingFastFrame())
475 {
476 LLFastTimer t(LLFastTimer::FTM_REBUILD);
477
478 ///////////////////////////////////
479 //
480 // StateSort
481 //
482 // Responsible for taking visible objects, and adding them to the appropriate draw orders.
483 // In the case of alpha objects, z-sorts them first.
484 // Also creates special lists for outlines and selected face rendering.
485 //
486 gFrameStats.start(LLFrameStats::STATE_SORT);
487 gPipeline.stateSort();
488 stop_glerror();
489
490 //////////////////////////////////////
491 //
492 // rebuildPools
493 //
494 //
495 gFrameStats.start(LLFrameStats::REBUILD);
496 gPipeline.rebuildPools();
497 stop_glerror();
498 }
499 }
500
501 //// render frontmost floater opaque for occlusion culling purposes
502 //LLFloater* frontmost_floaterp = gFloaterView->getFrontmost();
503 //// assumes frontmost floater with focus is opaque
504 //if (frontmost_floaterp && gFocusMgr.childHasKeyboardFocus(frontmost_floaterp))
505 //{
506 // glMatrixMode(GL_MODELVIEW);
507 // glPushMatrix();
508 // {
509 // LLGLSNoTexture gls_no_texture;
510
511 // glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
512 // glLoadIdentity();
513
514 // LLRect floater_rect = frontmost_floaterp->getScreenRect();
515 // // deflate by one pixel so rounding errors don't occlude outside of floater extents
516 // floater_rect.stretch(-1);
517 // LLRectf floater_3d_rect((F32)floater_rect.mLeft / (F32)gViewerWindow->getWindowWidth(),
518 // (F32)floater_rect.mTop / (F32)gViewerWindow->getWindowHeight(),
519 // (F32)floater_rect.mRight / (F32)gViewerWindow->getWindowWidth(),
520 // (F32)floater_rect.mBottom / (F32)gViewerWindow->getWindowHeight());
521 // floater_3d_rect.translate(-0.5f, -0.5f);
522 // glTranslatef(0.f, 0.f, -gCamera->getNear());
523 // glScalef(gCamera->getNear() * gCamera->getAspect() / sinf(gCamera->getView()), gCamera->getNear() / sinf(gCamera->getView()), 1.f);
524 // glColor4fv(LLColor4::white.mV);
525 // glBegin(GL_QUADS);
526 // {
527 // glVertex3f(floater_3d_rect.mLeft, floater_3d_rect.mBottom, 0.f);
528 // glVertex3f(floater_3d_rect.mLeft, floater_3d_rect.mTop, 0.f);
529 // glVertex3f(floater_3d_rect.mRight, floater_3d_rect.mTop, 0.f);
530 // glVertex3f(floater_3d_rect.mRight, floater_3d_rect.mBottom, 0.f);
531 // }
532 // glEnd();
533 // glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
534 // }
535 // glPopMatrix();
536 //}
537
538 if (gViewerWindow->renderingFastFrame())
539 {
540 gFrameStats.start(LLFrameStats::RENDER_SYNC);
541 gFrameStats.start(LLFrameStats::RENDER_GEOM);
542 }
543 else if (!(gLogoutRequestSent && gHaveSavedSnapshot)
544 && !gRestoreGL
545 && !gDisconnected)
546 {
547 gPipeline.renderGeom();
548 stop_glerror();
549 }
550
551 gFrameStats.start(LLFrameStats::RENDER_UI);
552
553 if (gHandleKeysAsync)
554 {
555 process_keystrokes_async();
556 stop_glerror();
557 }
558
559
560#ifndef LL_RELEASE_FOR_DOWNLOAD
561 LLGLState::checkStates();
562#endif
563 render_ui_and_swap();
564#ifndef LL_RELEASE_FOR_DOWNLOAD
565 LLGLState::checkStates();
566#endif
567
568 gFrameStats.start(LLFrameStats::MISC_END);
569 stop_glerror();
570
571}
572
573
574void render_ui_and_swap()
575{
576#ifndef LL_RELEASE_FOR_DOWNLOAD
577 LLGLState::checkStates();
578#endif
579
580 LLGLSDefault gls_default;
581 {
582 LLGLSUIDefault gls_ui;
583 gPipeline.disableLights();
584
585 if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
586 {
587 LLFastTimer t(LLFastTimer::FTM_RENDER_UI);
588 if (!gViewerWindow->renderingFastFrame() && !gDisconnected)
589 {
590 render_ui_3d();
591#ifndef LL_RELEASE_FOR_DOWNLOAD
592 LLGLState::checkStates();
593#endif
594 }
595
596 render_ui_2d();
597#ifndef LL_RELEASE_FOR_DOWNLOAD
598 LLGLState::checkStates();
599#endif
600 }
601
602 // now do the swap buffer
603 if (gDisplaySwapBuffers)
604 {
605 LLFastTimer t(LLFastTimer::FTM_SWAP);
606 gViewerWindow->mWindow->swapBuffers();
607 }
608 }
609
610 gViewerWindow->finishFirstFastFrame();
611}
612
613void render_ui_3d()
614{
615 LLGLSPipeline gls_pipeline;
616
617 //////////////////////////////////////
618 //
619 // Render 3D UI elements
620 // NOTE: zbuffer is cleared before we get here by LLDrawPoolHUD,
621 // so 3d elements requiring Z buffer are moved to LLDrawPoolHUD
622 //
623
624 // Render selections
625
626 glDisableClientState(GL_VERTEX_ARRAY);
627 glDisableClientState(GL_COLOR_ARRAY);
628 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
629 glDisableClientState(GL_NORMAL_ARRAY);
630
631 /////////////////////////////////////////////////////////////
632 //
633 // Render 2.5D elements (2D elements in the world)
634 // Stuff without z writes
635 //
636
637 // Debugging stuff goes before the UI.
638
639 if (gSavedSettings.getBOOL("ShowDepthBuffer"))
640 {
641 post_show_depth_buffer();
642 }
643
644 // Coordinate axes
645 if (gSavedSettings.getBOOL("ShowAxes"))
646 {
647 draw_axes();
648 }
649
650 stop_glerror();
651
652 gViewerWindow->renderSelections(FALSE, FALSE, TRUE); // Non HUD call in render_hud_elements
653 stop_glerror();
654}
655
656void render_ui_2d()
657{
658 LLGLSUIDefault gls_ui;
659
660 /////////////////////////////////////////////////////////////
661 //
662 // Render 2D UI elements that overlay the world (no z compare)
663
664 // Disable wireframe mode below here, as this is HUD/menus
665 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
666
667 // Menu overlays, HUD, etc
668 gViewerWindow->setup2DRender();
669
670 F32 zoom_factor = gCamera->getZoomFactor();
671 S16 sub_region = gCamera->getZoomSubRegion();
672
673 if (zoom_factor > 1.f)
674 {
675 //decompose subregion number to x and y values
676 int pos_y = sub_region / llceil(zoom_factor);
677 int pos_x = sub_region - (pos_y*llceil(zoom_factor));
678 // offset for this tile
679 LLFontGL::sCurOrigin.mX -= llround((F32)gViewerWindow->getWindowWidth() * (F32)pos_x / zoom_factor);
680 LLFontGL::sCurOrigin.mY -= llround((F32)gViewerWindow->getWindowHeight() * (F32)pos_y / zoom_factor);
681 }
682
683
684 stop_glerror();
685 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
686
687 // render outline for HUD
688 if (gAgent.getAvatarObject() && gAgent.getAvatarObject()->mHUDCurZoom < 0.98f)
689 {
690 glPushMatrix();
691 S32 half_width = (gViewerWindow->getWindowWidth() / 2);
692 S32 half_height = (gViewerWindow->getWindowHeight() / 2);
693 glTranslatef((F32)half_width, (F32)half_height, 0.f);
694 glScalef(gAgent.getAvatarObject()->mHUDCurZoom, gAgent.getAvatarObject()->mHUDCurZoom, gAgent.getAvatarObject()->mHUDCurZoom);
695 glColor4fv(LLColor4::white.mV);
696 gl_rect_2d(-half_width, half_height, half_width, -half_height, FALSE);
697 glPopMatrix();
698 stop_glerror();
699 }
700 gViewerWindow->draw();
701 if (gDebugSelect)
702 {
703 gViewerWindow->drawPickBuffer();
704 }
705
706 // reset current origin for font rendering, in case of tiling render
707 LLFontGL::sCurOrigin.set(0, 0);
708}
709
710void renderCoordinateAxes()
711{
712 LLGLSNoTexture gls_no_texture;
713 glBegin(GL_LINES);
714 glColor3f(1.0f, 0.0f, 0.0f); // i direction = X-Axis = red
715 glVertex3f(0.0f, 0.0f, 0.0f);
716 glVertex3f(2.0f, 0.0f, 0.0f);
717 glVertex3f(3.0f, 0.0f, 0.0f);
718 glVertex3f(5.0f, 0.0f, 0.0f);
719 glVertex3f(6.0f, 0.0f, 0.0f);
720 glVertex3f(8.0f, 0.0f, 0.0f);
721 // Make an X
722 glVertex3f(11.0f, 1.0f, 1.0f);
723 glVertex3f(11.0f, -1.0f, -1.0f);
724 glVertex3f(11.0f, 1.0f, -1.0f);
725 glVertex3f(11.0f, -1.0f, 1.0f);
726
727 glColor3f(0.0f, 1.0f, 0.0f); // j direction = Y-Axis = green
728 glVertex3f(0.0f, 0.0f, 0.0f);
729 glVertex3f(0.0f, 2.0f, 0.0f);
730 glVertex3f(0.0f, 3.0f, 0.0f);
731 glVertex3f(0.0f, 5.0f, 0.0f);
732 glVertex3f(0.0f, 6.0f, 0.0f);
733 glVertex3f(0.0f, 8.0f, 0.0f);
734 // Make a Y
735 glVertex3f(1.0f, 11.0f, 1.0f);
736 glVertex3f(0.0f, 11.0f, 0.0f);
737 glVertex3f(-1.0f, 11.0f, 1.0f);
738 glVertex3f(0.0f, 11.0f, 0.0f);
739 glVertex3f(0.0f, 11.0f, 0.0f);
740 glVertex3f(0.0f, 11.0f, -1.0f);
741
742 glColor3f(0.0f, 0.0f, 1.0f); // Z-Axis = blue
743 glVertex3f(0.0f, 0.0f, 0.0f);
744 glVertex3f(0.0f, 0.0f, 2.0f);
745 glVertex3f(0.0f, 0.0f, 3.0f);
746 glVertex3f(0.0f, 0.0f, 5.0f);
747 glVertex3f(0.0f, 0.0f, 6.0f);
748 glVertex3f(0.0f, 0.0f, 8.0f);
749 // Make a Z
750 glVertex3f(-1.0f, 1.0f, 11.0f);
751 glVertex3f(1.0f, 1.0f, 11.0f);
752 glVertex3f(1.0f, 1.0f, 11.0f);
753 glVertex3f(-1.0f, -1.0f, 11.0f);
754 glVertex3f(-1.0f, -1.0f, 11.0f);
755 glVertex3f(1.0f, -1.0f, 11.0f);
756 glEnd();
757}
758
759void draw_axes()
760{
761 LLGLSUIDefault gls_ui;
762 LLGLSNoTexture gls_no_texture;
763 // A vertical white line at origin
764 LLVector3 v = gAgent.getPositionAgent();
765 glBegin(GL_LINES);
766 glColor3f(1.0f, 1.0f, 1.0f);
767 glVertex3f(0.0f, 0.0f, 0.0f);
768 glVertex3f(0.0f, 0.0f, 40.0f);
769 glEnd();
770 // Some coordinate axes
771 glPushMatrix();
772 glTranslatef( v.mV[VX], v.mV[VY], v.mV[VZ] );
773 renderCoordinateAxes();
774 glPopMatrix();
775}
776
777
778void render_disconnected_background()
779{
780 if (!gDisconnectedImagep && gDisconnected)
781 {
782 llinfos << "Loading last bitmap..." << llendl;
783
784 char temp_str[MAX_PATH];
785 strcpy(temp_str, gDirUtilp->getLindenUserDir().c_str());
786 strcat(temp_str, gDirUtilp->getDirDelimiter().c_str());
787
788 strcat(temp_str, SCREEN_LAST_FILENAME);
789
790 LLPointer<LLImageBMP> image_bmp = new LLImageBMP;
791 if( !image_bmp->load(temp_str) )
792 {
793 //llinfos << "Bitmap load failed" << llendl;
794 return;
795 }
796
797 gDisconnectedImagep = new LLImageGL( FALSE );
798 LLPointer<LLImageRaw> raw = new LLImageRaw;
799 if (!image_bmp->decode(raw))
800 {
801 llinfos << "Bitmap decode failed" << llendl;
802 gDisconnectedImagep = NULL;
803 return;
804 }
805
806 U8 *rawp = raw->getData();
807 S32 npixels = (S32)image_bmp->getWidth()*(S32)image_bmp->getHeight();
808 for (S32 i = 0; i < npixels; i++)
809 {
810 S32 sum = 0;
811 sum = *rawp + *(rawp+1) + *(rawp+2);
812 sum /= 3;
813 *rawp = ((S32)sum*6 + *rawp)/7;
814 rawp++;
815 *rawp = ((S32)sum*6 + *rawp)/7;
816 rawp++;
817 *rawp = ((S32)sum*6 + *rawp)/7;
818 rawp++;
819 }
820
821
822 raw->expandToPowerOfTwo();
823 gDisconnectedImagep->createGLTexture(0, raw);
824 gStartImageGL = gDisconnectedImagep;
825 LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
826 }
827
828 // Make sure the progress view always fills the entire window.
829 S32 width = gViewerWindow->getWindowWidth();
830 S32 height = gViewerWindow->getWindowHeight();
831
832 if (gDisconnectedImagep)
833 {
834 LLGLSUIDefault gls_ui;
835 gViewerWindow->setup2DRender();
836 glPushMatrix();
837 {
838 // scale ui to reflect UIScaleFactor
839 // this can't be done in setup2DRender because it requires a
840 // pushMatrix/popMatrix pair
841 const LLVector2& display_scale = gViewerWindow->getDisplayScale();
842 glScalef(display_scale.mV[VX], display_scale.mV[VY], 1.f);
843
844 LLViewerImage::bindTexture(gDisconnectedImagep);
845 glColor4f(1.f, 1.f, 1.f, 1.f);
846 gl_rect_2d_simple_tex(width, height);
847 LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
848 }
849 glPopMatrix();
850 }
851}