PageRenderTime 51ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/llviewerdisplay.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1560 lines | 1085 code | 257 blank | 218 comment | 107 complexity | d0a8819b752d55bb193cd990c2345858 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llviewerdisplay.cpp
  3. * @brief LLViewerDisplay class implementation
  4. *
  5. * $LicenseInfo:firstyear=2004&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "llviewerprecompiledheaders.h"
  27. #include "llviewerdisplay.h"
  28. #include "llgl.h"
  29. #include "llrender.h"
  30. #include "llglheaders.h"
  31. #include "llagent.h"
  32. #include "llagentcamera.h"
  33. #include "llviewercontrol.h"
  34. #include "llcoord.h"
  35. #include "llcriticaldamp.h"
  36. #include "lldir.h"
  37. #include "lldynamictexture.h"
  38. #include "lldrawpoolalpha.h"
  39. #include "llfeaturemanager.h"
  40. //#include "llfirstuse.h"
  41. #include "llhudmanager.h"
  42. #include "llimagebmp.h"
  43. #include "llmemory.h"
  44. #include "llselectmgr.h"
  45. #include "llsky.h"
  46. #include "llstartup.h"
  47. #include "lltoolfocus.h"
  48. #include "lltoolmgr.h"
  49. #include "lltooldraganddrop.h"
  50. #include "lltoolpie.h"
  51. #include "lltracker.h"
  52. #include "lltrans.h"
  53. #include "llui.h"
  54. #include "llviewercamera.h"
  55. #include "llviewerobjectlist.h"
  56. #include "llviewerparcelmgr.h"
  57. #include "llviewerwindow.h"
  58. #include "llvoavatarself.h"
  59. #include "llvograss.h"
  60. #include "llworld.h"
  61. #include "pipeline.h"
  62. #include "llspatialpartition.h"
  63. #include "llappviewer.h"
  64. #include "llstartup.h"
  65. #include "llviewershadermgr.h"
  66. #include "llfasttimer.h"
  67. #include "llfloatertools.h"
  68. #include "llviewertexturelist.h"
  69. #include "llfocusmgr.h"
  70. #include "llcubemap.h"
  71. #include "llviewerregion.h"
  72. #include "lldrawpoolwater.h"
  73. #include "lldrawpoolbump.h"
  74. #include "llwlparammanager.h"
  75. #include "llwaterparammanager.h"
  76. #include "llpostprocess.h"
  77. extern LLPointer<LLViewerTexture> gStartTexture;
  78. LLPointer<LLViewerTexture> gDisconnectedImagep = NULL;
  79. // used to toggle renderer back on after teleport
  80. const F32 TELEPORT_RENDER_DELAY = 20.f; // Max time a teleport is allowed to take before we raise the curtain
  81. const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived.
  82. const F32 TELEPORT_LOCAL_DELAY = 1.0f; // Delay to prevent teleports after starting an in-sim teleport.
  83. BOOL gTeleportDisplay = FALSE;
  84. LLFrameTimer gTeleportDisplayTimer;
  85. LLFrameTimer gTeleportArrivalTimer;
  86. const F32 RESTORE_GL_TIME = 5.f; // Wait this long while reloading textures before we raise the curtain
  87. BOOL gForceRenderLandFence = FALSE;
  88. BOOL gDisplaySwapBuffers = FALSE;
  89. BOOL gDepthDirty = FALSE;
  90. BOOL gResizeScreenTexture = FALSE;
  91. BOOL gWindowResized = FALSE;
  92. BOOL gSnapshot = FALSE;
  93. U32 gRecentFrameCount = 0; // number of 'recent' frames
  94. LLFrameTimer gRecentFPSTime;
  95. LLFrameTimer gRecentMemoryTime;
  96. // Rendering stuff
  97. void pre_show_depth_buffer();
  98. void post_show_depth_buffer();
  99. void render_ui(F32 zoom_factor = 1.f, int subfield = 0);
  100. void render_hud_attachments();
  101. void render_ui_3d();
  102. void render_ui_2d();
  103. void render_disconnected_background();
  104. void display_startup()
  105. {
  106. if ( !gViewerWindow->getActive()
  107. || !gViewerWindow->getWindow()->getVisible()
  108. || gViewerWindow->getWindow()->getMinimized() )
  109. {
  110. return;
  111. }
  112. gPipeline.updateGL();
  113. // Update images?
  114. //gImageList.updateImages(0.01f);
  115. LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();
  116. LLGLSDefault gls_default;
  117. // Required for HTML update in login screen
  118. static S32 frame_count = 0;
  119. LLGLState::checkStates();
  120. LLGLState::checkTextureChannels();
  121. if (frame_count++ > 1) // make sure we have rendered a frame first
  122. {
  123. LLViewerDynamicTexture::updateAllInstances();
  124. }
  125. LLGLState::checkStates();
  126. LLGLState::checkTextureChannels();
  127. glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  128. LLGLSUIDefault gls_ui;
  129. gPipeline.disableLights();
  130. gViewerWindow->setup2DRender();
  131. gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
  132. gGL.color4f(1,1,1,1);
  133. gViewerWindow->draw();
  134. gGL.flush();
  135. LLVertexBuffer::unbind();
  136. LLGLState::checkStates();
  137. LLGLState::checkTextureChannels();
  138. gViewerWindow->getWindow()->swapBuffers();
  139. glClear(GL_DEPTH_BUFFER_BIT);
  140. }
  141. void display_update_camera()
  142. {
  143. LLMemType mt_uc(LLMemType::MTYPE_DISPLAY_UPDATE_CAMERA);
  144. // TODO: cut draw distance down if customizing avatar?
  145. // TODO: cut draw distance on per-parcel basis?
  146. // Cut draw distance in half when customizing avatar,
  147. // but on the viewer only.
  148. F32 final_far = gAgentCamera.mDrawDistance;
  149. if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode())
  150. {
  151. final_far *= 0.5f;
  152. }
  153. LLViewerCamera::getInstance()->setFar(final_far);
  154. gViewerWindow->setup3DRender();
  155. // update all the sky/atmospheric/water settings
  156. LLWLParamManager::getInstance()->update(LLViewerCamera::getInstance());
  157. LLWaterParamManager::getInstance()->update(LLViewerCamera::getInstance());
  158. // Update land visibility too
  159. LLWorld::getInstance()->setLandFarClip(final_far);
  160. }
  161. // Write some stats to llinfos
  162. void display_stats()
  163. {
  164. F32 fps_log_freq = gSavedSettings.getF32("FPSLogFrequency");
  165. if (fps_log_freq > 0.f && gRecentFPSTime.getElapsedTimeF32() >= fps_log_freq)
  166. {
  167. F32 fps = gRecentFrameCount / fps_log_freq;
  168. llinfos << llformat("FPS: %.02f", fps) << llendl;
  169. gRecentFrameCount = 0;
  170. gRecentFPSTime.reset();
  171. }
  172. F32 mem_log_freq = gSavedSettings.getF32("MemoryLogFrequency");
  173. if (mem_log_freq > 0.f && gRecentMemoryTime.getElapsedTimeF32() >= mem_log_freq)
  174. {
  175. gMemoryAllocated = LLMemory::getCurrentRSS();
  176. U32 memory = (U32)(gMemoryAllocated / (1024*1024));
  177. llinfos << llformat("MEMORY: %d MB", memory) << llendl;
  178. LLMemory::logMemoryInfo(TRUE) ;
  179. gRecentMemoryTime.reset();
  180. }
  181. }
  182. static LLFastTimer::DeclareTimer FTM_PICK("Picking");
  183. static LLFastTimer::DeclareTimer FTM_RENDER("Render", true);
  184. static LLFastTimer::DeclareTimer FTM_UPDATE_SKY("Update Sky");
  185. static LLFastTimer::DeclareTimer FTM_UPDATE_TEXTURES("Update Textures");
  186. static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE("Update Images");
  187. static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_CLASS("Class");
  188. static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_BUMP("Bump");
  189. static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_LIST("List");
  190. static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_DELETE("Delete");
  191. // Paint the display!
  192. void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
  193. {
  194. LLMemType mt_render(LLMemType::MTYPE_RENDER);
  195. LLFastTimer t(FTM_RENDER);
  196. if (gWindowResized)
  197. { //skip render on frames where window has been resized
  198. gGL.flush();
  199. glClear(GL_COLOR_BUFFER_BIT);
  200. gViewerWindow->getWindow()->swapBuffers();
  201. LLPipeline::refreshCachedSettings();
  202. gPipeline.resizeScreenTexture();
  203. gResizeScreenTexture = FALSE;
  204. gWindowResized = FALSE;
  205. return;
  206. }
  207. if (LLPipeline::sRenderDeferred)
  208. { //hack to make sky show up in deferred snapshots
  209. for_snapshot = FALSE;
  210. }
  211. if (LLPipeline::sRenderFrameTest)
  212. {
  213. send_agent_pause();
  214. }
  215. gSnapshot = for_snapshot;
  216. LLGLSDefault gls_default;
  217. LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL);
  218. LLVertexBuffer::unbind();
  219. LLGLState::checkStates();
  220. LLGLState::checkTextureChannels();
  221. stop_glerror();
  222. gPipeline.disableLights();
  223. stop_glerror();
  224. // Don't draw if the window is hidden or minimized.
  225. // In fact, must explicitly check the minimized state before drawing.
  226. // Attempting to draw into a minimized window causes a GL error. JC
  227. if ( !gViewerWindow->getActive()
  228. || !gViewerWindow->getWindow()->getVisible()
  229. || gViewerWindow->getWindow()->getMinimized() )
  230. {
  231. // Clean up memory the pools may have allocated
  232. if (rebuild)
  233. {
  234. stop_glerror();
  235. gPipeline.rebuildPools();
  236. stop_glerror();
  237. }
  238. stop_glerror();
  239. gViewerWindow->returnEmptyPicks();
  240. stop_glerror();
  241. return;
  242. }
  243. gViewerWindow->checkSettings();
  244. {
  245. LLFastTimer ftm(FTM_PICK);
  246. LLAppViewer::instance()->pingMainloopTimeout("Display:Pick");
  247. gViewerWindow->performPick();
  248. }
  249. LLAppViewer::instance()->pingMainloopTimeout("Display:CheckStates");
  250. LLGLState::checkStates();
  251. LLGLState::checkTextureChannels();
  252. //////////////////////////////////////////////////////////
  253. //
  254. // Logic for forcing window updates if we're in drone mode.
  255. //
  256. // *TODO: Investigate running display() during gHeadlessClient. See if this early exit is needed DK 2011-02-18
  257. if (gHeadlessClient)
  258. {
  259. #if LL_WINDOWS
  260. static F32 last_update_time = 0.f;
  261. if ((gFrameTimeSeconds - last_update_time) > 1.f)
  262. {
  263. InvalidateRect((HWND)gViewerWindow->getPlatformWindow(), NULL, FALSE);
  264. last_update_time = gFrameTimeSeconds;
  265. }
  266. #elif LL_DARWIN
  267. // MBW -- Do something clever here.
  268. #endif
  269. // Not actually rendering, don't bother.
  270. return;
  271. }
  272. //
  273. // Bail out if we're in the startup state and don't want to try to
  274. // render the world.
  275. //
  276. if (LLStartUp::getStartupState() < STATE_STARTED)
  277. {
  278. LLAppViewer::instance()->pingMainloopTimeout("Display:Startup");
  279. display_startup();
  280. return;
  281. }
  282. //LLGLState::verify(FALSE);
  283. /////////////////////////////////////////////////
  284. //
  285. // Update GL Texture statistics (used for discard logic?)
  286. //
  287. LLAppViewer::instance()->pingMainloopTimeout("Display:TextureStats");
  288. stop_glerror();
  289. LLImageGL::updateStats(gFrameTimeSeconds);
  290. LLVOAvatar::sRenderName = gSavedSettings.getS32("AvatarNameTagMode");
  291. LLVOAvatar::sRenderGroupTitles = (gSavedSettings.getBOOL("NameTagShowGroupTitles") && gSavedSettings.getS32("AvatarNameTagMode"));
  292. gPipeline.mBackfaceCull = TRUE;
  293. gFrameCount++;
  294. gRecentFrameCount++;
  295. if (gFocusMgr.getAppHasFocus())
  296. {
  297. gForegroundFrameCount++;
  298. }
  299. //////////////////////////////////////////////////////////
  300. //
  301. // Display start screen if we're teleporting, and skip render
  302. //
  303. if (gTeleportDisplay)
  304. {
  305. LLAppViewer::instance()->pingMainloopTimeout("Display:Teleport");
  306. const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived.
  307. S32 attach_count = 0;
  308. if (isAgentAvatarValid())
  309. {
  310. attach_count = gAgentAvatarp->getAttachmentCount();
  311. }
  312. F32 teleport_save_time = TELEPORT_EXPIRY + TELEPORT_EXPIRY_PER_ATTACHMENT * attach_count;
  313. F32 teleport_elapsed = gTeleportDisplayTimer.getElapsedTimeF32();
  314. F32 teleport_percent = teleport_elapsed * (100.f / teleport_save_time);
  315. if( (gAgent.getTeleportState() != LLAgent::TELEPORT_START) && (teleport_percent > 100.f) )
  316. {
  317. // Give up. Don't keep the UI locked forever.
  318. gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
  319. gAgent.setTeleportMessage(std::string());
  320. }
  321. const std::string& message = gAgent.getTeleportMessage();
  322. switch( gAgent.getTeleportState() )
  323. {
  324. case LLAgent::TELEPORT_START:
  325. // Transition to REQUESTED. Viewer has sent some kind
  326. // of TeleportRequest to the source simulator
  327. gTeleportDisplayTimer.reset();
  328. gViewerWindow->setShowProgress(TRUE);
  329. gViewerWindow->setProgressPercent(0);
  330. gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED );
  331. gAgent.setTeleportMessage(
  332. LLAgent::sTeleportProgressMessages["requesting"]);
  333. break;
  334. case LLAgent::TELEPORT_REQUESTED:
  335. // Waiting for source simulator to respond
  336. gViewerWindow->setProgressPercent( llmin(teleport_percent, 37.5f) );
  337. gViewerWindow->setProgressString(message);
  338. break;
  339. case LLAgent::TELEPORT_MOVING:
  340. // Viewer has received destination location from source simulator
  341. gViewerWindow->setProgressPercent( llmin(teleport_percent, 75.f) );
  342. gViewerWindow->setProgressString(message);
  343. break;
  344. case LLAgent::TELEPORT_START_ARRIVAL:
  345. // Transition to ARRIVING. Viewer has received avatar update, etc., from destination simulator
  346. gTeleportArrivalTimer.reset();
  347. gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel"));
  348. gViewerWindow->setProgressPercent(75.f);
  349. gAgent.setTeleportState( LLAgent::TELEPORT_ARRIVING );
  350. gAgent.setTeleportMessage(
  351. LLAgent::sTeleportProgressMessages["arriving"]);
  352. gTextureList.mForceResetTextureStats = TRUE;
  353. gAgentCamera.resetView(TRUE, TRUE);
  354. break;
  355. case LLAgent::TELEPORT_ARRIVING:
  356. // Make the user wait while content "pre-caches"
  357. {
  358. F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / TELEPORT_ARRIVAL_DELAY);
  359. if( arrival_fraction > 1.f )
  360. {
  361. arrival_fraction = 1.f;
  362. //LLFirstUse::useTeleport();
  363. gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
  364. }
  365. gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel"));
  366. gViewerWindow->setProgressPercent( arrival_fraction * 25.f + 75.f);
  367. gViewerWindow->setProgressString(message);
  368. }
  369. break;
  370. case LLAgent::TELEPORT_LOCAL:
  371. // Short delay when teleporting in the same sim (progress screen active but not shown - did not
  372. // fall-through from TELEPORT_START)
  373. {
  374. if( gTeleportDisplayTimer.getElapsedTimeF32() > TELEPORT_LOCAL_DELAY )
  375. {
  376. //LLFirstUse::useTeleport();
  377. gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
  378. }
  379. }
  380. break;
  381. case LLAgent::TELEPORT_NONE:
  382. // No teleport in progress
  383. gViewerWindow->setShowProgress(FALSE);
  384. gTeleportDisplay = FALSE;
  385. break;
  386. }
  387. }
  388. else if(LLAppViewer::instance()->logoutRequestSent())
  389. {
  390. LLAppViewer::instance()->pingMainloopTimeout("Display:Logout");
  391. F32 percent_done = gLogoutTimer.getElapsedTimeF32() * 100.f / gLogoutMaxTime;
  392. if (percent_done > 100.f)
  393. {
  394. percent_done = 100.f;
  395. }
  396. if( LLApp::isExiting() )
  397. {
  398. percent_done = 100.f;
  399. }
  400. gViewerWindow->setProgressPercent( percent_done );
  401. }
  402. else
  403. if (gRestoreGL)
  404. {
  405. LLAppViewer::instance()->pingMainloopTimeout("Display:RestoreGL");
  406. F32 percent_done = gRestoreGLTimer.getElapsedTimeF32() * 100.f / RESTORE_GL_TIME;
  407. if( percent_done > 100.f )
  408. {
  409. gViewerWindow->setShowProgress(FALSE);
  410. gRestoreGL = FALSE;
  411. }
  412. else
  413. {
  414. if( LLApp::isExiting() )
  415. {
  416. percent_done = 100.f;
  417. }
  418. gViewerWindow->setProgressPercent( percent_done );
  419. }
  420. }
  421. //////////////////////////
  422. //
  423. // Prepare for the next frame
  424. //
  425. /////////////////////////////
  426. //
  427. // Update the camera
  428. //
  429. //
  430. LLAppViewer::instance()->pingMainloopTimeout("Display:Camera");
  431. LLViewerCamera::getInstance()->setZoomParameters(zoom_factor, subfield);
  432. LLViewerCamera::getInstance()->setNear(MIN_NEAR_PLANE);
  433. //////////////////////////
  434. //
  435. // clear the next buffer
  436. // (must follow dynamic texture writing since that uses the frame buffer)
  437. //
  438. if (gDisconnected)
  439. {
  440. LLAppViewer::instance()->pingMainloopTimeout("Display:Disconnected");
  441. render_ui();
  442. }
  443. //////////////////////////
  444. //
  445. // Set rendering options
  446. //
  447. //
  448. LLAppViewer::instance()->pingMainloopTimeout("Display:RenderSetup");
  449. stop_glerror();
  450. ///////////////////////////////////////
  451. //
  452. // Slam lighting parameters back to our defaults.
  453. // Note that these are not the same as GL defaults...
  454. stop_glerror();
  455. gGL.setAmbientLightColor(LLColor4::white);
  456. stop_glerror();
  457. /////////////////////////////////////
  458. //
  459. // Render
  460. //
  461. // Actually push all of our triangles to the screen.
  462. //
  463. // do render-to-texture stuff here
  464. if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES))
  465. {
  466. LLAppViewer::instance()->pingMainloopTimeout("Display:DynamicTextures");
  467. LLFastTimer t(FTM_UPDATE_TEXTURES);
  468. if (LLViewerDynamicTexture::updateAllInstances())
  469. {
  470. gGL.setColorMask(true, true);
  471. glClear(GL_DEPTH_BUFFER_BIT);
  472. }
  473. }
  474. gViewerWindow->setup3DViewport();
  475. gPipeline.resetFrameStats(); // Reset per-frame statistics.
  476. if (!gDisconnected)
  477. {
  478. LLMemType mt_du(LLMemType::MTYPE_DISPLAY_UPDATE);
  479. LLAppViewer::instance()->pingMainloopTimeout("Display:Update");
  480. if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
  481. { //don't draw hud objects in this frame
  482. gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
  483. }
  484. if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES))
  485. { //don't draw hud particles in this frame
  486. gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES);
  487. }
  488. //upkeep gl name pools
  489. LLGLNamePool::upkeepPools();
  490. stop_glerror();
  491. display_update_camera();
  492. stop_glerror();
  493. // *TODO: merge these two methods
  494. {
  495. LLMemType mt_uh(LLMemType::MTYPE_DISPLAY_UPDATE_HUD);
  496. LLHUDManager::getInstance()->updateEffects();
  497. LLHUDObject::updateAll();
  498. stop_glerror();
  499. }
  500. {
  501. LLMemType mt_ug(LLMemType::MTYPE_DISPLAY_UPDATE_GEOM);
  502. const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time
  503. gPipeline.createObjects(max_geom_update_time);
  504. gPipeline.processPartitionQ();
  505. gPipeline.updateGeom(max_geom_update_time);
  506. stop_glerror();
  507. }
  508. gPipeline.updateGL();
  509. stop_glerror();
  510. S32 water_clip = 0;
  511. if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT) > 1) &&
  512. (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER) ||
  513. gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_VOIDWATER)))
  514. {
  515. if (LLViewerCamera::getInstance()->cameraUnderWater())
  516. {
  517. water_clip = -1;
  518. }
  519. else
  520. {
  521. water_clip = 1;
  522. }
  523. }
  524. LLAppViewer::instance()->pingMainloopTimeout("Display:Cull");
  525. //Increment drawable frame counter
  526. LLDrawable::incrementVisible();
  527. LLSpatialGroup::sNoDelete = TRUE;
  528. LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();
  529. /*if (LLPipeline::sUseOcclusion && LLPipeline::sRenderDeferred)
  530. { //force occlusion on for all render types if doing deferred render (tighter shadow frustum)
  531. LLPipeline::sUseOcclusion = 3;
  532. }*/
  533. S32 occlusion = LLPipeline::sUseOcclusion;
  534. if (gDepthDirty)
  535. { //depth buffer is invalid, don't overwrite occlusion state
  536. LLPipeline::sUseOcclusion = llmin(occlusion, 1);
  537. }
  538. gDepthDirty = FALSE;
  539. LLGLState::checkStates();
  540. LLGLState::checkTextureChannels();
  541. LLGLState::checkClientArrays();
  542. static LLCullResult result;
  543. LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
  544. gPipeline.updateCull(*LLViewerCamera::getInstance(), result, water_clip);
  545. stop_glerror();
  546. LLGLState::checkStates();
  547. LLGLState::checkTextureChannels();
  548. LLGLState::checkClientArrays();
  549. BOOL to_texture = gPipeline.canUseVertexShaders() &&
  550. LLPipeline::sRenderGlow;
  551. LLAppViewer::instance()->pingMainloopTimeout("Display:Swap");
  552. {
  553. LLMemType mt_ds(LLMemType::MTYPE_DISPLAY_SWAP);
  554. if (gResizeScreenTexture)
  555. {
  556. gResizeScreenTexture = FALSE;
  557. gPipeline.resizeScreenTexture();
  558. }
  559. gGL.setColorMask(true, true);
  560. glClearColor(0,0,0,0);
  561. LLGLState::checkStates();
  562. LLGLState::checkTextureChannels();
  563. LLGLState::checkClientArrays();
  564. if (!for_snapshot)
  565. {
  566. if (gFrameCount > 1)
  567. { //for some reason, ATI 4800 series will error out if you
  568. //try to generate a shadow before the first frame is through
  569. gPipeline.generateSunShadow(*LLViewerCamera::getInstance());
  570. }
  571. LLVertexBuffer::unbind();
  572. LLGLState::checkStates();
  573. LLGLState::checkTextureChannels();
  574. LLGLState::checkClientArrays();
  575. glh::matrix4f proj = glh_get_current_projection();
  576. glh::matrix4f mod = glh_get_current_modelview();
  577. glViewport(0,0,512,512);
  578. LLVOAvatar::updateFreezeCounter() ;
  579. if(!LLPipeline::sMemAllocationThrottled)
  580. {
  581. LLVOAvatar::updateImpostors();
  582. }
  583. glh_set_current_projection(proj);
  584. glh_set_current_modelview(mod);
  585. gGL.matrixMode(LLRender::MM_PROJECTION);
  586. gGL.loadMatrix(proj.m);
  587. gGL.matrixMode(LLRender::MM_MODELVIEW);
  588. gGL.loadMatrix(mod.m);
  589. gViewerWindow->setup3DViewport();
  590. LLGLState::checkStates();
  591. LLGLState::checkTextureChannels();
  592. LLGLState::checkClientArrays();
  593. }
  594. glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  595. }
  596. LLGLState::checkStates();
  597. LLGLState::checkClientArrays();
  598. //if (!for_snapshot)
  599. {
  600. LLMemType mt_gw(LLMemType::MTYPE_DISPLAY_GEN_REFLECTION);
  601. LLAppViewer::instance()->pingMainloopTimeout("Display:Imagery");
  602. gPipeline.generateWaterReflection(*LLViewerCamera::getInstance());
  603. gPipeline.generateHighlight(*LLViewerCamera::getInstance());
  604. gPipeline.renderPhysicsDisplay();
  605. }
  606. LLGLState::checkStates();
  607. LLGLState::checkClientArrays();
  608. //////////////////////////////////////
  609. //
  610. // Update images, using the image stats generated during object update/culling
  611. //
  612. // Can put objects onto the retextured list.
  613. //
  614. // Doing this here gives hardware occlusion queries extra time to complete
  615. LLAppViewer::instance()->pingMainloopTimeout("Display:UpdateImages");
  616. {
  617. LLMemType mt_iu(LLMemType::MTYPE_DISPLAY_IMAGE_UPDATE);
  618. LLFastTimer t(FTM_IMAGE_UPDATE);
  619. {
  620. LLFastTimer t(FTM_IMAGE_UPDATE_CLASS);
  621. LLViewerTexture::updateClass(LLViewerCamera::getInstance()->getVelocityStat()->getMean(),
  622. LLViewerCamera::getInstance()->getAngularVelocityStat()->getMean());
  623. }
  624. {
  625. LLFastTimer t(FTM_IMAGE_UPDATE_BUMP);
  626. gBumpImageList.updateImages(); // must be called before gTextureList version so that it's textures are thrown out first.
  627. }
  628. {
  629. LLFastTimer t(FTM_IMAGE_UPDATE_LIST);
  630. F32 max_image_decode_time = 0.050f*gFrameIntervalSeconds; // 50 ms/second decode time
  631. max_image_decode_time = llclamp(max_image_decode_time, 0.002f, 0.005f ); // min 2ms/frame, max 5ms/frame)
  632. gTextureList.updateImages(max_image_decode_time);
  633. }
  634. {
  635. LLFastTimer t(FTM_IMAGE_UPDATE_DELETE);
  636. //remove dead textures from GL
  637. LLImageGL::deleteDeadTextures();
  638. stop_glerror();
  639. }
  640. }
  641. LLGLState::checkStates();
  642. LLGLState::checkClientArrays();
  643. ///////////////////////////////////
  644. //
  645. // StateSort
  646. //
  647. // Responsible for taking visible objects, and adding them to the appropriate draw orders.
  648. // In the case of alpha objects, z-sorts them first.
  649. // Also creates special lists for outlines and selected face rendering.
  650. //
  651. LLAppViewer::instance()->pingMainloopTimeout("Display:StateSort");
  652. {
  653. LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
  654. LLMemType mt_ss(LLMemType::MTYPE_DISPLAY_STATE_SORT);
  655. gPipeline.stateSort(*LLViewerCamera::getInstance(), result);
  656. stop_glerror();
  657. if (rebuild)
  658. {
  659. //////////////////////////////////////
  660. //
  661. // rebuildPools
  662. //
  663. //
  664. gPipeline.rebuildPools();
  665. stop_glerror();
  666. }
  667. }
  668. LLGLState::checkStates();
  669. LLGLState::checkClientArrays();
  670. LLPipeline::sUseOcclusion = occlusion;
  671. {
  672. LLMemType mt_ds(LLMemType::MTYPE_DISPLAY_SKY);
  673. LLAppViewer::instance()->pingMainloopTimeout("Display:Sky");
  674. LLFastTimer t(FTM_UPDATE_SKY);
  675. gSky.updateSky();
  676. }
  677. if(gUseWireframe)
  678. {
  679. glClearColor(0.5f, 0.5f, 0.5f, 0.f);
  680. glClear(GL_COLOR_BUFFER_BIT);
  681. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  682. }
  683. LLAppViewer::instance()->pingMainloopTimeout("Display:RenderStart");
  684. //// render frontmost floater opaque for occlusion culling purposes
  685. //LLFloater* frontmost_floaterp = gFloaterView->getFrontmost();
  686. //// assumes frontmost floater with focus is opaque
  687. //if (frontmost_floaterp && gFocusMgr.childHasKeyboardFocus(frontmost_floaterp))
  688. //{
  689. // gGL.matrixMode(LLRender::MM_MODELVIEW);
  690. // gGL.pushMatrix();
  691. // {
  692. // gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  693. // glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
  694. // gGL.loadIdentity();
  695. // LLRect floater_rect = frontmost_floaterp->calcScreenRect();
  696. // // deflate by one pixel so rounding errors don't occlude outside of floater extents
  697. // floater_rect.stretch(-1);
  698. // LLRectf floater_3d_rect((F32)floater_rect.mLeft / (F32)gViewerWindow->getWindowWidthScaled(),
  699. // (F32)floater_rect.mTop / (F32)gViewerWindow->getWindowHeightScaled(),
  700. // (F32)floater_rect.mRight / (F32)gViewerWindow->getWindowWidthScaled(),
  701. // (F32)floater_rect.mBottom / (F32)gViewerWindow->getWindowHeightScaled());
  702. // floater_3d_rect.translate(-0.5f, -0.5f);
  703. // gGL.translatef(0.f, 0.f, -LLViewerCamera::getInstance()->getNear());
  704. // gGL.scalef(LLViewerCamera::getInstance()->getNear() * LLViewerCamera::getInstance()->getAspect() / sinf(LLViewerCamera::getInstance()->getView()), LLViewerCamera::getInstance()->getNear() / sinf(LLViewerCamera::getInstance()->getView()), 1.f);
  705. // gGL.color4fv(LLColor4::white.mV);
  706. // gGL.begin(LLVertexBuffer::QUADS);
  707. // {
  708. // gGL.vertex3f(floater_3d_rect.mLeft, floater_3d_rect.mBottom, 0.f);
  709. // gGL.vertex3f(floater_3d_rect.mLeft, floater_3d_rect.mTop, 0.f);
  710. // gGL.vertex3f(floater_3d_rect.mRight, floater_3d_rect.mTop, 0.f);
  711. // gGL.vertex3f(floater_3d_rect.mRight, floater_3d_rect.mBottom, 0.f);
  712. // }
  713. // gGL.end();
  714. // glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  715. // }
  716. // gGL.popMatrix();
  717. //}
  718. LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE;
  719. LLGLState::checkStates();
  720. LLGLState::checkClientArrays();
  721. stop_glerror();
  722. if (to_texture)
  723. {
  724. gGL.setColorMask(true, true);
  725. if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
  726. {
  727. gPipeline.mDeferredScreen.bindTarget();
  728. glClearColor(1,0,1,1);
  729. gPipeline.mDeferredScreen.clear();
  730. }
  731. else
  732. {
  733. gPipeline.mScreen.bindTarget();
  734. if (LLPipeline::sUnderWaterRender && !gPipeline.canUseWindLightShaders())
  735. {
  736. const LLColor4 &col = LLDrawPoolWater::sWaterFogColor;
  737. glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
  738. }
  739. gPipeline.mScreen.clear();
  740. }
  741. gGL.setColorMask(true, false);
  742. }
  743. LLAppViewer::instance()->pingMainloopTimeout("Display:RenderGeom");
  744. if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot())
  745. && !gRestoreGL)
  746. {
  747. LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
  748. LLMemType mt_rg(LLMemType::MTYPE_DISPLAY_RENDER_GEOM);
  749. gGL.setColorMask(true, false);
  750. if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
  751. {
  752. gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance());
  753. }
  754. else
  755. {
  756. gPipeline.renderGeom(*LLViewerCamera::getInstance(), TRUE);
  757. }
  758. gGL.setColorMask(true, true);
  759. //store this frame's modelview matrix for use
  760. //when rendering next frame's occlusion queries
  761. for (U32 i = 0; i < 16; i++)
  762. {
  763. gGLLastModelView[i] = gGLModelView[i];
  764. gGLLastProjection[i] = gGLProjection[i];
  765. }
  766. stop_glerror();
  767. }
  768. for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++)
  769. { //dummy cleanup of any currently bound textures
  770. if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE)
  771. {
  772. gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType());
  773. gGL.getTexUnit(i)->disable();
  774. }
  775. }
  776. LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush");
  777. if (to_texture)
  778. {
  779. LLMemType mt_rf(LLMemType::MTYPE_DISPLAY_RENDER_FLUSH);
  780. if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
  781. {
  782. gPipeline.mDeferredScreen.flush();
  783. if(LLRenderTarget::sUseFBO)
  784. {
  785. LLRenderTarget::copyContentsToFramebuffer(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(),
  786. gPipeline.mDeferredScreen.getHeight(), 0, 0,
  787. gPipeline.mDeferredScreen.getWidth(),
  788. gPipeline.mDeferredScreen.getHeight(),
  789. GL_DEPTH_BUFFER_BIT, GL_NEAREST);
  790. }
  791. }
  792. else
  793. {
  794. gPipeline.mScreen.flush();
  795. if(LLRenderTarget::sUseFBO)
  796. {
  797. LLRenderTarget::copyContentsToFramebuffer(gPipeline.mScreen, 0, 0, gPipeline.mScreen.getWidth(),
  798. gPipeline.mScreen.getHeight(), 0, 0,
  799. gPipeline.mScreen.getWidth(),
  800. gPipeline.mScreen.getHeight(),
  801. GL_DEPTH_BUFFER_BIT, GL_NEAREST);
  802. }
  803. }
  804. }
  805. if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
  806. {
  807. gPipeline.renderDeferredLighting();
  808. }
  809. LLPipeline::sUnderWaterRender = FALSE;
  810. LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI");
  811. if (!for_snapshot)
  812. {
  813. LLFastTimer t(FTM_RENDER_UI);
  814. render_ui();
  815. }
  816. LLSpatialGroup::sNoDelete = FALSE;
  817. gPipeline.clearReferences();
  818. gPipeline.rebuildGroups();
  819. }
  820. LLAppViewer::instance()->pingMainloopTimeout("Display:FrameStats");
  821. stop_glerror();
  822. if (LLPipeline::sRenderFrameTest)
  823. {
  824. send_agent_resume();
  825. LLPipeline::sRenderFrameTest = FALSE;
  826. }
  827. display_stats();
  828. LLAppViewer::instance()->pingMainloopTimeout("Display:Done");
  829. }
  830. void render_hud_attachments()
  831. {
  832. LLMemType mt_ra(LLMemType::MTYPE_DISPLAY_RENDER_ATTACHMENTS);
  833. gGL.matrixMode(LLRender::MM_PROJECTION);
  834. gGL.pushMatrix();
  835. gGL.matrixMode(LLRender::MM_MODELVIEW);
  836. gGL.pushMatrix();
  837. glh::matrix4f current_proj = glh_get_current_projection();
  838. glh::matrix4f current_mod = glh_get_current_modelview();
  839. // clamp target zoom level to reasonable values
  840. gAgentCamera.mHUDTargetZoom = llclamp(gAgentCamera.mHUDTargetZoom, 0.1f, 1.f);
  841. // smoothly interpolate current zoom level
  842. gAgentCamera.mHUDCurZoom = lerp(gAgentCamera.mHUDCurZoom, gAgentCamera.mHUDTargetZoom, LLCriticalDamp::getInterpolant(0.03f));
  843. if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices())
  844. {
  845. LLCamera hud_cam = *LLViewerCamera::getInstance();
  846. LLVector3 origin = hud_cam.getOrigin();
  847. hud_cam.setOrigin(-1.f,0,0);
  848. hud_cam.setAxes(LLVector3(1,0,0), LLVector3(0,1,0), LLVector3(0,0,1));
  849. LLViewerCamera::updateFrustumPlanes(hud_cam, TRUE);
  850. bool render_particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) && gSavedSettings.getBOOL("RenderHUDParticles");
  851. //only render hud objects
  852. gPipeline.pushRenderTypeMask();
  853. // turn off everything
  854. gPipeline.andRenderTypeMask(LLPipeline::END_RENDER_TYPES);
  855. // turn on HUD
  856. gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
  857. // turn on HUD particles
  858. gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES);
  859. // if particles are off, turn off hud-particles as well
  860. if (!render_particles)
  861. {
  862. // turn back off HUD particles
  863. gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES);
  864. }
  865. bool has_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
  866. if (has_ui)
  867. {
  868. gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI);
  869. }
  870. S32 use_occlusion = LLPipeline::sUseOcclusion;
  871. LLPipeline::sUseOcclusion = 0;
  872. //cull, sort, and render hud objects
  873. static LLCullResult result;
  874. LLSpatialGroup::sNoDelete = TRUE;
  875. LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
  876. gPipeline.updateCull(hud_cam, result);
  877. gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_BUMP);
  878. gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_SIMPLE);
  879. gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME);
  880. gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA);
  881. gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT);
  882. gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA);
  883. gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK);
  884. gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_BUMP);
  885. gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT);
  886. gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK);
  887. gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY);
  888. gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_SHINY);
  889. gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_INVISIBLE);
  890. gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY);
  891. gPipeline.stateSort(hud_cam, result);
  892. gPipeline.renderGeom(hud_cam);
  893. LLSpatialGroup::sNoDelete = FALSE;
  894. //gPipeline.clearReferences();
  895. render_hud_elements();
  896. //restore type mask
  897. gPipeline.popRenderTypeMask();
  898. if (has_ui)
  899. {
  900. gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI);
  901. }
  902. LLPipeline::sUseOcclusion = use_occlusion;
  903. }
  904. gGL.matrixMode(LLRender::MM_PROJECTION);
  905. gGL.popMatrix();
  906. gGL.matrixMode(LLRender::MM_MODELVIEW);
  907. gGL.popMatrix();
  908. glh_set_current_projection(current_proj);
  909. glh_set_current_modelview(current_mod);
  910. }
  911. LLRect get_whole_screen_region()
  912. {
  913. LLRect whole_screen = gViewerWindow->getWorldViewRectScaled();
  914. // apply camera zoom transform (for high res screenshots)
  915. F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor();
  916. S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion();
  917. if (zoom_factor > 1.f)
  918. {
  919. S32 num_horizontal_tiles = llceil(zoom_factor);
  920. S32 tile_width = llround((F32)gViewerWindow->getWorldViewWidthScaled() / zoom_factor);
  921. S32 tile_height = llround((F32)gViewerWindow->getWorldViewHeightScaled() / zoom_factor);
  922. int tile_y = sub_region / num_horizontal_tiles;
  923. int tile_x = sub_region - (tile_y * num_horizontal_tiles);
  924. whole_screen.setLeftTopAndSize(tile_x * tile_width, gViewerWindow->getWorldViewHeightScaled() - (tile_y * tile_height), tile_width, tile_height);
  925. }
  926. return whole_screen;
  927. }
  928. bool get_hud_matrices(const LLRect& screen_region, glh::matrix4f &proj, glh::matrix4f &model)
  929. {
  930. if (isAgentAvatarValid() && gAgentAvatarp->hasHUDAttachment())
  931. {
  932. F32 zoom_level = gAgentCamera.mHUDCurZoom;
  933. LLBBox hud_bbox = gAgentAvatarp->getHUDBBox();
  934. F32 hud_depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f);
  935. proj = gl_ortho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, hud_depth);
  936. proj.element(2,2) = -0.01f;
  937. F32 aspect_ratio = LLViewerCamera::getInstance()->getAspect();
  938. glh::matrix4f mat;
  939. F32 scale_x = (F32)gViewerWindow->getWorldViewWidthScaled() / (F32)screen_region.getWidth();
  940. F32 scale_y = (F32)gViewerWindow->getWorldViewHeightScaled() / (F32)screen_region.getHeight();
  941. mat.set_scale(glh::vec3f(scale_x, scale_y, 1.f));
  942. mat.set_translate(
  943. glh::vec3f(clamp_rescale((F32)(screen_region.getCenterX() - screen_region.mLeft), 0.f, (F32)gViewerWindow->getWorldViewWidthScaled(), 0.5f * scale_x * aspect_ratio, -0.5f * scale_x * aspect_ratio),
  944. clamp_rescale((F32)(screen_region.getCenterY() - screen_region.mBottom), 0.f, (F32)gViewerWindow->getWorldViewHeightScaled(), 0.5f * scale_y, -0.5f * scale_y),
  945. 0.f));
  946. proj *= mat;
  947. glh::matrix4f tmp_model((GLfloat*) OGL_TO_CFR_ROTATION);
  948. mat.set_scale(glh::vec3f(zoom_level, zoom_level, zoom_level));
  949. mat.set_translate(glh::vec3f(-hud_bbox.getCenterLocal().mV[VX] + (hud_depth * 0.5f), 0.f, 0.f));
  950. tmp_model *= mat;
  951. model = tmp_model;
  952. return TRUE;
  953. }
  954. else
  955. {
  956. return FALSE;
  957. }
  958. }
  959. bool get_hud_matrices(glh::matrix4f &proj, glh::matrix4f &model)
  960. {
  961. LLRect whole_screen = get_whole_screen_region();
  962. return get_hud_matrices(whole_screen, proj, model);
  963. }
  964. BOOL setup_hud_matrices()
  965. {
  966. LLRect whole_screen = get_whole_screen_region();
  967. return setup_hud_matrices(whole_screen);
  968. }
  969. BOOL setup_hud_matrices(const LLRect& screen_region)
  970. {
  971. glh::matrix4f proj, model;
  972. bool result = get_hud_matrices(screen_region, proj, model);
  973. if (!result) return result;
  974. // set up transform to keep HUD objects in front of camera
  975. gGL.matrixMode(LLRender::MM_PROJECTION);
  976. gGL.loadMatrix(proj.m);
  977. glh_set_current_projection(proj);
  978. gGL.matrixMode(LLRender::MM_MODELVIEW);
  979. gGL.loadMatrix(model.m);
  980. glh_set_current_modelview(model);
  981. return TRUE;
  982. }
  983. static LLFastTimer::DeclareTimer FTM_SWAP("Swap");
  984. void render_ui(F32 zoom_factor, int subfield)
  985. {
  986. LLMemType mt_ru(LLMemType::MTYPE_DISPLAY_RENDER_UI);
  987. LLGLState::checkStates();
  988. glh::matrix4f saved_view = glh_get_current_modelview();
  989. if (!gSnapshot)
  990. {
  991. gGL.pushMatrix();
  992. gGL.loadMatrix(gGLLastModelView);
  993. glh_set_current_modelview(glh_copy_matrix(gGLLastModelView));
  994. }
  995. {
  996. BOOL to_texture = gPipeline.canUseVertexShaders() &&
  997. LLPipeline::sRenderGlow;
  998. if (to_texture)
  999. {
  1000. gPipeline.renderBloom(gSnapshot, zoom_factor, subfield);
  1001. }
  1002. render_hud_elements();
  1003. render_hud_attachments();
  1004. }
  1005. LLGLSDefault gls_default;
  1006. LLGLSUIDefault gls_ui;
  1007. {
  1008. gPipeline.disableLights();
  1009. }
  1010. {
  1011. gGL.color4f(1,1,1,1);
  1012. if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
  1013. {
  1014. LLFastTimer t(FTM_RENDER_UI);
  1015. if (!gDisconnected)
  1016. {
  1017. render_ui_3d();
  1018. LLGLState::checkStates();
  1019. }
  1020. else
  1021. {
  1022. render_disconnected_background();
  1023. }
  1024. render_ui_2d();
  1025. LLGLState::checkStates();
  1026. }
  1027. gGL.flush();
  1028. {
  1029. gViewerWindow->setup2DRender();
  1030. gViewerWindow->updateDebugText();
  1031. gViewerWindow->drawDebugText();
  1032. }
  1033. LLVertexBuffer::unbind();
  1034. }
  1035. if (!gSnapshot)
  1036. {
  1037. glh_set_current_modelview(saved_view);
  1038. gGL.popMatrix();
  1039. }
  1040. if (gDisplaySwapBuffers)
  1041. {
  1042. LLFastTimer t(FTM_SWAP);
  1043. gViewerWindow->getWindow()->swapBuffers();
  1044. }
  1045. gDisplaySwapBuffers = TRUE;
  1046. }
  1047. void renderCoordinateAxes()
  1048. {
  1049. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  1050. gGL.begin(LLRender::LINES);
  1051. gGL.color3f(1.0f, 0.0f, 0.0f); // i direction = X-Axis = red
  1052. gGL.vertex3f(0.0f, 0.0f, 0.0f);
  1053. gGL.vertex3f(2.0f, 0.0f, 0.0f);
  1054. gGL.vertex3f(3.0f, 0.0f, 0.0f);
  1055. gGL.vertex3f(5.0f, 0.0f, 0.0f);
  1056. gGL.vertex3f(6.0f, 0.0f, 0.0f);
  1057. gGL.vertex3f(8.0f, 0.0f, 0.0f);
  1058. // Make an X
  1059. gGL.vertex3f(11.0f, 1.0f, 1.0f);
  1060. gGL.vertex3f(11.0f, -1.0f, -1.0f);
  1061. gGL.vertex3f(11.0f, 1.0f, -1.0f);
  1062. gGL.vertex3f(11.0f, -1.0f, 1.0f);
  1063. gGL.color3f(0.0f, 1.0f, 0.0f); // j direction = Y-Axis = green
  1064. gGL.vertex3f(0.0f, 0.0f, 0.0f);
  1065. gGL.vertex3f(0.0f, 2.0f, 0.0f);
  1066. gGL.vertex3f(0.0f, 3.0f, 0.0f);
  1067. gGL.vertex3f(0.0f, 5.0f, 0.0f);
  1068. gGL.vertex3f(0.0f, 6.0f, 0.0f);
  1069. gGL.vertex3f(0.0f, 8.0f, 0.0f);
  1070. // Make a Y
  1071. gGL.vertex3f(1.0f, 11.0f, 1.0f);
  1072. gGL.vertex3f(0.0f, 11.0f, 0.0f);
  1073. gGL.vertex3f(-1.0f, 11.0f, 1.0f);
  1074. gGL.vertex3f(0.0f, 11.0f, 0.0f);
  1075. gGL.vertex3f(0.0f, 11.0f, 0.0f);
  1076. gGL.vertex3f(0.0f, 11.0f, -1.0f);
  1077. gGL.color3f(0.0f, 0.0f, 1.0f); // Z-Axis = blue
  1078. gGL.vertex3f(0.0f, 0.0f, 0.0f);
  1079. gGL.vertex3f(0.0f, 0.0f, 2.0f);
  1080. gGL.vertex3f(0.0f, 0.0f, 3.0f);
  1081. gGL.vertex3f(0.0f, 0.0f, 5.0f);
  1082. gGL.vertex3f(0.0f, 0.0f, 6.0f);
  1083. gGL.vertex3f(0.0f, 0.0f, 8.0f);
  1084. // Make a Z
  1085. gGL.vertex3f(-1.0f, 1.0f, 11.0f);
  1086. gGL.vertex3f(1.0f, 1.0f, 11.0f);
  1087. gGL.vertex3f(1.0f, 1.0f, 11.0f);
  1088. gGL.vertex3f(-1.0f, -1.0f, 11.0f);
  1089. gGL.vertex3f(-1.0f, -1.0f, 11.0f);
  1090. gGL.vertex3f(1.0f, -1.0f, 11.0f);
  1091. gGL.end();
  1092. }
  1093. void draw_axes()
  1094. {
  1095. LLGLSUIDefault gls_ui;
  1096. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  1097. // A vertical white line at origin
  1098. LLVector3 v = gAgent.getPositionAgent();
  1099. gGL.begin(LLRender::LINES);
  1100. gGL.color3f(1.0f, 1.0f, 1.0f);
  1101. gGL.vertex3f(0.0f, 0.0f, 0.0f);
  1102. gGL.vertex3f(0.0f, 0.0f, 40.0f);
  1103. gGL.end();
  1104. // Some coordinate axes
  1105. gGL.pushMatrix();
  1106. gGL.translatef( v.mV[VX], v.mV[VY], v.mV[VZ] );
  1107. renderCoordinateAxes();
  1108. gGL.popMatrix();
  1109. }
  1110. void render_ui_3d()
  1111. {
  1112. LLGLSPipeline gls_pipeline;
  1113. //////////////////////////////////////
  1114. //
  1115. // Render 3D UI elements
  1116. // NOTE: zbuffer is cleared before we get here by LLDrawPoolHUD,
  1117. // so 3d elements requiring Z buffer are moved to LLDrawPoolHUD
  1118. //
  1119. /////////////////////////////////////////////////////////////
  1120. //
  1121. // Render 2.5D elements (2D elements in the world)
  1122. // Stuff without z writes
  1123. //
  1124. // Debugging stuff goes before the UI.
  1125. stop_glerror();
  1126. if (LLGLSLShader::sNoFixedFunction)
  1127. {
  1128. gUIProgram.bind();
  1129. }
  1130. // Coordinate axes
  1131. if (gSavedSettings.getBOOL("ShowAxes"))
  1132. {
  1133. draw_axes();
  1134. }
  1135. gViewerWindow->renderSelections(FALSE, FALSE, TRUE); // Non HUD call in render_hud_elements
  1136. stop_glerror();
  1137. }
  1138. void render_ui_2d()
  1139. {
  1140. LLGLSUIDefault gls_ui;
  1141. /////////////////////////////////////////////////////////////
  1142. //
  1143. // Render 2D UI elements that overlay the world (no z compare)
  1144. // Disable wireframe mode below here, as this is HUD/menus
  1145. glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  1146. // Menu overlays, HUD, etc
  1147. gViewerWindow->setup2DRender();
  1148. F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor();
  1149. S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion();
  1150. if (zoom_factor > 1.f)
  1151. {
  1152. //decompose subregion number to x and y values
  1153. int pos_y = sub_region / llceil(zoom_factor);
  1154. int pos_x = sub_region - (pos_y*llceil(zoom_factor));
  1155. // offset for this tile
  1156. LLFontGL::sCurOrigin.mX -= llround((F32)gViewerWindow->getWindowWidthScaled() * (F32)pos_x / zoom_factor);
  1157. LLFontGL::sCurOrigin.mY -= llround((F32)gViewerWindow->getWindowHeightScaled() * (F32)pos_y / zoom_factor);
  1158. }
  1159. stop_glerror();
  1160. //gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
  1161. // render outline for HUD
  1162. if (isAgentAvatarValid() && gAgentCamera.mHUDCurZoom < 0.98f)
  1163. {
  1164. gGL.pushMatrix();
  1165. S32 half_width = (gViewerWindow->getWorldViewWidthScaled() / 2);
  1166. S32 half_height = (gViewerWindow->getWorldViewHeightScaled() / 2);
  1167. gGL.scalef(LLUI::sGLScaleFactor.mV[0], LLUI::sGLScaleFactor.mV[1], 1.f);
  1168. gGL.translatef((F32)half_width, (F32)half_height, 0.f);
  1169. F32 zoom = gAgentCamera.mHUDCurZoom;
  1170. gGL.scalef(zoom,zoom,1.f);
  1171. gGL.color4fv(LLColor4::white.mV);
  1172. gl_rect_2d(-half_width, half_height, half_width, -half_height, FALSE);
  1173. gGL.popMatrix();
  1174. stop_glerror();
  1175. }
  1176. if (gSavedSettings.getBOOL("RenderUIBuffer"))
  1177. {
  1178. if (LLUI::sDirty)
  1179. {
  1180. LLUI::sDirty = FALSE;
  1181. LLRect t_rect;
  1182. gPipeline.mUIScreen.bindTarget();
  1183. gGL.setColorMask(true, true);
  1184. {
  1185. static const S32 pad = 8;
  1186. LLUI::sDirtyRect.mLeft -= pad;
  1187. LLUI::sDirtyRect.mRight += pad;
  1188. LLUI::sDirtyRect.mBottom -= pad;
  1189. LLUI::sDirtyRect.mTop += pad;
  1190. LLGLEnable scissor(GL_SCISSOR_TEST);
  1191. static LLRect last_rect = LLUI::sDirtyRect;
  1192. //union with last rect to avoid mouse poop
  1193. last_rect.unionWith(LLUI::sDirtyRect);
  1194. t_rect = LLUI::sDirtyRect;
  1195. LLUI::sDirtyRect = last_rect;
  1196. last_rect = t_rect;
  1197. last_rect.mLeft = LLRect::tCoordType(last_rect.mLeft / LLUI::sGLScaleFactor.mV[0]);
  1198. last_rect.mRight = LLRect::tCoordType(last_rect.mRight / LLUI::sGLScaleFactor.mV[0]);
  1199. last_rect.mTop = LLRect::tCoordType(last_rect.mTop / LLUI::sGLScaleFactor.mV[1]);
  1200. last_rect.mBottom = LLRect::tCoordType(last_rect.mBottom / LLUI::sGLScaleFactor.mV[1]);
  1201. LLRect clip_rect(last_rect);
  1202. glClear(GL_COLOR_BUFFER_BIT);
  1203. gViewerWindow->draw();
  1204. }
  1205. gPipeline.mUIScreen.flush();
  1206. gGL.setColorMask(true, false);
  1207. LLUI::sDirtyRect = t_rect;
  1208. }
  1209. LLGLDisable cull(GL_CULL_FACE);
  1210. LLGLDisable blend(GL_BLEND);
  1211. S32 width = gViewerWindow->getWindowWidthScaled();
  1212. S32 height = gViewerWindow->getWindowHeightScaled();
  1213. gGL.getTexUnit(0)->bind(&gPipeline.mUIScreen);
  1214. gGL.begin(LLRender::TRIANGLE_STRIP);
  1215. gGL.color4f(1,1,1,1);
  1216. gGL.texCoord2f(0, 0); gGL.vertex2i(0, 0);
  1217. gGL.texCoord2f(width, 0); gGL.vertex2i(width, 0);
  1218. gGL.texCoord2f(0, height); gGL.vertex2i(0, height);
  1219. gGL.texCoord2f(width, height); gGL.vertex2i(width, height);
  1220. gGL.end();
  1221. }
  1222. else
  1223. {
  1224. gViewerWindow->draw();
  1225. }
  1226. // reset current origin for font rendering, in case of tiling render
  1227. LLFontGL::sCurOrigin.set(0, 0);
  1228. }
  1229. void render_disconnected_background()
  1230. {
  1231. if (LLGLSLShader::sNoFixedFunction)
  1232. {
  1233. gUIProgram.bind();
  1234. }
  1235. gGL.color4f(1,1,1,1);
  1236. if (!gDisconnectedImagep && gDisconnected)
  1237. {
  1238. llinfos << "Loading last bitmap..." << llendl;
  1239. std::string temp_str;
  1240. temp_str = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter() + SCREEN_LAST_FILENAME;
  1241. LLPointer<LLImageBMP> image_bmp = new LLImageBMP;
  1242. if( !image_bmp->load(temp_str) )
  1243. {
  1244. //llinfos << "Bitmap load failed" << llendl;
  1245. return;
  1246. }
  1247. LLPointer<LLImageRaw> raw = new LLImageRaw;
  1248. if (!image_bmp->decode(raw, 0.0f))
  1249. {
  1250. llinfos << "Bitmap decode failed" << llendl;
  1251. gDisconnectedImagep = NULL;
  1252. return;
  1253. }
  1254. U8 *rawp = raw->getData();
  1255. S32 npixels = (S32)image_bmp->getWidth()*(S32)image_bmp->getHeight();
  1256. for (S32 i = 0; i < npixels; i++)
  1257. {
  1258. S32 sum = 0;
  1259. sum = *rawp + *(rawp+1) + *(rawp+2);
  1260. sum /= 3;
  1261. *rawp = ((S32)sum*6 + *rawp)/7;
  1262. rawp++;
  1263. *rawp = ((S32)sum*6 + *rawp)/7;
  1264. rawp++;
  1265. *rawp = ((S32)sum*6 + *rawp)/7;
  1266. rawp++;
  1267. }
  1268. raw->expandToPowerOfTwo();
  1269. gDisconnectedImagep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE );
  1270. gStartTexture = gDisconnectedImagep;
  1271. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  1272. }
  1273. // Make sure the progress view always fills the entire window.
  1274. S32 width = gViewerWindow->getWindowWidthScaled();
  1275. S32 height = gViewerWindow->getWindowHeightScaled();
  1276. if (gDisconnectedImagep)
  1277. {
  1278. LLGLSUIDefault gls_ui;
  1279. gViewerWindow->setup2DRender();
  1280. gGL.pushMatrix();
  1281. {
  1282. // scale ui to reflect UIScaleFactor
  1283. // this can't be done in setup2DRender because it requires a
  1284. // pushMatrix/popMatrix pair
  1285. const LLVector2& display_scale = gViewerWindow->getDisplayScale();
  1286. gGL.scalef(display_scale.mV[VX], display_scale.mV[VY], 1.f);
  1287. gGL.getTexUnit(0)->bind(gDisconnectedImagep);
  1288. gGL.color4f(1.f, 1.f, 1.f, 1.f);
  1289. gl_rect_2d_simple_tex(width, height);
  1290. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  1291. }
  1292. gGL.popMatrix();
  1293. }
  1294. gGL.flush();
  1295. if (LLGLSLShader::sNoFixedFunction)
  1296. {
  1297. gUIProgram.unbind();
  1298. }
  1299. }
  1300. void display_cleanup()
  1301. {
  1302. gDisconnectedImagep = NULL;
  1303. }