00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llvostars.h"
00035
00036 #include "lldrawpoolstars.h"
00037 #include "llface.h"
00038 #include "llsky.h"
00039 #include "llvosky.h"
00040 #include "llworld.h"
00041 #include "pipeline.h"
00042
00043 const U32 NUMBER_OF_STARS = 1000;
00044 const F32 DISTANCE_TO_STARS = (HORIZON_DIST - 10.f)*0.25f;
00045
00046
00047 LLVOStars::LLVOStars(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
00048 : LLStaticViewerObject(id, pcode, regionp)
00049 {
00050 initStars();
00051 }
00052
00053 LLVOStars::~LLVOStars()
00054 {
00055 delete[] mStarVertices;
00056 mStarVertices = NULL;
00057 delete[] mStarColors;
00058 mStarColors = NULL;
00059 delete[] mStarIntensities;
00060 mStarIntensities = NULL;
00061 }
00062
00063 LLDrawable *LLVOStars::createDrawable(LLPipeline *pipeline)
00064 {
00065 pipeline->allocDrawable(this);
00066 mDrawable->setLit(FALSE);
00067
00068 LLDrawPoolStars *poolp = (LLDrawPoolStars*) gPipeline.getPool(LLDrawPool::POOL_STARS);
00069
00070 mFace = mDrawable->addFace(poolp, NULL);
00071 mDrawable->setRenderType(LLPipeline::RENDER_TYPE_STARS);
00072 mFace->setSize(NUMBER_OF_STARS, NUMBER_OF_STARS);
00073
00074 return mDrawable;
00075 }
00076
00077 BOOL LLVOStars::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
00078 {
00079 return TRUE;
00080 }
00081
00082 BOOL LLVOStars::updateGeometry(LLDrawable *drawable)
00083 {
00084 updateStarColors();
00085 updateStarGeometry(drawable);
00086
00087 LLPipeline::sCompiles++;
00088 return TRUE;
00089 }
00090
00091 BOOL LLVOStars::updateStarGeometry(LLDrawable *drawable)
00092 {
00093 LLStrider<LLVector3> verticesp;
00094 LLStrider<LLVector3> normalsp;
00095 LLStrider<LLVector2> texCoordsp;
00096 LLStrider<LLColor4U> colorsp;
00097 LLStrider<U32> indicesp;
00098 S32 index_offset;
00099
00100 if (mFace->mVertexBuffer.isNull())
00101 {
00102 mFace->mVertexBuffer = new LLVertexBuffer(LLDrawPoolStars::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
00103 mFace->mVertexBuffer->allocateBuffer(mFace->getGeomCount(), mFace->getIndicesCount(), TRUE);
00104 mFace->setGeomIndex(0);
00105 mFace->setIndicesIndex(0);
00106 }
00107
00108 index_offset = mFace->getGeometryColors(verticesp,normalsp,texCoordsp,colorsp, indicesp);
00109
00110 if (-1 == index_offset)
00111 {
00112 return TRUE;
00113 }
00114
00115 for (U32 vtx = 0; vtx < NUMBER_OF_STARS; ++vtx)
00116 {
00117 *(verticesp++) = mStarVertices[vtx];
00118 *(colorsp++) = LLColor4U(mStarColors[vtx]);
00119 *(indicesp++) = index_offset + vtx;
00120 }
00121
00122 return TRUE;
00123 }
00124
00125
00126 void LLVOStars::initStars()
00127 {
00128
00129 mStarVertices = new LLVector3 [NUMBER_OF_STARS];
00130 mStarColors = new LLColor4 [NUMBER_OF_STARS];
00131 mStarIntensities = new F32 [NUMBER_OF_STARS];
00132
00133 LLVector3 * v_p = mStarVertices;
00134 LLColor4 * v_c = mStarColors;
00135 F32 * v_i = mStarIntensities;
00136
00137 U32 i;
00138 for (i = 0; i < NUMBER_OF_STARS; i++ )
00139 {
00140 v_p->mV[VX] = ll_frand() - 0.5f;
00141 v_p->mV[VY] = ll_frand() - 0.5f;
00142
00143
00144
00145 v_p->mV[VZ] = ll_frand()/2.f;
00146
00147 v_p->normVec();
00148 *v_p *= DISTANCE_TO_STARS;
00149 *v_i = llmin((F32)pow(ll_frand(),2.f) + 0.1f, 1.f);
00150 v_c->mV[VRED] = 0.75f + ll_frand() * 0.25f ;
00151 v_c->mV[VGREEN] = 1.f ;
00152 v_c->mV[VBLUE] = 0.75f + ll_frand() * 0.25f ;
00153 v_c->mV[VALPHA] = 1.f;
00154 v_c->clamp();
00155 v_p++;
00156 v_c++;
00157 v_i++;
00158 }
00159 }
00160
00161 void LLVOStars::updateStarColors()
00162 {
00163 LLColor4 * v_c;
00164 v_c = mStarColors;
00165 F32 * v_i = mStarIntensities;
00166 LLVector3* v_p = mStarVertices;
00167
00168 const F32 var = 0.15f;
00169 const F32 min = 0.5f;
00170 const F32 sunclose_max = 0.6f;
00171 const F32 sunclose_range = 1 - sunclose_max;
00172
00173 F32 below_horizon = - llmin(0.0f, gSky.mVOSkyp->getToSunLast().mV[2]);
00174 F32 brightness_factor = llmin(1.0f, below_horizon * 20);
00175
00176 static S32 swap = 0;
00177 swap++;
00178
00179 if ((swap % 2) == 1)
00180 {
00181 F32 intensity;
00182 U32 x;
00183 for (x = 0; x < NUMBER_OF_STARS; x++)
00184 {
00185 F32 sundir_factor = 1;
00186 LLVector3 tostar = *v_p;
00187 tostar.normVec();
00188 const F32 how_close_to_sun = tostar * gSky.mVOSkyp->getToSunLast();
00189 if (how_close_to_sun > sunclose_max)
00190 {
00191 sundir_factor = (1 - how_close_to_sun) / sunclose_range;
00192 }
00193 intensity = *(v_i);
00194 F32 alpha = v_c->mV[VALPHA] + (ll_frand() - 0.5f) * var * intensity;
00195 if (alpha < min * intensity)
00196 {
00197 alpha = min * intensity;
00198 }
00199 if (alpha > intensity)
00200 {
00201 alpha = intensity;
00202 }
00203 alpha *= brightness_factor * sundir_factor;
00204 alpha = llclamp(alpha, 0.f, 1.f);
00205 v_c->mV[VALPHA] = alpha;
00206 v_c++;
00207 v_i++;
00208 v_p++;
00209 }
00210 }
00211 }