aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/lldrawpoolalpha.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/lldrawpoolalpha.cpp661
1 files changed, 199 insertions, 462 deletions
diff --git a/linden/indra/newview/lldrawpoolalpha.cpp b/linden/indra/newview/lldrawpoolalpha.cpp
index c62db17..b50be95 100644
--- a/linden/indra/newview/lldrawpoolalpha.cpp
+++ b/linden/indra/newview/lldrawpoolalpha.cpp
@@ -29,11 +29,11 @@
29 29
30#include "lldrawpoolalpha.h" 30#include "lldrawpoolalpha.h"
31 31
32#include "llglheaders.h"
32#include "llviewercontrol.h" 33#include "llviewercontrol.h"
33#include "llcriticaldamp.h" 34#include "llcriticaldamp.h"
34#include "llfasttimer.h" 35#include "llfasttimer.h"
35 36
36#include "llagparray.h"
37#include "llcubemap.h" 37#include "llcubemap.h"
38#include "llsky.h" 38#include "llsky.h"
39#include "llagent.h" 39#include "llagent.h"
@@ -44,104 +44,25 @@
44#include "llviewerobjectlist.h" // For debugging 44#include "llviewerobjectlist.h" // For debugging
45#include "llviewerwindow.h" 45#include "llviewerwindow.h"
46#include "pipeline.h" 46#include "pipeline.h"
47 47#include "llviewerregion.h"
48const F32 MAX_DIST = 512.f;
49const F32 ALPHA_FALLOFF_START_DISTANCE = 0.8f;
50 48
51BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE; 49BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
52 50
53LLDrawPoolAlpha::LLDrawPoolAlpha() : 51LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) :
54 LLDrawPool(POOL_ALPHA, 52 LLRenderPass(type)
55 DATA_SIMPLE_IL_MASK | DATA_COLORS_MASK,
56 DATA_SIMPLE_NIL_MASK)
57{ 53{
58 mRebuiltLastFrame = FALSE;
59 mMinDistance = 0.f;
60 mMaxDistance = MAX_DIST;
61 mInvBinSize = NUM_ALPHA_BINS/(mMaxDistance - mMinDistance);
62 mCleanupUnused = TRUE;
63 //mRebuildFreq = -1 ; // Only rebuild if nearly full
64
65// for (S32 i = 0; i < NUM_ALPHA_BINS; i++)
66// {
67// mDistanceBins[i].realloc(200);
68// }
69}
70 54
71LLDrawPoolAlpha::~LLDrawPoolAlpha()
72{
73} 55}
74 56
75LLDrawPool *LLDrawPoolAlpha::instancePool() 57LLDrawPoolAlphaPostWater::LLDrawPoolAlphaPostWater()
58: LLDrawPoolAlpha(POOL_ALPHA_POST_WATER)
76{ 59{
77 llerrs << "Should never be calling instancePool on an alpha pool!" << llendl;
78 return NULL;
79} 60}
80 61
81void LLDrawPoolAlpha::enqueue(LLFace *facep) 62LLDrawPoolAlpha::~LLDrawPoolAlpha()
82{ 63{
83 if (!facep->isState(LLFace::GLOBAL))
84 {
85 facep->mCenterAgent = facep->mCenterLocal * facep->getRenderMatrix();
86 }
87 facep->mDistance = (facep->mCenterAgent - gCamera->getOrigin()) * gCamera->getAtAxis();
88
89 if (facep->isState(LLFace::BACKLIST))
90 {
91 mMoveFace.put(facep);
92 }
93 else
94 {
95 mDrawFace.put(facep);
96 }
97
98 {
99 S32 dist_bin = lltrunc( (mMaxDistance - (facep->mDistance+32))*mInvBinSize );
100
101 if (dist_bin >= NUM_ALPHA_BINS)
102 {
103 mDistanceBins[NUM_ALPHA_BINS-1].put(facep);
104 //mDistanceBins[NUM_ALPHA_BINS-1].push(facep, (U32)(void*)facep->getTexture());
105 }
106 else if (dist_bin > 0)
107 {
108 mDistanceBins[dist_bin].put(facep);
109 //mDistanceBins[dist_bin].push(facep, (U32)(void*)facep->getTexture());
110 }
111 else
112 {
113 mDistanceBins[0].put(facep);
114 //mDistanceBins[0].push(facep, (U32)(void*)facep->getTexture());
115 }
116 }
117} 64}
118 65
119BOOL LLDrawPoolAlpha::removeFace(LLFace *facep)
120{
121 BOOL removed = FALSE;
122
123 LLDrawPool::removeFace(facep);
124
125 {
126 for (S32 i = 0; i < NUM_ALPHA_BINS; i++)
127 {
128 if (mDistanceBins[i].removeObj(facep) != -1)
129 {
130 if (removed)
131 {
132 llerrs << "Warning! " << "Face in multiple distance bins on removal" << llendl;
133 }
134 removed = TRUE;
135 }
136 }
137 }
138 if (removed)
139 {
140 return TRUE;
141 }
142
143 return FALSE;
144}
145 66
146void LLDrawPoolAlpha::prerender() 67void LLDrawPoolAlpha::prerender()
147{ 68{
@@ -150,454 +71,270 @@ void LLDrawPoolAlpha::prerender()
150 71
151void LLDrawPoolAlpha::beginRenderPass(S32 pass) 72void LLDrawPoolAlpha::beginRenderPass(S32 pass)
152{ 73{
153 if (mDrawFace.empty())
154 {
155 // No alpha objects, early exit.
156 return;
157 }
158
159 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 74 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
160 glEnableClientState(GL_VERTEX_ARRAY);
161 glEnableClientState(GL_NORMAL_ARRAY); 75 glEnableClientState(GL_NORMAL_ARRAY);
162 if (gPipeline.getLightingDetail() >= 2) 76 glEnableClientState(GL_COLOR_ARRAY);
163 {
164 glEnableClientState(GL_COLOR_ARRAY);
165 }
166} 77}
167 78
168 79void setup_clip_plane(BOOL pre_water)
169void LLDrawPoolAlpha::render(S32 pass)
170{ 80{
171 LLFastTimer t(LLFastTimer::FTM_RENDER_ALPHA); 81 F32 height = gAgent.getRegion()->getWaterHeight();
82 BOOL above = gCamera->getOrigin().mV[2] > height ? TRUE : FALSE;
172 83
173 if (mDrawFace.empty()) 84 F64 plane[4];
174 { 85
175 // No alpha objects, early exit. 86 plane[0] = 0;
176 return; 87 plane[1] = 0;
177 } 88 plane[2] = above == pre_water ? -1.0 : 1.0;
178 89 plane[3] = -plane[2] * height;
179 GLfloat shiny[4] = 90
180 { 91 glClipPlane(GL_CLIP_PLANE0, plane);
181 0.00f, 92}
182 0.25f,
183 0.5f,
184 0.75f
185 };
186
187 GLint specularIndex = (mVertexShaderLevel > 0) ?
188 gPipeline.mObjectAlphaProgram.mAttribute[LLPipeline::GLSL_SPECULAR_COLOR] : 0;
189 93
190 S32 diffTex = 0; 94void LLDrawPoolAlphaPostWater::render(S32 pass)
191 S32 envTex = -1; 95{
96 LLFastTimer t(LLFastTimer::FTM_RENDER_ALPHA);
192 97
193 if (mVertexShaderLevel > 0) //alpha pass uses same shader as shiny/bump 98 if (gPipeline.hasRenderType(LLDrawPool::POOL_ALPHA))
194 { 99 {
195 envTex = gPipeline.mObjectAlphaProgram.enableTexture(LLPipeline::GLSL_ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB); 100 LLGLEnable clip(GL_CLIP_PLANE0);
196 LLCubeMap* cube_map = gSky.mVOSkyp->getCubeMap(); 101 setup_clip_plane(FALSE);
197 if (envTex >= 0 && cube_map) 102 LLDrawPoolAlpha::render(gPipeline.mAlphaGroupsPostWater);
198 {
199 cube_map->bind();
200 cube_map->setMatrix(1);
201 }
202
203 if (specularIndex > 0)
204 {
205 glVertexAttrib4fARB(specularIndex, 0, 0, 0, 0);
206 }
207
208 S32 scatterTex = gPipeline.mObjectAlphaProgram.enableTexture(LLPipeline::GLSL_SCATTER_MAP);
209 LLViewerImage::bindTexture(gSky.mVOSkyp->getScatterMap(), scatterTex);
210
211 diffTex = gPipeline.mObjectAlphaProgram.enableTexture(LLPipeline::GLSL_DIFFUSE_MAP);
212 } 103 }
213 104 else
214 bindGLVertexPointer();
215 bindGLTexCoordPointer();
216 bindGLNormalPointer();
217 if (gPipeline.getLightingDetail() >= 2)
218 { 105 {
219 bindGLColorPointer(); 106 LLDrawPoolAlpha::render(gPipeline.mAlphaGroupsPostWater);
220 } 107 }
108}
221 109
222 S32 i, j; 110void LLDrawPoolAlpha::render(S32 pass)
223 glAlphaFunc(GL_GREATER,0.01f); 111{
224 // This needs to be turned off or there will be lots of artifacting with the clouds - djs 112 LLFastTimer t(LLFastTimer::FTM_RENDER_ALPHA);
225 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); 113
114 LLGLEnable clip(GL_CLIP_PLANE0);
115 setup_clip_plane(TRUE);
116 render(gPipeline.mAlphaGroups);
117}
226 118
119void LLDrawPoolAlpha::render(std::vector<LLSpatialGroup*>& groups)
120{
121 LLGLDepthTest gls_depth(GL_TRUE);
227 LLGLSPipelineAlpha gls_pipeline_alpha; 122 LLGLSPipelineAlpha gls_pipeline_alpha;
228 123
229 LLDynamicArray<LLFace*>* distance_bins; 124 gPipeline.enableLightsDynamic(1.f);
230 distance_bins = mDistanceBins; 125 renderAlpha(getVertexDataMask(), groups);
231
232 S32 num_bins_no_alpha_test = ((gPickAlphaThreshold != 0.f) && gUsePickAlpha) ?
233 (NUM_ALPHA_BINS - llmax(2, (S32)(ALPHA_FALLOFF_START_DISTANCE * mInvBinSize))) :
234 NUM_ALPHA_BINS;
235
236 typedef std::vector<LLFace*> face_list_t;
237 126
238 for (i = 0; i < num_bins_no_alpha_test; i++) 127 if (sShowDebugAlpha)
239 { 128 {
240 S32 obj_count = distance_bins[i].count(); 129 glDisableClientState(GL_NORMAL_ARRAY);
241 130 glDisableClientState(GL_COLOR_ARRAY);
242 if (!obj_count) 131 gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
243 { 132 glColor4f(1,0,0,1);
244 continue; 133 LLViewerImage::sSmokeImagep->addTextureStats(1024.f*1024.f);
245 } 134 LLViewerImage::sSmokeImagep->bind();
246 else if (i > (NUM_ALPHA_BINS / 2) && obj_count < 100) 135 renderAlphaHighlight(LLVertexBuffer::MAP_VERTEX |
247 { 136 LLVertexBuffer::MAP_TEXCOORD, groups);
248 face_list_t pri_queue;
249 pri_queue.reserve(distance_bins[i].count());
250 for (j = 0; j < distance_bins[i].count(); j++)
251 {
252 pri_queue.push_back(distance_bins[i][j]);
253 }
254 std::sort(pri_queue.begin(), pri_queue.end(), LLFace::CompareDistanceGreater());
255
256 for (face_list_t::iterator iter = pri_queue.begin(); iter != pri_queue.end(); iter++)
257 {
258 const LLFace &face = *(*iter);
259 face.enableLights();
260 face.bindTexture(diffTex);
261 if ((mVertexShaderLevel > 0) && face.getTextureEntry() && specularIndex > 0)
262 {
263 U8 s = face.getTextureEntry()->getShiny();
264 glVertexAttrib4fARB(specularIndex, shiny[s], shiny[s], shiny[s], shiny[s]);
265 }
266 face.renderIndexed(getRawIndices());
267 mIndicesDrawn += face.getIndicesCount();
268 }
269 }
270 else
271 {
272 S32 count = distance_bins[i].count();
273 for (j = 0; j < count; j++)
274 {
275 const LLFace &face = *distance_bins[i][j];
276 face.enableLights();
277 face.bindTexture(diffTex);
278 if ((mVertexShaderLevel > 0) && face.getTextureEntry() && specularIndex > 0)
279 {
280 U8 s = face.getTextureEntry()->getShiny();
281 glVertexAttrib4fARB(specularIndex, shiny[s], shiny[s], shiny[s], shiny[s]);
282 }
283 face.renderIndexed(getRawIndices());
284 mIndicesDrawn += face.getIndicesCount();
285 }
286 }
287 } 137 }
138}
288 139
289 GLfloat ogl_matrix[16]; 140void LLDrawPoolAlpha::renderAlpha(U32 mask, std::vector<LLSpatialGroup*>& groups)
290 gCamera->getOpenGLTransform(ogl_matrix); 141{
142#if !LL_RELEASE_FOR_DOWNLOAD
143 LLGLState::checkClientArrays(mask);
144#endif
291 145
292 for (i = num_bins_no_alpha_test; i < NUM_ALPHA_BINS; i++) 146 LLSpatialBridge* last_bridge = NULL;
293 { 147 LLSpatialPartition* last_part = NULL;
294 BOOL use_pri_queue = distance_bins[i].count() < 100; 148 glPushMatrix();
149 LLGLDepthTest depth(GL_TRUE, GL_FALSE);
295 150
296 face_list_t pri_queue; 151 for (std::vector<LLSpatialGroup*>::iterator i = groups.begin(); i != groups.end(); ++i)
297 152 {
298 if (use_pri_queue) 153 LLSpatialGroup* group = *i;
299 { 154 if (group->mSpatialPartition->mRenderByGroup &&
300 pri_queue.reserve(distance_bins[i].count()); 155 !group->isDead())
301 for (j = 0; j < distance_bins[i].count(); j++)
302 {
303 pri_queue.push_back(distance_bins[i][j]);
304 }
305 std::sort(pri_queue.begin(), pri_queue.end(), LLFace::CompareDistanceGreater());
306 }
307
308 S32 count = distance_bins[i].count();
309 for (j = 0; j < count; j++)
310 { 156 {
311 const LLFace &face = use_pri_queue ? *pri_queue[j] : *distance_bins[i][j]; 157 LLSpatialPartition* part = group->mSpatialPartition;
312 F32 fade_value = face.mAlphaFade * gPickAlphaThreshold; 158 if (part != last_part)
313
314 face.enableLights();
315
316 if (fade_value < 1.f)
317 { 159 {
160 LLSpatialBridge* bridge = part->asBridge();
161 if (bridge != last_bridge)
318 { 162 {
319 LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE); 163 glPopMatrix();
320 glAlphaFunc(GL_LESS, fade_value); 164 glPushMatrix();
321 glBlendFunc(GL_ZERO, GL_ONE); 165 if (bridge)
322 LLViewerImage::bindTexture(gPipeline.mAlphaSizzleImagep, diffTex);
323 LLVector4 s_params(ogl_matrix[2], ogl_matrix[6], ogl_matrix[10], ogl_matrix[14]);
324 LLVector4 t_params(ogl_matrix[1], ogl_matrix[5], ogl_matrix[9], ogl_matrix[13]);
325
326 LLGLEnable gls_texgen_s(GL_TEXTURE_GEN_S);
327 LLGLEnable gls_texgen_t(GL_TEXTURE_GEN_T);
328 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
329 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
330 glTexGenfv(GL_S, GL_OBJECT_PLANE, s_params.mV);
331 glTexGenfv(GL_T, GL_OBJECT_PLANE, t_params.mV);
332 if ((mVertexShaderLevel > 0) && face.getTextureEntry() && specularIndex > 0)
333 { 166 {
334 U8 s = face.getTextureEntry()->getShiny(); 167 glMultMatrixf((F32*) bridge->mDrawable->getRenderMatrix().mMatrix);
335 glVertexAttrib4fARB(specularIndex, shiny[s], shiny[s], shiny[s], shiny[s]);
336 } 168 }
337 face.renderIndexed(getRawIndices()); 169 last_bridge = bridge;
338 } 170 }
339 171
340 { 172// if (!last_part || part->mDepthMask != last_part->mDepthMask)
341 // should get GL_GREATER to work, as it's faster 173// {
342 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_LESS); 174// glDepthMask(part->mDepthMask);
343 glAlphaFunc(GL_GEQUAL, fade_value); 175// }
344 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 176 last_part = part;
345 face.bindTexture(diffTex);
346 if ((mVertexShaderLevel > 0) && face.getTextureEntry() && specularIndex > 0)
347 {
348 U8 s = face.getTextureEntry()->getShiny();
349 glVertexAttrib4fARB(specularIndex, shiny[s], shiny[s], shiny[s], shiny[s]);
350 }
351 face.renderIndexed(getRawIndices());
352 }
353 } 177 }
354 178
355 // render opaque portion of actual texture 179 renderGroupAlpha(group,LLRenderPass::PASS_ALPHA,mask,TRUE);
356 glAlphaFunc(GL_GREATER, 0.98f);
357
358 face.bindTexture(diffTex);
359 face.renderIndexed(getRawIndices());
360
361 glAlphaFunc(GL_GREATER, 0.01f);
362
363 mIndicesDrawn += face.getIndicesCount();
364 } 180 }
365 } 181 }
182
183 glPopMatrix();
184}
366 185
367 if (mVertexShaderLevel > 0) //single pass shader driven shiny/bump 186void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask, std::vector<LLSpatialGroup*>& groups)
368 { 187{
369 gPipeline.mObjectAlphaProgram.disableTexture(LLPipeline::GLSL_ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB); 188#if !LL_RELEASE_FOR_DOWNLOAD
370 LLCubeMap* cube_map = gSky.mVOSkyp->getCubeMap(); 189 LLGLState::checkClientArrays(mask);
371 if (envTex >= 0 && cube_map) 190#endif
372 {
373 cube_map->restoreMatrix();
374 }
375 gPipeline.mObjectAlphaProgram.disableTexture(LLPipeline::GLSL_SCATTER_MAP);
376 gPipeline.mObjectAlphaProgram.disableTexture(LLPipeline::GLSL_DIFFUSE_MAP);
377
378 glClientActiveTextureARB(GL_TEXTURE0_ARB);
379 glActiveTextureARB(GL_TEXTURE0_ARB);
380 glEnable(GL_TEXTURE_2D);
381 }
382 191
383 if (sShowDebugAlpha) 192 LLSpatialBridge* last_bridge = NULL;
193 LLSpatialPartition* last_part = NULL;
194 glPushMatrix();
195
196 for (std::vector<LLSpatialGroup*>::iterator i = groups.begin(); i != groups.end(); ++i)
384 { 197 {
385 gPipeline.disableLights(); 198 LLSpatialGroup* group = *i;
386 if ((mVertexShaderLevel > 0)) 199 if (group->mSpatialPartition->mRenderByGroup &&
200 !group->isDead())
387 { 201 {
388 gPipeline.mHighlightProgram.bind(); 202 LLSpatialPartition* part = group->mSpatialPartition;
389 } 203 if (part != last_part)
390
391 LLViewerImage::sSmokeImagep->bind();
392 LLOverrideFaceColor override_color(this, 1.f, 0.f, 0.f, 1.f);
393 glColor4f(1.f, 0.f, 0.f, 1.f); // in case vertex shaders are enabled
394 glDisableClientState(GL_COLOR_ARRAY);
395
396 for (S32 i = 0; i < NUM_ALPHA_BINS; i++)
397 {
398 if (distance_bins[i].count() < 100)
399 { 204 {
400 face_list_t pri_queue; 205 LLSpatialBridge* bridge = part->asBridge();
401 pri_queue.reserve(distance_bins[i].count()); 206 if (bridge != last_bridge)
402 for (j = 0; j < distance_bins[i].count(); j++)
403 { 207 {
404 pri_queue.push_back(distance_bins[i][j]); 208 glPopMatrix();
405 } 209 glPushMatrix();
406 std::sort(pri_queue.begin(), pri_queue.end(), LLFace::CompareDistanceGreater()); 210 if (bridge)
407 211 {
408 for (face_list_t::iterator iter = pri_queue.begin(); iter != pri_queue.end(); iter++) 212 glMultMatrixf((F32*) bridge->mDrawable->getRenderMatrix().mMatrix);
409 { 213 }
410 const LLFace &face = *(*iter); 214 last_bridge = bridge;
411 face.renderIndexed(getRawIndices());
412 mIndicesDrawn += face.getIndicesCount();
413 } 215 }
216
217 last_part = part;
414 } 218 }
415 else 219
220 std::vector<LLDrawInfo*>& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];
221
222 for (std::vector<LLDrawInfo*>::const_iterator k = draw_info.begin(); k != draw_info.end(); ++k)
416 { 223 {
417 for (j = 0; j < distance_bins[i].count(); j++) 224 LLDrawInfo& params = **k;
225
226 if (params.mParticle)
418 { 227 {
419 const LLFace &face = *distance_bins[i][j]; 228 continue;
420 face.renderIndexed(getRawIndices());
421 mIndicesDrawn += face.getIndicesCount();
422 } 229 }
230 params.mVertexBuffer->setBuffer(mask);
231 U32* indices_pointer = (U32*) params.mVertexBuffer->getIndicesPointer();
232 glDrawRangeElements(GL_TRIANGLES, params.mStart, params.mEnd, params.mCount,
233 GL_UNSIGNED_INT, indices_pointer+params.mOffset);
234
235 addIndicesDrawn(params.mCount);
423 } 236 }
424 } 237 }
238 }
239 glPopMatrix();
240}
425 241
426 if ((mVertexShaderLevel > 0)) 242void LLDrawPoolAlpha::renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture)
427 { 243{
428 gPipeline.mHighlightProgram.unbind(); 244 BOOL light_enabled = TRUE;
429 }
430 245
431 } 246 std::vector<LLDrawInfo*>& draw_info = group->mDrawMap[type];
247
248 U32 prim_type = GL_TRIANGLES;
432 249
433} 250 //F32 width = (F32) gViewerWindow->getWindowDisplayWidth();
434 251
435void LLDrawPoolAlpha::renderForSelect() 252 //F32 view = gCamera->getView();
436{ 253
437 if (mDrawFace.empty() || !mMemory.count()) 254 if (group->mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_CLOUDS)
438 { 255 {
439 return; 256 glAlphaFunc(GL_GREATER, 0.f);
440 } 257 }
441 258 else
442 // force faces on focus object to proper alpha cutoff based on object bbox distance
443 if (gAgent.getFocusObject())
444 { 259 {
445 LLDrawable* drawablep = gAgent.getFocusObject()->mDrawable; 260 glAlphaFunc(GL_GREATER, 0.01f);
446
447 if (drawablep)
448 {
449 const S32 num_faces = drawablep->getNumFaces();
450
451 for (S32 f = 0; f < num_faces; f++)
452 {
453 LLFace* facep = drawablep->getFace(f);
454 facep->mDistance = gAgent.getFocusObjectDist();
455 }
456 }
457 } 261 }
458 262
459 glEnableClientState (GL_VERTEX_ARRAY); 263 /*LLGLEnable point_sprite(GL_POINT_SPRITE_ARB);
460 glEnableClientState (GL_TEXTURE_COORD_ARRAY);
461
462 LLGLSObjectSelectAlpha gls_alpha;
463
464 glBlendFunc(GL_ONE, GL_ZERO);
465 glAlphaFunc(gPickTransparent ? GL_GEQUAL : GL_GREATER, 0.f);
466
467 bindGLVertexPointer();
468 bindGLTexCoordPointer();
469 264
470 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); 265 if (gGLManager.mHasPointParameters)
471 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE); 266 {
472 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE); 267 glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, TRUE);
473 268 glPointParameterfARB(GL_POINT_SIZE_MIN_ARB, 0.f);
474 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS); 269 glPointParameterfARB(GL_POINT_SIZE_MAX_ARB, width*16.f);
475 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); 270 glPointSize(width/(view*view));
476 271 }*/
477 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
478 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
479
480 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
481 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);
482
483 LLDynamicArray<LLFace*>* distance_bins;
484 distance_bins = mDistanceBins;
485
486 S32 j;
487 S32 num_bins_no_alpha_test = (gPickAlphaThreshold != 0.f) ?
488 (NUM_ALPHA_BINS - llmax(2, (S32)(ALPHA_FALLOFF_START_DISTANCE * mInvBinSize))) :
489 NUM_ALPHA_BINS;
490 272
491 S32 i; 273 for (std::vector<LLDrawInfo*>::const_iterator k = draw_info.begin(); k != draw_info.end(); ++k)
492 for (i = 0; i < num_bins_no_alpha_test; i++)
493 { 274 {
494 S32 distance_bin_size = distance_bins[i].count(); 275 LLDrawInfo& params = **k;
495 for (j = 0; j < distance_bin_size; j++) 276 if (texture && params.mTexture.notNull())
496 { 277 {
497 const LLFace &face = *distance_bins[i][j]; 278 params.mTexture->bind();
498 if (face.getDrawable() && !face.getDrawable()->isDead() && (face.getViewerObject()->mGLName)) 279 params.mTexture->addTextureStats(params.mVSize);
280 if (params.mTextureMatrix)
499 { 281 {
500 face.bindTexture(); 282 glMatrixMode(GL_TEXTURE);
501 face.renderForSelect(); 283 glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix);
502 } 284 }
503 } 285 }
504 } 286
505 287 if (params.mFullbright)
506 for (i = num_bins_no_alpha_test; i < NUM_ALPHA_BINS; i++)
507 {
508 S32 distance_bin_size = distance_bins[i].count();
509 if (distance_bin_size)
510 { 288 {
511 for (j = 0; j < distance_bin_size; j++) 289 if (light_enabled)
512 { 290 {
513 const LLFace &face = *distance_bins[i][j]; 291 gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
514 292 light_enabled = FALSE;
515 glAlphaFunc(GL_GEQUAL, face.mAlphaFade * gPickAlphaTargetThreshold);
516
517 if (face.getDrawable() && !face.getDrawable()->isDead() && (face.getViewerObject()->mGLName))
518 {
519 face.bindTexture();
520 face.renderForSelect();
521 }
522 } 293 }
523 } 294 }
524 } 295 else if (!light_enabled)
525 296 {
526 glAlphaFunc(GL_GREATER, 0.01f); 297 gPipeline.enableLightsDynamic(1.f);
527 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 298 light_enabled = TRUE;
528 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 299 }
529 glDisableClientState (GL_TEXTURE_COORD_ARRAY);
530}
531
532
533void LLDrawPoolAlpha::renderFaceSelected(LLFace *facep,
534 LLImageGL *image,
535 const LLColor4 &color,
536 const S32 index_offset, const S32 index_count)
537{
538 facep->renderSelected(image, color, index_offset, index_count);
539}
540
541 300
542void LLDrawPoolAlpha::resetDrawOrders() 301 /*if (params.mParticle)
543{ 302 {
544 LLDrawPool::resetDrawOrders(); 303 F32 size = params.mPartSize;
304 size *= size;
305 float param[] = { 0, 0, 0.01f/size*view*view };
306 prim_type = GL_POINTS;
307 glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, param);
308 }
309 else*/
310 {
311 prim_type = GL_TRIANGLES;
312 }
545 313
546 for (S32 i = 0; i < NUM_ALPHA_BINS; i++) 314 params.mVertexBuffer->setBuffer(mask);
547 { 315 U32* indices_pointer = (U32*) params.mVertexBuffer->getIndicesPointer();
548 mDistanceBins[i].resize(0); 316 glDrawRangeElements(prim_type, params.mStart, params.mEnd, params.mCount,
549 } 317 GL_UNSIGNED_INT, indices_pointer+params.mOffset);
550} 318
319 addIndicesDrawn(params.mCount);
551 320
552BOOL LLDrawPoolAlpha::verify() const 321 if (params.mTextureMatrix && texture && params.mTexture.notNull())
553{
554 S32 i, j;
555 BOOL ok;
556 ok = LLDrawPool::verify();
557 for (i = 0; i < NUM_ALPHA_BINS; i++)
558 {
559 for (j = 0; j < mDistanceBins[i].count(); j++)
560 { 322 {
561 const LLFace &face = *mDistanceBins[i][j]; 323 glLoadIdentity();
562 if (!face.verify()) 324 glMatrixMode(GL_MODELVIEW);
563 {
564 ok = FALSE;
565 }
566 } 325 }
567 } 326 }
568 return ok;
569}
570
571LLViewerImage *LLDrawPoolAlpha::getDebugTexture()
572{
573 return LLViewerImage::sSmokeImagep;
574}
575
576
577LLColor3 LLDrawPoolAlpha::getDebugColor() const
578{
579 return LLColor3(1.f, 0.f, 0.f);
580}
581 327
582S32 LLDrawPoolAlpha::getMaterialAttribIndex() 328 if (!light_enabled)
583{ 329 {
584 return gPipeline.mObjectAlphaProgram.mAttribute[LLPipeline::GLSL_MATERIAL_COLOR]; 330 gPipeline.enableLightsDynamic(1.f);
585} 331 }
586 332
587// virtual 333 /*glPointSize(1.f);
588void LLDrawPoolAlpha::enableShade()
589{
590 glDisableClientState(GL_COLOR_ARRAY);
591}
592 334
593// virtual 335 if (gGLManager.mHasPointParameters)
594void LLDrawPoolAlpha::disableShade() 336 {
595{ 337 float param[] = {1, 0, 0 };
596 glEnableClientState(GL_COLOR_ARRAY); 338 glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, param);
597} 339 }*/
598 340}
599// virtual
600void LLDrawPoolAlpha::setShade(F32 shade)
601{
602 glColor4f(0,0,0,shade);
603}