diff options
Diffstat (limited to 'linden/indra/newview/pipeline.cpp')
-rw-r--r-- | linden/indra/newview/pipeline.cpp | 2891 |
1 files changed, 1989 insertions, 902 deletions
diff --git a/linden/indra/newview/pipeline.cpp b/linden/indra/newview/pipeline.cpp index a5b7d34..e0c2de7 100644 --- a/linden/indra/newview/pipeline.cpp +++ b/linden/indra/newview/pipeline.cpp | |||
@@ -50,6 +50,7 @@ | |||
50 | #include "v3color.h" | 50 | #include "v3color.h" |
51 | #include "llui.h" | 51 | #include "llui.h" |
52 | #include "llglheaders.h" | 52 | #include "llglheaders.h" |
53 | #include "llglimmediate.h" | ||
53 | 54 | ||
54 | // newview includes | 55 | // newview includes |
55 | #include "llagent.h" | 56 | #include "llagent.h" |
@@ -57,7 +58,6 @@ | |||
57 | #include "lldrawpoolalpha.h" | 58 | #include "lldrawpoolalpha.h" |
58 | #include "lldrawpoolavatar.h" | 59 | #include "lldrawpoolavatar.h" |
59 | #include "lldrawpoolground.h" | 60 | #include "lldrawpoolground.h" |
60 | #include "lldrawpoolsimple.h" | ||
61 | #include "lldrawpoolbump.h" | 61 | #include "lldrawpoolbump.h" |
62 | #include "lldrawpooltree.h" | 62 | #include "lldrawpooltree.h" |
63 | #include "lldrawpoolwater.h" | 63 | #include "lldrawpoolwater.h" |
@@ -96,6 +96,10 @@ | |||
96 | #include "llglslshader.h" | 96 | #include "llglslshader.h" |
97 | #include "llviewerjoystick.h" | 97 | #include "llviewerjoystick.h" |
98 | #include "llviewerdisplay.h" | 98 | #include "llviewerdisplay.h" |
99 | #include "llwlparammanager.h" | ||
100 | #include "llwaterparammanager.h" | ||
101 | #include "llspatialpartition.h" | ||
102 | |||
99 | 103 | ||
100 | #ifdef _DEBUG | 104 | #ifdef _DEBUG |
101 | // Debug indices is disabled for now for debug performance - djs 4/24/02 | 105 | // Debug indices is disabled for now for debug performance - djs 4/24/02 |
@@ -104,7 +108,7 @@ | |||
104 | //#define DEBUG_INDICES | 108 | //#define DEBUG_INDICES |
105 | #endif | 109 | #endif |
106 | 110 | ||
107 | #define AGGRESSIVE_OCCLUSION 0 | 111 | void render_ui_and_swap_if_needed(); |
108 | 112 | ||
109 | const F32 BACKLIGHT_DAY_MAGNITUDE_AVATAR = 0.2f; | 113 | const F32 BACKLIGHT_DAY_MAGNITUDE_AVATAR = 0.2f; |
110 | const F32 BACKLIGHT_NIGHT_MAGNITUDE_AVATAR = 0.1f; | 114 | const F32 BACKLIGHT_NIGHT_MAGNITUDE_AVATAR = 0.1f; |
@@ -112,15 +116,7 @@ const F32 BACKLIGHT_DAY_MAGNITUDE_OBJECT = 0.1f; | |||
112 | const F32 BACKLIGHT_NIGHT_MAGNITUDE_OBJECT = 0.08f; | 116 | const F32 BACKLIGHT_NIGHT_MAGNITUDE_OBJECT = 0.08f; |
113 | const S32 MAX_ACTIVE_OBJECT_QUIET_FRAMES = 40; | 117 | const S32 MAX_ACTIVE_OBJECT_QUIET_FRAMES = 40; |
114 | const S32 MAX_OFFSCREEN_GEOMETRY_CHANGES_PER_FRAME = 10; | 118 | const S32 MAX_OFFSCREEN_GEOMETRY_CHANGES_PER_FRAME = 10; |
115 | 119 | const U32 REFLECTION_MAP_RES = 128; | |
116 | // Guess on the number of visible objects in the scene, used to | ||
117 | // pre-size std::vector and other arrays. JC | ||
118 | const S32 ESTIMATED_VISIBLE_OBJECT_COUNT = 8192; | ||
119 | |||
120 | // If the sum of the X + Y + Z scale of an object exceeds this number, | ||
121 | // it will be considered a potential occluder. For instance, | ||
122 | // a box of size 6 x 6 x 1 has sum 13, which might be an occluder. JC | ||
123 | const F32 OCCLUDE_SCALE_SUM_THRESHOLD = 8.f; | ||
124 | 120 | ||
125 | // Max number of occluders to search for. JC | 121 | // Max number of occluders to search for. JC |
126 | const S32 MAX_OCCLUDER_COUNT = 2; | 122 | const S32 MAX_OCCLUDER_COUNT = 2; |
@@ -128,31 +124,21 @@ const S32 MAX_OCCLUDER_COUNT = 2; | |||
128 | extern S32 gBoxFrame; | 124 | extern S32 gBoxFrame; |
129 | extern BOOL gRenderLightGlows; | 125 | extern BOOL gRenderLightGlows; |
130 | extern BOOL gHideSelectedObjects; | 126 | extern BOOL gHideSelectedObjects; |
127 | extern BOOL gDisplaySwapBuffers; | ||
131 | 128 | ||
132 | BOOL gAvatarBacklight = FALSE; | 129 | // hack counter for rendering a fixed number of frames after toggling |
130 | // fullscreen to work around DEV-5361 | ||
131 | static S32 sDelayedVBOEnable = 0; | ||
133 | 132 | ||
134 | S32 gTrivialAccepts = 0; | 133 | BOOL gAvatarBacklight = FALSE; |
135 | 134 | ||
136 | BOOL gRenderForSelect = FALSE; | 135 | BOOL gRenderForSelect = FALSE; |
137 | 136 | ||
138 | LLPipeline gPipeline; | 137 | LLPipeline gPipeline; |
138 | const LLMatrix4* gGLLastMatrix = NULL; | ||
139 | 139 | ||
140 | //---------------------------------------- | 140 | //---------------------------------------- |
141 | 141 | ||
142 | void stamp(F32 x, F32 y, F32 xs, F32 ys) | ||
143 | { | ||
144 | glBegin(GL_QUADS); | ||
145 | glTexCoord2f(0,0); | ||
146 | glVertex3f(x, y, 0.0f); | ||
147 | glTexCoord2f(1,0); | ||
148 | glVertex3f(x+xs,y, 0.0f); | ||
149 | glTexCoord2f(1,1); | ||
150 | glVertex3f(x+xs,y+ys,0.0f); | ||
151 | glTexCoord2f(0,1); | ||
152 | glVertex3f(x, y+ys,0.0f); | ||
153 | glEnd(); | ||
154 | } | ||
155 | |||
156 | U32 nhpo2(U32 v) | 142 | U32 nhpo2(U32 v) |
157 | { | 143 | { |
158 | U32 r = 1; | 144 | U32 r = 1; |
@@ -162,11 +148,60 @@ U32 nhpo2(U32 v) | |||
162 | return r; | 148 | return r; |
163 | } | 149 | } |
164 | 150 | ||
151 | glh::matrix4f glh_copy_matrix(GLdouble* src) | ||
152 | { | ||
153 | glh::matrix4f ret; | ||
154 | for (U32 i = 0; i < 16; i++) | ||
155 | { | ||
156 | ret.m[i] = (F32) src[i]; | ||
157 | } | ||
158 | return ret; | ||
159 | } | ||
160 | |||
161 | glh::matrix4f glh_get_current_modelview() | ||
162 | { | ||
163 | return glh_copy_matrix(gGLModelView); | ||
164 | } | ||
165 | |||
166 | glh::matrix4f glh_get_current_projection() | ||
167 | { | ||
168 | return glh_copy_matrix(gGLProjection); | ||
169 | } | ||
170 | |||
171 | void glh_copy_matrix(glh::matrix4f& src, GLdouble* dst) | ||
172 | { | ||
173 | for (U32 i = 0; i < 16; i++) | ||
174 | { | ||
175 | dst[i] = src.m[i]; | ||
176 | } | ||
177 | } | ||
178 | |||
179 | void glh_set_current_modelview(glh::matrix4f& mat) | ||
180 | { | ||
181 | glh_copy_matrix(mat, gGLModelView); | ||
182 | } | ||
183 | |||
184 | void glh_set_current_projection(glh::matrix4f& mat) | ||
185 | { | ||
186 | glh_copy_matrix(mat, gGLProjection); | ||
187 | } | ||
188 | |||
189 | glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar) | ||
190 | { | ||
191 | glh::matrix4f ret( | ||
192 | 2.f/(right-left), 0.f, 0.f, -(right+left)/(right-left), | ||
193 | 0.f, 2.f/(top-bottom), 0.f, -(top+bottom)/(top-bottom), | ||
194 | 0.f, 0.f, -2.f/(zfar-znear), -(zfar+znear)/(zfar-znear), | ||
195 | 0.f, 0.f, 0.f, 1.f); | ||
196 | |||
197 | return ret; | ||
198 | } | ||
165 | 199 | ||
166 | //---------------------------------------- | 200 | //---------------------------------------- |
167 | 201 | ||
168 | S32 LLPipeline::sCompiles = 0; | 202 | S32 LLPipeline::sCompiles = 0; |
169 | 203 | ||
204 | BOOL LLPipeline::sDynamicLOD = TRUE; | ||
170 | BOOL LLPipeline::sShowHUDAttachments = TRUE; | 205 | BOOL LLPipeline::sShowHUDAttachments = TRUE; |
171 | BOOL LLPipeline::sRenderPhysicalBeacons = TRUE; | 206 | BOOL LLPipeline::sRenderPhysicalBeacons = TRUE; |
172 | BOOL LLPipeline::sRenderScriptedBeacons = FALSE; | 207 | BOOL LLPipeline::sRenderScriptedBeacons = FALSE; |
@@ -176,32 +211,59 @@ BOOL LLPipeline::sRenderSoundBeacons = FALSE; | |||
176 | BOOL LLPipeline::sRenderBeacons = FALSE; | 211 | BOOL LLPipeline::sRenderBeacons = FALSE; |
177 | BOOL LLPipeline::sRenderHighlight = TRUE; | 212 | BOOL LLPipeline::sRenderHighlight = TRUE; |
178 | BOOL LLPipeline::sRenderProcessBeacons = FALSE; | 213 | BOOL LLPipeline::sRenderProcessBeacons = FALSE; |
179 | BOOL LLPipeline::sUseOcclusion = FALSE; | 214 | S32 LLPipeline::sUseOcclusion = 0; |
215 | BOOL LLPipeline::sFastAlpha = TRUE; | ||
216 | BOOL LLPipeline::sDisableShaders = FALSE; | ||
217 | BOOL LLPipeline::sRenderBump = TRUE; | ||
218 | BOOL LLPipeline::sUseFarClip = TRUE; | ||
180 | BOOL LLPipeline::sSkipUpdate = FALSE; | 219 | BOOL LLPipeline::sSkipUpdate = FALSE; |
181 | BOOL LLPipeline::sDynamicReflections = FALSE; | 220 | BOOL LLPipeline::sDynamicReflections = FALSE; |
221 | BOOL LLPipeline::sWaterReflections = FALSE; | ||
182 | BOOL LLPipeline::sRenderGlow = FALSE; | 222 | BOOL LLPipeline::sRenderGlow = FALSE; |
223 | BOOL LLPipeline::sReflectionRender = FALSE; | ||
224 | BOOL LLPipeline::sImpostorRender = FALSE; | ||
225 | BOOL LLPipeline::sUnderWaterRender = FALSE; | ||
226 | BOOL LLPipeline::sTextureBindTest = FALSE; | ||
227 | BOOL LLPipeline::sRenderFrameTest = FALSE; | ||
228 | |||
229 | static LLCullResult* sCull = NULL; | ||
230 | |||
231 | static const U32 gl_cube_face[] = | ||
232 | { | ||
233 | GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, | ||
234 | GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, | ||
235 | GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, | ||
236 | GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, | ||
237 | GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, | ||
238 | GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, | ||
239 | }; | ||
240 | |||
241 | void validate_framebuffer_object(); | ||
183 | 242 | ||
184 | LLPipeline::LLPipeline() : | 243 | LLPipeline::LLPipeline() : |
185 | mScreenTex(0), | 244 | mCubeBuffer(NULL), |
186 | mGlowMap(0), | 245 | mInitialized(FALSE), |
187 | mGlowBuffer(0), | ||
188 | mVertexShadersEnabled(FALSE), | 246 | mVertexShadersEnabled(FALSE), |
189 | mVertexShadersLoaded(0), | 247 | mVertexShadersLoaded(0), |
190 | mLastRebuildPool(NULL), | 248 | mLastRebuildPool(NULL), |
191 | mAlphaPool(NULL), | 249 | mAlphaPool(NULL), |
192 | mAlphaPoolPostWater(NULL), | ||
193 | mSkyPool(NULL), | 250 | mSkyPool(NULL), |
194 | mStarsPool(NULL), | ||
195 | mTerrainPool(NULL), | 251 | mTerrainPool(NULL), |
196 | mWaterPool(NULL), | 252 | mWaterPool(NULL), |
197 | mGroundPool(NULL), | 253 | mGroundPool(NULL), |
198 | mSimplePool(NULL), | 254 | mSimplePool(NULL), |
255 | mInvisiblePool(NULL), | ||
199 | mGlowPool(NULL), | 256 | mGlowPool(NULL), |
200 | mBumpPool(NULL), | 257 | mBumpPool(NULL), |
258 | mWLSkyPool(NULL), | ||
201 | mLightMask(0), | 259 | mLightMask(0), |
202 | mLightMovingMask(0) | 260 | mLightMovingMask(0) |
203 | { | 261 | { |
204 | mFramebuffer[0] = mFramebuffer[1] = 0; | 262 | //mFramebuffer[0] = mFramebuffer[1] = mFramebuffer[2] = mFramebuffer[3] = 0; |
263 | mBlurCubeBuffer[0] = mBlurCubeBuffer[1] = mBlurCubeBuffer[2] = 0; | ||
264 | mBlurCubeTexture[0] = mBlurCubeTexture[1] = mBlurCubeTexture[2] = 0; | ||
265 | |||
266 | //mDepthbuffer[0] = mDepthbuffer[1] = 0; | ||
205 | mCubeFrameBuffer = 0; | 267 | mCubeFrameBuffer = 0; |
206 | mCubeDepth = 0; | 268 | mCubeDepth = 0; |
207 | } | 269 | } |
@@ -210,27 +272,17 @@ void LLPipeline::init() | |||
210 | { | 272 | { |
211 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 273 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
212 | 274 | ||
275 | sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); | ||
276 | sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); | ||
277 | |||
213 | mInitialized = TRUE; | 278 | mInitialized = TRUE; |
214 | 279 | ||
215 | stop_glerror(); | 280 | stop_glerror(); |
216 | 281 | ||
217 | //create object partitions | ||
218 | //MUST MATCH declaration of eObjectPartitions | ||
219 | mObjectPartition.push_back(new LLVolumePartition()); //PARTITION_VOLUME | ||
220 | mObjectPartition.push_back(new LLBridgePartition()); //PARTITION_BRIDGE | ||
221 | mObjectPartition.push_back(new LLHUDPartition()); //PARTITION_HUD | ||
222 | mObjectPartition.push_back(new LLTerrainPartition()); //PARTITION_TERRAIN | ||
223 | mObjectPartition.push_back(new LLWaterPartition()); //PARTITION_WATER | ||
224 | mObjectPartition.push_back(new LLTreePartition()); //PARTITION_TREE | ||
225 | mObjectPartition.push_back(new LLParticlePartition()); //PARTITION_PARTICLE | ||
226 | mObjectPartition.push_back(new LLCloudPartition()); //PARTITION_CLOUD | ||
227 | mObjectPartition.push_back(new LLGrassPartition()); //PARTITION_GRASS | ||
228 | mObjectPartition.push_back(NULL); //PARTITION_NONE | ||
229 | |||
230 | //create render pass pools | 282 | //create render pass pools |
231 | getPool(LLDrawPool::POOL_ALPHA); | 283 | getPool(LLDrawPool::POOL_ALPHA); |
232 | getPool(LLDrawPool::POOL_ALPHA_POST_WATER); | ||
233 | getPool(LLDrawPool::POOL_SIMPLE); | 284 | getPool(LLDrawPool::POOL_SIMPLE); |
285 | getPool(LLDrawPool::POOL_INVISIBLE); | ||
234 | getPool(LLDrawPool::POOL_BUMP); | 286 | getPool(LLDrawPool::POOL_BUMP); |
235 | getPool(LLDrawPool::POOL_GLOW); | 287 | getPool(LLDrawPool::POOL_GLOW); |
236 | 288 | ||
@@ -239,7 +291,6 @@ void LLPipeline::init() | |||
239 | 291 | ||
240 | mRenderTypeMask = 0xffffffff; // All render types start on | 292 | mRenderTypeMask = 0xffffffff; // All render types start on |
241 | mRenderDebugFeatureMask = 0xffffffff; // All debugging features on | 293 | mRenderDebugFeatureMask = 0xffffffff; // All debugging features on |
242 | mRenderFeatureMask = 0; // All features start off | ||
243 | mRenderDebugMask = 0; // All debug starts off | 294 | mRenderDebugMask = 0; // All debug starts off |
244 | 295 | ||
245 | mOldRenderDebugMask = mRenderDebugMask; | 296 | mOldRenderDebugMask = mRenderDebugMask; |
@@ -249,9 +300,10 @@ void LLPipeline::init() | |||
249 | stop_glerror(); | 300 | stop_glerror(); |
250 | 301 | ||
251 | // Enable features | 302 | // Enable features |
252 | stop_glerror(); | ||
253 | 303 | ||
254 | LLShaderMgr::setShaders(); | 304 | LLShaderMgr::setShaders(); |
305 | |||
306 | stop_glerror(); | ||
255 | } | 307 | } |
256 | 308 | ||
257 | LLPipeline::~LLPipeline() | 309 | LLPipeline::~LLPipeline() |
@@ -261,6 +313,8 @@ LLPipeline::~LLPipeline() | |||
261 | 313 | ||
262 | void LLPipeline::cleanup() | 314 | void LLPipeline::cleanup() |
263 | { | 315 | { |
316 | assertInitialized(); | ||
317 | |||
264 | for(pool_set_t::iterator iter = mPools.begin(); | 318 | for(pool_set_t::iterator iter = mPools.begin(); |
265 | iter != mPools.end(); ) | 319 | iter != mPools.end(); ) |
266 | { | 320 | { |
@@ -295,12 +349,8 @@ void LLPipeline::cleanup() | |||
295 | 349 | ||
296 | delete mAlphaPool; | 350 | delete mAlphaPool; |
297 | mAlphaPool = NULL; | 351 | mAlphaPool = NULL; |
298 | delete mAlphaPoolPostWater; | ||
299 | mAlphaPoolPostWater = NULL; | ||
300 | delete mSkyPool; | 352 | delete mSkyPool; |
301 | mSkyPool = NULL; | 353 | mSkyPool = NULL; |
302 | delete mStarsPool; | ||
303 | mStarsPool = NULL; | ||
304 | delete mTerrainPool; | 354 | delete mTerrainPool; |
305 | mTerrainPool = NULL; | 355 | mTerrainPool = NULL; |
306 | delete mWaterPool; | 356 | delete mWaterPool; |
@@ -309,10 +359,15 @@ void LLPipeline::cleanup() | |||
309 | mGroundPool = NULL; | 359 | mGroundPool = NULL; |
310 | delete mSimplePool; | 360 | delete mSimplePool; |
311 | mSimplePool = NULL; | 361 | mSimplePool = NULL; |
362 | delete mInvisiblePool; | ||
363 | mInvisiblePool = NULL; | ||
312 | delete mGlowPool; | 364 | delete mGlowPool; |
313 | mGlowPool = NULL; | 365 | mGlowPool = NULL; |
314 | delete mBumpPool; | 366 | delete mBumpPool; |
315 | mBumpPool = NULL; | 367 | mBumpPool = NULL; |
368 | // don't delete wl sky pool it was handled above in the for loop | ||
369 | //delete mWLSkyPool; | ||
370 | mWLSkyPool = NULL; | ||
316 | 371 | ||
317 | releaseGLBuffers(); | 372 | releaseGLBuffers(); |
318 | 373 | ||
@@ -321,21 +376,9 @@ void LLPipeline::cleanup() | |||
321 | mFaceSelectImagep = NULL; | 376 | mFaceSelectImagep = NULL; |
322 | mAlphaSizzleImagep = NULL; | 377 | mAlphaSizzleImagep = NULL; |
323 | 378 | ||
324 | for (S32 i = 0; i < NUM_PARTITIONS-1; i++) | ||
325 | { | ||
326 | delete mObjectPartition[i]; | ||
327 | } | ||
328 | mObjectPartition.clear(); | ||
329 | |||
330 | mVisibleList.clear(); | ||
331 | mVisibleGroups.clear(); | ||
332 | mDrawableGroups.clear(); | ||
333 | mActiveGroups.clear(); | ||
334 | mVisibleBridge.clear(); | ||
335 | mMovedBridge.clear(); | 379 | mMovedBridge.clear(); |
336 | mOccludedBridge.clear(); | 380 | |
337 | mAlphaGroups.clear(); | 381 | mInitialized = FALSE; |
338 | clearRenderMap(); | ||
339 | } | 382 | } |
340 | 383 | ||
341 | //============================================================================ | 384 | //============================================================================ |
@@ -345,39 +388,47 @@ void LLPipeline::destroyGL() | |||
345 | stop_glerror(); | 388 | stop_glerror(); |
346 | unloadShaders(); | 389 | unloadShaders(); |
347 | mHighlightFaces.clear(); | 390 | mHighlightFaces.clear(); |
348 | mVisibleList.clear(); | 391 | |
349 | mVisibleGroups.clear(); | 392 | resetDrawOrders(); |
350 | mDrawableGroups.clear(); | 393 | |
351 | mActiveGroups.clear(); | ||
352 | mVisibleBridge.clear(); | ||
353 | mOccludedBridge.clear(); | ||
354 | mAlphaGroups.clear(); | ||
355 | clearRenderMap(); | ||
356 | resetVertexBuffers(); | 394 | resetVertexBuffers(); |
357 | 395 | ||
358 | releaseGLBuffers(); | 396 | releaseGLBuffers(); |
359 | } | ||
360 | 397 | ||
361 | void LLPipeline::releaseGLBuffers() | 398 | if (LLVertexBuffer::sEnableVBOs) |
362 | { | ||
363 | if (mGlowMap) | ||
364 | { | 399 | { |
365 | glDeleteTextures(1, &mGlowMap); | 400 | // render 30 frames after switching to work around DEV-5361 |
366 | mGlowMap = 0; | 401 | sDelayedVBOEnable = 30; |
402 | LLVertexBuffer::sEnableVBOs = FALSE; | ||
367 | } | 403 | } |
404 | } | ||
368 | 405 | ||
369 | if (mGlowBuffer) | 406 | void LLPipeline::resizeScreenTexture() |
407 | { | ||
408 | if (gPipeline.canUseVertexShaders() && assertInitialized()) | ||
370 | { | 409 | { |
371 | glDeleteTextures(1, &mGlowBuffer); | 410 | GLuint resX = gViewerWindow->getWindowDisplayWidth(); |
372 | mGlowBuffer = 0; | 411 | GLuint resY = gViewerWindow->getWindowDisplayHeight(); |
373 | } | 412 | |
413 | U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor"); | ||
414 | if (res_mod > 1) | ||
415 | { | ||
416 | resX /= res_mod; | ||
417 | resY /= res_mod; | ||
418 | } | ||
419 | |||
420 | mScreen.release(); | ||
421 | mScreen.allocate(resX, resY, GL_RGBA, TRUE, GL_TEXTURE_RECTANGLE_ARB); | ||
374 | 422 | ||
375 | if (mScreenTex) | 423 | llinfos << "RESIZED SCREEN TEXTURE: " << resX << "x" << resY << llendl; |
376 | { | ||
377 | glDeleteTextures(1, &mScreenTex); | ||
378 | mScreenTex = 0; | ||
379 | } | 424 | } |
425 | } | ||
380 | 426 | ||
427 | |||
428 | void LLPipeline::releaseGLBuffers() | ||
429 | { | ||
430 | assertInitialized(); | ||
431 | |||
381 | if (mCubeBuffer) | 432 | if (mCubeBuffer) |
382 | { | 433 | { |
383 | mCubeBuffer = NULL; | 434 | mCubeBuffer = NULL; |
@@ -390,27 +441,152 @@ void LLPipeline::releaseGLBuffers() | |||
390 | mCubeDepth = mCubeFrameBuffer = 0; | 441 | mCubeDepth = mCubeFrameBuffer = 0; |
391 | } | 442 | } |
392 | 443 | ||
393 | if (mFramebuffer[0]) | 444 | /*if (mFramebuffer[0]) |
445 | { | ||
446 | glDeleteFramebuffersEXT(4, mFramebuffer); | ||
447 | mFramebuffer[0] = mFramebuffer[1] = mFramebuffer[2] = mFramebuffer[3] = 0; | ||
448 | }*/ | ||
449 | |||
450 | if (mBlurCubeBuffer[0]) | ||
451 | { | ||
452 | glDeleteFramebuffersEXT(3, mBlurCubeBuffer); | ||
453 | mBlurCubeBuffer[0] = mBlurCubeBuffer[1] = mBlurCubeBuffer[2] = 0; | ||
454 | } | ||
455 | |||
456 | if (mBlurCubeTexture[0]) | ||
394 | { | 457 | { |
395 | glDeleteFramebuffersEXT(2, mFramebuffer); | 458 | glDeleteTextures(3, mBlurCubeTexture); |
396 | mFramebuffer[0] = mFramebuffer[1] = 0; | 459 | mBlurCubeTexture[0] = mBlurCubeTexture[1] = mBlurCubeTexture[2] = 0; |
397 | } | 460 | } |
461 | |||
462 | mWaterRef.release(); | ||
463 | mWaterDis.release(); | ||
464 | mScreen.release(); | ||
465 | |||
466 | for (U32 i = 0; i < 3; i++) | ||
467 | { | ||
468 | mGlow[i].release(); | ||
469 | } | ||
470 | |||
471 | LLVOAvatar::resetImpostors(); | ||
472 | } | ||
473 | |||
474 | void LLPipeline::createGLBuffers() | ||
475 | { | ||
476 | assertInitialized(); | ||
477 | |||
478 | if (LLPipeline::sDynamicReflections || | ||
479 | LLPipeline::sWaterReflections) | ||
480 | { //water reflection texture | ||
481 | U32 res = (U32) gSavedSettings.getS32("RenderWaterRefResolution"); | ||
482 | |||
483 | mWaterRef.allocate(res,res,GL_RGBA,TRUE); | ||
484 | mWaterDis.allocate(res,res,GL_RGBA,TRUE); | ||
485 | |||
486 | if (LLPipeline::sDynamicReflections) | ||
487 | { | ||
488 | //reflection map generation buffers | ||
489 | if (mCubeFrameBuffer == 0) | ||
490 | { | ||
491 | glGenFramebuffersEXT(1, &mCubeFrameBuffer); | ||
492 | glGenRenderbuffersEXT(1, &mCubeDepth); | ||
493 | |||
494 | U32 res = REFLECTION_MAP_RES; | ||
495 | |||
496 | glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mCubeDepth); | ||
497 | |||
498 | glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,GL_DEPTH_COMPONENT,res,res); | ||
499 | |||
500 | glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); | ||
501 | } | ||
502 | |||
503 | if (mCubeBuffer.isNull()) | ||
504 | { | ||
505 | res = 128; | ||
506 | mCubeBuffer = new LLCubeMap(); | ||
507 | mCubeBuffer->initGL(); | ||
508 | glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mCubeBuffer->getGLName()); | ||
509 | glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
510 | glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
511 | glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
512 | glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
513 | |||
514 | for (U32 i = 0; i < 6; i++) | ||
515 | { | ||
516 | glTexImage2D(gl_cube_face[i], 0, GL_RGBA, res, res, 0, GL_RGBA, GL_FLOAT, NULL); | ||
517 | } | ||
518 | } | ||
519 | |||
520 | if (mBlurCubeBuffer[0] == 0) | ||
521 | { | ||
522 | glGenFramebuffersEXT(3, mBlurCubeBuffer); | ||
523 | } | ||
524 | |||
525 | if (mBlurCubeTexture[0] == 0) | ||
526 | { | ||
527 | glGenTextures(3, mBlurCubeTexture); | ||
528 | } | ||
529 | |||
530 | res = (U32) gSavedSettings.getS32("RenderReflectionRes"); | ||
531 | |||
532 | for (U32 j = 0; j < 3; j++) | ||
533 | { | ||
534 | glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mBlurCubeTexture[j]); | ||
535 | glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
536 | glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
537 | glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
538 | glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
539 | |||
540 | for (U32 i = 0; i < 6; i++) | ||
541 | { | ||
542 | glTexImage2D(gl_cube_face[i], 0, GL_RGBA, res, res, 0, GL_RGBA, GL_FLOAT, NULL); | ||
543 | } | ||
544 | } | ||
545 | } | ||
546 | } | ||
547 | |||
548 | stop_glerror(); | ||
549 | |||
550 | if (LLPipeline::sRenderGlow) | ||
551 | { //screen space glow buffers | ||
552 | const U32 glow_res = llmax(1, | ||
553 | llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow"))); | ||
554 | |||
555 | for (U32 i = 0; i < 3; i++) | ||
556 | { | ||
557 | mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE); | ||
558 | } | ||
559 | } | ||
560 | |||
561 | GLuint resX = gViewerWindow->getWindowDisplayWidth(); | ||
562 | GLuint resY = gViewerWindow->getWindowDisplayHeight(); | ||
563 | |||
564 | mScreen.allocate(resX, resY, GL_RGBA, TRUE, GL_TEXTURE_RECTANGLE_ARB); | ||
398 | } | 565 | } |
399 | 566 | ||
400 | void LLPipeline::restoreGL() | 567 | void LLPipeline::restoreGL() |
401 | { | 568 | { |
402 | resetVertexBuffers(); | 569 | assertInitialized(); |
403 | 570 | ||
404 | if (mVertexShadersEnabled) | 571 | if (mVertexShadersEnabled) |
405 | { | 572 | { |
406 | LLShaderMgr::setShaders(); | 573 | LLShaderMgr::setShaders(); |
407 | } | 574 | } |
408 | 575 | ||
409 | for (U32 i = 0; i < mObjectPartition.size()-1; i++) | 576 | if (gWorldp) |
410 | { | 577 | { |
411 | if (mObjectPartition[i]) | 578 | for (LLWorld::region_list_t::iterator iter = gWorldp->getRegionList().begin(); |
579 | iter != gWorldp->getRegionList().end(); ++iter) | ||
412 | { | 580 | { |
413 | mObjectPartition[i]->restoreGL(); | 581 | LLViewerRegion* region = *iter; |
582 | for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) | ||
583 | { | ||
584 | LLSpatialPartition* part = region->getSpatialPartition(i); | ||
585 | if (part) | ||
586 | { | ||
587 | part->restoreGL(); | ||
588 | } | ||
589 | } | ||
414 | } | 590 | } |
415 | } | 591 | } |
416 | } | 592 | } |
@@ -421,7 +597,7 @@ BOOL LLPipeline::canUseVertexShaders() | |||
421 | if (!gGLManager.mHasVertexShader || | 597 | if (!gGLManager.mHasVertexShader || |
422 | !gGLManager.mHasFragmentShader || | 598 | !gGLManager.mHasFragmentShader || |
423 | !gFeatureManagerp->isFeatureAvailable("VertexShaderEnable") || | 599 | !gFeatureManagerp->isFeatureAvailable("VertexShaderEnable") || |
424 | mVertexShadersLoaded == -1) | 600 | (assertInitialized() && mVertexShadersLoaded != 1) ) |
425 | { | 601 | { |
426 | return FALSE; | 602 | return FALSE; |
427 | } | 603 | } |
@@ -431,12 +607,31 @@ BOOL LLPipeline::canUseVertexShaders() | |||
431 | } | 607 | } |
432 | } | 608 | } |
433 | 609 | ||
610 | BOOL LLPipeline::canUseWindLightShaders() const | ||
611 | { | ||
612 | return (!LLPipeline::sDisableShaders && | ||
613 | gWLSkyProgram.mProgramObject != 0 && | ||
614 | LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_WINDLIGHT) > 1); | ||
615 | } | ||
616 | |||
617 | BOOL LLPipeline::canUseWindLightShadersOnObjects() const | ||
618 | { | ||
619 | return (canUseWindLightShaders() | ||
620 | && LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_OBJECT) > 0); | ||
621 | } | ||
622 | |||
434 | void LLPipeline::unloadShaders() | 623 | void LLPipeline::unloadShaders() |
435 | { | 624 | { |
436 | LLShaderMgr::unloadShaders(); | 625 | LLShaderMgr::unloadShaders(); |
626 | |||
437 | mVertexShadersLoaded = 0; | 627 | mVertexShadersLoaded = 0; |
438 | } | 628 | } |
439 | 629 | ||
630 | void LLPipeline::assertInitializedDoError() | ||
631 | { | ||
632 | llerrs << "LLPipeline used when uninitialized." << llendl; | ||
633 | } | ||
634 | |||
440 | //============================================================================ | 635 | //============================================================================ |
441 | 636 | ||
442 | void LLPipeline::enableShadows(const BOOL enable_shadows) | 637 | void LLPipeline::enableShadows(const BOOL enable_shadows) |
@@ -458,6 +653,8 @@ S32 LLPipeline::getMaxLightingDetail() const | |||
458 | 653 | ||
459 | S32 LLPipeline::setLightingDetail(S32 level) | 654 | S32 LLPipeline::setLightingDetail(S32 level) |
460 | { | 655 | { |
656 | assertInitialized(); | ||
657 | |||
461 | if (level < 0) | 658 | if (level < 0) |
462 | { | 659 | { |
463 | level = gSavedSettings.getS32("RenderLightingDetail"); | 660 | level = gSavedSettings.getS32("RenderLightingDetail"); |
@@ -466,10 +663,7 @@ S32 LLPipeline::setLightingDetail(S32 level) | |||
466 | if (level != mLightingDetail) | 663 | if (level != mLightingDetail) |
467 | { | 664 | { |
468 | gSavedSettings.setS32("RenderLightingDetail", level); | 665 | gSavedSettings.setS32("RenderLightingDetail", level); |
469 | if (level >= 2) | 666 | |
470 | { | ||
471 | gObjectList.relightAllObjects(); | ||
472 | } | ||
473 | mLightingDetail = level; | 667 | mLightingDetail = level; |
474 | 668 | ||
475 | if (mVertexShadersLoaded == 1) | 669 | if (mVertexShadersLoaded == 1) |
@@ -487,9 +681,9 @@ public: | |||
487 | 681 | ||
488 | LLOctreeDirtyTexture(const std::set<LLViewerImage*>& textures) : mTextures(textures) { } | 682 | LLOctreeDirtyTexture(const std::set<LLViewerImage*>& textures) : mTextures(textures) { } |
489 | 683 | ||
490 | virtual void visit(const LLOctreeState<LLDrawable>* state) | 684 | virtual void visit(const LLOctreeNode<LLDrawable>* node) |
491 | { | 685 | { |
492 | LLSpatialGroup* group = (LLSpatialGroup*) state->getNode()->getListener(0); | 686 | LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); |
493 | 687 | ||
494 | if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && !group->getData().empty()) | 688 | if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && !group->getData().empty()) |
495 | { | 689 | { |
@@ -517,6 +711,8 @@ public: | |||
517 | // Called when a texture changes # of channels (causes faces to move to alpha pool) | 711 | // Called when a texture changes # of channels (causes faces to move to alpha pool) |
518 | void LLPipeline::dirtyPoolObjectTextures(const std::set<LLViewerImage*>& textures) | 712 | void LLPipeline::dirtyPoolObjectTextures(const std::set<LLViewerImage*>& textures) |
519 | { | 713 | { |
714 | assertInitialized(); | ||
715 | |||
520 | // *TODO: This is inefficient and causes frame spikes; need a better way to do this | 716 | // *TODO: This is inefficient and causes frame spikes; need a better way to do this |
521 | // Most of the time is spent in dirty.traverse. | 717 | // Most of the time is spent in dirty.traverse. |
522 | 718 | ||
@@ -529,18 +725,29 @@ void LLPipeline::dirtyPoolObjectTextures(const std::set<LLViewerImage*>& texture | |||
529 | } | 725 | } |
530 | } | 726 | } |
531 | 727 | ||
532 | LLOctreeDirtyTexture dirty(textures); | 728 | if (gWorldp) |
533 | for (U32 i = 0; i < mObjectPartition.size(); i++) | ||
534 | { | 729 | { |
535 | if (mObjectPartition[i]) | 730 | LLOctreeDirtyTexture dirty(textures); |
731 | for (LLWorld::region_list_t::iterator iter = gWorldp->getRegionList().begin(); | ||
732 | iter != gWorldp->getRegionList().end(); ++iter) | ||
536 | { | 733 | { |
537 | dirty.traverse(mObjectPartition[i]->mOctree); | 734 | LLViewerRegion* region = *iter; |
735 | for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) | ||
736 | { | ||
737 | LLSpatialPartition* part = region->getSpatialPartition(i); | ||
738 | if (part) | ||
739 | { | ||
740 | dirty.traverse(part->mOctree); | ||
741 | } | ||
742 | } | ||
538 | } | 743 | } |
539 | } | 744 | } |
540 | } | 745 | } |
541 | 746 | ||
542 | LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) | 747 | LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) |
543 | { | 748 | { |
749 | assertInitialized(); | ||
750 | |||
544 | LLDrawPool *poolp = NULL; | 751 | LLDrawPool *poolp = NULL; |
545 | switch( type ) | 752 | switch( type ) |
546 | { | 753 | { |
@@ -548,6 +755,10 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) | |||
548 | poolp = mSimplePool; | 755 | poolp = mSimplePool; |
549 | break; | 756 | break; |
550 | 757 | ||
758 | case LLDrawPool::POOL_INVISIBLE: | ||
759 | poolp = mInvisiblePool; | ||
760 | break; | ||
761 | |||
551 | case LLDrawPool::POOL_GLOW: | 762 | case LLDrawPool::POOL_GLOW: |
552 | poolp = mGlowPool; | 763 | poolp = mGlowPool; |
553 | break; | 764 | break; |
@@ -568,10 +779,6 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) | |||
568 | poolp = mAlphaPool; | 779 | poolp = mAlphaPool; |
569 | break; | 780 | break; |
570 | 781 | ||
571 | case LLDrawPool::POOL_ALPHA_POST_WATER: | ||
572 | poolp = mAlphaPoolPostWater; | ||
573 | break; | ||
574 | |||
575 | case LLDrawPool::POOL_AVATAR: | 782 | case LLDrawPool::POOL_AVATAR: |
576 | break; // Do nothing | 783 | break; // Do nothing |
577 | 784 | ||
@@ -579,10 +786,6 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) | |||
579 | poolp = mSkyPool; | 786 | poolp = mSkyPool; |
580 | break; | 787 | break; |
581 | 788 | ||
582 | case LLDrawPool::POOL_STARS: | ||
583 | poolp = mStarsPool; | ||
584 | break; | ||
585 | |||
586 | case LLDrawPool::POOL_WATER: | 789 | case LLDrawPool::POOL_WATER: |
587 | poolp = mWaterPool; | 790 | poolp = mWaterPool; |
588 | break; | 791 | break; |
@@ -591,6 +794,10 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) | |||
591 | poolp = mGroundPool; | 794 | poolp = mGroundPool; |
592 | break; | 795 | break; |
593 | 796 | ||
797 | case LLDrawPool::POOL_WL_SKY: | ||
798 | poolp = mWLSkyPool; | ||
799 | break; | ||
800 | |||
594 | default: | 801 | default: |
595 | llassert(0); | 802 | llassert(0); |
596 | llerrs << "Invalid Pool Type in LLPipeline::findPool() type=" << type << llendl; | 803 | llerrs << "Invalid Pool Type in LLPipeline::findPool() type=" << type << llendl; |
@@ -638,7 +845,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerImage* image | |||
638 | bool alpha = te->getColor().mV[3] < 0.999f; | 845 | bool alpha = te->getColor().mV[3] < 0.999f; |
639 | if (imagep) | 846 | if (imagep) |
640 | { | 847 | { |
641 | alpha = alpha || (imagep->getComponents() == 4) || (imagep->getComponents() == 2); | 848 | alpha = alpha || (imagep->getComponents() == 4 && ! imagep->mIsMediaTexture) || (imagep->getComponents() == 2); |
642 | } | 849 | } |
643 | 850 | ||
644 | if (alpha) | 851 | if (alpha) |
@@ -659,6 +866,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerImage* image | |||
659 | void LLPipeline::addPool(LLDrawPool *new_poolp) | 866 | void LLPipeline::addPool(LLDrawPool *new_poolp) |
660 | { | 867 | { |
661 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 868 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
869 | assertInitialized(); | ||
662 | mPools.insert(new_poolp); | 870 | mPools.insert(new_poolp); |
663 | addToQuickLookup( new_poolp ); | 871 | addToQuickLookup( new_poolp ); |
664 | } | 872 | } |
@@ -686,6 +894,8 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) | |||
686 | { | 894 | { |
687 | LLFastTimer t(LLFastTimer::FTM_PIPELINE); | 895 | LLFastTimer t(LLFastTimer::FTM_PIPELINE); |
688 | 896 | ||
897 | assertInitialized(); | ||
898 | |||
689 | LLPointer<LLDrawable> drawablep = drawable; // make sure this doesn't get deleted before we are done | 899 | LLPointer<LLDrawable> drawablep = drawable; // make sure this doesn't get deleted before we are done |
690 | 900 | ||
691 | // Based on flags, remove the drawable from the queues that it's on. | 901 | // Based on flags, remove the drawable from the queues that it's on. |
@@ -721,8 +931,13 @@ U32 LLPipeline::addObject(LLViewerObject *vobj) | |||
721 | return 0; | 931 | return 0; |
722 | } | 932 | } |
723 | 933 | ||
724 | LLDrawable *drawablep = vobj->createDrawable(this); | 934 | LLDrawable* drawablep = vobj->mDrawable; |
725 | 935 | ||
936 | if (!drawablep) | ||
937 | { | ||
938 | drawablep = vobj->createDrawable(this); | ||
939 | } | ||
940 | |||
726 | llassert(drawablep); | 941 | llassert(drawablep); |
727 | 942 | ||
728 | if (vobj->getParent()) | 943 | if (vobj->getParent()) |
@@ -742,8 +957,14 @@ U32 LLPipeline::addObject(LLViewerObject *vobj) | |||
742 | 957 | ||
743 | void LLPipeline::resetFrameStats() | 958 | void LLPipeline::resetFrameStats() |
744 | { | 959 | { |
960 | assertInitialized(); | ||
961 | |||
745 | mTrianglesDrawnStat.addValue(mTrianglesDrawn/1000.f); | 962 | mTrianglesDrawnStat.addValue(mTrianglesDrawn/1000.f); |
746 | 963 | ||
964 | if (mBatchCount > 0) | ||
965 | { | ||
966 | mMeanBatchSize = gPipeline.mTrianglesDrawn/gPipeline.mBatchCount; | ||
967 | } | ||
747 | mTrianglesDrawn = 0; | 968 | mTrianglesDrawn = 0; |
748 | sCompiles = 0; | 969 | sCompiles = 0; |
749 | mVerticesRelit = 0; | 970 | mVerticesRelit = 0; |
@@ -775,6 +996,9 @@ void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep) | |||
775 | { | 996 | { |
776 | return; | 997 | return; |
777 | } | 998 | } |
999 | |||
1000 | assertInitialized(); | ||
1001 | |||
778 | // update drawable now | 1002 | // update drawable now |
779 | drawablep->clearState(LLDrawable::MOVE_UNDAMPED); // force to DAMPED | 1003 | drawablep->clearState(LLDrawable::MOVE_UNDAMPED); // force to DAMPED |
780 | drawablep->updateMove(); // returns done | 1004 | drawablep->updateMove(); // returns done |
@@ -801,6 +1025,9 @@ void LLPipeline::updateMoveNormalAsync(LLDrawable* drawablep) | |||
801 | { | 1025 | { |
802 | return; | 1026 | return; |
803 | } | 1027 | } |
1028 | |||
1029 | assertInitialized(); | ||
1030 | |||
804 | // update drawable now | 1031 | // update drawable now |
805 | drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED | 1032 | drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED |
806 | drawablep->updateMove(); | 1033 | drawablep->updateMove(); |
@@ -836,7 +1063,7 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list) | |||
836 | 1063 | ||
837 | void LLPipeline::updateMove() | 1064 | void LLPipeline::updateMove() |
838 | { | 1065 | { |
839 | //LLFastTimer t(LLFastTimer::FTM_UPDATE_MOVE); | 1066 | LLFastTimer t(LLFastTimer::FTM_UPDATE_MOVE); |
840 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 1067 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
841 | 1068 | ||
842 | if (gSavedSettings.getBOOL("FreezeTime")) | 1069 | if (gSavedSettings.getBOOL("FreezeTime")) |
@@ -844,6 +1071,8 @@ void LLPipeline::updateMove() | |||
844 | return; | 1071 | return; |
845 | } | 1072 | } |
846 | 1073 | ||
1074 | assertInitialized(); | ||
1075 | |||
847 | for (LLDrawable::drawable_set_t::iterator iter = mRetexturedList.begin(); | 1076 | for (LLDrawable::drawable_set_t::iterator iter = mRetexturedList.begin(); |
848 | iter != mRetexturedList.end(); ++iter) | 1077 | iter != mRetexturedList.end(); ++iter) |
849 | { | 1078 | { |
@@ -881,11 +1110,18 @@ void LLPipeline::updateMove() | |||
881 | //balance octrees | 1110 | //balance octrees |
882 | { | 1111 | { |
883 | LLFastTimer ot(LLFastTimer::FTM_OCTREE_BALANCE); | 1112 | LLFastTimer ot(LLFastTimer::FTM_OCTREE_BALANCE); |
884 | for (U32 i = 0; i < mObjectPartition.size()-1; i++) | 1113 | |
1114 | for (LLWorld::region_list_t::iterator iter = gWorldp->getRegionList().begin(); | ||
1115 | iter != gWorldp->getRegionList().end(); ++iter) | ||
885 | { | 1116 | { |
886 | if (mObjectPartition[i]) | 1117 | LLViewerRegion* region = *iter; |
1118 | for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) | ||
887 | { | 1119 | { |
888 | mObjectPartition[i]->mOctree->balance(); | 1120 | LLSpatialPartition* part = region->getSpatialPartition(i); |
1121 | if (part) | ||
1122 | { | ||
1123 | part->mOctree->balance(); | ||
1124 | } | ||
889 | } | 1125 | } |
890 | } | 1126 | } |
891 | } | 1127 | } |
@@ -915,35 +1151,80 @@ F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera | |||
915 | return radius*radius * 3.14159f; | 1151 | return radius*radius * 3.14159f; |
916 | } | 1152 | } |
917 | 1153 | ||
918 | void LLPipeline::updateCull(LLCamera& camera) | 1154 | void LLPipeline::grabReferences(LLCullResult& result) |
1155 | { | ||
1156 | sCull = &result; | ||
1157 | } | ||
1158 | |||
1159 | void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip) | ||
919 | { | 1160 | { |
920 | LLFastTimer t(LLFastTimer::FTM_CULL); | 1161 | LLFastTimer t(LLFastTimer::FTM_CULL); |
921 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 1162 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
922 | 1163 | ||
923 | mVisibleList.clear(); | 1164 | grabReferences(result); |
924 | mVisibleGroups.clear(); | 1165 | |
925 | mDrawableGroups.clear(); | 1166 | sCull->clear(); |
926 | mActiveGroups.clear(); | 1167 | |
927 | gTrivialAccepts = 0; | 1168 | BOOL to_texture = LLPipeline::sUseOcclusion > 1 && |
928 | mVisibleBridge.clear(); | 1169 | !hasRenderType(LLPipeline::RENDER_TYPE_HUD) && |
1170 | !sReflectionRender && | ||
1171 | gPipeline.canUseVertexShaders() && | ||
1172 | sRenderGlow && | ||
1173 | gGLManager.mHasFramebufferObject; | ||
929 | 1174 | ||
930 | processOcclusion(camera); | 1175 | if (to_texture) |
1176 | { | ||
1177 | mScreen.bindTarget(); | ||
1178 | } | ||
1179 | |||
1180 | glPushMatrix(); | ||
1181 | gGLLastMatrix = NULL; | ||
1182 | glLoadMatrixd(gGLLastModelView); | ||
931 | 1183 | ||
932 | for (U32 i = 0; i < mObjectPartition.size(); i++) | 1184 | LLVertexBuffer::unbind(); |
933 | { | 1185 | LLGLDisable blend(GL_BLEND); |
934 | if (mObjectPartition[i] && hasRenderType(mObjectPartition[i]->mDrawableType)) | 1186 | LLGLDisable test(GL_ALPHA_TEST); |
1187 | LLViewerImage::unbindTexture(0, GL_TEXTURE_2D); | ||
1188 | |||
1189 | glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); | ||
1190 | LLGLDepthTest depth(GL_TRUE, GL_FALSE); | ||
1191 | |||
1192 | for (LLWorld::region_list_t::iterator iter = gWorldp->getRegionList().begin(); | ||
1193 | iter != gWorldp->getRegionList().end(); ++iter) | ||
1194 | { | ||
1195 | LLViewerRegion* region = *iter; | ||
1196 | if (water_clip != 0) | ||
1197 | { | ||
1198 | LLPlane plane(LLVector3(0,0, (F32) -water_clip), (F32) water_clip*region->getWaterHeight()); | ||
1199 | camera.setUserClipPlane(plane); | ||
1200 | } | ||
1201 | else | ||
935 | { | 1202 | { |
936 | mObjectPartition[i]->cull(camera); | 1203 | camera.disableUserClipPlane(); |
1204 | } | ||
1205 | |||
1206 | for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) | ||
1207 | { | ||
1208 | LLSpatialPartition* part = region->getSpatialPartition(i); | ||
1209 | if (part) | ||
1210 | { | ||
1211 | if (hasRenderType(part->mDrawableType)) | ||
1212 | { | ||
1213 | part->cull(camera); | ||
1214 | } | ||
1215 | } | ||
937 | } | 1216 | } |
938 | } | 1217 | } |
939 | 1218 | ||
1219 | camera.disableUserClipPlane(); | ||
1220 | |||
940 | if (gSky.mVOSkyp.notNull() && gSky.mVOSkyp->mDrawable.notNull()) | 1221 | if (gSky.mVOSkyp.notNull() && gSky.mVOSkyp->mDrawable.notNull()) |
941 | { | 1222 | { |
942 | // Hack for sky - always visible. | 1223 | // Hack for sky - always visible. |
943 | if (hasRenderType(LLPipeline::RENDER_TYPE_SKY)) | 1224 | if (hasRenderType(LLPipeline::RENDER_TYPE_SKY)) |
944 | { | 1225 | { |
945 | gSky.mVOSkyp->mDrawable->setVisible(camera); | 1226 | gSky.mVOSkyp->mDrawable->setVisible(camera); |
946 | mVisibleList.push_back(gSky.mVOSkyp->mDrawable); | 1227 | sCull->pushDrawable(gSky.mVOSkyp->mDrawable); |
947 | gSky.updateCull(); | 1228 | gSky.updateCull(); |
948 | stop_glerror(); | 1229 | stop_glerror(); |
949 | } | 1230 | } |
@@ -953,20 +1234,35 @@ void LLPipeline::updateCull(LLCamera& camera) | |||
953 | llinfos << "No sky drawable!" << llendl; | 1234 | llinfos << "No sky drawable!" << llendl; |
954 | } | 1235 | } |
955 | 1236 | ||
956 | if (hasRenderType(LLPipeline::RENDER_TYPE_GROUND) && gSky.mVOGroundp.notNull() && gSky.mVOGroundp->mDrawable.notNull()) | 1237 | if (hasRenderType(LLPipeline::RENDER_TYPE_GROUND) && |
1238 | !gPipeline.canUseWindLightShaders() && | ||
1239 | gSky.mVOGroundp.notNull() && | ||
1240 | gSky.mVOGroundp->mDrawable.notNull() && | ||
1241 | !LLPipeline::sWaterReflections) | ||
957 | { | 1242 | { |
958 | gSky.mVOGroundp->mDrawable->setVisible(camera); | 1243 | gSky.mVOGroundp->mDrawable->setVisible(camera); |
959 | mVisibleList.push_back(gSky.mVOGroundp->mDrawable); | 1244 | sCull->pushDrawable(gSky.mVOGroundp->mDrawable); |
1245 | } | ||
1246 | |||
1247 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); | ||
1248 | glPopMatrix(); | ||
1249 | |||
1250 | if (to_texture) | ||
1251 | { | ||
1252 | mScreen.flush(); | ||
1253 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); | ||
960 | } | 1254 | } |
961 | } | 1255 | } |
962 | 1256 | ||
963 | void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera, BOOL active) | 1257 | void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) |
964 | { | 1258 | { |
965 | if (group->getData().empty()) | 1259 | if (group->getData().empty()) |
966 | { | 1260 | { |
967 | return; | 1261 | return; |
968 | } | 1262 | } |
969 | 1263 | ||
1264 | group->setVisible(); | ||
1265 | |||
970 | if (!sSkipUpdate) | 1266 | if (!sSkipUpdate) |
971 | { | 1267 | { |
972 | group->updateDistance(camera); | 1268 | group->updateDistance(camera); |
@@ -978,29 +1274,39 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera, BOOL act | |||
978 | { | 1274 | { |
979 | return; | 1275 | return; |
980 | } | 1276 | } |
1277 | |||
1278 | assertInitialized(); | ||
981 | 1279 | ||
982 | group->mLastRenderTime = gFrameTimeSeconds; | ||
983 | if (!group->mSpatialPartition->mRenderByGroup) | 1280 | if (!group->mSpatialPartition->mRenderByGroup) |
984 | { //render by drawable | 1281 | { //render by drawable |
985 | mDrawableGroups.push_back(group); | 1282 | sCull->pushDrawableGroup(group); |
986 | for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) | ||
987 | { | ||
988 | markVisible(*i, camera); | ||
989 | } | ||
990 | } | 1283 | } |
991 | else | 1284 | else |
992 | { //render by group | 1285 | { //render by group |
993 | if (active) | 1286 | sCull->pushVisibleGroup(group); |
994 | { | 1287 | } |
995 | mActiveGroups.push_back(group); | 1288 | |
996 | } | 1289 | mNumVisibleNodes++; |
997 | else | 1290 | } |
998 | { | 1291 | |
999 | mVisibleGroups.push_back(group); | 1292 | void LLPipeline::markOccluder(LLSpatialGroup* group) |
1000 | for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i) | 1293 | { |
1294 | if (sUseOcclusion > 1 && group && !group->isState(LLSpatialGroup::ACTIVE_OCCLUSION)) | ||
1295 | { | ||
1296 | LLSpatialGroup* parent = group->getParent(); | ||
1297 | |||
1298 | if (!parent || !parent->isState(LLSpatialGroup::OCCLUDED)) | ||
1299 | { //only mark top most occluders as active occlusion | ||
1300 | sCull->pushOcclusionGroup(group); | ||
1301 | group->setState(LLSpatialGroup::ACTIVE_OCCLUSION); | ||
1302 | |||
1303 | if (parent && | ||
1304 | !parent->isState(LLSpatialGroup::ACTIVE_OCCLUSION) && | ||
1305 | parent->getElementCount() == 0 && | ||
1306 | parent->needsUpdate()) | ||
1001 | { | 1307 | { |
1002 | LLSpatialBridge* bridge = *i; | 1308 | sCull->pushOcclusionGroup(group); |
1003 | markVisible(bridge, camera); | 1309 | parent->setState(LLSpatialGroup::ACTIVE_OCCLUSION); |
1004 | } | 1310 | } |
1005 | } | 1311 | } |
1006 | } | 1312 | } |
@@ -1008,38 +1314,37 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera, BOOL act | |||
1008 | 1314 | ||
1009 | void LLPipeline::doOcclusion(LLCamera& camera) | 1315 | void LLPipeline::doOcclusion(LLCamera& camera) |
1010 | { | 1316 | { |
1011 | if (sUseOcclusion) | 1317 | LLVertexBuffer::unbind(); |
1318 | if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) | ||
1012 | { | 1319 | { |
1013 | for (U32 i = 0; i < mObjectPartition.size(); i++) | 1320 | glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE); |
1014 | { | 1321 | } |
1015 | if (mObjectPartition[i] && hasRenderType(mObjectPartition[i]->mDrawableType)) | 1322 | else |
1016 | { | 1323 | { |
1017 | mObjectPartition[i]->doOcclusion(&camera); | 1324 | glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); |
1018 | } | 1325 | } |
1019 | } | 1326 | LLGLDisable blend(GL_BLEND); |
1020 | 1327 | LLGLDisable test(GL_ALPHA_TEST); | |
1021 | #if AGGRESSIVE_OCCLUSION | 1328 | LLViewerImage::unbindTexture(0, GL_TEXTURE_2D); |
1022 | for (LLSpatialBridge::bridge_vector_t::iterator i = mVisibleBridge.begin(); i != mVisibleBridge.end(); ++i) | 1329 | LLGLDepthTest depth(GL_TRUE, GL_FALSE); |
1330 | |||
1331 | if (LLPipeline::sUseOcclusion > 1) | ||
1332 | { | ||
1333 | for (LLCullResult::sg_list_t::iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter) | ||
1023 | { | 1334 | { |
1024 | LLSpatialBridge* bridge = *i; | 1335 | LLSpatialGroup* group = *iter; |
1025 | if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) | 1336 | group->doOcclusion(&camera); |
1026 | { | 1337 | group->clearState(LLSpatialGroup::ACTIVE_OCCLUSION); |
1027 | glPushMatrix(); | ||
1028 | glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); | ||
1029 | LLCamera trans = bridge->transformCamera(camera); | ||
1030 | bridge->doOcclusion(&trans); | ||
1031 | glPopMatrix(); | ||
1032 | mOccludedBridge.push_back(bridge); | ||
1033 | } | ||
1034 | } | 1338 | } |
1035 | #endif | ||
1036 | } | 1339 | } |
1340 | |||
1341 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); | ||
1037 | } | 1342 | } |
1038 | 1343 | ||
1039 | BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority) | 1344 | BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority) |
1040 | { | 1345 | { |
1041 | BOOL update_complete = drawablep->updateGeometry(priority); | 1346 | BOOL update_complete = drawablep->updateGeometry(priority); |
1042 | if (update_complete) | 1347 | if (update_complete && assertInitialized()) |
1043 | { | 1348 | { |
1044 | drawablep->setState(LLDrawable::BUILT); | 1349 | drawablep->setState(LLDrawable::BUILT); |
1045 | mGeometryChanges++; | 1350 | mGeometryChanges++; |
@@ -1055,6 +1360,17 @@ void LLPipeline::updateGeom(F32 max_dtime) | |||
1055 | 1360 | ||
1056 | LLFastTimer t(LLFastTimer::FTM_GEO_UPDATE); | 1361 | LLFastTimer t(LLFastTimer::FTM_GEO_UPDATE); |
1057 | 1362 | ||
1363 | assertInitialized(); | ||
1364 | |||
1365 | if (sDelayedVBOEnable > 0) | ||
1366 | { | ||
1367 | if (--sDelayedVBOEnable <= 0) | ||
1368 | { | ||
1369 | resetVertexBuffers(); | ||
1370 | LLVertexBuffer::sEnableVBOs = TRUE; | ||
1371 | } | ||
1372 | } | ||
1373 | |||
1058 | // notify various object types to reset internal cost metrics, etc. | 1374 | // notify various object types to reset internal cost metrics, etc. |
1059 | // for now, only LLVOVolume does this to throttle LOD changes | 1375 | // for now, only LLVOVolume does this to throttle LOD changes |
1060 | LLVOVolume::preUpdateGeom(); | 1376 | LLVOVolume::preUpdateGeom(); |
@@ -1091,9 +1407,10 @@ void LLPipeline::updateGeom(F32 max_dtime) | |||
1091 | 1407 | ||
1092 | // Iterate through some drawables on the non-priority build queue | 1408 | // Iterate through some drawables on the non-priority build queue |
1093 | S32 min_count = 16; | 1409 | S32 min_count = 16; |
1094 | if (mBuildQ2.size() > 1000) | 1410 | S32 size = (S32) mBuildQ2.size(); |
1411 | if (size > 1024) | ||
1095 | { | 1412 | { |
1096 | min_count = mBuildQ2.size(); | 1413 | min_count = llclamp((S32) (size * (F32) size/4096), 16, size); |
1097 | } | 1414 | } |
1098 | 1415 | ||
1099 | S32 count = 0; | 1416 | S32 count = 0; |
@@ -1144,44 +1461,25 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera) | |||
1144 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 1461 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
1145 | if(!drawablep || drawablep->isDead()) | 1462 | if(!drawablep || drawablep->isDead()) |
1146 | { | 1463 | { |
1147 | llwarns << "LLPipeline::markVisible called with NULL drawablep" << llendl; | ||
1148 | return; | 1464 | return; |
1149 | } | 1465 | } |
1150 | 1466 | ||
1151 | |||
1152 | #if LL_DEBUG | ||
1153 | if (drawablep->isSpatialBridge()) | 1467 | if (drawablep->isSpatialBridge()) |
1154 | { | 1468 | { |
1155 | if (std::find(mVisibleBridge.begin(), mVisibleBridge.end(), (LLSpatialBridge*) drawablep) != | 1469 | sCull->pushBridge((LLSpatialBridge*) drawablep); |
1156 | mVisibleBridge.end()) | ||
1157 | { | ||
1158 | llerrs << "Spatial bridge marked visible redundantly." << llendl; | ||
1159 | } | ||
1160 | } | 1470 | } |
1161 | else | 1471 | else |
1162 | { | 1472 | { |
1163 | if (std::find(mVisibleList.begin(), mVisibleList.end(), drawablep) != | 1473 | sCull->pushDrawable(drawablep); |
1164 | mVisibleList.end()) | ||
1165 | { | ||
1166 | llerrs << "Drawable marked visible redundantly." << llendl; | ||
1167 | } | ||
1168 | } | 1474 | } |
1169 | #endif | ||
1170 | 1475 | ||
1171 | if (drawablep->isSpatialBridge()) | ||
1172 | { | ||
1173 | mVisibleBridge.push_back((LLSpatialBridge*) drawablep); | ||
1174 | } | ||
1175 | else | ||
1176 | { | ||
1177 | mVisibleList.push_back(drawablep); | ||
1178 | } | ||
1179 | drawablep->setVisible(camera); | 1476 | drawablep->setVisible(camera); |
1180 | } | 1477 | } |
1181 | 1478 | ||
1182 | void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) | 1479 | void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) |
1183 | { | 1480 | { |
1184 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 1481 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
1482 | |||
1185 | if (!drawablep) | 1483 | if (!drawablep) |
1186 | { | 1484 | { |
1187 | llerrs << "Sending null drawable to moved list!" << llendl; | 1485 | llerrs << "Sending null drawable to moved list!" << llendl; |
@@ -1200,6 +1498,7 @@ void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) | |||
1200 | markMoved(drawablep->getParent(), damped_motion); | 1498 | markMoved(drawablep->getParent(), damped_motion); |
1201 | } | 1499 | } |
1202 | 1500 | ||
1501 | assertInitialized(); | ||
1203 | 1502 | ||
1204 | if (!drawablep->isState(LLDrawable::ON_MOVE_LIST)) | 1503 | if (!drawablep->isState(LLDrawable::ON_MOVE_LIST)) |
1205 | { | 1504 | { |
@@ -1226,11 +1525,14 @@ void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) | |||
1226 | void LLPipeline::markShift(LLDrawable *drawablep) | 1525 | void LLPipeline::markShift(LLDrawable *drawablep) |
1227 | { | 1526 | { |
1228 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 1527 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
1528 | |||
1229 | if (!drawablep || drawablep->isDead()) | 1529 | if (!drawablep || drawablep->isDead()) |
1230 | { | 1530 | { |
1231 | return; | 1531 | return; |
1232 | } | 1532 | } |
1233 | 1533 | ||
1534 | assertInitialized(); | ||
1535 | |||
1234 | if (!drawablep->isState(LLDrawable::ON_SHIFT_LIST)) | 1536 | if (!drawablep->isState(LLDrawable::ON_SHIFT_LIST)) |
1235 | { | 1537 | { |
1236 | drawablep->getVObj()->setChanged(LLXform::SHIFTED | LLXform::SILHOUETTE); | 1538 | drawablep->getVObj()->setChanged(LLXform::SHIFTED | LLXform::SILHOUETTE); |
@@ -1246,6 +1548,14 @@ void LLPipeline::markShift(LLDrawable *drawablep) | |||
1246 | void LLPipeline::shiftObjects(const LLVector3 &offset) | 1548 | void LLPipeline::shiftObjects(const LLVector3 &offset) |
1247 | { | 1549 | { |
1248 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 1550 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
1551 | |||
1552 | assertInitialized(); | ||
1553 | |||
1554 | //do a swap to indicate an invalid previous frame camera | ||
1555 | render_ui_and_swap_if_needed(); | ||
1556 | glClear(GL_DEPTH_BUFFER_BIT); | ||
1557 | gDisplaySwapBuffers = FALSE; | ||
1558 | |||
1249 | for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); | 1559 | for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); |
1250 | iter != mShiftList.end(); iter++) | 1560 | iter != mShiftList.end(); iter++) |
1251 | { | 1561 | { |
@@ -1259,11 +1569,17 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) | |||
1259 | } | 1569 | } |
1260 | mShiftList.resize(0); | 1570 | mShiftList.resize(0); |
1261 | 1571 | ||
1262 | for (U32 i = 0; i < mObjectPartition.size()-1; i++) | 1572 | for (LLWorld::region_list_t::iterator iter = gWorldp->getRegionList().begin(); |
1573 | iter != gWorldp->getRegionList().end(); ++iter) | ||
1263 | { | 1574 | { |
1264 | if (mObjectPartition[i]) | 1575 | LLViewerRegion* region = *iter; |
1576 | for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) | ||
1265 | { | 1577 | { |
1266 | mObjectPartition[i]->shift(offset); | 1578 | LLSpatialPartition* part = region->getSpatialPartition(i); |
1579 | if (part) | ||
1580 | { | ||
1581 | part->shift(offset); | ||
1582 | } | ||
1267 | } | 1583 | } |
1268 | } | 1584 | } |
1269 | } | 1585 | } |
@@ -1271,7 +1587,8 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) | |||
1271 | void LLPipeline::markTextured(LLDrawable *drawablep) | 1587 | void LLPipeline::markTextured(LLDrawable *drawablep) |
1272 | { | 1588 | { |
1273 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 1589 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
1274 | if (drawablep && !drawablep->isDead()) | 1590 | |
1591 | if (drawablep && !drawablep->isDead() && assertInitialized()) | ||
1275 | { | 1592 | { |
1276 | mRetexturedList.insert(drawablep); | 1593 | mRetexturedList.insert(drawablep); |
1277 | } | 1594 | } |
@@ -1281,7 +1598,7 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f | |||
1281 | { | 1598 | { |
1282 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 1599 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
1283 | 1600 | ||
1284 | if (drawablep && !drawablep->isDead()) | 1601 | if (drawablep && !drawablep->isDead() && assertInitialized()) |
1285 | { | 1602 | { |
1286 | if (!drawablep->isState(LLDrawable::BUILT)) | 1603 | if (!drawablep->isState(LLDrawable::BUILT)) |
1287 | { | 1604 | { |
@@ -1305,60 +1622,94 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f | |||
1305 | drawablep->getVObj()->setChanged(LLXform::SILHOUETTE); | 1622 | drawablep->getVObj()->setChanged(LLXform::SILHOUETTE); |
1306 | } | 1623 | } |
1307 | drawablep->setState(flag); | 1624 | drawablep->setState(flag); |
1308 | if ((flag & LLDrawable::REBUILD_LIGHTING) && drawablep->getLit()) | ||
1309 | { | ||
1310 | if (drawablep->isLight()) | ||
1311 | { | ||
1312 | drawablep->clearState(LLDrawable::LIGHTING_BUILT); | ||
1313 | } | ||
1314 | else | ||
1315 | { | ||
1316 | drawablep->clearState(LLDrawable::LIGHTING_BUILT); | ||
1317 | } | ||
1318 | } | ||
1319 | } | 1625 | } |
1320 | } | 1626 | } |
1321 | 1627 | ||
1322 | void LLPipeline::markRelight(LLDrawable *drawablep, const BOOL priority) | 1628 | void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) |
1323 | { | 1629 | { |
1324 | if (getLightingDetail() >= 2) | 1630 | const U32 face_mask = (1 << LLPipeline::RENDER_TYPE_AVATAR) | |
1631 | (1 << LLPipeline::RENDER_TYPE_GROUND) | | ||
1632 | (1 << LLPipeline::RENDER_TYPE_TERRAIN) | | ||
1633 | (1 << LLPipeline::RENDER_TYPE_TREE) | | ||
1634 | (1 << LLPipeline::RENDER_TYPE_SKY) | | ||
1635 | (1 << LLPipeline::RENDER_TYPE_WATER); | ||
1636 | |||
1637 | if (mRenderTypeMask & face_mask) | ||
1325 | { | 1638 | { |
1326 | markRebuild(drawablep, LLDrawable::REBUILD_LIGHTING, FALSE); | 1639 | //clear faces from face pools |
1640 | LLFastTimer t(LLFastTimer::FTM_RESET_DRAWORDER); | ||
1641 | gPipeline.resetDrawOrders(); | ||
1327 | } | 1642 | } |
1328 | } | ||
1329 | 1643 | ||
1330 | void LLPipeline::stateSort(LLCamera& camera) | ||
1331 | { | ||
1332 | LLFastTimer ftm(LLFastTimer::FTM_STATESORT); | 1644 | LLFastTimer ftm(LLFastTimer::FTM_STATESORT); |
1333 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 1645 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
1334 | 1646 | ||
1335 | for (LLSpatialGroup::sg_vector_t::iterator iter = mVisibleGroups.begin(); iter != mVisibleGroups.end(); ++iter) | 1647 | grabReferences(result); |
1648 | |||
1336 | { | 1649 | { |
1337 | stateSort(*iter, camera); | 1650 | for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) |
1651 | { | ||
1652 | LLSpatialGroup* group = *iter; | ||
1653 | group->checkOcclusion(); | ||
1654 | if (sUseOcclusion && group->isState(LLSpatialGroup::OCCLUDED)) | ||
1655 | { | ||
1656 | markOccluder(group); | ||
1657 | } | ||
1658 | else | ||
1659 | { | ||
1660 | group->setVisible(); | ||
1661 | for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) | ||
1662 | { | ||
1663 | markVisible(*i, camera); | ||
1664 | } | ||
1665 | } | ||
1666 | } | ||
1667 | |||
1668 | for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) | ||
1669 | { | ||
1670 | LLSpatialGroup* group = *iter; | ||
1671 | group->checkOcclusion(); | ||
1672 | if (sUseOcclusion && group->isState(LLSpatialGroup::OCCLUDED)) | ||
1673 | { | ||
1674 | markOccluder(group); | ||
1675 | } | ||
1676 | else | ||
1677 | { | ||
1678 | group->setVisible(); | ||
1679 | stateSort(group, camera); | ||
1680 | } | ||
1681 | } | ||
1338 | } | 1682 | } |
1339 | 1683 | ||
1340 | for (LLSpatialBridge::bridge_vector_t::iterator i = mVisibleBridge.begin(); i != mVisibleBridge.end(); ++i) | ||
1341 | { | 1684 | { |
1342 | LLSpatialBridge* bridge = *i; | 1685 | for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) |
1343 | if (!bridge->isDead()) | ||
1344 | { | 1686 | { |
1345 | stateSort(bridge, camera); | 1687 | LLCullResult::bridge_list_t::iterator cur_iter = i; |
1688 | LLSpatialBridge* bridge = *cur_iter; | ||
1689 | LLSpatialGroup* group = bridge->getSpatialGroup(); | ||
1690 | if (!bridge->isDead() && group && !group->isState(LLSpatialGroup::OCCLUDED)) | ||
1691 | { | ||
1692 | stateSort(bridge, camera); | ||
1693 | } | ||
1346 | } | 1694 | } |
1347 | } | 1695 | } |
1348 | 1696 | ||
1349 | for (LLDrawable::drawable_vector_t::iterator iter = mVisibleList.begin(); | ||
1350 | iter != mVisibleList.end(); iter++) | ||
1351 | { | 1697 | { |
1352 | LLDrawable *drawablep = *iter; | 1698 | LLFastTimer ftm(LLFastTimer::FTM_STATESORT_DRAWABLE); |
1353 | if (!drawablep->isDead()) | 1699 | for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); |
1700 | iter != sCull->endVisibleList(); ++iter) | ||
1354 | { | 1701 | { |
1355 | stateSort(drawablep, camera); | 1702 | LLDrawable *drawablep = *iter; |
1703 | if (!drawablep->isDead()) | ||
1704 | { | ||
1705 | stateSort(drawablep, camera); | ||
1706 | } | ||
1356 | } | 1707 | } |
1357 | } | 1708 | } |
1358 | 1709 | ||
1359 | for (LLSpatialGroup::sg_vector_t::iterator iter = mActiveGroups.begin(); iter != mActiveGroups.end(); ++iter) | ||
1360 | { | 1710 | { |
1361 | stateSort(*iter, camera); | 1711 | LLFastTimer ftm(LLFastTimer::FTM_CLIENT_COPY); |
1712 | LLVertexBuffer::clientCopy(); | ||
1362 | } | 1713 | } |
1363 | 1714 | ||
1364 | postSort(camera); | 1715 | postSort(camera); |
@@ -1375,19 +1726,12 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) | |||
1375 | stateSort(drawablep, camera); | 1726 | stateSort(drawablep, camera); |
1376 | } | 1727 | } |
1377 | } | 1728 | } |
1378 | |||
1379 | #if !LL_DARWIN | ||
1380 | if (gFrameTimeSeconds - group->mLastUpdateTime > 4.f) | ||
1381 | { | ||
1382 | group->makeStatic(); | ||
1383 | } | ||
1384 | #endif | ||
1385 | } | 1729 | } |
1386 | 1730 | ||
1387 | void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) | 1731 | void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) |
1388 | { | 1732 | { |
1389 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 1733 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
1390 | if (!sSkipUpdate) | 1734 | if (!sSkipUpdate && bridge->getSpatialGroup()->changeLOD()) |
1391 | { | 1735 | { |
1392 | bridge->updateDistance(camera); | 1736 | bridge->updateDistance(camera); |
1393 | } | 1737 | } |
@@ -1396,8 +1740,7 @@ void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) | |||
1396 | void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) | 1740 | void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) |
1397 | { | 1741 | { |
1398 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 1742 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
1399 | LLFastTimer ftm(LLFastTimer::FTM_STATESORT_DRAWABLE); | 1743 | |
1400 | |||
1401 | if (!drawablep | 1744 | if (!drawablep |
1402 | || drawablep->isDead() | 1745 | || drawablep->isDead() |
1403 | || !hasRenderType(drawablep->getRenderType())) | 1746 | || !hasRenderType(drawablep->getRenderType())) |
@@ -1414,6 +1757,17 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) | |||
1414 | } | 1757 | } |
1415 | } | 1758 | } |
1416 | 1759 | ||
1760 | if (drawablep->isAvatar()) | ||
1761 | { //don't draw avatars beyond render distance or if we don't have a spatial group. | ||
1762 | if ((drawablep->getSpatialGroup() == NULL) || | ||
1763 | (drawablep->getSpatialGroup()->mDistance > LLVOAvatar::sRenderDistance)) | ||
1764 | { | ||
1765 | return; | ||
1766 | } | ||
1767 | } | ||
1768 | |||
1769 | assertInitialized(); | ||
1770 | |||
1417 | if (hasRenderType(drawablep->mRenderType)) | 1771 | if (hasRenderType(drawablep->mRenderType)) |
1418 | { | 1772 | { |
1419 | if (!drawablep->isState(LLDrawable::INVISIBLE|LLDrawable::FORCE_INVISIBLE)) | 1773 | if (!drawablep->isState(LLDrawable::INVISIBLE|LLDrawable::FORCE_INVISIBLE)) |
@@ -1427,17 +1781,21 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) | |||
1427 | } | 1781 | } |
1428 | } | 1782 | } |
1429 | 1783 | ||
1430 | if (!drawablep->isActive() && drawablep->isVisible()) | 1784 | LLSpatialGroup* group = drawablep->getSpatialGroup(); |
1785 | if (!group || group->changeLOD()) | ||
1431 | { | 1786 | { |
1432 | if (!sSkipUpdate) | 1787 | if (!drawablep->isActive() && drawablep->isVisible()) |
1433 | { | 1788 | { |
1434 | drawablep->updateDistance(camera); | 1789 | if (!sSkipUpdate) |
1790 | { | ||
1791 | drawablep->updateDistance(camera); | ||
1792 | } | ||
1793 | } | ||
1794 | else if (drawablep->isAvatar() && drawablep->isVisible()) | ||
1795 | { | ||
1796 | LLVOAvatar* vobj = (LLVOAvatar*) drawablep->getVObj().get(); | ||
1797 | vobj->updateVisibility(); | ||
1435 | } | 1798 | } |
1436 | } | ||
1437 | else if (drawablep->isAvatar() && drawablep->isVisible()) | ||
1438 | { | ||
1439 | LLVOAvatar* vobj = (LLVOAvatar*) drawablep->getVObj().get(); | ||
1440 | vobj->updateVisibility(FALSE); | ||
1441 | } | 1799 | } |
1442 | 1800 | ||
1443 | for (LLDrawable::face_list_t::iterator iter = drawablep->mFaces.begin(); | 1801 | for (LLDrawable::face_list_t::iterator iter = drawablep->mFaces.begin(); |
@@ -1457,15 +1815,16 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) | |||
1457 | } | 1815 | } |
1458 | } | 1816 | } |
1459 | } | 1817 | } |
1460 | 1818 | ||
1461 | |||
1462 | mNumVisibleFaces += drawablep->getNumFaces(); | 1819 | mNumVisibleFaces += drawablep->getNumFaces(); |
1463 | } | 1820 | } |
1464 | 1821 | ||
1465 | 1822 | ||
1466 | void LLPipeline::forAllDrawables(LLSpatialGroup::sg_vector_t& groups, void (*func)(LLDrawable*)) | 1823 | void forAllDrawables(LLCullResult::sg_list_t::iterator begin, |
1824 | LLCullResult::sg_list_t::iterator end, | ||
1825 | void (*func)(LLDrawable*)) | ||
1467 | { | 1826 | { |
1468 | for (LLSpatialGroup::sg_vector_t::iterator i = groups.begin(); i != groups.end(); ++i) | 1827 | for (LLCullResult::sg_list_t::iterator i = begin; i != end; ++i) |
1469 | { | 1828 | { |
1470 | for (LLSpatialGroup::element_iter j = (*i)->getData().begin(); j != (*i)->getData().end(); ++j) | 1829 | for (LLSpatialGroup::element_iter j = (*i)->getData().begin(); j != (*i)->getData().end(); ++j) |
1471 | { | 1830 | { |
@@ -1476,9 +1835,8 @@ void LLPipeline::forAllDrawables(LLSpatialGroup::sg_vector_t& groups, void (*fun | |||
1476 | 1835 | ||
1477 | void LLPipeline::forAllVisibleDrawables(void (*func)(LLDrawable*)) | 1836 | void LLPipeline::forAllVisibleDrawables(void (*func)(LLDrawable*)) |
1478 | { | 1837 | { |
1479 | forAllDrawables(mDrawableGroups, func); | 1838 | forAllDrawables(sCull->beginDrawableGroups(), sCull->endDrawableGroups(), func); |
1480 | forAllDrawables(mVisibleGroups, func); | 1839 | forAllDrawables(sCull->beginVisibleGroups(), sCull->endVisibleGroups(), func); |
1481 | forAllDrawables(mActiveGroups, func); | ||
1482 | } | 1840 | } |
1483 | 1841 | ||
1484 | //function for creating scripted beacons | 1842 | //function for creating scripted beacons |
@@ -1498,7 +1856,8 @@ void renderScriptedBeacons(LLDrawable* drawablep) | |||
1498 | if (gPipeline.sRenderHighlight) | 1856 | if (gPipeline.sRenderHighlight) |
1499 | { | 1857 | { |
1500 | S32 face_id; | 1858 | S32 face_id; |
1501 | for (face_id = 0; face_id < drawablep->getNumFaces(); face_id++) | 1859 | S32 count = drawablep->getNumFaces(); |
1860 | for (face_id = 0; face_id < count; face_id++) | ||
1502 | { | 1861 | { |
1503 | gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); | 1862 | gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); |
1504 | } | 1863 | } |
@@ -1523,7 +1882,8 @@ void renderScriptedTouchBeacons(LLDrawable* drawablep) | |||
1523 | if (gPipeline.sRenderHighlight) | 1882 | if (gPipeline.sRenderHighlight) |
1524 | { | 1883 | { |
1525 | S32 face_id; | 1884 | S32 face_id; |
1526 | for (face_id = 0; face_id < drawablep->getNumFaces(); face_id++) | 1885 | S32 count = drawablep->getNumFaces(); |
1886 | for (face_id = 0; face_id < count; face_id++) | ||
1527 | { | 1887 | { |
1528 | gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); | 1888 | gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); |
1529 | } | 1889 | } |
@@ -1547,7 +1907,8 @@ void renderPhysicalBeacons(LLDrawable* drawablep) | |||
1547 | if (gPipeline.sRenderHighlight) | 1907 | if (gPipeline.sRenderHighlight) |
1548 | { | 1908 | { |
1549 | S32 face_id; | 1909 | S32 face_id; |
1550 | for (face_id = 0; face_id < drawablep->getNumFaces(); face_id++) | 1910 | S32 count = drawablep->getNumFaces(); |
1911 | for (face_id = 0; face_id < count; face_id++) | ||
1551 | { | 1912 | { |
1552 | gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); | 1913 | gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); |
1553 | } | 1914 | } |
@@ -1571,7 +1932,8 @@ void renderParticleBeacons(LLDrawable* drawablep) | |||
1571 | if (gPipeline.sRenderHighlight) | 1932 | if (gPipeline.sRenderHighlight) |
1572 | { | 1933 | { |
1573 | S32 face_id; | 1934 | S32 face_id; |
1574 | for (face_id = 0; face_id < drawablep->getNumFaces(); face_id++) | 1935 | S32 count = drawablep->getNumFaces(); |
1936 | for (face_id = 0; face_id < count; face_id++) | ||
1575 | { | 1937 | { |
1576 | gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); | 1938 | gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); |
1577 | } | 1939 | } |
@@ -1579,73 +1941,61 @@ void renderParticleBeacons(LLDrawable* drawablep) | |||
1579 | } | 1941 | } |
1580 | } | 1942 | } |
1581 | 1943 | ||
1582 | void LLPipeline::postSort(LLCamera& camera) | 1944 | void renderSoundHighlights(LLDrawable* drawablep) |
1583 | { | 1945 | { |
1584 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 1946 | // Look for attachments, objects, etc. |
1585 | LLFastTimer ftm(LLFastTimer::FTM_STATESORT_POSTSORT); | 1947 | LLViewerObject *vobj = drawablep->getVObj(); |
1586 | //reset render data sets | 1948 | if (vobj && vobj->isAudioSource()) |
1587 | clearRenderMap(); | ||
1588 | mAlphaGroups.clear(); | ||
1589 | mAlphaGroupsPostWater.clear(); | ||
1590 | |||
1591 | if (!gSavedSettings.getBOOL("RenderRippleWater") && hasRenderType(LLDrawPool::POOL_ALPHA)) | ||
1592 | { //turn off clip plane for non-ripple water | ||
1593 | toggleRenderType(LLDrawPool::POOL_ALPHA); | ||
1594 | } | ||
1595 | |||
1596 | F32 water_height = gAgent.getRegion()->getWaterHeight(); | ||
1597 | BOOL above_water = gCamera->getOrigin().mV[2] > water_height ? TRUE : FALSE; | ||
1598 | |||
1599 | //prepare occlusion geometry | ||
1600 | if (sUseOcclusion) | ||
1601 | { | 1949 | { |
1602 | for (U32 i = 0; i < mObjectPartition.size(); i++) | 1950 | if (gPipeline.sRenderHighlight) |
1603 | { | 1951 | { |
1604 | if (mObjectPartition[i] && hasRenderType(mObjectPartition[i]->mDrawableType)) | 1952 | S32 face_id; |
1953 | S32 count = drawablep->getNumFaces(); | ||
1954 | for (face_id = 0; face_id < count; face_id++) | ||
1605 | { | 1955 | { |
1606 | mObjectPartition[i]->buildOcclusion(); | 1956 | gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); |
1607 | } | ||
1608 | } | ||
1609 | |||
1610 | #if AGGRESSIVE_OCCLUSION | ||
1611 | for (LLSpatialBridge::bridge_vector_t::iterator i = mVisibleBridge.begin(); i != mVisibleBridge.end(); ++i) | ||
1612 | { | ||
1613 | LLSpatialBridge* bridge = *i; | ||
1614 | if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) | ||
1615 | { | ||
1616 | bridge->buildOcclusion(); | ||
1617 | } | 1957 | } |
1618 | } | 1958 | } |
1619 | #endif | ||
1620 | } | 1959 | } |
1960 | } | ||
1621 | 1961 | ||
1962 | void LLPipeline::postSort(LLCamera& camera) | ||
1963 | { | ||
1964 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | ||
1965 | LLFastTimer ftm(LLFastTimer::FTM_STATESORT_POSTSORT); | ||
1622 | 1966 | ||
1623 | if (!sSkipUpdate) | 1967 | assertInitialized(); |
1968 | |||
1969 | //rebuild drawable geometry | ||
1970 | for (LLCullResult::sg_list_t::iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i) | ||
1624 | { | 1971 | { |
1625 | //rebuild drawable geometry | 1972 | LLSpatialGroup* group = *i; |
1626 | for (LLSpatialGroup::sg_vector_t::iterator i = mDrawableGroups.begin(); i != mDrawableGroups.end(); ++i) | 1973 | if (!sUseOcclusion || |
1974 | !group->isState(LLSpatialGroup::OCCLUDED)) | ||
1627 | { | 1975 | { |
1628 | LLSpatialGroup* group = *i; | ||
1629 | group->rebuildGeom(); | 1976 | group->rebuildGeom(); |
1630 | } | 1977 | } |
1631 | } | 1978 | } |
1632 | 1979 | ||
1633 | //build render map | 1980 | //build render map |
1634 | for (LLSpatialGroup::sg_vector_t::iterator i = mVisibleGroups.begin(); i != mVisibleGroups.end(); ++i) | 1981 | for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) |
1635 | { | 1982 | { |
1636 | LLSpatialGroup* group = *i; | 1983 | LLSpatialGroup* group = *i; |
1637 | if (!sSkipUpdate) | 1984 | if (sUseOcclusion && |
1985 | group->isState(LLSpatialGroup::OCCLUDED)) | ||
1638 | { | 1986 | { |
1639 | group->rebuildGeom(); | 1987 | continue; |
1640 | } | 1988 | } |
1989 | |||
1990 | group->rebuildGeom(); | ||
1991 | |||
1641 | for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j) | 1992 | for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j) |
1642 | { | 1993 | { |
1643 | LLSpatialGroup::drawmap_elem_t& src_vec = j->second; | 1994 | LLSpatialGroup::drawmap_elem_t& src_vec = j->second; |
1644 | LLSpatialGroup::drawmap_elem_t& dest_vec = mRenderMap[j->first]; | 1995 | |
1645 | 1996 | for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k) | |
1646 | for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k) | ||
1647 | { | 1997 | { |
1648 | dest_vec.push_back(*k); | 1998 | sCull->pushDrawInfo(j->first, *k); |
1649 | } | 1999 | } |
1650 | } | 2000 | } |
1651 | 2001 | ||
@@ -1653,95 +2003,47 @@ void LLPipeline::postSort(LLCamera& camera) | |||
1653 | 2003 | ||
1654 | if (alpha != group->mDrawMap.end()) | 2004 | if (alpha != group->mDrawMap.end()) |
1655 | { //store alpha groups for sorting | 2005 | { //store alpha groups for sorting |
2006 | LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); | ||
1656 | if (!sSkipUpdate) | 2007 | if (!sSkipUpdate) |
1657 | { | 2008 | { |
1658 | group->updateDistance(camera); | 2009 | if (bridge) |
1659 | } | ||
1660 | |||
1661 | if (hasRenderType(LLDrawPool::POOL_ALPHA)) | ||
1662 | { | ||
1663 | BOOL above = group->mObjectBounds[0].mV[2] + group->mObjectBounds[1].mV[2] > water_height ? TRUE : FALSE; | ||
1664 | BOOL below = group->mObjectBounds[0].mV[2] - group->mObjectBounds[1].mV[2] < water_height ? TRUE : FALSE; | ||
1665 | |||
1666 | if (below == above_water || above == below) | ||
1667 | { | 2010 | { |
1668 | mAlphaGroups.push_back(group); | 2011 | LLCamera trans_camera = bridge->transformCamera(camera); |
2012 | group->updateDistance(trans_camera); | ||
1669 | } | 2013 | } |
1670 | 2014 | else | |
1671 | if (above == above_water || below == above) | ||
1672 | { | 2015 | { |
1673 | mAlphaGroupsPostWater.push_back(group); | 2016 | group->updateDistance(camera); |
1674 | } | 2017 | } |
1675 | } | 2018 | } |
1676 | else | 2019 | |
2020 | if (hasRenderType(LLDrawPool::POOL_ALPHA)) | ||
1677 | { | 2021 | { |
1678 | mAlphaGroupsPostWater.push_back(group); | 2022 | sCull->pushAlphaGroup(group); |
1679 | } | 2023 | } |
1680 | } | 2024 | } |
1681 | } | 2025 | } |
1682 | |||
1683 | //store active alpha groups | ||
1684 | for (LLSpatialGroup::sg_vector_t::iterator i = mActiveGroups.begin(); i != mActiveGroups.end(); ++i) | ||
1685 | { | ||
1686 | LLSpatialGroup* group = *i; | ||
1687 | if (!sSkipUpdate) | ||
1688 | { | ||
1689 | group->rebuildGeom(); | ||
1690 | } | ||
1691 | LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA); | ||
1692 | 2026 | ||
1693 | if (alpha != group->mDrawMap.end()) | 2027 | { |
2028 | //sort by texture or bump map | ||
2029 | for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; ++i) | ||
1694 | { | 2030 | { |
1695 | LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); | 2031 | //if (!mRenderMap[i].empty()) |
1696 | LLCamera trans_camera = bridge->transformCamera(camera); | ||
1697 | if (!sSkipUpdate) | ||
1698 | { | ||
1699 | group->updateDistance(trans_camera); | ||
1700 | } | ||
1701 | |||
1702 | if (hasRenderType(LLDrawPool::POOL_ALPHA)) | ||
1703 | { | 2032 | { |
1704 | LLSpatialGroup* bridge_group = bridge->getSpatialGroup(); | 2033 | if (i == LLRenderPass::PASS_BUMP) |
1705 | BOOL above = bridge_group->mObjectBounds[0].mV[2] + bridge_group->mObjectBounds[1].mV[2] > water_height ? TRUE : FALSE; | ||
1706 | BOOL below = bridge_group->mObjectBounds[0].mV[2] - bridge_group->mObjectBounds[1].mV[2] < water_height ? TRUE : FALSE; | ||
1707 | |||
1708 | |||
1709 | if (below == above_water || above == below) | ||
1710 | { | 2034 | { |
1711 | mAlphaGroups.push_back(group); | 2035 | std::sort(sCull->beginRenderMap(i), sCull->endRenderMap(i), LLDrawInfo::CompareBump()); |
1712 | } | 2036 | } |
1713 | 2037 | else | |
1714 | if (above == above_water || below == above) | ||
1715 | { | 2038 | { |
1716 | mAlphaGroupsPostWater.push_back(group); | 2039 | std::sort(sCull->beginRenderMap(i), sCull->endRenderMap(i), LLDrawInfo::CompareTexturePtrMatrix()); |
1717 | } | 2040 | } |
1718 | } | 2041 | } |
1719 | else | ||
1720 | { | ||
1721 | mAlphaGroupsPostWater.push_back(group); | ||
1722 | } | ||
1723 | } | 2042 | } |
1724 | } | ||
1725 | 2043 | ||
1726 | //sort by texture or bump map | 2044 | std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater()); |
1727 | for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; ++i) | ||
1728 | { | ||
1729 | if (!mRenderMap[i].empty()) | ||
1730 | { | ||
1731 | if (i == LLRenderPass::PASS_BUMP) | ||
1732 | { | ||
1733 | std::sort(mRenderMap[i].begin(), mRenderMap[i].end(), LLDrawInfo::CompareBump()); | ||
1734 | } | ||
1735 | else | ||
1736 | { | ||
1737 | std::sort(mRenderMap[i].begin(), mRenderMap[i].end(), LLDrawInfo::CompareTexturePtr()); | ||
1738 | } | ||
1739 | } | ||
1740 | } | 2045 | } |
1741 | 2046 | ||
1742 | std::sort(mAlphaGroups.begin(), mAlphaGroups.end(), LLSpatialGroup::CompareDepthGreater()); | ||
1743 | std::sort(mAlphaGroupsPostWater.begin(), mAlphaGroupsPostWater.end(), LLSpatialGroup::CompareDepthGreater()); | ||
1744 | |||
1745 | // only render if the flag is set. The flag is only set if the right key is pressed, we are in edit mode or the toggle is set in the menus | 2047 | // only render if the flag is set. The flag is only set if the right key is pressed, we are in edit mode or the toggle is set in the menus |
1746 | if (sRenderProcessBeacons) | 2048 | if (sRenderProcessBeacons) |
1747 | { | 2049 | { |
@@ -1771,7 +2073,7 @@ void LLPipeline::postSort(LLCamera& camera) | |||
1771 | // If god mode, also show audio cues | 2073 | // If god mode, also show audio cues |
1772 | if (sRenderSoundBeacons && gAudiop) | 2074 | if (sRenderSoundBeacons && gAudiop) |
1773 | { | 2075 | { |
1774 | // Update all of our audio sources, clean up dead ones. | 2076 | // Walk all sound sources and render out beacons for them. Note, this isn't done in the ForAllVisibleDrawables function, because some are not visible. |
1775 | LLAudioEngine::source_map::iterator iter; | 2077 | LLAudioEngine::source_map::iterator iter; |
1776 | for (iter = gAudiop->mAllSources.begin(); iter != gAudiop->mAllSources.end(); ++iter) | 2078 | for (iter = gAudiop->mAllSources.begin(); iter != gAudiop->mAllSources.end(); ++iter) |
1777 | { | 2079 | { |
@@ -1785,6 +2087,8 @@ void LLPipeline::postSort(LLCamera& camera) | |||
1785 | gObjectList.addDebugBeacon(pos, "", LLColor4(1.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth")); | 2087 | gObjectList.addDebugBeacon(pos, "", LLColor4(1.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth")); |
1786 | } | 2088 | } |
1787 | } | 2089 | } |
2090 | // now deal with highlights for all those seeable sound sources | ||
2091 | forAllVisibleDrawables(renderSoundHighlights); | ||
1788 | } | 2092 | } |
1789 | } | 2093 | } |
1790 | 2094 | ||
@@ -1815,7 +2119,7 @@ void LLPipeline::postSort(LLCamera& camera) | |||
1815 | } | 2119 | } |
1816 | 2120 | ||
1817 | 2121 | ||
1818 | static void render_hud_elements() | 2122 | void render_hud_elements() |
1819 | { | 2123 | { |
1820 | LLFastTimer t(LLFastTimer::FTM_RENDER_UI); | 2124 | LLFastTimer t(LLFastTimer::FTM_RENDER_UI); |
1821 | gPipeline.disableLights(); | 2125 | gPipeline.disableLights(); |
@@ -1824,8 +2128,14 @@ static void render_hud_elements() | |||
1824 | 2128 | ||
1825 | LLGLDisable fog(GL_FOG); | 2129 | LLGLDisable fog(GL_FOG); |
1826 | LLGLSUIDefault gls_ui; | 2130 | LLGLSUIDefault gls_ui; |
2131 | |||
2132 | LLGLEnable stencil(GL_STENCIL_TEST); | ||
2133 | glStencilFunc(GL_ALWAYS, 255, 0xFFFFFFFF); | ||
2134 | glStencilMask(0xFFFFFFFF); | ||
2135 | glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); | ||
1827 | 2136 | ||
1828 | if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) | 2137 | gGL.start(); |
2138 | if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) | ||
1829 | { | 2139 | { |
1830 | gViewerWindow->renderSelections(FALSE, FALSE, FALSE); // For HUD version in render_ui_3d() | 2140 | gViewerWindow->renderSelections(FALSE, FALSE, FALSE); // For HUD version in render_ui_3d() |
1831 | 2141 | ||
@@ -1857,11 +2167,15 @@ static void render_hud_elements() | |||
1857 | { | 2167 | { |
1858 | LLHUDText::renderAllHUD(); | 2168 | LLHUDText::renderAllHUD(); |
1859 | } | 2169 | } |
2170 | gGL.stop(); | ||
1860 | } | 2171 | } |
1861 | 2172 | ||
1862 | void LLPipeline::renderHighlights() | 2173 | void LLPipeline::renderHighlights() |
1863 | { | 2174 | { |
1864 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 2175 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
2176 | |||
2177 | assertInitialized(); | ||
2178 | |||
1865 | // Draw 3D UI elements here (before we clear the Z buffer in POOL_HUD) | 2179 | // Draw 3D UI elements here (before we clear the Z buffer in POOL_HUD) |
1866 | // Render highlighted faces. | 2180 | // Render highlighted faces. |
1867 | LLColor4 color(1.f, 1.f, 1.f, 0.5f); | 2181 | LLColor4 color(1.f, 1.f, 1.f, 0.5f); |
@@ -1871,7 +2185,7 @@ void LLPipeline::renderHighlights() | |||
1871 | if ((LLShaderMgr::sVertexShaderLevel[LLShaderMgr::SHADER_INTERFACE] > 0)) | 2185 | if ((LLShaderMgr::sVertexShaderLevel[LLShaderMgr::SHADER_INTERFACE] > 0)) |
1872 | { | 2186 | { |
1873 | gHighlightProgram.bind(); | 2187 | gHighlightProgram.bind(); |
1874 | gHighlightProgram.vertexAttrib4f(LLShaderMgr::MATERIAL_COLOR,1,0,0,0.5f); | 2188 | gHighlightProgram.vertexAttrib4f(LLShaderMgr::MATERIAL_COLOR,1,1,1,0.5f); |
1875 | } | 2189 | } |
1876 | 2190 | ||
1877 | if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED)) | 2191 | if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED)) |
@@ -1883,7 +2197,8 @@ void LLPipeline::renderHighlights() | |||
1883 | } | 2197 | } |
1884 | mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); | 2198 | mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); |
1885 | 2199 | ||
1886 | for (U32 i = 0; i < mSelectedFaces.size(); i++) | 2200 | U32 count = mSelectedFaces.size(); |
2201 | for (U32 i = 0; i < count; i++) | ||
1887 | { | 2202 | { |
1888 | LLFace *facep = mSelectedFaces[i]; | 2203 | LLFace *facep = mSelectedFaces[i]; |
1889 | if (!facep || facep->getDrawable()->isDead()) | 2204 | if (!facep || facep->getDrawable()->isDead()) |
@@ -1900,7 +2215,12 @@ void LLPipeline::renderHighlights() | |||
1900 | { | 2215 | { |
1901 | // Paint 'em red! | 2216 | // Paint 'em red! |
1902 | color.setVec(1.f, 0.f, 0.f, 0.5f); | 2217 | color.setVec(1.f, 0.f, 0.f, 0.5f); |
1903 | for (U32 i = 0; i < mHighlightFaces.size(); i++) | 2218 | if ((LLShaderMgr::sVertexShaderLevel[LLShaderMgr::SHADER_INTERFACE] > 0)) |
2219 | { | ||
2220 | gHighlightProgram.vertexAttrib4f(LLShaderMgr::MATERIAL_COLOR,1,0,0,0.5f); | ||
2221 | } | ||
2222 | int count = mHighlightFaces.size(); | ||
2223 | for (S32 i = 0; i < count; i++) | ||
1904 | { | 2224 | { |
1905 | LLFace* facep = mHighlightFaces[i]; | 2225 | LLFace* facep = mHighlightFaces[i]; |
1906 | facep->renderSelected(LLViewerImage::sNullImagep, color); | 2226 | facep->renderSelected(LLViewerImage::sNullImagep, color); |
@@ -1917,11 +2237,26 @@ void LLPipeline::renderHighlights() | |||
1917 | } | 2237 | } |
1918 | } | 2238 | } |
1919 | 2239 | ||
1920 | void LLPipeline::renderGeom(LLCamera& camera) | 2240 | void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) |
1921 | { | 2241 | { |
1922 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 2242 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
1923 | LLFastTimer t(LLFastTimer::FTM_RENDER_GEOMETRY); | 2243 | LLFastTimer t(LLFastTimer::FTM_RENDER_GEOMETRY); |
1924 | 2244 | ||
2245 | assertInitialized(); | ||
2246 | |||
2247 | F64 saved_modelview[16]; | ||
2248 | F64 saved_projection[16]; | ||
2249 | |||
2250 | //HACK: preserve/restore matrices around HUD render | ||
2251 | if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) | ||
2252 | { | ||
2253 | for (U32 i = 0; i < 16; i++) | ||
2254 | { | ||
2255 | saved_modelview[i] = gGLModelView[i]; | ||
2256 | saved_projection[i] = gGLProjection[i]; | ||
2257 | } | ||
2258 | } | ||
2259 | |||
1925 | if (!mAlphaSizzleImagep) | 2260 | if (!mAlphaSizzleImagep) |
1926 | { | 2261 | { |
1927 | mAlphaSizzleImagep = gImageList.getImage(LLUUID(gViewerArt.getString("alpha_sizzle.tga")), MIPMAP_TRUE, TRUE); | 2262 | mAlphaSizzleImagep = gImageList.getImage(LLUUID(gViewerArt.getString("alpha_sizzle.tga")), MIPMAP_TRUE, TRUE); |
@@ -1952,11 +2287,8 @@ void LLPipeline::renderGeom(LLCamera& camera) | |||
1952 | } | 2287 | } |
1953 | } | 2288 | } |
1954 | 2289 | ||
1955 | { | 2290 | LLVertexBuffer::startRender(); |
1956 | //LLFastTimer ftm(LLFastTimer::FTM_TEMP6); | 2291 | |
1957 | LLVertexBuffer::startRender(); | ||
1958 | } | ||
1959 | |||
1960 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) | 2292 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) |
1961 | { | 2293 | { |
1962 | LLDrawPool *poolp = *iter; | 2294 | LLDrawPool *poolp = *iter; |
@@ -1966,6 +2298,14 @@ void LLPipeline::renderGeom(LLCamera& camera) | |||
1966 | } | 2298 | } |
1967 | } | 2299 | } |
1968 | 2300 | ||
2301 | //by bao | ||
2302 | //fake vertex buffer updating | ||
2303 | //to guaranttee at least updating one VBO buffer every frame | ||
2304 | //to walk around the bug caused by ATI card --> DEV-3855 | ||
2305 | // | ||
2306 | if(forceVBOUpdate) | ||
2307 | gSky.mVOSkyp->updateDummyVertexBuffer() ; | ||
2308 | |||
1969 | gFrameStats.start(LLFrameStats::RENDER_GEOM); | 2309 | gFrameStats.start(LLFrameStats::RENDER_GEOM); |
1970 | 2310 | ||
1971 | // Initialize lots of GL state to "safe" values | 2311 | // Initialize lots of GL state to "safe" values |
@@ -1976,13 +2316,18 @@ void LLPipeline::renderGeom(LLCamera& camera) | |||
1976 | LLGLSPipeline gls_pipeline; | 2316 | LLGLSPipeline gls_pipeline; |
1977 | 2317 | ||
1978 | LLGLState gls_color_material(GL_COLOR_MATERIAL, mLightingDetail < 2); | 2318 | LLGLState gls_color_material(GL_COLOR_MATERIAL, mLightingDetail < 2); |
1979 | // LLGLState normalize(GL_NORMALIZE, TRUE); | 2319 | |
1980 | |||
1981 | // Toggle backface culling for debugging | 2320 | // Toggle backface culling for debugging |
1982 | LLGLEnable cull_face(mBackfaceCull ? GL_CULL_FACE : 0); | 2321 | LLGLEnable cull_face(mBackfaceCull ? GL_CULL_FACE : 0); |
1983 | // Set fog | 2322 | // Set fog |
1984 | LLGLEnable fog_enable(hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG) ? GL_FOG : 0); | 2323 | BOOL use_fog = hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG); |
2324 | LLGLEnable fog_enable(use_fog && | ||
2325 | !gPipeline.canUseWindLightShadersOnObjects() ? GL_FOG : 0); | ||
1985 | gSky.updateFog(camera.getFar()); | 2326 | gSky.updateFog(camera.getFar()); |
2327 | if (!use_fog) | ||
2328 | { | ||
2329 | sUnderWaterRender = FALSE; | ||
2330 | } | ||
1986 | 2331 | ||
1987 | LLViewerImage::sDefaultImagep->bind(0); | 2332 | LLViewerImage::sDefaultImagep->bind(0); |
1988 | LLViewerImage::sDefaultImagep->setClamp(FALSE, FALSE); | 2333 | LLViewerImage::sDefaultImagep->setClamp(FALSE, FALSE); |
@@ -1993,13 +2338,10 @@ void LLPipeline::renderGeom(LLCamera& camera) | |||
1993 | // | 2338 | // |
1994 | // | 2339 | // |
1995 | stop_glerror(); | 2340 | stop_glerror(); |
1996 | BOOL did_hud_elements = LLDrawPoolWater::sSkipScreenCopy; | 2341 | BOOL occlude = sUseOcclusion > 1; |
1997 | BOOL occlude = sUseOcclusion; | 2342 | |
1998 | |||
1999 | U32 cur_type = 0; | 2343 | U32 cur_type = 0; |
2000 | 2344 | ||
2001 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); | ||
2002 | |||
2003 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PICKING)) | 2345 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PICKING)) |
2004 | { | 2346 | { |
2005 | gObjectList.renderObjectsForSelect(camera); | 2347 | gObjectList.renderObjectsForSelect(camera); |
@@ -2008,6 +2350,8 @@ void LLPipeline::renderGeom(LLCamera& camera) | |||
2008 | { | 2350 | { |
2009 | LLFastTimer t(LLFastTimer::FTM_POOLS); | 2351 | LLFastTimer t(LLFastTimer::FTM_POOLS); |
2010 | calcNearbyLights(camera); | 2352 | calcNearbyLights(camera); |
2353 | setupHWLights(NULL); | ||
2354 | |||
2011 | pool_set_t::iterator iter1 = mPools.begin(); | 2355 | pool_set_t::iterator iter1 = mPools.begin(); |
2012 | while ( iter1 != mPools.end() ) | 2356 | while ( iter1 != mPools.end() ) |
2013 | { | 2357 | { |
@@ -2018,23 +2362,18 @@ void LLPipeline::renderGeom(LLCamera& camera) | |||
2018 | if (occlude && cur_type > LLDrawPool::POOL_AVATAR) | 2362 | if (occlude && cur_type > LLDrawPool::POOL_AVATAR) |
2019 | { | 2363 | { |
2020 | occlude = FALSE; | 2364 | occlude = FALSE; |
2365 | gGLLastMatrix = NULL; | ||
2366 | glLoadMatrixd(gGLModelView); | ||
2021 | doOcclusion(camera); | 2367 | doOcclusion(camera); |
2022 | } | 2368 | } |
2023 | 2369 | ||
2024 | if (cur_type > LLDrawPool::POOL_ALPHA_POST_WATER && !did_hud_elements) | ||
2025 | { | ||
2026 | renderHighlights(); | ||
2027 | // Draw 3D UI elements here (before we clear the Z buffer in POOL_HUD) | ||
2028 | render_hud_elements(); | ||
2029 | did_hud_elements = TRUE; | ||
2030 | } | ||
2031 | |||
2032 | pool_set_t::iterator iter2 = iter1; | 2370 | pool_set_t::iterator iter2 = iter1; |
2033 | if (hasRenderType(poolp->getType()) && poolp->getNumPasses() > 0) | 2371 | if (hasRenderType(poolp->getType()) && poolp->getNumPasses() > 0) |
2034 | { | 2372 | { |
2035 | LLFastTimer t(LLFastTimer::FTM_POOLRENDER); | 2373 | LLFastTimer t(LLFastTimer::FTM_POOLRENDER); |
2036 | 2374 | ||
2037 | setupHWLights(poolp); | 2375 | gGLLastMatrix = NULL; |
2376 | glLoadMatrixd(gGLModelView); | ||
2038 | 2377 | ||
2039 | for( S32 i = 0; i < poolp->getNumPasses(); i++ ) | 2378 | for( S32 i = 0; i < poolp->getNumPasses(); i++ ) |
2040 | { | 2379 | { |
@@ -2049,11 +2388,10 @@ void LLPipeline::renderGeom(LLCamera& camera) | |||
2049 | 2388 | ||
2050 | p->resetTrianglesDrawn(); | 2389 | p->resetTrianglesDrawn(); |
2051 | p->render(i); | 2390 | p->render(i); |
2052 | mTrianglesDrawn += p->getTrianglesDrawn(); | ||
2053 | } | 2391 | } |
2054 | poolp->endRenderPass(i); | 2392 | poolp->endRenderPass(i); |
2055 | #ifndef LL_RELEASE_FOR_DOWNLOAD | 2393 | #ifndef LL_RELEASE_FOR_DOWNLOAD |
2056 | #if LL_DEBUG_GL | 2394 | # if LL_DEBUG_GL |
2057 | GLint depth; | 2395 | GLint depth; |
2058 | glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); | 2396 | glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); |
2059 | if (depth > 3) | 2397 | if (depth > 3) |
@@ -2063,7 +2401,7 @@ void LLPipeline::renderGeom(LLCamera& camera) | |||
2063 | LLGLState::checkStates(); | 2401 | LLGLState::checkStates(); |
2064 | LLGLState::checkTextureChannels(); | 2402 | LLGLState::checkTextureChannels(); |
2065 | LLGLState::checkClientArrays(); | 2403 | LLGLState::checkClientArrays(); |
2066 | #endif | 2404 | # endif |
2067 | #endif | 2405 | #endif |
2068 | } | 2406 | } |
2069 | } | 2407 | } |
@@ -2090,94 +2428,69 @@ void LLPipeline::renderGeom(LLCamera& camera) | |||
2090 | LLGLState::checkClientArrays(); | 2428 | LLGLState::checkClientArrays(); |
2091 | #endif | 2429 | #endif |
2092 | 2430 | ||
2431 | gGLLastMatrix = NULL; | ||
2432 | glLoadMatrixd(gGLModelView); | ||
2433 | |||
2093 | if (occlude) | 2434 | if (occlude) |
2094 | { | 2435 | { |
2095 | doOcclusion(camera); | ||
2096 | occlude = FALSE; | 2436 | occlude = FALSE; |
2097 | } | 2437 | gGLLastMatrix = NULL; |
2098 | 2438 | glLoadMatrixd(gGLModelView); | |
2099 | if (!did_hud_elements) | 2439 | doOcclusion(camera); |
2100 | { | ||
2101 | renderHighlights(); | ||
2102 | render_hud_elements(); | ||
2103 | } | 2440 | } |
2104 | 2441 | ||
2105 | stop_glerror(); | 2442 | stop_glerror(); |
2106 | 2443 | ||
2107 | { | ||
2108 | LLVertexBuffer::stopRender(); | ||
2109 | } | ||
2110 | |||
2111 | #ifndef LL_RELEASE_FOR_DOWNLOAD | 2444 | #ifndef LL_RELEASE_FOR_DOWNLOAD |
2112 | LLGLState::checkStates(); | 2445 | LLGLState::checkStates(); |
2113 | LLGLState::checkTextureChannels(); | 2446 | LLGLState::checkTextureChannels(); |
2114 | LLGLState::checkClientArrays(); | 2447 | LLGLState::checkClientArrays(); |
2115 | #endif | 2448 | #endif |
2116 | 2449 | ||
2450 | if (!sReflectionRender) | ||
2451 | { | ||
2452 | renderHighlights(); | ||
2453 | } | ||
2454 | |||
2117 | // Contains a list of the faces of objects that are physical or | 2455 | // Contains a list of the faces of objects that are physical or |
2118 | // have touch-handlers. | 2456 | // have touch-handlers. |
2119 | mHighlightFaces.clear(); | 2457 | mHighlightFaces.clear(); |
2120 | 2458 | ||
2121 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | 2459 | render_hud_elements(); |
2122 | 2460 | ||
2123 | if (!hasRenderType(LLPipeline::RENDER_TYPE_HUD) && | 2461 | LLVertexBuffer::stopRender(); |
2124 | !LLDrawPoolWater::sSkipScreenCopy && | 2462 | LLVertexBuffer::unbind(); |
2125 | sRenderGlow && | 2463 | |
2126 | gGLManager.mHasFramebufferObject) | ||
2127 | { | ||
2128 | const U32 glow_res = nhpo2(gSavedSettings.getS32("RenderGlowResolution")); | ||
2129 | if (mGlowMap == 0) | ||
2130 | { | ||
2131 | glGenTextures(1, &mGlowMap); | ||
2132 | glBindTexture(GL_TEXTURE_2D, mGlowMap); | ||
2133 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
2134 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
2135 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
2136 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
2137 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glow_res, glow_res, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); | ||
2138 | } | ||
2139 | 2464 | ||
2140 | if (mGlowBuffer == 0) | 2465 | //HACK: preserve/restore matrices around HUD render |
2466 | if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) | ||
2467 | { | ||
2468 | for (U32 i = 0; i < 16; i++) | ||
2141 | { | 2469 | { |
2142 | glGenTextures(1, &mGlowBuffer); | 2470 | gGLModelView[i] = saved_modelview[i]; |
2143 | glBindTexture(GL_TEXTURE_2D, mGlowBuffer); | 2471 | gGLProjection[i] = saved_projection[i]; |
2144 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
2145 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
2146 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
2147 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
2148 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glow_res, glow_res, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); | ||
2149 | } | 2472 | } |
2150 | |||
2151 | bindScreenToTexture(); | ||
2152 | renderBloom(mScreenTex, mGlowMap, mGlowBuffer, glow_res, LLVector2(0,0), mScreenScale); | ||
2153 | } | 2473 | } |
2474 | |||
2475 | #ifndef LL_RELEASE_FOR_DOWNLOAD | ||
2476 | LLGLState::checkStates(); | ||
2477 | LLGLState::checkTextureChannels(); | ||
2478 | LLGLState::checkClientArrays(); | ||
2479 | #endif | ||
2154 | } | 2480 | } |
2155 | 2481 | ||
2156 | void LLPipeline::processOcclusion(LLCamera& camera) | 2482 | void LLPipeline::addTrianglesDrawn(S32 count) |
2157 | { | 2483 | { |
2158 | //process occlusion (readback) | 2484 | assertInitialized(); |
2159 | if (sUseOcclusion) | 2485 | mTrianglesDrawn += count; |
2486 | mBatchCount++; | ||
2487 | mMaxBatchSize = llmax(mMaxBatchSize, count); | ||
2488 | mMinBatchSize = llmin(mMinBatchSize, count); | ||
2489 | |||
2490 | if (LLPipeline::sRenderFrameTest) | ||
2160 | { | 2491 | { |
2161 | for (U32 i = 0; i < mObjectPartition.size(); i++) | 2492 | gViewerWindow->getWindow()->swapBuffers(); |
2162 | { | 2493 | ms_sleep(16); |
2163 | if (mObjectPartition[i] && hasRenderType(mObjectPartition[i]->mDrawableType)) | ||
2164 | { | ||
2165 | mObjectPartition[i]->processOcclusion(&camera); | ||
2166 | } | ||
2167 | } | ||
2168 | |||
2169 | #if AGGRESSIVE_OCCLUSION | ||
2170 | for (LLSpatialBridge::bridge_vector_t::iterator i = mOccludedBridge.begin(); i != mOccludedBridge.end(); ++i) | ||
2171 | { | ||
2172 | LLSpatialBridge* bridge = *i; | ||
2173 | if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) | ||
2174 | { | ||
2175 | LLCamera trans = bridge->transformCamera(camera); | ||
2176 | bridge->processOcclusion(&trans); | ||
2177 | } | ||
2178 | } | ||
2179 | #endif | ||
2180 | mOccludedBridge.clear(); | ||
2181 | } | 2494 | } |
2182 | } | 2495 | } |
2183 | 2496 | ||
@@ -2185,24 +2498,41 @@ void LLPipeline::renderDebug() | |||
2185 | { | 2498 | { |
2186 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 2499 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
2187 | 2500 | ||
2501 | assertInitialized(); | ||
2502 | |||
2503 | gGL.start(); | ||
2504 | |||
2188 | // Disable all client state | 2505 | // Disable all client state |
2189 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); | 2506 | //glDisableClientState(GL_TEXTURE_COORD_ARRAY); |
2190 | glDisableClientState(GL_NORMAL_ARRAY); | 2507 | //glDisableClientState(GL_NORMAL_ARRAY); |
2191 | glDisableClientState(GL_COLOR_ARRAY); | 2508 | //glDisableClientState(GL_COLOR_ARRAY); |
2509 | |||
2510 | gGLLastMatrix = NULL; | ||
2511 | glLoadMatrixd(gGLModelView); | ||
2512 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); | ||
2192 | 2513 | ||
2193 | // Debug stuff. | 2514 | // Debug stuff. |
2194 | for (U32 i = 0; i < mObjectPartition.size(); i++) | 2515 | for (LLWorld::region_list_t::iterator iter = gWorldp->getRegionList().begin(); |
2516 | iter != gWorldp->getRegionList().end(); ++iter) | ||
2195 | { | 2517 | { |
2196 | if (mObjectPartition[i] && hasRenderType(mObjectPartition[i]->mDrawableType)) | 2518 | LLViewerRegion* region = *iter; |
2519 | for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) | ||
2197 | { | 2520 | { |
2198 | mObjectPartition[i]->renderDebug(); | 2521 | LLSpatialPartition* part = region->getSpatialPartition(i); |
2522 | if (part) | ||
2523 | { | ||
2524 | if (hasRenderType(part->mDrawableType)) | ||
2525 | { | ||
2526 | part->renderDebug(); | ||
2527 | } | ||
2528 | } | ||
2199 | } | 2529 | } |
2200 | } | 2530 | } |
2201 | 2531 | ||
2202 | for (LLSpatialBridge::bridge_vector_t::iterator i = mVisibleBridge.begin(); i != mVisibleBridge.end(); ++i) | 2532 | for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) |
2203 | { | 2533 | { |
2204 | LLSpatialBridge* bridge = *i; | 2534 | LLSpatialBridge* bridge = *i; |
2205 | if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) | 2535 | if (!bridge->isDead() && !bridge->isState(LLSpatialGroup::OCCLUDED) && hasRenderType(bridge->mDrawableType)) |
2206 | { | 2536 | { |
2207 | glPushMatrix(); | 2537 | glPushMatrix(); |
2208 | glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); | 2538 | glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); |
@@ -2211,51 +2541,6 @@ void LLPipeline::renderDebug() | |||
2211 | } | 2541 | } |
2212 | } | 2542 | } |
2213 | 2543 | ||
2214 | if (mRenderDebugMask & LLPipeline::RENDER_DEBUG_LIGHT_TRACE) | ||
2215 | { | ||
2216 | LLGLSNoTexture no_texture; | ||
2217 | |||
2218 | LLVector3 pos, pos1; | ||
2219 | |||
2220 | for (LLDrawable::drawable_vector_t::iterator iter = mVisibleList.begin(); | ||
2221 | iter != mVisibleList.end(); iter++) | ||
2222 | { | ||
2223 | LLDrawable *drawablep = *iter; | ||
2224 | if (drawablep->isDead()) | ||
2225 | { | ||
2226 | continue; | ||
2227 | } | ||
2228 | for (LLDrawable::drawable_set_t::iterator iter = drawablep->mLightSet.begin(); | ||
2229 | iter != drawablep->mLightSet.end(); iter++) | ||
2230 | { | ||
2231 | LLDrawable *targetp = *iter; | ||
2232 | if (targetp->isDead() || !targetp->getVObj()->getNumTEs()) | ||
2233 | { | ||
2234 | continue; | ||
2235 | } | ||
2236 | else | ||
2237 | { | ||
2238 | if (targetp->getTextureEntry(0)) | ||
2239 | { | ||
2240 | if (drawablep->getVObj()->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) | ||
2241 | { | ||
2242 | glColor4f(0.f, 1.f, 0.f, 1.f); | ||
2243 | gObjectList.addDebugBeacon(drawablep->getPositionAgent(), "TC"); | ||
2244 | } | ||
2245 | else | ||
2246 | { | ||
2247 | glColor4fv (targetp->getTextureEntry(0)->getColor().mV); | ||
2248 | } | ||
2249 | glBegin(GL_LINES); | ||
2250 | glVertex3fv(targetp->getPositionAgent().mV); | ||
2251 | glVertex3fv(drawablep->getPositionAgent().mV); | ||
2252 | glEnd(); | ||
2253 | } | ||
2254 | } | ||
2255 | } | ||
2256 | } | ||
2257 | } | ||
2258 | |||
2259 | if (mRenderDebugMask & RENDER_DEBUG_COMPOSITION) | 2544 | if (mRenderDebugMask & RENDER_DEBUG_COMPOSITION) |
2260 | { | 2545 | { |
2261 | // Debug composition layers | 2546 | // Debug composition layers |
@@ -2263,9 +2548,9 @@ void LLPipeline::renderDebug() | |||
2263 | 2548 | ||
2264 | LLGLSNoTexture gls_no_texture; | 2549 | LLGLSNoTexture gls_no_texture; |
2265 | 2550 | ||
2266 | glBegin(GL_POINTS); | ||
2267 | if (gAgent.getRegion()) | 2551 | if (gAgent.getRegion()) |
2268 | { | 2552 | { |
2553 | gGL.begin(GL_POINTS); | ||
2269 | // Draw the composition layer for the region that I'm in. | 2554 | // Draw the composition layer for the region that I'm in. |
2270 | for (x = 0; x <= 260; x++) | 2555 | for (x = 0; x <= 260; x++) |
2271 | { | 2556 | { |
@@ -2273,25 +2558,36 @@ void LLPipeline::renderDebug() | |||
2273 | { | 2558 | { |
2274 | if ((x > 255) || (y > 255)) | 2559 | if ((x > 255) || (y > 255)) |
2275 | { | 2560 | { |
2276 | glColor4f(1.f, 0.f, 0.f, 1.f); | 2561 | gGL.color4f(1.f, 0.f, 0.f, 1.f); |
2277 | } | 2562 | } |
2278 | else | 2563 | else |
2279 | { | 2564 | { |
2280 | glColor4f(0.f, 0.f, 1.f, 1.f); | 2565 | gGL.color4f(0.f, 0.f, 1.f, 1.f); |
2281 | } | 2566 | } |
2282 | F32 z = gAgent.getRegion()->getCompositionXY((S32)x, (S32)y); | 2567 | F32 z = gAgent.getRegion()->getCompositionXY((S32)x, (S32)y); |
2283 | z *= 5.f; | 2568 | z *= 5.f; |
2284 | z += 50.f; | 2569 | z += 50.f; |
2285 | glVertex3f(x, y, z); | 2570 | gGL.vertex3f(x, y, z); |
2286 | } | 2571 | } |
2287 | } | 2572 | } |
2573 | gGL.end(); | ||
2288 | } | 2574 | } |
2289 | glEnd(); | ||
2290 | } | 2575 | } |
2576 | gGL.stop(); | ||
2291 | } | 2577 | } |
2292 | 2578 | ||
2293 | void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects) | 2579 | void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects) |
2294 | { | 2580 | { |
2581 | assertInitialized(); | ||
2582 | |||
2583 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); | ||
2584 | gPipeline.resetDrawOrders(); | ||
2585 | |||
2586 | for (std::set<LLViewerObject*>::iterator iter = objects.begin(); iter != objects.end(); ++iter) | ||
2587 | { | ||
2588 | stateSort((*iter)->mDrawable, *gCamera); | ||
2589 | } | ||
2590 | |||
2295 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 2591 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
2296 | 2592 | ||
2297 | LLVertexBuffer::startRender(); | 2593 | LLVertexBuffer::startRender(); |
@@ -2319,7 +2615,10 @@ void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects) | |||
2319 | { | 2615 | { |
2320 | LLFacePool* face_pool = (LLFacePool*) poolp; | 2616 | LLFacePool* face_pool = (LLFacePool*) poolp; |
2321 | face_pool->renderForSelect(); | 2617 | face_pool->renderForSelect(); |
2322 | 2618 | ||
2619 | gGLLastMatrix = NULL; | ||
2620 | glLoadMatrixd(gGLModelView); | ||
2621 | |||
2323 | #ifndef LL_RELEASE_FOR_DOWNLOAD | 2622 | #ifndef LL_RELEASE_FOR_DOWNLOAD |
2324 | if (poolp->getType() != last_type) | 2623 | if (poolp->getType() != last_type) |
2325 | { | 2624 | { |
@@ -2330,9 +2629,8 @@ void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects) | |||
2330 | } | 2629 | } |
2331 | #endif | 2630 | #endif |
2332 | } | 2631 | } |
2333 | } | 2632 | } |
2334 | 2633 | ||
2335 | LLGLEnable tex(GL_TEXTURE_2D); | ||
2336 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); | 2634 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
2337 | LLGLEnable alpha_test(GL_ALPHA_TEST); | 2635 | LLGLEnable alpha_test(GL_ALPHA_TEST); |
2338 | if (gPickTransparent) | 2636 | if (gPickTransparent) |
@@ -2387,17 +2685,22 @@ void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects) | |||
2387 | LLVOAvatar* avatarp = gAgent.getAvatarObject(); | 2685 | LLVOAvatar* avatarp = gAgent.getAvatarObject(); |
2388 | if (avatarp && sShowHUDAttachments) | 2686 | if (avatarp && sShowHUDAttachments) |
2389 | { | 2687 | { |
2390 | glMatrixMode(GL_PROJECTION); | 2688 | glh::matrix4f save_proj(glh_get_current_projection()); |
2391 | glPushMatrix(); | 2689 | glh::matrix4f save_model(glh_get_current_modelview()); |
2392 | glMatrixMode(GL_MODELVIEW); | 2690 | |
2393 | glPushMatrix(); | 2691 | U32 viewport[4]; |
2394 | 2692 | ||
2693 | for (U32 i = 0; i < 4; i++) | ||
2694 | { | ||
2695 | viewport[i] = gGLViewport[i]; | ||
2696 | } | ||
2697 | |||
2395 | setup_hud_matrices(TRUE); | 2698 | setup_hud_matrices(TRUE); |
2396 | LLViewerJointAttachment* attachmentp; | 2699 | for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); |
2397 | for (attachmentp = avatarp->mAttachmentPoints.getFirstData(); | 2700 | iter != avatarp->mAttachmentPoints.end(); ) |
2398 | attachmentp; | ||
2399 | attachmentp = avatarp->mAttachmentPoints.getNextData()) | ||
2400 | { | 2701 | { |
2702 | LLVOAvatar::attachment_map_t::iterator curiter = iter++; | ||
2703 | LLViewerJointAttachment* attachmentp = curiter->second; | ||
2401 | if (attachmentp->getIsHUDAttachment()) | 2704 | if (attachmentp->getIsHUDAttachment()) |
2402 | { | 2705 | { |
2403 | LLViewerObject* objectp = attachmentp->getObject(); | 2706 | LLViewerObject* objectp = attachmentp->getObject(); |
@@ -2436,15 +2739,27 @@ void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects) | |||
2436 | } | 2739 | } |
2437 | 2740 | ||
2438 | glMatrixMode(GL_PROJECTION); | 2741 | glMatrixMode(GL_PROJECTION); |
2439 | glPopMatrix(); | 2742 | glLoadMatrixf(save_proj.m); |
2743 | glh_set_current_projection(save_proj); | ||
2744 | |||
2440 | glMatrixMode(GL_MODELVIEW); | 2745 | glMatrixMode(GL_MODELVIEW); |
2441 | glPopMatrix(); | 2746 | glLoadMatrixf(save_model.m); |
2747 | glh_set_current_modelview(save_model); | ||
2748 | |||
2749 | |||
2750 | for (U32 i = 0; i < 4; i++) | ||
2751 | { | ||
2752 | gGLViewport[i] = viewport[i]; | ||
2753 | } | ||
2754 | glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); | ||
2442 | } | 2755 | } |
2443 | 2756 | ||
2444 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | 2757 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); |
2445 | glDisableClientState( GL_TEXTURE_COORD_ARRAY ); | 2758 | glDisableClientState( GL_TEXTURE_COORD_ARRAY ); |
2446 | 2759 | ||
2447 | LLVertexBuffer::stopRender(); | 2760 | LLVertexBuffer::stopRender(); |
2761 | |||
2762 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | ||
2448 | } | 2763 | } |
2449 | 2764 | ||
2450 | void LLPipeline::renderFaceForUVSelect(LLFace* facep) | 2765 | void LLPipeline::renderFaceForUVSelect(LLFace* facep) |
@@ -2455,6 +2770,9 @@ void LLPipeline::renderFaceForUVSelect(LLFace* facep) | |||
2455 | void LLPipeline::rebuildPools() | 2770 | void LLPipeline::rebuildPools() |
2456 | { | 2771 | { |
2457 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 2772 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
2773 | |||
2774 | assertInitialized(); | ||
2775 | |||
2458 | S32 max_count = mPools.size(); | 2776 | S32 max_count = mPools.size(); |
2459 | pool_set_t::iterator iter1 = mPools.upper_bound(mLastRebuildPool); | 2777 | pool_set_t::iterator iter1 = mPools.upper_bound(mLastRebuildPool); |
2460 | while(max_count > 0 && mPools.size() > 0) // && num_rebuilds < MAX_REBUILDS) | 2778 | while(max_count > 0 && mPools.size() > 0) // && num_rebuilds < MAX_REBUILDS) |
@@ -2492,6 +2810,9 @@ void LLPipeline::rebuildPools() | |||
2492 | void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) | 2810 | void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) |
2493 | { | 2811 | { |
2494 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 2812 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
2813 | |||
2814 | assertInitialized(); | ||
2815 | |||
2495 | switch( new_poolp->getType() ) | 2816 | switch( new_poolp->getType() ) |
2496 | { | 2817 | { |
2497 | case LLDrawPool::POOL_SIMPLE: | 2818 | case LLDrawPool::POOL_SIMPLE: |
@@ -2506,6 +2827,18 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) | |||
2506 | } | 2827 | } |
2507 | break; | 2828 | break; |
2508 | 2829 | ||
2830 | case LLDrawPool::POOL_INVISIBLE: | ||
2831 | if (mInvisiblePool) | ||
2832 | { | ||
2833 | llassert(0); | ||
2834 | llwarns << "Ignoring duplicate simple pool." << llendl; | ||
2835 | } | ||
2836 | else | ||
2837 | { | ||
2838 | mInvisiblePool = (LLRenderPass*) new_poolp; | ||
2839 | } | ||
2840 | break; | ||
2841 | |||
2509 | case LLDrawPool::POOL_GLOW: | 2842 | case LLDrawPool::POOL_GLOW: |
2510 | if (mGlowPool) | 2843 | if (mGlowPool) |
2511 | { | 2844 | { |
@@ -2550,18 +2883,6 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) | |||
2550 | } | 2883 | } |
2551 | break; | 2884 | break; |
2552 | 2885 | ||
2553 | case LLDrawPool::POOL_ALPHA_POST_WATER: | ||
2554 | if( mAlphaPoolPostWater ) | ||
2555 | { | ||
2556 | llassert(0); | ||
2557 | llwarns << "LLPipeline::addPool(): Ignoring duplicate Alpha pool" << llendl; | ||
2558 | } | ||
2559 | else | ||
2560 | { | ||
2561 | mAlphaPoolPostWater = new_poolp; | ||
2562 | } | ||
2563 | break; | ||
2564 | |||
2565 | case LLDrawPool::POOL_AVATAR: | 2886 | case LLDrawPool::POOL_AVATAR: |
2566 | break; // Do nothing | 2887 | break; // Do nothing |
2567 | 2888 | ||
@@ -2576,18 +2897,6 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) | |||
2576 | mSkyPool = new_poolp; | 2897 | mSkyPool = new_poolp; |
2577 | } | 2898 | } |
2578 | break; | 2899 | break; |
2579 | |||
2580 | case LLDrawPool::POOL_STARS: | ||
2581 | if( mStarsPool ) | ||
2582 | { | ||
2583 | llassert(0); | ||
2584 | llwarns << "LLPipeline::addPool(): Ignoring duplicate Stars pool" << llendl; | ||
2585 | } | ||
2586 | else | ||
2587 | { | ||
2588 | mStarsPool = new_poolp; | ||
2589 | } | ||
2590 | break; | ||
2591 | 2900 | ||
2592 | case LLDrawPool::POOL_WATER: | 2901 | case LLDrawPool::POOL_WATER: |
2593 | if( mWaterPool ) | 2902 | if( mWaterPool ) |
@@ -2613,6 +2922,18 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) | |||
2613 | } | 2922 | } |
2614 | break; | 2923 | break; |
2615 | 2924 | ||
2925 | case LLDrawPool::POOL_WL_SKY: | ||
2926 | if( mWLSkyPool ) | ||
2927 | { | ||
2928 | llassert(0); | ||
2929 | llwarns << "LLPipeline::addPool(): Ignoring duplicate WLSky Pool" << llendl; | ||
2930 | } | ||
2931 | else | ||
2932 | { | ||
2933 | mWLSkyPool = new_poolp; | ||
2934 | } | ||
2935 | break; | ||
2936 | |||
2616 | default: | 2937 | default: |
2617 | llassert(0); | 2938 | llassert(0); |
2618 | llwarns << "Invalid Pool Type in LLPipeline::addPool()" << llendl; | 2939 | llwarns << "Invalid Pool Type in LLPipeline::addPool()" << llendl; |
@@ -2622,6 +2943,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) | |||
2622 | 2943 | ||
2623 | void LLPipeline::removePool( LLDrawPool* poolp ) | 2944 | void LLPipeline::removePool( LLDrawPool* poolp ) |
2624 | { | 2945 | { |
2946 | assertInitialized(); | ||
2625 | removeFromQuickLookup(poolp); | 2947 | removeFromQuickLookup(poolp); |
2626 | mPools.erase(poolp); | 2948 | mPools.erase(poolp); |
2627 | delete poolp; | 2949 | delete poolp; |
@@ -2629,6 +2951,7 @@ void LLPipeline::removePool( LLDrawPool* poolp ) | |||
2629 | 2951 | ||
2630 | void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) | 2952 | void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) |
2631 | { | 2953 | { |
2954 | assertInitialized(); | ||
2632 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 2955 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
2633 | switch( poolp->getType() ) | 2956 | switch( poolp->getType() ) |
2634 | { | 2957 | { |
@@ -2637,6 +2960,16 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) | |||
2637 | mSimplePool = NULL; | 2960 | mSimplePool = NULL; |
2638 | break; | 2961 | break; |
2639 | 2962 | ||
2963 | case LLDrawPool::POOL_INVISIBLE: | ||
2964 | llassert(mInvisiblePool == poolp); | ||
2965 | mInvisiblePool = NULL; | ||
2966 | break; | ||
2967 | |||
2968 | case LLDrawPool::POOL_WL_SKY: | ||
2969 | llassert(mWLSkyPool == poolp); | ||
2970 | mWLSkyPool = NULL; | ||
2971 | break; | ||
2972 | |||
2640 | case LLDrawPool::POOL_GLOW: | 2973 | case LLDrawPool::POOL_GLOW: |
2641 | llassert(mGlowPool == poolp); | 2974 | llassert(mGlowPool == poolp); |
2642 | mGlowPool = NULL; | 2975 | mGlowPool = NULL; |
@@ -2674,11 +3007,6 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) | |||
2674 | mAlphaPool = NULL; | 3007 | mAlphaPool = NULL; |
2675 | break; | 3008 | break; |
2676 | 3009 | ||
2677 | case LLDrawPool::POOL_ALPHA_POST_WATER: | ||
2678 | llassert( poolp == mAlphaPoolPostWater ); | ||
2679 | mAlphaPoolPostWater = NULL; | ||
2680 | break; | ||
2681 | |||
2682 | case LLDrawPool::POOL_AVATAR: | 3010 | case LLDrawPool::POOL_AVATAR: |
2683 | break; // Do nothing | 3011 | break; // Do nothing |
2684 | 3012 | ||
@@ -2687,11 +3015,6 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) | |||
2687 | mSkyPool = NULL; | 3015 | mSkyPool = NULL; |
2688 | break; | 3016 | break; |
2689 | 3017 | ||
2690 | case LLDrawPool::POOL_STARS: | ||
2691 | llassert( poolp == mStarsPool ); | ||
2692 | mStarsPool = NULL; | ||
2693 | break; | ||
2694 | |||
2695 | case LLDrawPool::POOL_WATER: | 3018 | case LLDrawPool::POOL_WATER: |
2696 | llassert( poolp == mWaterPool ); | 3019 | llassert( poolp == mWaterPool ); |
2697 | mWaterPool = NULL; | 3020 | mWaterPool = NULL; |
@@ -2711,6 +3034,7 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) | |||
2711 | 3034 | ||
2712 | void LLPipeline::resetDrawOrders() | 3035 | void LLPipeline::resetDrawOrders() |
2713 | { | 3036 | { |
3037 | assertInitialized(); | ||
2714 | // Iterate through all of the draw pools and rebuild them. | 3038 | // Iterate through all of the draw pools and rebuild them. |
2715 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) | 3039 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) |
2716 | { | 3040 | { |
@@ -2725,7 +3049,7 @@ void LLPipeline::resetDrawOrders() | |||
2725 | 3049 | ||
2726 | void LLPipeline::setupAvatarLights(BOOL for_edit) | 3050 | void LLPipeline::setupAvatarLights(BOOL for_edit) |
2727 | { | 3051 | { |
2728 | const LLColor4 black(0,0,0,1); | 3052 | assertInitialized(); |
2729 | 3053 | ||
2730 | if (for_edit) | 3054 | if (for_edit) |
2731 | { | 3055 | { |
@@ -2740,8 +3064,8 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) | |||
2740 | 3064 | ||
2741 | mHWLightColors[1] = diffuse; | 3065 | mHWLightColors[1] = diffuse; |
2742 | glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse.mV); | 3066 | glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse.mV); |
2743 | glLightfv(GL_LIGHT1, GL_AMBIENT, black.mV); | 3067 | glLightfv(GL_LIGHT1, GL_AMBIENT, LLColor4::black.mV); |
2744 | glLightfv(GL_LIGHT1, GL_SPECULAR, black.mV); | 3068 | glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV); |
2745 | glLightfv(GL_LIGHT1, GL_POSITION, light_pos.mV); | 3069 | glLightfv(GL_LIGHT1, GL_POSITION, light_pos.mV); |
2746 | glLightf (GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0f); | 3070 | glLightf (GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0f); |
2747 | glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f); | 3071 | glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f); |
@@ -2756,7 +3080,7 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) | |||
2756 | LLVector4 backlight_pos = LLVector4(lerp(opposite_pos, orthog_light_pos, 0.3f), 0.0f); | 3080 | LLVector4 backlight_pos = LLVector4(lerp(opposite_pos, orthog_light_pos, 0.3f), 0.0f); |
2757 | backlight_pos.normVec(); | 3081 | backlight_pos.normVec(); |
2758 | 3082 | ||
2759 | LLColor4 light_diffuse = mSunDiffuse * mSunShadowFactor; | 3083 | LLColor4 light_diffuse = mSunDiffuse; |
2760 | LLColor4 backlight_diffuse(1.f - light_diffuse.mV[VRED], 1.f - light_diffuse.mV[VGREEN], 1.f - light_diffuse.mV[VBLUE], 1.f); | 3084 | LLColor4 backlight_diffuse(1.f - light_diffuse.mV[VRED], 1.f - light_diffuse.mV[VGREEN], 1.f - light_diffuse.mV[VBLUE], 1.f); |
2761 | F32 max_component = 0.001f; | 3085 | F32 max_component = 0.001f; |
2762 | for (S32 i = 0; i < 3; i++) | 3086 | for (S32 i = 0; i < 3; i++) |
@@ -2780,8 +3104,8 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) | |||
2780 | mHWLightColors[1] = backlight_diffuse; | 3104 | mHWLightColors[1] = backlight_diffuse; |
2781 | glLightfv(GL_LIGHT1, GL_POSITION, backlight_pos.mV); // this is just sun/moon direction | 3105 | glLightfv(GL_LIGHT1, GL_POSITION, backlight_pos.mV); // this is just sun/moon direction |
2782 | glLightfv(GL_LIGHT1, GL_DIFFUSE, backlight_diffuse.mV); | 3106 | glLightfv(GL_LIGHT1, GL_DIFFUSE, backlight_diffuse.mV); |
2783 | glLightfv(GL_LIGHT1, GL_AMBIENT, black.mV); | 3107 | glLightfv(GL_LIGHT1, GL_AMBIENT, LLColor4::black.mV); |
2784 | glLightfv(GL_LIGHT1, GL_SPECULAR, black.mV); | 3108 | glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV); |
2785 | glLightf (GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0f); | 3109 | glLightf (GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0f); |
2786 | glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f); | 3110 | glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f); |
2787 | glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f); | 3111 | glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f); |
@@ -2790,10 +3114,10 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) | |||
2790 | } | 3114 | } |
2791 | else | 3115 | else |
2792 | { | 3116 | { |
2793 | mHWLightColors[1] = black; | 3117 | mHWLightColors[1] = LLColor4::black; |
2794 | glLightfv(GL_LIGHT1, GL_DIFFUSE, black.mV); | 3118 | glLightfv(GL_LIGHT1, GL_DIFFUSE, LLColor4::black.mV); |
2795 | glLightfv(GL_LIGHT1, GL_AMBIENT, black.mV); | 3119 | glLightfv(GL_LIGHT1, GL_AMBIENT, LLColor4::black.mV); |
2796 | glLightfv(GL_LIGHT1, GL_SPECULAR, black.mV); | 3120 | glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV); |
2797 | } | 3121 | } |
2798 | } | 3122 | } |
2799 | 3123 | ||
@@ -2829,13 +3153,15 @@ static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_ | |||
2829 | 3153 | ||
2830 | void LLPipeline::calcNearbyLights(LLCamera& camera) | 3154 | void LLPipeline::calcNearbyLights(LLCamera& camera) |
2831 | { | 3155 | { |
3156 | assertInitialized(); | ||
3157 | |||
2832 | if (mLightingDetail >= 1) | 3158 | if (mLightingDetail >= 1) |
2833 | { | 3159 | { |
2834 | // mNearbyLight (and all light_set_t's) are sorted such that | 3160 | // mNearbyLight (and all light_set_t's) are sorted such that |
2835 | // begin() == the closest light and rbegin() == the farthest light | 3161 | // begin() == the closest light and rbegin() == the farthest light |
2836 | const S32 MAX_LOCAL_LIGHTS = 6; | 3162 | const S32 MAX_LOCAL_LIGHTS = 6; |
2837 | // LLVector3 cam_pos = gAgent.getCameraPositionAgent(); | 3163 | // LLVector3 cam_pos = gAgent.getCameraPositionAgent(); |
2838 | LLVector3 cam_pos = LLPipeline::sSkipUpdate || LLViewerJoystick::sOverrideCamera ? | 3164 | LLVector3 cam_pos = LLViewerJoystick::sOverrideCamera ? |
2839 | camera.getOrigin() : | 3165 | camera.getOrigin() : |
2840 | gAgent.getPositionAgent(); | 3166 | gAgent.getPositionAgent(); |
2841 | 3167 | ||
@@ -2933,7 +3259,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) | |||
2933 | 3259 | ||
2934 | void LLPipeline::setupHWLights(LLDrawPool* pool) | 3260 | void LLPipeline::setupHWLights(LLDrawPool* pool) |
2935 | { | 3261 | { |
2936 | const LLColor4 black(0,0,0,1); | 3262 | assertInitialized(); |
2937 | 3263 | ||
2938 | // Ambient | 3264 | // Ambient |
2939 | LLColor4 ambient = gSky.getTotalAmbientColor(); | 3265 | LLColor4 ambient = gSky.getTotalAmbientColor(); |
@@ -2941,7 +3267,6 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) | |||
2941 | 3267 | ||
2942 | // Light 0 = Sun or Moon (All objects) | 3268 | // Light 0 = Sun or Moon (All objects) |
2943 | { | 3269 | { |
2944 | mSunShadowFactor = 1.f; // no shadowing by defailt | ||
2945 | if (gSky.getSunDirection().mV[2] >= NIGHTTIME_ELEVATION_COS) | 3270 | if (gSky.getSunDirection().mV[2] >= NIGHTTIME_ELEVATION_COS) |
2946 | { | 3271 | { |
2947 | mSunDir.setVec(gSky.getSunDirection()); | 3272 | mSunDir.setVec(gSky.getSunDirection()); |
@@ -2950,7 +3275,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) | |||
2950 | else | 3275 | else |
2951 | { | 3276 | { |
2952 | mSunDir.setVec(gSky.getMoonDirection()); | 3277 | mSunDir.setVec(gSky.getMoonDirection()); |
2953 | mSunDiffuse.setVec(gSky.getMoonDiffuseColor() * 1.5f); | 3278 | mSunDiffuse.setVec(gSky.getMoonDiffuseColor()); |
2954 | } | 3279 | } |
2955 | 3280 | ||
2956 | F32 max_color = llmax(mSunDiffuse.mV[0], mSunDiffuse.mV[1], mSunDiffuse.mV[2]); | 3281 | F32 max_color = llmax(mSunDiffuse.mV[0], mSunDiffuse.mV[1], mSunDiffuse.mV[2]); |
@@ -2961,12 +3286,12 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) | |||
2961 | mSunDiffuse.clamp(); | 3286 | mSunDiffuse.clamp(); |
2962 | 3287 | ||
2963 | LLVector4 light_pos(mSunDir, 0.0f); | 3288 | LLVector4 light_pos(mSunDir, 0.0f); |
2964 | LLColor4 light_diffuse = mSunDiffuse * mSunShadowFactor; | 3289 | LLColor4 light_diffuse = mSunDiffuse; |
2965 | mHWLightColors[0] = light_diffuse; | 3290 | mHWLightColors[0] = light_diffuse; |
2966 | glLightfv(GL_LIGHT0, GL_POSITION, light_pos.mV); // this is just sun/moon direction | 3291 | glLightfv(GL_LIGHT0, GL_POSITION, light_pos.mV); // this is just sun/moon direction |
2967 | glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse.mV); | 3292 | glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse.mV); |
2968 | glLightfv(GL_LIGHT0, GL_AMBIENT, black.mV); | 3293 | glLightfv(GL_LIGHT0, GL_AMBIENT, LLColor4::black.mV); |
2969 | glLightfv(GL_LIGHT0, GL_SPECULAR, black.mV); | 3294 | glLightfv(GL_LIGHT0, GL_SPECULAR, LLColor4::black.mV); |
2970 | glLightf (GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0f); | 3295 | glLightf (GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0f); |
2971 | glLightf (GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.0f); | 3296 | glLightf (GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.0f); |
2972 | glLightf (GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.0f); | 3297 | glLightf (GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.0f); |
@@ -3002,7 +3327,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) | |||
3002 | LLColor4 light_color = light->getLightColor(); | 3327 | LLColor4 light_color = light->getLightColor(); |
3003 | light_color.mV[3] = 0.0f; | 3328 | light_color.mV[3] = 0.0f; |
3004 | 3329 | ||
3005 | F32 fade = LLPipeline::sSkipUpdate ? 1.f : iter->fade; | 3330 | F32 fade = iter->fade; |
3006 | if (fade < LIGHT_FADE_TIME) | 3331 | if (fade < LIGHT_FADE_TIME) |
3007 | { | 3332 | { |
3008 | // fade in/out light | 3333 | // fade in/out light |
@@ -3043,8 +3368,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) | |||
3043 | S32 gllight = GL_LIGHT0+cur_light; | 3368 | S32 gllight = GL_LIGHT0+cur_light; |
3044 | glLightfv(gllight, GL_POSITION, light_pos_gl.mV); | 3369 | glLightfv(gllight, GL_POSITION, light_pos_gl.mV); |
3045 | glLightfv(gllight, GL_DIFFUSE, light_color.mV); | 3370 | glLightfv(gllight, GL_DIFFUSE, light_color.mV); |
3046 | glLightfv(gllight, GL_AMBIENT, black.mV); | 3371 | glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV); |
3047 | glLightfv(gllight, GL_SPECULAR, black.mV); | 3372 | glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV); |
3048 | glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f); | 3373 | glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f); |
3049 | glLightf (gllight, GL_LINEAR_ATTENUATION, atten); | 3374 | glLightf (gllight, GL_LINEAR_ATTENUATION, atten); |
3050 | glLightf (gllight, GL_QUADRATIC_ATTENUATION, quad); | 3375 | glLightf (gllight, GL_QUADRATIC_ATTENUATION, quad); |
@@ -3059,11 +3384,41 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) | |||
3059 | } | 3384 | } |
3060 | for ( ; cur_light < 8 ; cur_light++) | 3385 | for ( ; cur_light < 8 ; cur_light++) |
3061 | { | 3386 | { |
3062 | mHWLightColors[cur_light] = black; | 3387 | mHWLightColors[cur_light] = LLColor4::black; |
3063 | S32 gllight = GL_LIGHT0+cur_light; | 3388 | S32 gllight = GL_LIGHT0+cur_light; |
3064 | glLightfv(gllight, GL_DIFFUSE, black.mV); | 3389 | glLightfv(gllight, GL_DIFFUSE, LLColor4::black.mV); |
3065 | glLightfv(gllight, GL_AMBIENT, black.mV); | 3390 | glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV); |
3066 | glLightfv(gllight, GL_SPECULAR, black.mV); | 3391 | glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV); |
3392 | } | ||
3393 | |||
3394 | if (gAgent.getAvatarObject() && | ||
3395 | gAgent.getAvatarObject()->mSpecialRenderMode == 3) | ||
3396 | { | ||
3397 | LLColor4 light_color = LLColor4::white; | ||
3398 | light_color.mV[3] = 0.0f; | ||
3399 | |||
3400 | LLVector3 light_pos(gCamera->getOrigin()); | ||
3401 | LLVector4 light_pos_gl(light_pos, 1.0f); | ||
3402 | |||
3403 | F32 light_radius = 16.f; | ||
3404 | F32 atten, quad; | ||
3405 | |||
3406 | { | ||
3407 | F32 x = 3.f; | ||
3408 | atten = x / (light_radius); // % of brightness at radius | ||
3409 | quad = 0.0f; | ||
3410 | } | ||
3411 | //mHWLightColors[cur_light] = light_color; | ||
3412 | S32 gllight = GL_LIGHT2; | ||
3413 | glLightfv(gllight, GL_POSITION, light_pos_gl.mV); | ||
3414 | glLightfv(gllight, GL_DIFFUSE, light_color.mV); | ||
3415 | glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV); | ||
3416 | glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV); | ||
3417 | glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f); | ||
3418 | glLightf (gllight, GL_LINEAR_ATTENUATION, atten); | ||
3419 | glLightf (gllight, GL_QUADRATIC_ATTENUATION, quad); | ||
3420 | glLightf (gllight, GL_SPOT_EXPONENT, 0.0f); | ||
3421 | glLightf (gllight, GL_SPOT_CUTOFF, 180.0f); | ||
3067 | } | 3422 | } |
3068 | 3423 | ||
3069 | // Init GL state | 3424 | // Init GL state |
@@ -3075,8 +3430,9 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) | |||
3075 | mLightMask = 0; | 3430 | mLightMask = 0; |
3076 | } | 3431 | } |
3077 | 3432 | ||
3078 | void LLPipeline::enableLights(U32 mask, F32 shadow_factor) | 3433 | void LLPipeline::enableLights(U32 mask) |
3079 | { | 3434 | { |
3435 | assertInitialized(); | ||
3080 | if (mLightingDetail == 0) | 3436 | if (mLightingDetail == 0) |
3081 | { | 3437 | { |
3082 | mask &= 0xf003; // sun and backlight only (and fullbright bit) | 3438 | mask &= 0xf003; // sun and backlight only (and fullbright bit) |
@@ -3113,8 +3469,9 @@ void LLPipeline::enableLights(U32 mask, F32 shadow_factor) | |||
3113 | } | 3469 | } |
3114 | } | 3470 | } |
3115 | 3471 | ||
3116 | void LLPipeline::enableLightsStatic(F32 shadow_factor) | 3472 | void LLPipeline::enableLightsStatic() |
3117 | { | 3473 | { |
3474 | assertInitialized(); | ||
3118 | U32 mask = 0x01; // Sun | 3475 | U32 mask = 0x01; // Sun |
3119 | if (mLightingDetail >= 2) | 3476 | if (mLightingDetail >= 2) |
3120 | { | 3477 | { |
@@ -3125,39 +3482,55 @@ void LLPipeline::enableLightsStatic(F32 shadow_factor) | |||
3125 | { | 3482 | { |
3126 | mask |= 0xff & (~2); // Hardware local lights | 3483 | mask |= 0xff & (~2); // Hardware local lights |
3127 | } | 3484 | } |
3128 | enableLights(mask, shadow_factor); | 3485 | enableLights(mask); |
3129 | } | 3486 | } |
3130 | 3487 | ||
3131 | void LLPipeline::enableLightsDynamic(F32 shadow_factor) | 3488 | void LLPipeline::enableLightsDynamic() |
3132 | { | 3489 | { |
3490 | assertInitialized(); | ||
3133 | U32 mask = 0xff & (~2); // Local lights | 3491 | U32 mask = 0xff & (~2); // Local lights |
3134 | enableLights(mask, shadow_factor); | 3492 | enableLights(mask); |
3135 | if (mLightingDetail >= 2) | 3493 | if (mLightingDetail >= 2) |
3136 | { | 3494 | { |
3137 | glColor4f(0.f, 0.f, 0.f, 1.f); // no local lighting by default | 3495 | glColor4f(0.f, 0.f, 0.f, 1.f); // no local lighting by default |
3138 | } | 3496 | } |
3497 | |||
3498 | LLVOAvatar* avatarp = gAgent.getAvatarObject(); | ||
3499 | |||
3500 | if (avatarp && getLightingDetail() <= 0) | ||
3501 | { | ||
3502 | if (avatarp->mSpecialRenderMode == 0) // normal | ||
3503 | { | ||
3504 | gPipeline.enableLightsAvatar(); | ||
3505 | } | ||
3506 | else if (avatarp->mSpecialRenderMode >= 1) // anim preview | ||
3507 | { | ||
3508 | gPipeline.enableLightsAvatarEdit(LLColor4(0.7f, 0.6f, 0.3f, 1.f)); | ||
3509 | } | ||
3510 | } | ||
3139 | } | 3511 | } |
3140 | 3512 | ||
3141 | void LLPipeline::enableLightsAvatar(F32 shadow_factor) | 3513 | void LLPipeline::enableLightsAvatar() |
3142 | { | 3514 | { |
3143 | U32 mask = 0xff; // All lights | 3515 | U32 mask = 0xff; // All lights |
3144 | setupAvatarLights(FALSE); | 3516 | setupAvatarLights(FALSE); |
3145 | enableLights(mask, shadow_factor); | 3517 | enableLights(mask); |
3146 | } | 3518 | } |
3147 | 3519 | ||
3148 | void LLPipeline::enableLightsAvatarEdit(const LLColor4& color) | 3520 | void LLPipeline::enableLightsAvatarEdit(const LLColor4& color) |
3149 | { | 3521 | { |
3150 | U32 mask = 0x2002; // Avatar backlight only, set ambient | 3522 | U32 mask = 0x2002; // Avatar backlight only, set ambient |
3151 | setupAvatarLights(TRUE); | 3523 | setupAvatarLights(TRUE); |
3152 | enableLights(mask, 1.0f); | 3524 | enableLights(mask); |
3153 | 3525 | ||
3154 | glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV); | 3526 | glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV); |
3155 | } | 3527 | } |
3156 | 3528 | ||
3157 | void LLPipeline::enableLightsFullbright(const LLColor4& color) | 3529 | void LLPipeline::enableLightsFullbright(const LLColor4& color) |
3158 | { | 3530 | { |
3531 | assertInitialized(); | ||
3159 | U32 mask = 0x1000; // Non-0 mask, set ambient | 3532 | U32 mask = 0x1000; // Non-0 mask, set ambient |
3160 | enableLights(mask, 1.f); | 3533 | enableLights(mask); |
3161 | 3534 | ||
3162 | glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV); | 3535 | glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV); |
3163 | if (mLightingDetail >= 2) | 3536 | if (mLightingDetail >= 2) |
@@ -3168,19 +3541,10 @@ void LLPipeline::enableLightsFullbright(const LLColor4& color) | |||
3168 | 3541 | ||
3169 | void LLPipeline::disableLights() | 3542 | void LLPipeline::disableLights() |
3170 | { | 3543 | { |
3171 | enableLights(0, 0.f); // no lighting (full bright) | 3544 | enableLights(0); // no lighting (full bright) |
3172 | glColor4f(1.f, 1.f, 1.f, 1.f); // lighting color = white by default | 3545 | glColor4f(1.f, 1.f, 1.f, 1.f); // lighting color = white by default |
3173 | } | 3546 | } |
3174 | 3547 | ||
3175 | // Call *after*s etting up lights | ||
3176 | void LLPipeline::setAmbient(const LLColor4& ambient) | ||
3177 | { | ||
3178 | mLightMask |= 0x4000; // tweak mask so that ambient will get reset | ||
3179 | LLColor4 amb = ambient + gSky.getTotalAmbientColor(); | ||
3180 | amb.clamp(); | ||
3181 | glLightModelfv(GL_LIGHT_MODEL_AMBIENT,amb.mV); | ||
3182 | } | ||
3183 | |||
3184 | //============================================================================ | 3548 | //============================================================================ |
3185 | 3549 | ||
3186 | class LLMenuItemGL; | 3550 | class LLMenuItemGL; |
@@ -3188,55 +3552,10 @@ class LLInvFVBridge; | |||
3188 | struct cat_folder_pair; | 3552 | struct cat_folder_pair; |
3189 | class LLVOBranch; | 3553 | class LLVOBranch; |
3190 | class LLVOLeaf; | 3554 | class LLVOLeaf; |
3191 | class Foo; | ||
3192 | |||
3193 | void scale_stamp(const F32 x, const F32 y, const F32 xs, const F32 ys) | ||
3194 | { | ||
3195 | stamp(0.25f + 0.5f*x, | ||
3196 | 0.5f + 0.45f*y, | ||
3197 | 0.5f*xs, | ||
3198 | 0.45f*ys); | ||
3199 | } | ||
3200 | |||
3201 | void drawBars(const F32 begin, const F32 end, const F32 height = 1.f) | ||
3202 | { | ||
3203 | if (begin >= 0 && end <=1) | ||
3204 | { | ||
3205 | F32 lines = 40.0f; | ||
3206 | S32 ibegin = (S32)(begin * lines); | ||
3207 | S32 iend = (S32)(end * lines); | ||
3208 | F32 fbegin = begin * lines - ibegin; | ||
3209 | F32 fend = end * lines - iend; | ||
3210 | |||
3211 | F32 line_height = height/lines; | ||
3212 | |||
3213 | if (iend == ibegin) | ||
3214 | { | ||
3215 | scale_stamp(fbegin, (F32)ibegin/lines,fend-fbegin, line_height); | ||
3216 | } | ||
3217 | else | ||
3218 | { | ||
3219 | // Beginning row | ||
3220 | scale_stamp(fbegin, (F32)ibegin/lines, 1.0f-fbegin, line_height); | ||
3221 | |||
3222 | // End row | ||
3223 | scale_stamp(0.0, (F32)iend/lines, fend, line_height); | ||
3224 | |||
3225 | // Middle rows | ||
3226 | for (S32 l = (ibegin+1); l < iend; l++) | ||
3227 | { | ||
3228 | scale_stamp(0.0f, (F32)l/lines, 1.0f, line_height); | ||
3229 | } | ||
3230 | } | ||
3231 | } | ||
3232 | } | ||
3233 | 3555 | ||
3234 | void LLPipeline::findReferences(LLDrawable *drawablep) | 3556 | void LLPipeline::findReferences(LLDrawable *drawablep) |
3235 | { | 3557 | { |
3236 | if (std::find(mVisibleList.begin(), mVisibleList.end(), drawablep) != mVisibleList.end()) | 3558 | assertInitialized(); |
3237 | { | ||
3238 | llinfos << "In mVisibleList" << llendl; | ||
3239 | } | ||
3240 | if (mLights.find(drawablep) != mLights.end()) | 3559 | if (mLights.find(drawablep) != mLights.end()) |
3241 | { | 3560 | { |
3242 | llinfos << "In mLights" << llendl; | 3561 | llinfos << "In mLights" << llendl; |
@@ -3278,13 +3597,16 @@ void LLPipeline::findReferences(LLDrawable *drawablep) | |||
3278 | 3597 | ||
3279 | BOOL LLPipeline::verify() | 3598 | BOOL LLPipeline::verify() |
3280 | { | 3599 | { |
3281 | BOOL ok = TRUE; | 3600 | BOOL ok = assertInitialized(); |
3282 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) | 3601 | if (ok) |
3283 | { | 3602 | { |
3284 | LLDrawPool *poolp = *iter; | 3603 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) |
3285 | if (!poolp->verify()) | ||
3286 | { | 3604 | { |
3287 | ok = FALSE; | 3605 | LLDrawPool *poolp = *iter; |
3606 | if (!poolp->verify()) | ||
3607 | { | ||
3608 | ok = FALSE; | ||
3609 | } | ||
3288 | } | 3610 | } |
3289 | } | 3611 | } |
3290 | 3612 | ||
@@ -3396,7 +3718,7 @@ bool LLRayAABB(const LLVector3 ¢er, const LLVector3 &size, const LLVector3& | |||
3396 | 3718 | ||
3397 | void LLPipeline::setLight(LLDrawable *drawablep, BOOL is_light) | 3719 | void LLPipeline::setLight(LLDrawable *drawablep, BOOL is_light) |
3398 | { | 3720 | { |
3399 | if (drawablep) | 3721 | if (drawablep && assertInitialized()) |
3400 | { | 3722 | { |
3401 | if (is_light) | 3723 | if (is_light) |
3402 | { | 3724 | { |
@@ -3408,12 +3730,12 @@ void LLPipeline::setLight(LLDrawable *drawablep, BOOL is_light) | |||
3408 | drawablep->clearState(LLDrawable::LIGHT); | 3730 | drawablep->clearState(LLDrawable::LIGHT); |
3409 | mLights.erase(drawablep); | 3731 | mLights.erase(drawablep); |
3410 | } | 3732 | } |
3411 | markRelight(drawablep); | ||
3412 | } | 3733 | } |
3413 | } | 3734 | } |
3414 | 3735 | ||
3415 | void LLPipeline::setActive(LLDrawable *drawablep, BOOL active) | 3736 | void LLPipeline::setActive(LLDrawable *drawablep, BOOL active) |
3416 | { | 3737 | { |
3738 | assertInitialized(); | ||
3417 | if (active) | 3739 | if (active) |
3418 | { | 3740 | { |
3419 | mActiveQ.insert(drawablep); | 3741 | mActiveQ.insert(drawablep); |
@@ -3634,7 +3956,22 @@ BOOL LLPipeline::getProcessBeacons(void* data) | |||
3634 | 3956 | ||
3635 | LLViewerObject* LLPipeline::pickObject(const LLVector3 &start, const LLVector3 &end, LLVector3 &collision) | 3957 | LLViewerObject* LLPipeline::pickObject(const LLVector3 &start, const LLVector3 &end, LLVector3 &collision) |
3636 | { | 3958 | { |
3637 | LLDrawable* drawable = mObjectPartition[PARTITION_VOLUME]->pickDrawable(start, end, collision); | 3959 | LLDrawable* drawable = NULL; |
3960 | |||
3961 | for (LLWorld::region_list_t::iterator iter = gWorldp->getRegionList().begin(); | ||
3962 | iter != gWorldp->getRegionList().end(); ++iter) | ||
3963 | { | ||
3964 | LLViewerRegion* region = *iter; | ||
3965 | LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_VOLUME); | ||
3966 | if (part) | ||
3967 | { | ||
3968 | LLDrawable* hit = part->pickDrawable(start, end, collision); | ||
3969 | if (hit) | ||
3970 | { | ||
3971 | drawable = hit; | ||
3972 | } | ||
3973 | } | ||
3974 | } | ||
3638 | return drawable ? drawable->getVObj().get() : NULL; | 3975 | return drawable ? drawable->getVObj().get() : NULL; |
3639 | } | 3976 | } |
3640 | 3977 | ||
@@ -3642,31 +3979,23 @@ LLSpatialPartition* LLPipeline::getSpatialPartition(LLViewerObject* vobj) | |||
3642 | { | 3979 | { |
3643 | if (vobj) | 3980 | if (vobj) |
3644 | { | 3981 | { |
3645 | return getSpatialPartition(vobj->getPartitionType()); | 3982 | LLViewerRegion* region = vobj->getRegion(); |
3983 | if (region) | ||
3984 | { | ||
3985 | return region->getSpatialPartition(vobj->getPartitionType()); | ||
3986 | } | ||
3646 | } | 3987 | } |
3647 | return NULL; | 3988 | return NULL; |
3648 | } | 3989 | } |
3649 | 3990 | ||
3650 | LLSpatialPartition* LLPipeline::getSpatialPartition(U32 type) | ||
3651 | { | ||
3652 | if (type < mObjectPartition.size()) | ||
3653 | { | ||
3654 | return mObjectPartition[type]; | ||
3655 | } | ||
3656 | return NULL; | ||
3657 | } | ||
3658 | 3991 | ||
3659 | void LLPipeline::clearRenderMap() | 3992 | void LLPipeline::resetVertexBuffers(LLDrawable* drawable) |
3660 | { | 3993 | { |
3661 | for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) | 3994 | if (!drawable || drawable->isDead()) |
3662 | { | 3995 | { |
3663 | mRenderMap[i].clear(); | 3996 | return; |
3664 | } | 3997 | } |
3665 | } | ||
3666 | |||
3667 | 3998 | ||
3668 | void LLPipeline::resetVertexBuffers(LLDrawable* drawable) | ||
3669 | { | ||
3670 | if (!drawable) | 3999 | if (!drawable) |
3671 | { | 4000 | { |
3672 | return; | 4001 | return; |
@@ -3682,36 +4011,63 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable) | |||
3682 | 4011 | ||
3683 | void LLPipeline::resetVertexBuffers() | 4012 | void LLPipeline::resetVertexBuffers() |
3684 | { | 4013 | { |
3685 | for (U32 i = 0; i < mObjectPartition.size(); ++i) | 4014 | sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); |
4015 | |||
4016 | if (gWorldp) | ||
3686 | { | 4017 | { |
3687 | if (mObjectPartition[i]) | 4018 | for (LLWorld::region_list_t::iterator iter = gWorldp->getRegionList().begin(); |
4019 | iter != gWorldp->getRegionList().end(); ++iter) | ||
3688 | { | 4020 | { |
3689 | mObjectPartition[i]->resetVertexBuffers(); | 4021 | LLViewerRegion* region = *iter; |
4022 | for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) | ||
4023 | { | ||
4024 | LLSpatialPartition* part = region->getSpatialPartition(i); | ||
4025 | if (part) | ||
4026 | { | ||
4027 | part->resetVertexBuffers(); | ||
4028 | } | ||
4029 | } | ||
3690 | } | 4030 | } |
3691 | } | 4031 | } |
3692 | 4032 | ||
3693 | resetDrawOrders(); | 4033 | resetDrawOrders(); |
3694 | 4034 | ||
3695 | if (gSky.mVOSkyp.notNull()) | 4035 | gSky.resetVertexBuffers(); |
4036 | |||
4037 | if (LLVertexBuffer::sGLCount > 0) | ||
3696 | { | 4038 | { |
3697 | resetVertexBuffers(gSky.mVOSkyp->mDrawable); | 4039 | LLVertexBuffer::cleanupClass(); |
3698 | resetVertexBuffers(gSky.mVOGroundp->mDrawable); | ||
3699 | resetVertexBuffers(gSky.mVOStarsp->mDrawable); | ||
3700 | markRebuild(gSky.mVOSkyp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); | ||
3701 | markRebuild(gSky.mVOGroundp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); | ||
3702 | markRebuild(gSky.mVOStarsp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); | ||
3703 | } | 4040 | } |
3704 | 4041 | ||
4042 | //delete all name pool caches | ||
4043 | LLGLNamePool::cleanupPools(); | ||
4044 | |||
3705 | if (LLVertexBuffer::sGLCount > 0) | 4045 | if (LLVertexBuffer::sGLCount > 0) |
3706 | { | 4046 | { |
3707 | LLVertexBuffer::cleanupClass(); | 4047 | llwarns << "VBO wipe failed." << llendl; |
3708 | } | 4048 | } |
4049 | |||
4050 | if (!LLVertexBuffer::sStreamIBOPool.mNameList.empty() || | ||
4051 | !LLVertexBuffer::sStreamVBOPool.mNameList.empty() || | ||
4052 | !LLVertexBuffer::sDynamicIBOPool.mNameList.empty() || | ||
4053 | !LLVertexBuffer::sDynamicVBOPool.mNameList.empty()) | ||
4054 | { | ||
4055 | llwarns << "VBO name pool cleanup failed." << llendl; | ||
4056 | } | ||
4057 | |||
4058 | LLVertexBuffer::unbind(); | ||
4059 | |||
4060 | LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind"); | ||
3709 | } | 4061 | } |
3710 | 4062 | ||
3711 | void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture) | 4063 | void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture) |
3712 | { | 4064 | { |
3713 | mSimplePool->renderStatic(type, mask, texture); | 4065 | assertInitialized(); |
3714 | mSimplePool->renderActive(type, mask, texture); | 4066 | gGLLastMatrix = NULL; |
4067 | glLoadMatrixd(gGLLastModelView); | ||
4068 | mSimplePool->renderGroups(type, mask, texture); | ||
4069 | gGLLastMatrix = NULL; | ||
4070 | glLoadMatrixd(gGLLastModelView); | ||
3715 | } | 4071 | } |
3716 | 4072 | ||
3717 | void LLPipeline::setUseVBO(BOOL use_vbo) | 4073 | void LLPipeline::setUseVBO(BOOL use_vbo) |
@@ -3759,26 +4115,42 @@ void apply_cube_face_rotation(U32 face) | |||
3759 | break; | 4115 | break; |
3760 | } | 4116 | } |
3761 | } | 4117 | } |
3762 | void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam, GLsizei res) | 4118 | void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam) |
3763 | { | 4119 | { |
4120 | #ifndef LL_RELEASE_FOR_DOWNLOAD | ||
4121 | LLGLState::checkStates(); | ||
4122 | LLGLState::checkTextureChannels(); | ||
4123 | LLGLState::checkClientArrays(); | ||
4124 | #endif | ||
4125 | |||
4126 | assertInitialized(); | ||
4127 | |||
3764 | //render dynamic cube map | 4128 | //render dynamic cube map |
3765 | U32 type_mask = gPipeline.getRenderTypeMask(); | 4129 | U32 type_mask = gPipeline.getRenderTypeMask(); |
3766 | BOOL use_occlusion = LLPipeline::sUseOcclusion; | 4130 | S32 use_occlusion = LLPipeline::sUseOcclusion; |
3767 | LLPipeline::sUseOcclusion = FALSE; | 4131 | LLPipeline::sUseOcclusion = 0; |
3768 | LLPipeline::sSkipUpdate = TRUE; | 4132 | LLPipeline::sSkipUpdate = TRUE; |
3769 | static GLuint blur_tex = 0; | 4133 | U32 res = REFLECTION_MAP_RES; |
3770 | if (!blur_tex) | ||
3771 | { | ||
3772 | glGenTextures(1, &blur_tex); | ||
3773 | } | ||
3774 | 4134 | ||
3775 | BOOL reattach = FALSE; | 4135 | LLPipeline::sReflectionRender = TRUE; |
3776 | if (mCubeFrameBuffer == 0) | 4136 | |
3777 | { | 4137 | cube_map->bind(); |
3778 | glGenFramebuffersEXT(1, &mCubeFrameBuffer); | 4138 | GLint width; |
3779 | glGenRenderbuffersEXT(1, &mCubeDepth); | 4139 | glGetTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL_TEXTURE_WIDTH, &width); |
3780 | reattach = TRUE; | 4140 | if (width != res) |
4141 | { | ||
4142 | glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
4143 | glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
4144 | glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
4145 | glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
4146 | |||
4147 | for (U32 i = 0; i < 6; i++) | ||
4148 | { | ||
4149 | glTexImage2D(gl_cube_face[i], 0, GL_RGBA, res, res, 0, GL_RGBA, GL_FLOAT, NULL); | ||
4150 | } | ||
3781 | } | 4151 | } |
4152 | glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0); | ||
4153 | cube_map->disable(); | ||
3782 | 4154 | ||
3783 | BOOL toggle_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); | 4155 | BOOL toggle_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); |
3784 | if (toggle_ui) | 4156 | if (toggle_ui) |
@@ -3788,10 +4160,9 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam, | |||
3788 | 4160 | ||
3789 | U32 cube_mask = (1 << LLPipeline::RENDER_TYPE_SIMPLE) | | 4161 | U32 cube_mask = (1 << LLPipeline::RENDER_TYPE_SIMPLE) | |
3790 | (1 << LLPipeline::RENDER_TYPE_WATER) | | 4162 | (1 << LLPipeline::RENDER_TYPE_WATER) | |
3791 | (1 << LLPipeline::RENDER_TYPE_BUMP) | | 4163 | //(1 << LLPipeline::RENDER_TYPE_BUMP) | |
3792 | (1 << LLPipeline::RENDER_TYPE_ALPHA) | | 4164 | (1 << LLPipeline::RENDER_TYPE_ALPHA) | |
3793 | (1 << LLPipeline::RENDER_TYPE_TREE) | | 4165 | (1 << LLPipeline::RENDER_TYPE_TREE) | |
3794 | (1 << LLDrawPool::POOL_ALPHA_POST_WATER) | | ||
3795 | //(1 << LLPipeline::RENDER_TYPE_PARTICLES) | | 4166 | //(1 << LLPipeline::RENDER_TYPE_PARTICLES) | |
3796 | (1 << LLPipeline::RENDER_TYPE_CLOUDS) | | 4167 | (1 << LLPipeline::RENDER_TYPE_CLOUDS) | |
3797 | //(1 << LLPipeline::RENDER_TYPE_STARS) | | 4168 | //(1 << LLPipeline::RENDER_TYPE_STARS) | |
@@ -3801,9 +4172,11 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam, | |||
3801 | (1 << LLPipeline::RENDER_TYPE_VOLUME) | | 4172 | (1 << LLPipeline::RENDER_TYPE_VOLUME) | |
3802 | (1 << LLPipeline::RENDER_TYPE_TERRAIN) | | 4173 | (1 << LLPipeline::RENDER_TYPE_TERRAIN) | |
3803 | (1 << LLPipeline::RENDER_TYPE_SKY) | | 4174 | (1 << LLPipeline::RENDER_TYPE_SKY) | |
4175 | (1 << LLPipeline::RENDER_TYPE_WL_SKY) | | ||
3804 | (1 << LLPipeline::RENDER_TYPE_GROUND); | 4176 | (1 << LLPipeline::RENDER_TYPE_GROUND); |
3805 | 4177 | ||
3806 | LLDrawPoolWater::sSkipScreenCopy = TRUE; | 4178 | LLDrawPoolWater::sSkipScreenCopy = TRUE; |
4179 | LLPipeline::sSkipUpdate = TRUE; | ||
3807 | cube_mask = cube_mask & type_mask; | 4180 | cube_mask = cube_mask & type_mask; |
3808 | gPipeline.setRenderTypeMask(cube_mask); | 4181 | gPipeline.setRenderTypeMask(cube_mask); |
3809 | 4182 | ||
@@ -3816,57 +4189,23 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam, | |||
3816 | 4189 | ||
3817 | glClearColor(0,0,0,0); | 4190 | glClearColor(0,0,0,0); |
3818 | 4191 | ||
3819 | U32 cube_face[] = | ||
3820 | { | ||
3821 | GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, | ||
3822 | GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, | ||
3823 | GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, | ||
3824 | GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, | ||
3825 | GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, | ||
3826 | GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, | ||
3827 | }; | ||
3828 | |||
3829 | LLVector3 origin = cube_cam.getOrigin(); | 4192 | LLVector3 origin = cube_cam.getOrigin(); |
3830 | 4193 | ||
3831 | gPipeline.calcNearbyLights(cube_cam); | 4194 | gPipeline.calcNearbyLights(cube_cam); |
3832 | 4195 | ||
3833 | cube_map->bind(); | 4196 | stop_glerror(); |
3834 | for (S32 i = 0; i < 6; i++) | 4197 | LLViewerImage::unbindTexture(0, GL_TEXTURE_2D); |
3835 | { | 4198 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mCubeFrameBuffer); |
3836 | GLint res_x, res_y; | 4199 | glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, |
3837 | glGetTexLevelParameteriv(cube_face[i], 0, GL_TEXTURE_WIDTH, &res_x); | 4200 | GL_RENDERBUFFER_EXT, mCubeDepth); |
3838 | glGetTexLevelParameteriv(cube_face[i], 0, GL_TEXTURE_HEIGHT, &res_y); | 4201 | stop_glerror(); |
3839 | |||
3840 | if (res_x != res || res_y != res) | ||
3841 | { | ||
3842 | glTexImage2D(cube_face[i],0,GL_RGBA,res,res,0,GL_RGBA,GL_FLOAT,NULL); | ||
3843 | reattach = TRUE; | ||
3844 | } | ||
3845 | } | ||
3846 | cube_map->disable(); | ||
3847 | |||
3848 | if (reattach) | ||
3849 | { | ||
3850 | glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mCubeDepth); | ||
3851 | GLint res_x, res_y; | ||
3852 | glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_WIDTH_EXT, &res_x); | ||
3853 | glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_HEIGHT_EXT, &res_y); | ||
3854 | |||
3855 | if (res_x != res || res_y != res) | ||
3856 | { | ||
3857 | glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,GL_DEPTH_COMPONENT24,res,res); | ||
3858 | } | ||
3859 | |||
3860 | glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); | ||
3861 | } | ||
3862 | 4202 | ||
3863 | for (S32 i = 0; i < 6; i++) | 4203 | for (S32 i = 0; i < 6; i++) |
3864 | { | 4204 | { |
3865 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mCubeFrameBuffer); | 4205 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mCubeFrameBuffer); |
3866 | glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, | 4206 | glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, |
3867 | cube_face[i], cube_map->getGLName(), 0); | 4207 | gl_cube_face[i], cube_map->getGLName(), 0); |
3868 | glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, | 4208 | validate_framebuffer_object(); |
3869 | GL_RENDERBUFFER_EXT, mCubeDepth); | ||
3870 | glMatrixMode(GL_PROJECTION); | 4209 | glMatrixMode(GL_PROJECTION); |
3871 | glLoadIdentity(); | 4210 | glLoadIdentity(); |
3872 | gluPerspective(90.f, 1.f, 0.1f, 1024.f); | 4211 | gluPerspective(90.f, 1.f, 0.1f, 1024.f); |
@@ -3879,23 +4218,29 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam, | |||
3879 | cube_cam.setOrigin(origin); | 4218 | cube_cam.setOrigin(origin); |
3880 | LLViewerCamera::updateFrustumPlanes(cube_cam); | 4219 | LLViewerCamera::updateFrustumPlanes(cube_cam); |
3881 | cube_cam.setOrigin(gCamera->getOrigin()); | 4220 | cube_cam.setOrigin(gCamera->getOrigin()); |
3882 | gPipeline.updateCull(cube_cam); | 4221 | static LLCullResult result; |
3883 | gPipeline.stateSort(cube_cam); | 4222 | gPipeline.updateCull(cube_cam, result); |
4223 | gPipeline.stateSort(cube_cam, result); | ||
3884 | 4224 | ||
4225 | glClearColor(0,0,0,0); | ||
4226 | glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); | ||
3885 | glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); | 4227 | glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); |
4228 | glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE); | ||
4229 | stop_glerror(); | ||
3886 | gPipeline.renderGeom(cube_cam); | 4230 | gPipeline.renderGeom(cube_cam); |
3887 | } | 4231 | } |
3888 | 4232 | ||
3889 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); | 4233 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); |
3890 | 4234 | ||
3891 | cube_cam.setOrigin(origin); | 4235 | cube_cam.setOrigin(origin); |
3892 | gPipeline.resetDrawOrders(); | ||
3893 | gShinyOrigin.setVec(cube_cam.getOrigin(), cube_cam.getFar()*2.f); | 4236 | gShinyOrigin.setVec(cube_cam.getOrigin(), cube_cam.getFar()*2.f); |
3894 | glMatrixMode(GL_PROJECTION); | 4237 | glMatrixMode(GL_PROJECTION); |
3895 | glPopMatrix(); | 4238 | glPopMatrix(); |
3896 | glMatrixMode(GL_MODELVIEW); | 4239 | glMatrixMode(GL_MODELVIEW); |
3897 | glPopMatrix(); | 4240 | glPopMatrix(); |
3898 | 4241 | ||
4242 | gViewerWindow->setupViewport(); | ||
4243 | |||
3899 | gPipeline.setRenderTypeMask(type_mask); | 4244 | gPipeline.setRenderTypeMask(type_mask); |
3900 | LLPipeline::sUseOcclusion = use_occlusion; | 4245 | LLPipeline::sUseOcclusion = use_occlusion; |
3901 | LLPipeline::sSkipUpdate = FALSE; | 4246 | LLPipeline::sSkipUpdate = FALSE; |
@@ -3905,12 +4250,21 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam, | |||
3905 | gPipeline.toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI); | 4250 | gPipeline.toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI); |
3906 | } | 4251 | } |
3907 | LLDrawPoolWater::sSkipScreenCopy = FALSE; | 4252 | LLDrawPoolWater::sSkipScreenCopy = FALSE; |
4253 | LLPipeline::sSkipUpdate = FALSE; | ||
4254 | LLPipeline::sReflectionRender = FALSE; | ||
4255 | |||
4256 | #ifndef LL_RELEASE_FOR_DOWNLOAD | ||
4257 | LLGLState::checkStates(); | ||
4258 | LLGLState::checkTextureChannels(); | ||
4259 | LLGLState::checkClientArrays(); | ||
4260 | #endif | ||
4261 | |||
3908 | } | 4262 | } |
3909 | 4263 | ||
3910 | //send cube map vertices and texture coordinates | 4264 | //send cube map vertices and texture coordinates |
3911 | void render_cube_map() | 4265 | void render_cube_map() |
3912 | { | 4266 | { |
3913 | U32 idx[36]; | 4267 | U16 idx[36]; |
3914 | 4268 | ||
3915 | idx[0] = 1; idx[1] = 0; idx[2] = 2; //front | 4269 | idx[0] = 1; idx[1] = 0; idx[2] = 2; //front |
3916 | idx[3] = 3; idx[4] = 2; idx[5] = 0; | 4270 | idx[3] = 3; idx[4] = 2; idx[5] = 0; |
@@ -3943,18 +4297,54 @@ void render_cube_map() | |||
3943 | vert[6] = r.scaledVec(LLVector3(-1,-1,-1)); // 6 - right bottom back | 4297 | vert[6] = r.scaledVec(LLVector3(-1,-1,-1)); // 6 - right bottom back |
3944 | vert[7] = r.scaledVec(LLVector3(1,-1,-1)); // 7 -left bottom back | 4298 | vert[7] = r.scaledVec(LLVector3(1,-1,-1)); // 7 -left bottom back |
3945 | 4299 | ||
3946 | glBegin(GL_TRIANGLES); | 4300 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
3947 | for (U32 i = 0; i < 36; i++) | 4301 | glTexCoordPointer(3, GL_FLOAT, 0, vert); |
3948 | { | 4302 | glVertexPointer(3, GL_FLOAT, 0, vert); |
3949 | glTexCoord3fv(vert[idx[i]].mV); | 4303 | |
3950 | glVertex3fv(vert[idx[i]].mV); | 4304 | glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, (GLushort*) idx); |
4305 | |||
4306 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); | ||
4307 | } | ||
4308 | |||
4309 | void validate_framebuffer_object() | ||
4310 | { | ||
4311 | GLenum status; | ||
4312 | status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); | ||
4313 | switch(status) | ||
4314 | { | ||
4315 | case GL_FRAMEBUFFER_COMPLETE_EXT: | ||
4316 | //framebuffer OK, no error. | ||
4317 | break; | ||
4318 | case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: | ||
4319 | // frame buffer not OK: probably means unsupported depth buffer format | ||
4320 | llerrs << "Framebuffer Incomplete Dimensions." << llendl; | ||
4321 | break; | ||
4322 | case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: | ||
4323 | // frame buffer not OK: probably means unsupported depth buffer format | ||
4324 | llerrs << "Framebuffer Incomplete Attachment." << llendl; | ||
4325 | break; | ||
4326 | case GL_FRAMEBUFFER_UNSUPPORTED_EXT: | ||
4327 | /* choose different formats */ | ||
4328 | llerrs << "Framebuffer unsupported." << llendl; | ||
4329 | break; | ||
4330 | default: | ||
4331 | llerrs << "Unknown framebuffer status." << llendl; | ||
4332 | break; | ||
3951 | } | 4333 | } |
3952 | glEnd(); | ||
3953 | } | 4334 | } |
3954 | 4335 | ||
3955 | void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out, U32 res) | 4336 | void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out) |
3956 | { | 4337 | { |
3957 | LLGLEnable cube(GL_TEXTURE_CUBE_MAP_ARB); | 4338 | #ifndef LL_RELEASE_FOR_DOWNLOAD |
4339 | LLGLState::checkStates(); | ||
4340 | LLGLState::checkTextureChannels(); | ||
4341 | LLGLState::checkClientArrays(); | ||
4342 | #endif | ||
4343 | |||
4344 | assertInitialized(); | ||
4345 | |||
4346 | U32 res = (U32) gSavedSettings.getS32("RenderReflectionRes"); | ||
4347 | enableLightsFullbright(LLColor4::white); | ||
3958 | LLGLDepthTest depth(GL_FALSE); | 4348 | LLGLDepthTest depth(GL_FALSE); |
3959 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | 4349 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
3960 | glMatrixMode(GL_PROJECTION); | 4350 | glMatrixMode(GL_PROJECTION); |
@@ -3964,27 +4354,33 @@ void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out, U32 | |||
3964 | glMatrixMode(GL_MODELVIEW); | 4354 | glMatrixMode(GL_MODELVIEW); |
3965 | glPushMatrix(); | 4355 | glPushMatrix(); |
3966 | 4356 | ||
4357 | cube_out->enableTexture(0); | ||
4358 | cube_out->bind(); | ||
4359 | GLint width; | ||
4360 | glGetTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL_TEXTURE_WIDTH, &width); | ||
4361 | if (width != res) | ||
4362 | { | ||
4363 | glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
4364 | glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
4365 | glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
4366 | glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
4367 | |||
4368 | for (U32 i = 0; i < 6; i++) | ||
4369 | { | ||
4370 | glTexImage2D(gl_cube_face[i], 0, GL_RGBA, res, res, 0, GL_RGBA, GL_FLOAT, NULL); | ||
4371 | } | ||
4372 | } | ||
4373 | glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0); | ||
4374 | |||
3967 | glViewport(0, 0, res, res); | 4375 | glViewport(0, 0, res, res); |
3968 | LLGLEnable blend(GL_BLEND); | 4376 | LLGLEnable blend(GL_BLEND); |
3969 | 4377 | ||
3970 | S32 kernel = 2; | 4378 | S32 kernel = 2; |
3971 | F32 step = 90.f/res; | 4379 | F32 step = 90.f/res; |
3972 | F32 alpha = 1.f/((kernel*2)+1); | 4380 | F32 alpha = 1.f / ((kernel*2)+1); |
3973 | |||
3974 | glColor4f(alpha,alpha,alpha,alpha*1.25f); | ||
3975 | |||
3976 | S32 x = 0; | ||
3977 | |||
3978 | U32 cube_face[] = | ||
3979 | { | ||
3980 | GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, | ||
3981 | GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, | ||
3982 | GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, | ||
3983 | GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, | ||
3984 | GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, | ||
3985 | GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, | ||
3986 | }; | ||
3987 | 4381 | ||
4382 | gGL.color4f(alpha,alpha,alpha,alpha*1.25f); | ||
4383 | |||
3988 | LLVector3 axis[] = | 4384 | LLVector3 axis[] = |
3989 | { | 4385 | { |
3990 | LLVector3(1,0,0), | 4386 | LLVector3(1,0,0), |
@@ -3992,117 +4388,121 @@ void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out, U32 | |||
3992 | LLVector3(0,0,1) | 4388 | LLVector3(0,0,1) |
3993 | }; | 4389 | }; |
3994 | 4390 | ||
3995 | 4391 | stop_glerror(); | |
3996 | glBlendFunc(GL_ONE, GL_ONE); | 4392 | glViewport(0,0,res, res); |
4393 | gGL.blendFunc(GL_ONE, GL_ONE); | ||
4394 | cube_in->enableTexture(0); | ||
3997 | //3-axis blur | 4395 | //3-axis blur |
3998 | for (U32 j = 0; j < 3; j++) | 4396 | for (U32 j = 0; j < 3; j++) |
3999 | { | 4397 | { |
4000 | glViewport(0,0,res, res*6); | 4398 | stop_glerror(); |
4001 | glClear(GL_COLOR_BUFFER_BIT); | 4399 | |
4002 | if (j == 0) | 4400 | if (j == 0) |
4003 | { | 4401 | { |
4004 | cube_in->bind(); | 4402 | cube_in->bind(); |
4005 | } | 4403 | } |
4404 | else | ||
4405 | { | ||
4406 | glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mBlurCubeTexture[j-1]); | ||
4407 | } | ||
4408 | |||
4409 | stop_glerror(); | ||
4410 | |||
4411 | LLViewerImage::unbindTexture(0, GL_TEXTURE_2D); | ||
4412 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mBlurCubeBuffer[j]); | ||
4413 | stop_glerror(); | ||
4006 | 4414 | ||
4007 | for (U32 i = 0; i < 6; i++) | 4415 | for (U32 i = 0; i < 6; i++) |
4008 | { | 4416 | { |
4009 | glViewport(0,i*res, res, res); | 4417 | stop_glerror(); |
4418 | glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, | ||
4419 | GL_COLOR_ATTACHMENT0_EXT, | ||
4420 | gl_cube_face[i], | ||
4421 | j < 2 ? mBlurCubeTexture[j] : cube_out->getGLName(), 0); | ||
4422 | validate_framebuffer_object(); | ||
4423 | glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); | ||
4424 | glClear(GL_COLOR_BUFFER_BIT); | ||
4010 | glLoadIdentity(); | 4425 | glLoadIdentity(); |
4011 | apply_cube_face_rotation(i); | 4426 | apply_cube_face_rotation(i); |
4012 | for (x = -kernel; x <= kernel; ++x) | 4427 | for (S32 x = -kernel; x <= kernel; ++x) |
4013 | { | 4428 | { |
4014 | glPushMatrix(); | 4429 | glPushMatrix(); |
4015 | glRotatef(x*step, axis[j].mV[0], axis[j].mV[1], axis[j].mV[2]); | 4430 | glRotatef(x*step, axis[j].mV[0], axis[j].mV[1], axis[j].mV[2]); |
4016 | render_cube_map(); | 4431 | render_cube_map(); |
4017 | glPopMatrix(); | 4432 | glPopMatrix(); |
4018 | } | 4433 | } |
4434 | stop_glerror(); | ||
4019 | } | 4435 | } |
4020 | |||
4021 | //readback | ||
4022 | if (j == 0) | ||
4023 | { | ||
4024 | cube_out->bind(); | ||
4025 | } | ||
4026 | for (U32 i = 0; i < 6; i++) | ||
4027 | { | ||
4028 | glCopyTexImage2D(cube_face[i], 0, GL_RGBA, 0, i*res, res, res, 0); | ||
4029 | } | ||
4030 | } | 4436 | } |
4437 | |||
4438 | stop_glerror(); | ||
4439 | |||
4440 | glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0); | ||
4031 | 4441 | ||
4442 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); | ||
4443 | glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE); | ||
4032 | glMatrixMode(GL_PROJECTION); | 4444 | glMatrixMode(GL_PROJECTION); |
4033 | glPopMatrix(); | 4445 | glPopMatrix(); |
4034 | glMatrixMode(GL_MODELVIEW); | 4446 | glMatrixMode(GL_MODELVIEW); |
4035 | glPopMatrix(); | 4447 | glPopMatrix(); |
4036 | 4448 | ||
4037 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | 4449 | cube_in->disableTexture(); |
4038 | glClear(GL_COLOR_BUFFER_BIT); | 4450 | gViewerWindow->setupViewport(); |
4451 | gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
4452 | |||
4453 | #ifndef LL_RELEASE_FOR_DOWNLOAD | ||
4454 | LLGLState::checkStates(); | ||
4455 | LLGLState::checkTextureChannels(); | ||
4456 | LLGLState::checkClientArrays(); | ||
4457 | #endif | ||
4039 | } | 4458 | } |
4040 | 4459 | ||
4041 | void LLPipeline::bindScreenToTexture() | 4460 | void LLPipeline::bindScreenToTexture() |
4042 | { | 4461 | { |
4043 | LLGLEnable gl_texture_2d(GL_TEXTURE_2D); | 4462 | |
4044 | 4463 | } | |
4045 | GLint* viewport = (GLint*) gGLViewport; | ||
4046 | GLuint resX = nhpo2(viewport[2]); | ||
4047 | GLuint resY = nhpo2(viewport[3]); | ||
4048 | 4464 | ||
4049 | if (mScreenTex == 0) | 4465 | void LLPipeline::renderBloom(BOOL for_snapshot) |
4466 | { | ||
4467 | if (!(gPipeline.canUseVertexShaders() && | ||
4468 | sRenderGlow && | ||
4469 | gGLManager.mHasFramebufferObject)) | ||
4050 | { | 4470 | { |
4051 | glGenTextures(1, &mScreenTex); | 4471 | return; |
4052 | glBindTexture(GL_TEXTURE_2D, mScreenTex); | ||
4053 | |||
4054 | gImageList.updateMaxResidentTexMem(-1, resX*resY*3); | ||
4055 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, resX, resY, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); | ||
4056 | |||
4057 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
4058 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
4059 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
4060 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
4061 | } | 4472 | } |
4062 | 4473 | ||
4063 | glBindTexture(GL_TEXTURE_2D, mScreenTex); | 4474 | #ifndef LL_RELEASE_FOR_DOWNLOAD |
4064 | GLint cResX; | 4475 | LLGLState::checkStates(); |
4065 | GLint cResY; | 4476 | LLGLState::checkTextureChannels(); |
4066 | glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &cResX); | 4477 | #endif |
4067 | glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &cResY); | 4478 | |
4479 | assertInitialized(); | ||
4068 | 4480 | ||
4069 | if (cResX != (GLint)resX || cResY != (GLint)resY) | 4481 | if (gUseWireframe) |
4070 | { | 4482 | { |
4071 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, resX, resY, 0, GL_RGB, GL_FLOAT, NULL); | 4483 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); |
4072 | gImageList.updateMaxResidentTexMem(-1, resX*resY*3); | ||
4073 | } | 4484 | } |
4074 | 4485 | ||
4075 | glCopyTexSubImage2D(GL_TEXTURE_2D, 0, viewport[0], viewport[1], 0, 0, viewport[2], viewport[3]); | 4486 | U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor"); |
4076 | 4487 | ||
4077 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 4488 | LLVector2 tc1(0,0); |
4078 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 4489 | LLVector2 tc2((F32) gViewerWindow->getWindowDisplayWidth(), |
4079 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 4490 | (F32) gViewerWindow->getWindowDisplayHeight()); |
4080 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
4081 | |||
4082 | |||
4083 | mScreenScale.mV[0] = (float) viewport[2]/resX; | ||
4084 | mScreenScale.mV[1] = (float) viewport[3]/resY; | ||
4085 | |||
4086 | LLImageGL::sBoundTextureMemory += resX * resY * 3; | ||
4087 | } | ||
4088 | 4491 | ||
4089 | void LLPipeline::renderBloom(GLuint source, GLuint dest, GLuint buffer, U32 res, LLVector2 tc1, LLVector2 tc2) | 4492 | if (res_mod > 1) |
4090 | { | 4493 | { |
4091 | gGlowProgram.bind(); | 4494 | tc2 /= (F32) res_mod; |
4495 | } | ||
4092 | 4496 | ||
4093 | LLGLEnable tex(GL_TEXTURE_2D); | 4497 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
4498 | |||
4499 | LLFastTimer ftm(LLFastTimer::FTM_RENDER_BLOOM); | ||
4500 | gGL.start(); | ||
4094 | LLGLDepthTest depth(GL_FALSE); | 4501 | LLGLDepthTest depth(GL_FALSE); |
4095 | LLGLDisable blend(GL_BLEND); | 4502 | LLGLDisable blend(GL_BLEND); |
4096 | LLGLDisable cull(GL_CULL_FACE); | 4503 | LLGLDisable cull(GL_CULL_FACE); |
4097 | 4504 | ||
4098 | if (mFramebuffer[0] == 0) | 4505 | enableLightsFullbright(LLColor4(1,1,1,1)); |
4099 | { | ||
4100 | glGenFramebuffersEXT(2, mFramebuffer); | ||
4101 | } | ||
4102 | |||
4103 | GLint viewport[4]; | ||
4104 | glGetIntegerv(GL_VIEWPORT, viewport); | ||
4105 | glViewport(0,0,res,res); | ||
4106 | 4506 | ||
4107 | glMatrixMode(GL_PROJECTION); | 4507 | glMatrixMode(GL_PROJECTION); |
4108 | glPushMatrix(); | 4508 | glPushMatrix(); |
@@ -4111,82 +4511,769 @@ void LLPipeline::renderBloom(GLuint source, GLuint dest, GLuint buffer, U32 res, | |||
4111 | glPushMatrix(); | 4511 | glPushMatrix(); |
4112 | glLoadIdentity(); | 4512 | glLoadIdentity(); |
4113 | 4513 | ||
4114 | glBindTexture(GL_TEXTURE_2D, source); | ||
4115 | |||
4116 | S32 kernel = gSavedSettings.getS32("RenderGlowSize")*2; | ||
4117 | |||
4118 | LLGLDisable test(GL_ALPHA_TEST); | 4514 | LLGLDisable test(GL_ALPHA_TEST); |
4119 | 4515 | ||
4120 | F32 delta = 1.f/(res*gSavedSettings.getF32("RenderGlowStrength")); | 4516 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
4517 | glClearColor(0,0,0,0); | ||
4518 | |||
4519 | if (for_snapshot) | ||
4520 | { | ||
4521 | mGlow[1].bindTexture(); | ||
4522 | { | ||
4523 | //LLGLEnable stencil(GL_STENCIL_TEST); | ||
4524 | //glStencilFunc(GL_NOTEQUAL, 255, 0xFFFFFFFF); | ||
4525 | //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); | ||
4526 | //LLGLDisable blend(GL_BLEND); | ||
4527 | LLGLEnable blend(GL_BLEND); | ||
4528 | gGL.blendFunc(GL_ONE, GL_ONE); | ||
4529 | tc2.setVec(1,1); | ||
4530 | gGL.begin(GL_TRIANGLE_STRIP); | ||
4531 | gGL.color4f(1,1,1,1); | ||
4532 | gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); | ||
4533 | gGL.vertex2f(-1,-1); | ||
4534 | |||
4535 | gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); | ||
4536 | gGL.vertex2f(-1,1); | ||
4537 | |||
4538 | gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); | ||
4539 | gGL.vertex2f(1,-1); | ||
4540 | |||
4541 | gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); | ||
4542 | gGL.vertex2f(1,1); | ||
4543 | gGL.end(); | ||
4544 | |||
4545 | gGL.flush(); | ||
4546 | gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
4547 | } | ||
4121 | 4548 | ||
4122 | for (S32 i = 0; i < kernel; i++) | 4549 | gGL.stop(); |
4550 | glMatrixMode(GL_PROJECTION); | ||
4551 | glPopMatrix(); | ||
4552 | glMatrixMode(GL_MODELVIEW); | ||
4553 | glPopMatrix(); | ||
4554 | |||
4555 | return; | ||
4556 | } | ||
4557 | |||
4123 | { | 4558 | { |
4124 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFramebuffer[i%2]); | 4559 | { |
4125 | glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, | 4560 | LLFastTimer ftm(LLFastTimer::FTM_RENDER_BLOOM_FBO); |
4126 | GL_COLOR_ATTACHMENT0_EXT, | 4561 | mGlow[2].bindTarget(); |
4127 | GL_TEXTURE_2D, | 4562 | mGlow[2].clear(); |
4128 | i%2 == 0 ? buffer : dest, 0); | 4563 | } |
4564 | |||
4565 | gGlowExtractProgram.bind(); | ||
4566 | F32 minLum = llclamp(gSavedSettings.getF32("RenderGlowMinLuminance"), 0.0f, 1.0f); | ||
4567 | F32 maxAlpha = gSavedSettings.getF32("RenderGlowMaxExtractAlpha"); | ||
4568 | F32 warmthAmount = gSavedSettings.getF32("RenderGlowWarmthAmount"); | ||
4569 | LLVector3 lumWeights = gSavedSettings.getVector3("RenderGlowLumWeights"); | ||
4570 | LLVector3 warmthWeights = gSavedSettings.getVector3("RenderGlowWarmthWeights"); | ||
4571 | gGlowExtractProgram.uniform1f("minLuminance", minLum); | ||
4572 | gGlowExtractProgram.uniform1f("maxExtractAlpha", maxAlpha); | ||
4573 | gGlowExtractProgram.uniform3f("lumWeights", lumWeights.mV[0], lumWeights.mV[1], lumWeights.mV[2]); | ||
4574 | gGlowExtractProgram.uniform3f("warmthWeights", warmthWeights.mV[0], warmthWeights.mV[1], warmthWeights.mV[2]); | ||
4575 | gGlowExtractProgram.uniform1f("warmthAmount", warmthAmount); | ||
4576 | LLGLEnable blend_on(GL_BLEND); | ||
4577 | LLGLEnable test(GL_ALPHA_TEST); | ||
4578 | glAlphaFunc(GL_GREATER, 0.f); | ||
4579 | gGL.blendFunc(GL_SRC_ALPHA, GL_ONE); | ||
4580 | LLViewerImage::unbindTexture(0, GL_TEXTURE_2D); | ||
4129 | 4581 | ||
4130 | glBindTexture(GL_TEXTURE_2D, i == 0 ? source : | 4582 | glDisable(GL_TEXTURE_2D); |
4131 | i%2==0 ? dest : | 4583 | glEnable(GL_TEXTURE_RECTANGLE_ARB); |
4132 | buffer); | 4584 | mScreen.bindTexture(); |
4585 | |||
4586 | gGL.color4f(1,1,1,1); | ||
4587 | gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); | ||
4588 | gGL.begin(GL_TRIANGLE_STRIP); | ||
4589 | gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); | ||
4590 | gGL.vertex2f(-1,-1); | ||
4133 | 4591 | ||
4134 | glUniform1fARB(gGlowProgram.mUniform[LLShaderMgr::GLOW_DELTA],delta); | 4592 | gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); |
4593 | gGL.vertex2f(-1,1); | ||
4594 | |||
4595 | gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); | ||
4596 | gGL.vertex2f(1,-1); | ||
4597 | |||
4598 | gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); | ||
4599 | gGL.vertex2f(1,1); | ||
4600 | gGL.end(); | ||
4601 | |||
4602 | glEnable(GL_TEXTURE_2D); | ||
4603 | glDisable(GL_TEXTURE_RECTANGLE_ARB); | ||
4604 | |||
4605 | mGlow[2].flush(); | ||
4606 | } | ||
4607 | |||
4608 | tc1.setVec(0,0); | ||
4609 | tc2.setVec(1,1); | ||
4610 | |||
4611 | |||
4612 | |||
4613 | // power of two between 1 and 1024 | ||
4614 | U32 glowResPow = gSavedSettings.getS32("RenderGlowResolutionPow"); | ||
4615 | const U32 glow_res = llmax(1, | ||
4616 | llmin(1024, 1 << glowResPow)); | ||
4135 | 4617 | ||
4136 | glBegin(GL_TRIANGLE_STRIP); | 4618 | S32 kernel = gSavedSettings.getS32("RenderGlowIterations")*2; |
4137 | glTexCoord2f(tc1.mV[0], tc1.mV[1]); | 4619 | F32 delta = gSavedSettings.getF32("RenderGlowWidth") / glow_res; |
4138 | glVertex2f(-1,-1); | 4620 | // Use half the glow width if we have the res set to less than 9 so that it looks |
4621 | // almost the same in either case. | ||
4622 | if (glowResPow < 9) | ||
4623 | { | ||
4624 | delta *= 0.5f; | ||
4625 | } | ||
4626 | F32 strength = gSavedSettings.getF32("RenderGlowStrength"); | ||
4627 | |||
4628 | gGlowProgram.bind(); | ||
4629 | gGlowProgram.uniform1f("glowStrength", strength); | ||
4630 | |||
4631 | for (S32 i = 0; i < kernel; i++) | ||
4632 | { | ||
4633 | LLViewerImage::unbindTexture(0, GL_TEXTURE_2D); | ||
4634 | { | ||
4635 | LLFastTimer ftm(LLFastTimer::FTM_RENDER_BLOOM_FBO); | ||
4636 | mGlow[i%2].bindTarget(); | ||
4637 | mGlow[i%2].clear(); | ||
4638 | } | ||
4639 | |||
4640 | if (i == 0) | ||
4641 | { | ||
4642 | mGlow[2].bindTexture(); | ||
4643 | } | ||
4644 | else | ||
4645 | { | ||
4646 | mGlow[(i-1)%2].bindTexture(); | ||
4647 | } | ||
4648 | |||
4649 | if (i%2 == 0) | ||
4650 | { | ||
4651 | gGlowProgram.uniform2f("glowDelta", delta, 0); | ||
4652 | } | ||
4653 | else | ||
4654 | { | ||
4655 | gGlowProgram.uniform2f("glowDelta", 0, delta); | ||
4656 | } | ||
4657 | |||
4658 | gGL.begin(GL_TRIANGLE_STRIP); | ||
4659 | gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); | ||
4660 | gGL.vertex2f(-1,-1); | ||
4139 | 4661 | ||
4140 | glTexCoord2f(tc1.mV[0], tc2.mV[1]); | 4662 | gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); |
4141 | glVertex2f(-1,1); | 4663 | gGL.vertex2f(-1,1); |
4142 | 4664 | ||
4143 | glTexCoord2f(tc2.mV[0], tc1.mV[1]); | 4665 | gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); |
4144 | glVertex2f(1,-1); | 4666 | gGL.vertex2f(1,-1); |
4145 | 4667 | ||
4146 | glTexCoord2f(tc2.mV[0], tc2.mV[1]); | 4668 | gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); |
4147 | glVertex2f(1,1); | 4669 | gGL.vertex2f(1,1); |
4148 | glEnd(); | 4670 | gGL.end(); |
4149 | |||
4150 | tc1.setVec(0,0); | ||
4151 | tc2.setVec(1,1); | ||
4152 | 4671 | ||
4672 | mGlow[i%2].flush(); | ||
4153 | } | 4673 | } |
4154 | 4674 | ||
4155 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); | ||
4156 | gGlowProgram.unbind(); | 4675 | gGlowProgram.unbind(); |
4157 | 4676 | ||
4158 | glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); | 4677 | if (LLRenderTarget::sUseFBO) |
4678 | { | ||
4679 | LLFastTimer ftm(LLFastTimer::FTM_RENDER_BLOOM_FBO); | ||
4680 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); | ||
4681 | } | ||
4682 | |||
4683 | gViewerWindow->setupViewport(); | ||
4159 | 4684 | ||
4160 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_GLOW)) | 4685 | /*mGlow[1].bindTexture(); |
4161 | { | 4686 | { |
4162 | glClear(GL_COLOR_BUFFER_BIT); | 4687 | LLGLEnable stencil(GL_STENCIL_TEST); |
4688 | glStencilFunc(GL_NOTEQUAL, 255, 0xFFFFFFFF); | ||
4689 | glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); | ||
4690 | LLGLDisable blend(GL_BLEND); | ||
4691 | |||
4692 | gGL.begin(GL_TRIANGLE_STRIP); | ||
4693 | gGL.color4f(1,1,1,1); | ||
4694 | gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); | ||
4695 | gGL.vertex2f(-1,-1); | ||
4696 | |||
4697 | gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); | ||
4698 | gGL.vertex2f(-1,1); | ||
4699 | |||
4700 | gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); | ||
4701 | gGL.vertex2f(1,-1); | ||
4702 | |||
4703 | gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); | ||
4704 | gGL.vertex2f(1,1); | ||
4705 | gGL.end(); | ||
4706 | |||
4707 | gGL.flush(); | ||
4163 | } | 4708 | } |
4164 | 4709 | ||
4165 | glBindTexture(GL_TEXTURE_2D, dest); | 4710 | if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_GLOW)) |
4166 | { | 4711 | { |
4712 | tc2.setVec((F32) gViewerWindow->getWindowDisplayWidth(), | ||
4713 | (F32) gViewerWindow->getWindowDisplayHeight()); | ||
4714 | |||
4715 | if (res_mod > 1) | ||
4716 | { | ||
4717 | tc2 /= (F32) res_mod; | ||
4718 | } | ||
4719 | |||
4167 | LLGLEnable blend(GL_BLEND); | 4720 | LLGLEnable blend(GL_BLEND); |
4168 | glBlendFunc(GL_SRC_ALPHA, GL_ONE); | 4721 | gGL.blendFunc(GL_ONE, GL_ONE); |
4722 | |||
4723 | glDisable(GL_TEXTURE_2D); | ||
4724 | glEnable(GL_TEXTURE_RECTANGLE_ARB); | ||
4725 | mScreen.bindTexture(); | ||
4726 | |||
4727 | gGL.begin(GL_TRIANGLE_STRIP); | ||
4728 | gGL.color4f(1,1,1,1); | ||
4729 | gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); | ||
4730 | gGL.vertex2f(-1,-1); | ||
4731 | |||
4732 | gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); | ||
4733 | gGL.vertex2f(-1,1); | ||
4734 | |||
4735 | gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); | ||
4736 | gGL.vertex2f(1,-1); | ||
4737 | |||
4738 | gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); | ||
4739 | gGL.vertex2f(1,1); | ||
4740 | gGL.end(); | ||
4169 | 4741 | ||
4170 | glBegin(GL_TRIANGLE_STRIP); | 4742 | gGL.flush(); |
4171 | glColor4f(1,1,1,1); | ||
4172 | glTexCoord2f(tc1.mV[0], tc1.mV[1]); | ||
4173 | glVertex2f(-1,-1); | ||
4174 | 4743 | ||
4175 | glTexCoord2f(tc1.mV[0], tc2.mV[1]); | 4744 | glEnable(GL_TEXTURE_2D); |
4176 | glVertex2f(-1,1); | 4745 | glDisable(GL_TEXTURE_RECTANGLE_ARB); |
4746 | |||
4747 | gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
4748 | }*/ | ||
4749 | gGL.stop(); | ||
4750 | |||
4751 | { | ||
4752 | LLVertexBuffer::unbind(); | ||
4753 | |||
4754 | F32 uv0[] = | ||
4755 | { | ||
4756 | tc1.mV[0], tc1.mV[1], | ||
4757 | tc1.mV[0], tc2.mV[1], | ||
4758 | tc2.mV[0], tc1.mV[1], | ||
4759 | tc2.mV[0], tc2.mV[1] | ||
4760 | }; | ||
4761 | |||
4762 | tc2.setVec((F32) gViewerWindow->getWindowDisplayWidth(), | ||
4763 | (F32) gViewerWindow->getWindowDisplayHeight()); | ||
4764 | |||
4765 | if (res_mod > 1) | ||
4766 | { | ||
4767 | tc2 /= (F32) res_mod; | ||
4768 | } | ||
4769 | |||
4770 | F32 uv1[] = | ||
4771 | { | ||
4772 | tc1.mV[0], tc1.mV[1], | ||
4773 | tc1.mV[0], tc2.mV[1], | ||
4774 | tc2.mV[0], tc1.mV[1], | ||
4775 | tc2.mV[0], tc2.mV[1] | ||
4776 | }; | ||
4777 | |||
4778 | F32 v[] = | ||
4779 | { | ||
4780 | -1,-1, | ||
4781 | -1,1, | ||
4782 | 1,-1, | ||
4783 | 1,1 | ||
4784 | }; | ||
4785 | |||
4786 | LLGLDisable blend(GL_BLEND); | ||
4787 | |||
4788 | |||
4789 | //tex unit 0 | ||
4790 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); | ||
4791 | glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE); | ||
4792 | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); | ||
4793 | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); | ||
4794 | |||
4795 | mGlow[1].bindTexture(); | ||
4796 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); | ||
4797 | glTexCoordPointer(2, GL_FLOAT, 0, uv0); | ||
4798 | glActiveTextureARB(GL_TEXTURE1_ARB); | ||
4799 | glEnable(GL_TEXTURE_RECTANGLE_ARB); | ||
4177 | 4800 | ||
4178 | glTexCoord2f(tc2.mV[0], tc1.mV[1]); | 4801 | //tex unit 1 |
4179 | glVertex2f(1,-1); | 4802 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); |
4803 | glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD); | ||
4804 | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB); | ||
4805 | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); | ||
4806 | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE); | ||
4807 | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); | ||
4180 | 4808 | ||
4181 | glTexCoord2f(tc2.mV[0], tc2.mV[1]); | 4809 | glClientActiveTextureARB(GL_TEXTURE1_ARB); |
4182 | glVertex2f(1,1); | 4810 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
4183 | glEnd(); | 4811 | glTexCoordPointer(2, GL_FLOAT, 0, uv1); |
4184 | 4812 | ||
4185 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | 4813 | glVertexPointer(2, GL_FLOAT, 0, v); |
4814 | |||
4815 | mScreen.bindTexture(); | ||
4816 | |||
4817 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | ||
4818 | |||
4819 | glDisable(GL_TEXTURE_RECTANGLE_ARB); | ||
4820 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); | ||
4821 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | ||
4822 | glClientActiveTextureARB(GL_TEXTURE0_ARB); | ||
4823 | glActiveTextureARB(GL_TEXTURE0_ARB); | ||
4824 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); | ||
4825 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | ||
4186 | } | 4826 | } |
4827 | |||
4828 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
4829 | glMatrixMode(GL_PROJECTION); | ||
4830 | glPopMatrix(); | ||
4831 | glMatrixMode(GL_MODELVIEW); | ||
4832 | glPopMatrix(); | ||
4833 | |||
4834 | #ifndef LL_RELEASE_FOR_DOWNLOAD | ||
4835 | LLGLState::checkStates(); | ||
4836 | LLGLState::checkTextureChannels(); | ||
4837 | #endif | ||
4838 | |||
4839 | } | ||
4840 | |||
4841 | void LLPipeline::processImagery(LLCamera& camera) | ||
4842 | { | ||
4843 | for (LLWorld::region_list_t::iterator iter = gWorldp->getRegionList().begin(); | ||
4844 | iter != gWorldp->getRegionList().end(); ++iter) | ||
4845 | { | ||
4846 | LLViewerRegion* region = *iter; | ||
4847 | LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_VOLUME); | ||
4848 | if (part) | ||
4849 | { | ||
4850 | part->processImagery(&camera); | ||
4851 | } | ||
4852 | } | ||
4853 | } | ||
4854 | |||
4855 | |||
4856 | inline float sgn(float a) | ||
4857 | { | ||
4858 | if (a > 0.0F) return (1.0F); | ||
4859 | if (a < 0.0F) return (-1.0F); | ||
4860 | return (0.0F); | ||
4861 | } | ||
4862 | |||
4863 | void LLPipeline::generateWaterReflection(LLCamera& camera_in) | ||
4864 | { | ||
4865 | if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate) | ||
4866 | { | ||
4867 | LLCamera camera = camera_in; | ||
4868 | camera.setFar(camera.getFar()*0.87654321f); | ||
4869 | LLPipeline::sReflectionRender = TRUE; | ||
4870 | S32 occlusion = LLPipeline::sUseOcclusion; | ||
4871 | LLPipeline::sUseOcclusion = llmin(occlusion, 1); | ||
4872 | U32 type_mask = gPipeline.mRenderTypeMask; | ||
4873 | |||
4874 | glh::matrix4f projection = glh_get_current_projection(); | ||
4875 | glh::matrix4f mat; | ||
4876 | |||
4877 | stop_glerror(); | ||
4878 | LLPlane plane; | ||
4879 | |||
4880 | F32 height = gAgent.getRegion()->getWaterHeight(); | ||
4881 | F32 to_clip = fabsf(camera.getOrigin().mV[2]-height); | ||
4882 | F32 pad = -to_clip*0.05f; //amount to "pad" clip plane by | ||
4883 | |||
4884 | //plane params | ||
4885 | LLVector3 pnorm; | ||
4886 | F32 pd; | ||
4887 | |||
4888 | S32 water_clip = 0; | ||
4889 | if (!gCamera->cameraUnderWater()) | ||
4890 | { //camera is above water, clip plane points up | ||
4891 | pnorm.setVec(0,0,1); | ||
4892 | pd = -height; | ||
4893 | plane.setVec(pnorm, pd); | ||
4894 | water_clip = -1; | ||
4895 | } | ||
4896 | else | ||
4897 | { //camera is below water, clip plane points down | ||
4898 | pnorm = LLVector3(0,0,-1); | ||
4899 | pd = height; | ||
4900 | plane.setVec(pnorm, pd); | ||
4901 | water_clip = 1; | ||
4902 | } | ||
4903 | |||
4904 | |||
4905 | |||
4906 | if (!gCamera->cameraUnderWater()) | ||
4907 | { //generate planar reflection map | ||
4908 | LLViewerImage::unbindTexture(0, GL_TEXTURE_2D); | ||
4909 | glClearColor(0,0,0,0); | ||
4910 | glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); | ||
4911 | mWaterRef.bindTarget(); | ||
4912 | mWaterRef.getViewport(gGLViewport); | ||
4913 | mWaterRef.clear(); | ||
4914 | glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE); | ||
4915 | |||
4916 | stop_glerror(); | ||
4917 | |||
4918 | LLVector3 origin = camera.getOrigin(); | ||
4919 | |||
4920 | glPushMatrix(); | ||
4921 | |||
4922 | mat.set_scale(glh::vec3f(1,1,-1)); | ||
4923 | mat.set_translate(glh::vec3f(0,0,height*2.f)); | ||
4924 | |||
4925 | glh::matrix4f current = glh_get_current_modelview(); | ||
4926 | |||
4927 | mat = current * mat; | ||
4928 | |||
4929 | glh_set_current_modelview(mat); | ||
4930 | glLoadMatrixf(mat.m); | ||
4931 | |||
4932 | LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE); | ||
4933 | |||
4934 | glCullFace(GL_FRONT); | ||
4935 | |||
4936 | //initial sky pass (no user clip plane) | ||
4937 | { //mask out everything but the sky | ||
4938 | U32 tmp = mRenderTypeMask; | ||
4939 | mRenderTypeMask &= ((1 << LLPipeline::RENDER_TYPE_SKY) | | ||
4940 | (1 << LLPipeline::RENDER_TYPE_CLOUDS) | | ||
4941 | (1 << LLPipeline::RENDER_TYPE_WL_SKY)); | ||
4942 | |||
4943 | static LLCullResult result; | ||
4944 | updateCull(camera, result); | ||
4945 | stateSort(camera, result); | ||
4946 | renderGeom(camera, TRUE); | ||
4947 | |||
4948 | mRenderTypeMask = tmp; | ||
4949 | } | ||
4950 | |||
4951 | if (LLDrawPoolWater::sNeedsReflectionUpdate) | ||
4952 | { | ||
4953 | mRenderTypeMask &= ~((1<<LLPipeline::RENDER_TYPE_WATER) | | ||
4954 | (1<<LLPipeline::RENDER_TYPE_GROUND) | | ||
4955 | (1<<LLPipeline::RENDER_TYPE_SKY) | | ||
4956 | (1<<LLPipeline::RENDER_TYPE_CLOUDS) | | ||
4957 | (1<<LLPipeline::RENDER_TYPE_WL_SKY)); | ||
4958 | |||
4959 | if (gSavedSettings.getBOOL("RenderWaterReflections")) | ||
4960 | { //mask out selected geometry based on reflection detail | ||
4961 | |||
4962 | S32 detail = gSavedSettings.getS32("RenderReflectionDetail"); | ||
4963 | if (detail < 3) | ||
4964 | { | ||
4965 | mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_PARTICLES); | ||
4966 | if (detail < 2) | ||
4967 | { | ||
4968 | mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_AVATAR); | ||
4969 | if (detail < 1) | ||
4970 | { | ||
4971 | mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_VOLUME); | ||
4972 | } | ||
4973 | } | ||
4974 | } | ||
4975 | |||
4976 | LLSpatialPartition::sFreezeState = TRUE; | ||
4977 | LLPipeline::sSkipUpdate = TRUE; | ||
4978 | LLGLUserClipPlane clip_plane(plane, mat, projection); | ||
4979 | static LLCullResult result; | ||
4980 | updateCull(camera, result, 1); | ||
4981 | stateSort(camera, result); | ||
4982 | renderGeom(camera); | ||
4983 | LLSpatialPartition::sFreezeState = FALSE; | ||
4984 | LLPipeline::sSkipUpdate = FALSE; | ||
4985 | } | ||
4986 | } | ||
4987 | glCullFace(GL_BACK); | ||
4988 | glPopMatrix(); | ||
4989 | mWaterRef.flush(); | ||
4990 | |||
4991 | glh_set_current_modelview(current); | ||
4992 | } | ||
4993 | |||
4994 | //render distortion map | ||
4995 | static BOOL last_update = TRUE; | ||
4996 | if (last_update) | ||
4997 | { | ||
4998 | camera.setFar(camera_in.getFar()); | ||
4999 | mRenderTypeMask = type_mask & (~(1<<LLPipeline::RENDER_TYPE_WATER) | | ||
5000 | (1<<LLPipeline::RENDER_TYPE_GROUND)); | ||
5001 | stop_glerror(); | ||
5002 | |||
5003 | LLPipeline::sUnderWaterRender = gCamera->cameraUnderWater() ? FALSE : TRUE; | ||
5004 | |||
5005 | if (LLPipeline::sUnderWaterRender) | ||
5006 | { | ||
5007 | mRenderTypeMask &= ~((1<<LLPipeline::RENDER_TYPE_GROUND) | | ||
5008 | (1<<LLPipeline::RENDER_TYPE_SKY) | | ||
5009 | (1<<LLPipeline::RENDER_TYPE_CLOUDS) | | ||
5010 | (1<<LLPipeline::RENDER_TYPE_WL_SKY)); | ||
5011 | } | ||
5012 | LLViewerCamera::updateFrustumPlanes(camera); | ||
5013 | |||
5014 | LLViewerImage::unbindTexture(0, GL_TEXTURE_2D); | ||
5015 | LLColor4& col = LLDrawPoolWater::sWaterFogColor; | ||
5016 | glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f); | ||
5017 | glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); | ||
5018 | mWaterDis.bindTarget(); | ||
5019 | mWaterDis.getViewport(gGLViewport); | ||
5020 | mWaterDis.clear(); | ||
5021 | glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE); | ||
5022 | |||
5023 | if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate) | ||
5024 | { | ||
5025 | //clip out geometry on the same side of water as the camera | ||
5026 | mat = glh_get_current_modelview(); | ||
5027 | LLGLUserClipPlane clip_plane(LLPlane(-pnorm, -(pd+pad)), mat, projection); | ||
5028 | static LLCullResult result; | ||
5029 | updateCull(camera, result, water_clip); | ||
5030 | stateSort(camera, result); | ||
5031 | renderGeom(camera); | ||
5032 | } | ||
5033 | |||
5034 | LLPipeline::sUnderWaterRender = FALSE; | ||
5035 | mWaterDis.flush(); | ||
5036 | } | ||
5037 | last_update = LLDrawPoolWater::sNeedsReflectionUpdate; | ||
5038 | |||
5039 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); | ||
5040 | LLPipeline::sReflectionRender = FALSE; | ||
5041 | |||
5042 | if (!LLRenderTarget::sUseFBO) | ||
5043 | { | ||
5044 | glClear(GL_DEPTH_BUFFER_BIT); | ||
5045 | } | ||
5046 | glClearColor(0.f, 0.f, 0.f, 0.f); | ||
5047 | |||
5048 | gViewerWindow->setupViewport(); | ||
5049 | mRenderTypeMask = type_mask; | ||
5050 | LLDrawPoolWater::sNeedsReflectionUpdate = FALSE; | ||
5051 | gCamera->setUserClipPlane(LLPlane(-pnorm, -pd)); | ||
5052 | LLPipeline::sUseOcclusion = occlusion; | ||
5053 | } | ||
5054 | } | ||
5055 | |||
5056 | LLCubeMap* LLPipeline::findReflectionMap(const LLVector3& location) | ||
5057 | { | ||
5058 | LLViewerRegion* region = gWorldp->getRegionFromPosAgent(location); | ||
5059 | if (region) | ||
5060 | { | ||
5061 | LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_VOLUME); | ||
5062 | if (part) | ||
5063 | { | ||
5064 | LLSpatialGroup::OctreeNode* node = part->mOctree->getNodeAt(LLVector3d(location), 32.0); | ||
5065 | if (node) | ||
5066 | { | ||
5067 | LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); | ||
5068 | return group->mReflectionMap; | ||
5069 | } | ||
5070 | } | ||
5071 | } | ||
5072 | |||
5073 | return NULL; | ||
5074 | } | ||
5075 | |||
5076 | void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture) | ||
5077 | { | ||
5078 | #if !LL_RELEASE_FOR_DOWNLOAD | ||
5079 | LLGLState::checkClientArrays(mask); | ||
5080 | #endif | ||
5081 | |||
5082 | for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) | ||
5083 | { | ||
5084 | LLSpatialGroup* group = *i; | ||
5085 | if (!group->isDead() && | ||
5086 | (!sUseOcclusion || !group->isState(LLSpatialGroup::OCCLUDED)) && | ||
5087 | gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) && | ||
5088 | group->mDrawMap.find(type) != group->mDrawMap.end()) | ||
5089 | { | ||
5090 | pass->renderGroup(group,type,mask,texture); | ||
5091 | } | ||
5092 | } | ||
5093 | } | ||
5094 | |||
5095 | void LLPipeline::generateImpostor(LLVOAvatar* avatar) | ||
5096 | { | ||
5097 | static LLCullResult result; | ||
5098 | result.clear(); | ||
5099 | grabReferences(result); | ||
5100 | |||
5101 | if (!avatar || !avatar->mDrawable) | ||
5102 | { | ||
5103 | return; | ||
5104 | } | ||
5105 | |||
5106 | assertInitialized(); | ||
5107 | |||
5108 | if (!avatar->mImpostor.isComplete()) | ||
5109 | { | ||
5110 | avatar->mImpostor.allocate(128,256,GL_RGBA,TRUE); | ||
5111 | avatar->mImpostor.bindTexture(); | ||
5112 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||
5113 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||
5114 | LLImageGL::unbindTexture(0, GL_TEXTURE_2D); | ||
5115 | } | ||
5116 | |||
5117 | U32 mask = (1<<LLPipeline::RENDER_TYPE_VOLUME) | | ||
5118 | (1<<LLPipeline::RENDER_TYPE_AVATAR) | | ||
5119 | (1<<LLPipeline::RENDER_TYPE_BUMP) | | ||
5120 | (1<<LLPipeline::RENDER_TYPE_GRASS) | | ||
5121 | (1<<LLPipeline::RENDER_TYPE_SIMPLE) | | ||
5122 | (1<<LLPipeline::RENDER_TYPE_ALPHA) | | ||
5123 | (1<<LLPipeline::RENDER_TYPE_INVISIBLE); | ||
5124 | |||
5125 | mask = mask & gPipeline.getRenderTypeMask(); | ||
5126 | U32 saved_mask = gPipeline.mRenderTypeMask; | ||
5127 | gPipeline.mRenderTypeMask = mask; | ||
5128 | |||
5129 | S32 occlusion = sUseOcclusion; | ||
5130 | sUseOcclusion = 0; | ||
5131 | sReflectionRender = TRUE; | ||
5132 | sImpostorRender = TRUE; | ||
5133 | |||
5134 | markVisible(avatar->mDrawable, *gCamera); | ||
5135 | LLVOAvatar::sUseImpostors = FALSE; | ||
5136 | |||
5137 | LLVOAvatar::attachment_map_t::iterator iter; | ||
5138 | for (iter = avatar->mAttachmentPoints.begin(); | ||
5139 | iter != avatar->mAttachmentPoints.end(); | ||
5140 | ++iter) | ||
5141 | { | ||
5142 | LLViewerObject* object = iter->second->getObject(); | ||
5143 | if (object) | ||
5144 | { | ||
5145 | markVisible(object->mDrawable->getSpatialBridge(), *gCamera); | ||
5146 | } | ||
5147 | } | ||
5148 | |||
5149 | stateSort(*gCamera, result); | ||
5150 | |||
5151 | glClearColor(0.0f,0.0f,0.0f,0.0f); | ||
5152 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | ||
5153 | glStencilMask(0xFFFFFFFF); | ||
5154 | glClearStencil(0); | ||
5155 | |||
5156 | { | ||
5157 | LLGLEnable scissor(GL_SCISSOR_TEST); | ||
5158 | glScissor(0, 0, 128, 256); | ||
5159 | avatar->mImpostor.bindTarget(); | ||
5160 | avatar->mImpostor.getViewport(gGLViewport); | ||
5161 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | ||
5162 | } | ||
5163 | |||
5164 | LLGLEnable stencil(GL_STENCIL_TEST); | ||
5165 | |||
5166 | glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF); | ||
5167 | glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); | ||
5168 | |||
5169 | const LLVector3* ext = avatar->mDrawable->getSpatialExtents(); | ||
5170 | LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset()); | ||
5171 | |||
5172 | LLCamera camera = *gCamera; | ||
5173 | |||
5174 | camera.lookAt(gCamera->getOrigin(), pos, gCamera->getUpAxis()); | ||
5175 | |||
5176 | LLVector2 tdim; | ||
5177 | |||
5178 | LLVector3 half_height = (ext[1]-ext[0])*0.5f; | ||
5179 | |||
5180 | LLVector3 left = camera.getLeftAxis(); | ||
5181 | left *= left; | ||
5182 | left.normVec(); | ||
5183 | |||
5184 | LLVector3 up = camera.getUpAxis(); | ||
5185 | up *= up; | ||
5186 | up.normVec(); | ||
5187 | |||
5188 | tdim.mV[0] = fabsf(half_height * left); | ||
5189 | tdim.mV[1] = fabsf(half_height * up); | ||
5190 | |||
5191 | glMatrixMode(GL_PROJECTION); | ||
5192 | glPushMatrix(); | ||
5193 | glh::matrix4f ortho = gl_ortho(-tdim.mV[0], tdim.mV[0], -tdim.mV[1], tdim.mV[1], 1.0, 256.0); | ||
5194 | glh_set_current_projection(ortho); | ||
5195 | glLoadMatrixf(ortho.m); | ||
5196 | |||
5197 | glMatrixMode(GL_MODELVIEW); | ||
5198 | glPushMatrix(); | ||
5199 | glh::matrix4f mat; | ||
5200 | camera.getOpenGLTransform(mat.m); | ||
5201 | |||
5202 | mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat; | ||
5203 | |||
5204 | glLoadMatrixf(mat.m); | ||
5205 | glh_set_current_modelview(mat); | ||
5206 | |||
5207 | renderGeom(camera); | ||
5208 | |||
5209 | glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); | ||
5210 | glStencilFunc(GL_EQUAL, 1, 0xFFFFFF); | ||
5211 | |||
5212 | { | ||
5213 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | ||
5214 | LLVector3 left = camera.getLeftAxis()*tdim.mV[0]*2.f; | ||
5215 | LLVector3 up = camera.getUpAxis()*tdim.mV[1]*2.f; | ||
5216 | |||
5217 | LLGLEnable blend(GL_BLEND); | ||
5218 | gGL.blendFunc(GL_ONE, GL_ONE); | ||
5219 | LLImageGL::unbindTexture(0, GL_TEXTURE_2D); | ||
5220 | |||
5221 | LLGLDepthTest depth(GL_FALSE, GL_FALSE); | ||
5222 | |||
5223 | gGL.start(); | ||
5224 | gGL.color4ub(0,0,0,1); | ||
5225 | gGL.begin(GL_QUADS); | ||
5226 | gGL.vertex3fv((pos+left-up).mV); | ||
5227 | gGL.vertex3fv((pos-left-up).mV); | ||
5228 | gGL.vertex3fv((pos-left+up).mV); | ||
5229 | gGL.vertex3fv((pos+left+up).mV); | ||
5230 | gGL.end(); | ||
5231 | gGL.stop(); | ||
5232 | |||
5233 | gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
5234 | } | ||
5235 | |||
5236 | avatar->mImpostor.flush(); | ||
5237 | |||
5238 | avatar->setImpostorDim(tdim); | ||
5239 | |||
5240 | LLVOAvatar::sUseImpostors = TRUE; | ||
5241 | sUseOcclusion = occlusion; | ||
5242 | sReflectionRender = FALSE; | ||
5243 | sImpostorRender = FALSE; | ||
5244 | gPipeline.mRenderTypeMask = saved_mask; | ||
4187 | 5245 | ||
4188 | glMatrixMode(GL_PROJECTION); | 5246 | glMatrixMode(GL_PROJECTION); |
4189 | glPopMatrix(); | 5247 | glPopMatrix(); |
4190 | glMatrixMode(GL_MODELVIEW); | 5248 | glMatrixMode(GL_MODELVIEW); |
4191 | glPopMatrix(); | 5249 | glPopMatrix(); |
5250 | |||
5251 | avatar->mNeedsImpostorUpdate = FALSE; | ||
5252 | avatar->cacheImpostorValues(); | ||
4192 | } | 5253 | } |
5254 | |||
5255 | BOOL LLPipeline::hasRenderBatches(const U32 type) const | ||
5256 | { | ||
5257 | return sCull->getRenderMapSize(type) > 0; | ||
5258 | } | ||
5259 | |||
5260 | LLCullResult::drawinfo_list_t::iterator LLPipeline::beginRenderMap(U32 type) | ||
5261 | { | ||
5262 | return sCull->beginRenderMap(type); | ||
5263 | } | ||
5264 | |||
5265 | LLCullResult::drawinfo_list_t::iterator LLPipeline::endRenderMap(U32 type) | ||
5266 | { | ||
5267 | return sCull->endRenderMap(type); | ||
5268 | } | ||
5269 | |||
5270 | LLCullResult::sg_list_t::iterator LLPipeline::beginAlphaGroups() | ||
5271 | { | ||
5272 | return sCull->beginAlphaGroups(); | ||
5273 | } | ||
5274 | |||
5275 | LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups() | ||
5276 | { | ||
5277 | return sCull->endAlphaGroups(); | ||
5278 | } | ||
5279 | |||