00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "pipeline.h"
00035
00036 #include "llvowlsky.h"
00037 #include "llsky.h"
00038 #include "lldrawpoolwlsky.h"
00039 #include "llface.h"
00040 #include "llwlparammanager.h"
00041 #include "llviewercontrol.h"
00042
00043 #define DOME_SLICES 1
00044 const F32 LLVOWLSky::DISTANCE_TO_STARS = (HORIZON_DIST - 10.f)*0.25f;
00045
00046 const U32 LLVOWLSky::MIN_SKY_DETAIL = 3;
00047 const U32 LLVOWLSky::MAX_SKY_DETAIL = 180;
00048
00049 inline U32 LLVOWLSky::getNumStacks(void)
00050 {
00051 return gSavedSettings.getU32("WLSkyDetail");
00052 }
00053
00054 inline U32 LLVOWLSky::getNumSlices(void)
00055 {
00056 return 2 * gSavedSettings.getU32("WLSkyDetail");
00057 }
00058
00059 inline U32 LLVOWLSky::getFanNumVerts(void)
00060 {
00061 return getNumSlices() + 1;
00062 }
00063
00064 inline U32 LLVOWLSky::getFanNumIndices(void)
00065 {
00066 return getNumSlices() * 3;
00067 }
00068
00069 inline U32 LLVOWLSky::getStripsNumVerts(void)
00070 {
00071 return (getNumStacks() - 1) * getNumSlices();
00072 }
00073
00074 inline U32 LLVOWLSky::getStripsNumIndices(void)
00075 {
00076 return 2 * ((getNumStacks() - 2) * (getNumSlices() + 1)) + 1 ;
00077 }
00078
00079 inline U32 LLVOWLSky::getStarsNumVerts(void)
00080 {
00081 return 1000;
00082 }
00083
00084 inline U32 LLVOWLSky::getStarsNumIndices(void)
00085 {
00086 return 1000;
00087 }
00088
00089 LLVOWLSky::LLVOWLSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
00090 : LLStaticViewerObject(id, pcode, regionp)
00091 {
00092 initStars();
00093 }
00094
00095 void LLVOWLSky::initSunDirection(LLVector3 const & sun_direction,
00096 LLVector3 const & sun_angular_velocity)
00097 {
00098 }
00099
00100 BOOL LLVOWLSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
00101 {
00102 return TRUE;
00103 }
00104
00105 BOOL LLVOWLSky::isActive(void) const
00106 {
00107 return FALSE;
00108 }
00109
00110 LLDrawable * LLVOWLSky::createDrawable(LLPipeline * pipeline)
00111 {
00112 pipeline->allocDrawable(this);
00113
00114
00115 gPipeline.getPool(LLDrawPool::POOL_WL_SKY);
00116
00117 mDrawable->setRenderType(LLPipeline::RENDER_TYPE_WL_SKY);
00118
00119 return mDrawable;
00120 }
00121
00122 inline F32 LLVOWLSky::calcPhi(U32 i)
00123 {
00124
00125 F32 t = float(i) / float(getNumStacks());
00126
00127
00128 t = t*t*t*t;
00129
00130
00131 t = 1.f - t;
00132 t = t*t;
00133 t = 1.f - t;
00134
00135 return (F_PI / 8.f) * t;
00136 }
00137
00138 #if !DOME_SLICES
00139 static const F32 Q = (1.f + sqrtf(5.f))/2.f;
00140
00141
00142 static const LLVector3 icosahedron_vert[] =
00143 {
00144 LLVector3(0,1.f,Q),
00145 LLVector3(0,-1.f,Q),
00146 LLVector3(0,-1.f,-Q),
00147 LLVector3(0,1.f,-Q),
00148
00149 LLVector3(Q,0,1.f),
00150 LLVector3(-Q,0,1.f),
00151 LLVector3(-Q,0,-1.f),
00152 LLVector3(Q,0,-1.f),
00153
00154 LLVector3(1,-Q,0.f),
00155 LLVector3(-1,-Q,0.f),
00156 LLVector3(-1,Q,0.f),
00157 LLVector3(1,Q,0.f),
00158 };
00159
00160
00161 static const U32 icosahedron_ind[] =
00162 {
00163 5,0,1,
00164 10,0,5,
00165 5,1,9,
00166 10,5,6,
00167 6,5,9,
00168 11,0,10,
00169 3,11,10,
00170 3,10,6,
00171 3,6,2,
00172 7,3,2,
00173 8,7,2,
00174 4,7,8,
00175 1,4,8,
00176 9,8,2,
00177 9,2,6,
00178 11,3,7,
00179 4,0,11,
00180 4,11,7,
00181 1,0,4,
00182 1,8,9,
00183 };
00184
00185
00186
00187 void subdivide(LLVertexBuffer& in, LLVertexBuffer* ret)
00188 {
00189 S32 tri_in = in.getNumIndices()/3;
00190
00191 ret->allocateBuffer(tri_in*4*3, tri_in*4*3, TRUE);
00192
00193 LLStrider<LLVector3> vin, vout;
00194 LLStrider<U16> indin, indout;
00195
00196 ret->getVertexStrider(vout);
00197 in.getVertexStrider(vin);
00198
00199 ret->getIndexStrider(indout);
00200 in.getIndexStrider(indin);
00201
00202
00203 for (S32 i = 0; i < tri_in; i++)
00204 {
00205 LLVector3 v0 = vin[*indin++];
00206 LLVector3 v1 = vin[*indin++];
00207 LLVector3 v2 = vin[*indin++];
00208
00209 LLVector3 v3 = (v0 + v1) * 0.5f;
00210 LLVector3 v4 = (v1 + v2) * 0.5f;
00211 LLVector3 v5 = (v2 + v0) * 0.5f;
00212
00213 *vout++ = v0;
00214 *vout++ = v3;
00215 *vout++ = v5;
00216
00217 *vout++ = v3;
00218 *vout++ = v4;
00219 *vout++ = v5;
00220
00221 *vout++ = v3;
00222 *vout++ = v1;
00223 *vout++ = v4;
00224
00225 *vout++ = v5;
00226 *vout++ = v4;
00227 *vout++ = v2;
00228 }
00229
00230 for (S32 i = 0; i < ret->getNumIndices(); i++)
00231 {
00232 *indout++ = i;
00233 }
00234
00235 }
00236
00237 void chop(LLVertexBuffer& in, LLVertexBuffer* out)
00238 {
00239
00240 F32 d = LLWLParamManager::sParamMgr->getDomeOffset() * LLWLParamManager::sParamMgr->getDomeRadius();
00241
00242 std::vector<LLVector3> vert;
00243
00244 LLStrider<LLVector3> vin;
00245 LLStrider<U16> index;
00246
00247 in.getVertexStrider(vin);
00248 in.getIndexStrider(index);
00249
00250 U32 tri_count = in.getNumIndices()/3;
00251 for (U32 i = 0; i < tri_count; i++)
00252 {
00253 LLVector3 &v1 = vin[index[i*3+0]];
00254 LLVector3 &v2 = vin[index[i*3+1]];
00255 LLVector3 &v3 = vin[index[i*3+2]];
00256
00257 if (v1.mV[1] > d ||
00258 v2.mV[1] > d ||
00259 v3.mV[1] > d)
00260 {
00261 v1.mV[1] = llmax(v1.mV[1], d);
00262 v2.mV[1] = llmax(v1.mV[1], d);
00263 v3.mV[1] = llmax(v1.mV[1], d);
00264
00265 vert.push_back(v1);
00266 vert.push_back(v2);
00267 vert.push_back(v3);
00268 }
00269 }
00270
00271 out->allocateBuffer(vert.size(), vert.size(), TRUE);
00272
00273 LLStrider<LLVector3> vout;
00274 out->getVertexStrider(vout);
00275 out->getIndexStrider(index);
00276
00277 for (U32 i = 0; i < vert.size(); i++)
00278 {
00279 *vout++ = vert[i];
00280 *index++ = i;
00281 }
00282 }
00283 #endif // !DOME_SLICES
00284
00285 void LLVOWLSky::resetVertexBuffers()
00286 {
00287 mFanVerts = NULL;
00288 mStripsVerts.clear();
00289 mStarsVerts = NULL;
00290
00291 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
00292 }
00293
00294 void LLVOWLSky::cleanupGL()
00295 {
00296 mFanVerts = NULL;
00297 mStripsVerts.clear();
00298 mStarsVerts = NULL;
00299
00300 LLDrawPoolWLSky::cleanupGL();
00301 }
00302
00303 void LLVOWLSky::restoreGL()
00304 {
00305 LLDrawPoolWLSky::restoreGL();
00306 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
00307 }
00308
00309 BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
00310 {
00311 LLFastTimer ftm(LLFastTimer::FTM_GEO_SKY);
00312 LLStrider<LLVector3> vertices;
00313 LLStrider<LLVector2> texCoords;
00314 LLStrider<U16> indices;
00315
00316 #if DOME_SLICES
00317 {
00318 mFanVerts = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
00319 mFanVerts->allocateBuffer(getFanNumVerts(), getFanNumIndices(), TRUE);
00320
00321 BOOL success = mFanVerts->getVertexStrider(vertices)
00322 && mFanVerts->getTexCoordStrider(texCoords)
00323 && mFanVerts->getIndexStrider(indices);
00324
00325 if(!success)
00326 {
00327 llerrs << "Failed updating WindLight sky geometry." << llendl;
00328 }
00329
00330 buildFanBuffer(vertices, texCoords, indices);
00331
00332 mFanVerts->setBuffer(0);
00333 }
00334
00335 {
00336 const U32 max_buffer_bytes = gSavedSettings.getS32("RenderMaxVBOSize")*1024;
00337 const U32 data_mask = LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK;
00338 const U32 max_verts = max_buffer_bytes / LLVertexBuffer::calcStride(data_mask);
00339
00340 const U32 total_stacks = getNumStacks();
00341
00342 const U32 verts_per_stack = getNumSlices();
00343
00344
00345
00346 const U32 stacks_per_seg = (max_verts - verts_per_stack) / verts_per_stack;
00347
00348
00349 const U32 strips_segments = (total_stacks+stacks_per_seg-1) / stacks_per_seg;
00350
00351 llinfos << "WL Skydome strips in " << strips_segments << " batches." << llendl;
00352
00353 mStripsVerts.resize(strips_segments, NULL);
00354
00355 for (U32 i = 0; i < strips_segments ;++i)
00356 {
00357 LLVertexBuffer * segment = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
00358 mStripsVerts[i] = segment;
00359
00360 U32 num_stacks_this_seg = stacks_per_seg;
00361 if ((i == strips_segments - 1) && (total_stacks % stacks_per_seg) != 0)
00362 {
00363
00364 num_stacks_this_seg = total_stacks % stacks_per_seg;
00365 }
00366
00367
00368 const U32 begin_stack = i * stacks_per_seg;
00369 const U32 end_stack = begin_stack + num_stacks_this_seg;
00370 llassert(end_stack <= total_stacks);
00371
00372 const U32 num_verts_this_seg = verts_per_stack * (num_stacks_this_seg+1);
00373 llassert(num_verts_this_seg <= max_verts);
00374
00375 const U32 num_indices_this_seg = 1+num_stacks_this_seg*(2+2*verts_per_stack);
00376 llassert(num_indices_this_seg * sizeof(U16) <= max_buffer_bytes);
00377
00378 segment->allocateBuffer(num_verts_this_seg, num_indices_this_seg, TRUE);
00379
00380
00381 BOOL success = segment->getVertexStrider(vertices)
00382 && segment->getTexCoordStrider(texCoords)
00383 && segment->getIndexStrider(indices);
00384
00385 if(!success)
00386 {
00387 llerrs << "Failed updating WindLight sky geometry." << llendl;
00388 }
00389
00390
00391 buildStripsBuffer(begin_stack, end_stack, vertices, texCoords, indices);
00392
00393
00394 segment->setBuffer(0);
00395 }
00396 }
00397 #else
00398 mStripsVerts = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
00399
00400 const F32 RADIUS = LLWLParamManager::sParamMgr->getDomeRadius();
00401
00402 LLPointer<LLVertexBuffer> temp = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, 0);
00403 temp->allocateBuffer(12, 60, TRUE);
00404
00405 BOOL success = temp->getVertexStrider(vertices)
00406 && temp->getIndexStrider(indices);
00407
00408 if (success)
00409 {
00410 for (U32 i = 0; i < 12; i++)
00411 {
00412 *vertices++ = icosahedron_vert[i];
00413 }
00414
00415 for (U32 i = 0; i < 60; i++)
00416 {
00417 *indices++ = icosahedron_ind[i];
00418 }
00419 }
00420
00421
00422 LLPointer<LLVertexBuffer> temp2;
00423
00424 for (U32 i = 0; i < 8; i++)
00425 {
00426 temp2 = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, 0);
00427 subdivide(*temp, temp2);
00428 temp = temp2;
00429 }
00430
00431 temp->getVertexStrider(vertices);
00432 for (S32 i = 0; i < temp->getNumVerts(); i++)
00433 {
00434 LLVector3 v = vertices[i];
00435 v.normVec();
00436 vertices[i] = v*RADIUS;
00437 }
00438
00439 temp2 = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, 0);
00440 chop(*temp, temp2);
00441
00442 mStripsVerts->allocateBuffer(temp2->getNumVerts(), temp2->getNumIndices(), TRUE);
00443
00444 success = mStripsVerts->getVertexStrider(vertices)
00445 && mStripsVerts->getTexCoordStrider(texCoords)
00446 && mStripsVerts->getIndexStrider(indices);
00447
00448 LLStrider<LLVector3> v;
00449 temp2->getVertexStrider(v);
00450 LLStrider<U16> ind;
00451 temp2->getIndexStrider(ind);
00452
00453 if (success)
00454 {
00455 for (S32 i = 0; i < temp2->getNumVerts(); ++i)
00456 {
00457 LLVector3 vert = *v++;
00458 vert.normVec();
00459 F32 z0 = vert.mV[2];
00460 F32 x0 = vert.mV[0];
00461
00462 vert *= RADIUS;
00463
00464 *vertices++ = vert;
00465 *texCoords++ = LLVector2((-z0 + 1.f) / 2.f, (-x0 + 1.f) / 2.f);
00466 }
00467
00468 for (S32 i = 0; i < temp2->getNumIndices(); ++i)
00469 {
00470 *indices++ = *ind++;
00471 }
00472 }
00473
00474 mStripsVerts->setBuffer(0);
00475 #endif
00476
00477 updateStarColors();
00478 updateStarGeometry(drawable);
00479
00480 LLPipeline::sCompiles++;
00481
00482 return TRUE;
00483 }
00484
00485 void LLVOWLSky::drawStars(void)
00486 {
00487
00488 if (mStarsVerts.notNull())
00489 {
00490 mStarsVerts->setBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK);
00491 mStarsVerts->draw(LLVertexBuffer::POINTS, getStarsNumIndices(), 0);
00492 }
00493 }
00494
00495 void LLVOWLSky::drawDome(void)
00496 {
00497 if (mStripsVerts.empty())
00498 {
00499 updateGeometry(mDrawable);
00500 }
00501
00502 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
00503
00504 const U32 data_mask = LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK;
00505
00506 #if DOME_SLICES
00507 std::vector< LLPointer<LLVertexBuffer> >::const_iterator strips_vbo_iter, end_strips;
00508 end_strips = mStripsVerts.end();
00509 for(strips_vbo_iter = mStripsVerts.begin(); strips_vbo_iter != end_strips; ++strips_vbo_iter)
00510 {
00511 LLVertexBuffer * strips_segment = strips_vbo_iter->get();
00512
00513 strips_segment->setBuffer(data_mask);
00514
00515 strips_segment->drawRange(
00516 LLVertexBuffer::TRIANGLE_STRIP,
00517 0, strips_segment->getRequestedVerts()-1, strips_segment->getRequestedIndices(),
00518 0);
00519 gPipeline.addTrianglesDrawn(strips_segment->getRequestedIndices() - 2);
00520 }
00521
00522 #else
00523 mStripsVerts->setBuffer(data_mask);
00524 glDrawRangeElements(
00525 GL_TRIANGLES,
00526 0, mStripsVerts->getNumVerts()-1, mStripsVerts->getNumIndices(),
00527 GL_UNSIGNED_SHORT,
00528 mStripsVerts->getIndicesPointer());
00529 #endif
00530
00531 LLVertexBuffer::unbind();
00532 }
00533
00534 void LLVOWLSky::initStars()
00535 {
00536
00537 mStarVertices.resize(getStarsNumVerts());
00538 mStarColors.resize(getStarsNumVerts());
00539 mStarIntensities.resize(getStarsNumVerts());
00540
00541 std::vector<LLVector3>::iterator v_p = mStarVertices.begin();
00542 std::vector<LLColor4>::iterator v_c = mStarColors.begin();
00543 std::vector<F32>::iterator v_i = mStarIntensities.begin();
00544
00545 U32 i;
00546 for (i = 0; i < getStarsNumVerts(); ++i)
00547 {
00548 v_p->mV[VX] = ll_frand() - 0.5f;
00549 v_p->mV[VY] = ll_frand() - 0.5f;
00550
00551
00552
00553 v_p->mV[VZ] = ll_frand()/2.f;
00554
00555 v_p->normVec();
00556 *v_p *= DISTANCE_TO_STARS;
00557 *v_i = llmin((F32)pow(ll_frand(),2.f) + 0.1f, 1.f);
00558 v_c->mV[VRED] = 0.75f + ll_frand() * 0.25f ;
00559 v_c->mV[VGREEN] = 1.f ;
00560 v_c->mV[VBLUE] = 0.75f + ll_frand() * 0.25f ;
00561 v_c->mV[VALPHA] = 1.f;
00562 v_c->clamp();
00563 v_p++;
00564 v_c++;
00565 v_i++;
00566 }
00567 }
00568
00569 void LLVOWLSky::buildFanBuffer(LLStrider<LLVector3> & vertices,
00570 LLStrider<LLVector2> & texCoords,
00571 LLStrider<U16> & indices)
00572 {
00573 const F32 RADIUS = LLWLParamManager::instance()->getDomeRadius();
00574
00575 U32 i, num_slices;
00576 F32 phi0, theta, x0, y0, z0;
00577
00578
00579 U32 count_verts = 0;
00580 U32 count_indices = 0;
00581
00582
00583 *vertices++ = LLVector3(0.f, RADIUS, 0.f);
00584 *texCoords++ = LLVector2(0.5f, 0.5f);
00585 ++count_verts;
00586
00587 num_slices = getNumSlices();
00588
00589
00590 phi0 = calcPhi(1);
00591 for(i = 0; i < num_slices; ++i) {
00592 theta = 2.f * F_PI * float(i) / float(num_slices);
00593
00594
00595
00596 x0 = sin(phi0) * cos(theta);
00597 y0 = cos(phi0);
00598 z0 = sin(phi0) * sin(theta);
00599
00600 *vertices++ = LLVector3(x0 * RADIUS, y0 * RADIUS, z0 * RADIUS);
00601
00602
00603
00604
00605 *texCoords++ = LLVector2((-z0 + 1.f) / 2.f, (-x0 + 1.f) / 2.f);
00606 ++count_verts;
00607
00608 if (i > 0)
00609 {
00610 *indices++ = 0;
00611 *indices++ = i;
00612 *indices++ = i+1;
00613 count_indices += 3;
00614 }
00615 }
00616
00617
00618
00619 *indices++ = 0;
00620 *indices++ = num_slices;
00621 *indices++ = 1;
00622 count_indices += 3;
00623
00624
00625 llassert(getFanNumVerts() == count_verts);
00626 llassert(getFanNumIndices() == count_indices);
00627 }
00628
00629 void LLVOWLSky::buildStripsBuffer(U32 begin_stack, U32 end_stack,
00630 LLStrider<LLVector3> & vertices,
00631 LLStrider<LLVector2> & texCoords,
00632 LLStrider<U16> & indices)
00633 {
00634 const F32 RADIUS = LLWLParamManager::instance()->getDomeRadius();
00635
00636 U32 i, j, num_slices, num_stacks;
00637 F32 phi0, theta, x0, y0, z0;
00638
00639
00640 U32 count_verts = 0;
00641 U32 count_indices = 0;
00642
00643 num_slices = getNumSlices();
00644 num_stacks = getNumStacks();
00645
00646 llassert(end_stack <= num_stacks);
00647
00648
00649 for(i = begin_stack + 1; i <= end_stack+1; ++i)
00650 {
00651 phi0 = calcPhi(i);
00652
00653 for(j = 0; j < num_slices; ++j)
00654 {
00655 theta = F_TWO_PI * (float(j) / float(num_slices));
00656
00657
00658
00659 x0 = sin(phi0) * cos(theta);
00660 y0 = cos(phi0);
00661 z0 = sin(phi0) * sin(theta);
00662
00663 if (i == num_stacks-2)
00664 {
00665 *vertices++ = LLVector3(x0*RADIUS, y0*RADIUS-1024.f*2.f, z0*RADIUS);
00666 }
00667 else if (i == num_stacks-1)
00668 {
00669 *vertices++ = LLVector3(0, y0*RADIUS-1024.f*2.f, 0);
00670 }
00671 else
00672 {
00673 *vertices++ = LLVector3(x0 * RADIUS, y0 * RADIUS, z0 * RADIUS);
00674 }
00675 ++count_verts;
00676
00677
00678
00679
00680
00681 *texCoords++ = LLVector2((-z0 + 1.f) / 2.f, (-x0 + 1.f) / 2.f);
00682 }
00683 }
00684
00685
00686 *indices++ = 0 ;
00687 count_indices++ ;
00688 S32 k = 0 ;
00689 for(i = 1; i <= end_stack - begin_stack; ++i)
00690 {
00691 *indices++ = i * num_slices + k ;
00692 count_indices++ ;
00693
00694 k = (k+1) % num_slices ;
00695 for(j = 0; j < num_slices ; ++j)
00696 {
00697 *indices++ = (i-1) * num_slices + k ;
00698 *indices++ = i * num_slices + k ;
00699
00700 count_indices += 2 ;
00701
00702 k = (k+1) % num_slices ;
00703 }
00704
00705 if((--k) < 0)
00706 {
00707 k = num_slices - 1 ;
00708 }
00709
00710 *indices++ = i * num_slices + k ;
00711 count_indices++ ;
00712 }
00713 }
00714
00715 void LLVOWLSky::updateStarColors()
00716 {
00717 std::vector<LLColor4>::iterator v_c = mStarColors.begin();
00718 std::vector<F32>::iterator v_i = mStarIntensities.begin();
00719 std::vector<LLVector3>::iterator v_p = mStarVertices.begin();
00720
00721 const F32 var = 0.15f;
00722 const F32 min = 0.5f;
00723 const F32 sunclose_max = 0.6f;
00724 const F32 sunclose_range = 1 - sunclose_max;
00725
00726
00727
00728
00729 static S32 swap = 0;
00730 swap++;
00731
00732 if ((swap % 2) == 1)
00733 {
00734 F32 intensity;
00735 U32 x;
00736 for (x = 0; x < getStarsNumVerts(); ++x)
00737 {
00738 F32 sundir_factor = 1;
00739 LLVector3 tostar = *v_p;
00740 tostar.normVec();
00741 const F32 how_close_to_sun = tostar * gSky.mVOSkyp->getToSunLast();
00742 if (how_close_to_sun > sunclose_max)
00743 {
00744 sundir_factor = (1 - how_close_to_sun) / sunclose_range;
00745 }
00746 intensity = *(v_i);
00747 F32 alpha = v_c->mV[VALPHA] + (ll_frand() - 0.5f) * var * intensity;
00748 if (alpha < min * intensity)
00749 {
00750 alpha = min * intensity;
00751 }
00752 if (alpha > intensity)
00753 {
00754 alpha = intensity;
00755 }
00756
00757
00758 alpha = llclamp(alpha, 0.f, 1.f);
00759 v_c->mV[VALPHA] = alpha;
00760 v_c++;
00761 v_i++;
00762 v_p++;
00763 }
00764 }
00765 }
00766
00767 BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable)
00768 {
00769 LLStrider<LLVector3> verticesp;
00770 LLStrider<LLColor4U> colorsp;
00771 LLStrider<U16> indicesp;
00772
00773 if (mStarsVerts.isNull())
00774 {
00775 mStarsVerts = new LLVertexBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK, GL_DYNAMIC_DRAW);
00776 mStarsVerts->allocateBuffer(getStarsNumVerts(), getStarsNumIndices(), TRUE);
00777 }
00778
00779 BOOL success = mStarsVerts->getVertexStrider(verticesp)
00780 && mStarsVerts->getIndexStrider(indicesp)
00781 && mStarsVerts->getColorStrider(colorsp);
00782
00783 if(!success)
00784 {
00785 llerrs << "Failed updating star geometry." << llendl;
00786 }
00787
00788
00789
00790
00791 for (U32 vtx = 0; vtx < getStarsNumVerts(); ++vtx)
00792 {
00793 *(verticesp++) = mStarVertices[vtx];
00794 *(colorsp++) = LLColor4U(mStarColors[vtx]);
00795 *(indicesp++) = vtx;
00796 }
00797
00798 mStarsVerts->setBuffer(0);
00799 return TRUE;
00800 }