00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "std3d.h"
00027 #include "3d/material.h"
00028 #include "cloud.h"
00029 #include "cloud_scape.h"
00030 #include "noise_3d.h"
00031 #include "nel/3d/scissor.h"
00032 #include "nel/3d/viewport.h"
00033 #include "3d/driver.h"
00034
00035 using namespace NLMISC;
00036
00037 namespace NL3D
00038 {
00039
00040
00041 CCloud::CCloud (CCloudScape *pCloudScape)
00042 {
00043 _CloudScape = pCloudScape;
00044 _Driver = _CloudScape->_Driver;
00045 CloudPower = 255;
00046 LastCloudPower = 255;
00047 CloudDistAtt = 0;
00048 CloudDiffuse = CRGBA(255,255,255,255);
00049 CloudAmbient = CRGBA(120,140,160,255);
00050 _WaitState = 0;
00051 _BillSize = 0;
00052 _OldBillSize = 0;
00053 _UStart = _VStart = _WStart = NULL;
00054 }
00055
00056
00057 CCloud::~CCloud()
00058 {
00059 delete _UStart;
00060 delete _VStart;
00061 delete _WStart;
00062 }
00063
00064
00065 void CCloud::init (uint32 nVoxelW, uint32 nVoxelH, uint32 nVoxelD, float rBaseFreq, uint32 nNbOctave)
00066 {
00067 if (_UStart != NULL)
00068 return;
00069
00070 _BaseFreq = rBaseFreq;
00071 _BillSize = 0;
00072 _OldBillSize = 0;
00073
00074 _NbOctave = nNbOctave;
00075 _UStart = new double[_NbOctave];
00076 _VStart = new double[_NbOctave];
00077 _WStart = new double[_NbOctave];
00078
00079 uint32 i;
00080 for (i = 0; i < _NbOctave; ++i)
00081 {
00082 _UStart[i] = ((double)rand())/RAND_MAX;
00083 _VStart[i] = ((double)rand())/RAND_MAX;
00084 _WStart[i] = ((double)rand())/RAND_MAX;
00085 }
00086
00087 _Width = raiseToNextPowerOf2 (nVoxelW);
00088 _Height = raiseToNextPowerOf2 (nVoxelH);
00089 _Depth = raiseToNextPowerOf2 (nVoxelD);
00090 uint32 vdpo2 = getPowerOf2(_Depth);
00091 _NbW = 1 << (vdpo2 / 2);
00092 if ((vdpo2 & 1) != 0)
00093 _NbH = 2 << (vdpo2 / 2);
00094 else
00095 _NbH = 1 << (vdpo2 / 2);
00096
00097 _MemBill = NULL;
00098 _MemOldBill = NULL;
00099
00100 float scale = 20.0f + 10.0f*((float)rand())/RAND_MAX;;
00101 _Size.x = scale * _Width/_Depth;
00102 scale = 20.0f + 10.0f*((float)rand())/RAND_MAX;;
00103 _Size.y = scale * _Height/_Depth;
00104 scale = 20.0f + 10.0f*((float)rand())/RAND_MAX;;
00105 _Size.z = scale * _Depth/_Depth;
00106
00107 }
00108
00109
00110 void CCloud::generate (CNoise3d &noise)
00111 {
00112 float dU, dV, dW;
00113 uint32 nOct;
00114 CQuadUV qc;
00115
00116
00117 setMode2D ();
00118
00119
00120 CVertexBuffer &rVB = _CloudScape->_VertexBuffer;
00121 uint32 nVSize = rVB.getVertexSize ();
00122 CVector *pVertices = (CVector*)rVB.getVertexCoordPointer (0);
00123 *pVertices = CVector(0.0f, 0.0f, 0.0f); pVertices = (CVector*)( ((uint8*)pVertices) + nVSize );
00124 *pVertices = CVector((float)_NbW*_Width,0.0f, 0.0f); pVertices = (CVector*)( ((uint8*)pVertices) + nVSize );
00125 *pVertices = CVector((float)_NbW*_Width,(float)_NbH*_Height,0.0f); pVertices = (CVector*)( ((uint8*)pVertices) + nVSize );
00126 *pVertices = CVector(0.0f, (float)_NbH*_Height,0.0f);
00127 _CloudScape->_MatClear.setColor (CRGBA(0,0,0,0));
00128 _Driver->activeVertexBuffer (rVB);
00129 _Driver->renderQuads (_CloudScape->_MatClear, 0, 1);
00130
00131
00132 for (nOct = 0; nOct < _NbOctave; ++nOct)
00133 {
00134 dU = (_BaseFreq*((float)_Width)/noise.getWidth())*(1<<nOct);
00135 dV = (_BaseFreq*((float)_Height)/noise.getHeight())*(1<<nOct);
00136 dW = (_BaseFreq*((float)_Depth)/noise.getDepth())*(1<<nOct);
00137
00138
00139 noise.renderGrid (_NbW, _NbH, _Width, _Height,
00140 (float)_UStart[nOct], (float)_VStart[nOct], (float)_WStart[nOct], dU, dV, dW,
00141 1.0f/(2<<nOct));
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 noise.flush ();
00161 }
00162
00163
00164 CUV *pUV = (CUV*)rVB.getTexCoordPointer (0, 0);
00165 pUV->U = 0.0f; pUV->V = 0.0f; pUV = (CUV*)( ((uint8*)pUV) + nVSize );
00166 pUV->U = 1.0f; pUV->V = 0.0f; pUV = (CUV*)( ((uint8*)pUV) + nVSize );
00167 pUV->U = 1.0f; pUV->V = 1.0f; pUV = (CUV*)( ((uint8*)pUV) + nVSize );
00168 pUV->U = 0.0f; pUV->V = 1.0f;
00169 uint8 colpow = (uint8)(255-(((uint32)CloudPower*(255-(uint32)CloudDistAtt)) / 255));
00170 _CloudTexClamp->ToClamp.setColor (CRGBA(255, 255, 255, colpow));
00171 _Driver->activeVertexBuffer (rVB);
00172 _Driver->renderQuads (_CloudTexClamp->ToClamp, 0, 1);
00173
00174
00175 _Driver->copyFrameBufferToTexture (_CloudTexTmp->Tex, 0, 0, 0, 0, 0, _Width*_NbW, _Height*_NbH);
00176
00177 _CloudTexTmp->Tex->setFilterMode (ITexture::Nearest, ITexture::NearestMipMapOff);
00178 }
00179
00180
00181
00182 void CCloud::light ()
00183 {
00184 uint32 i, j;
00185
00186
00187 setMode2D ();
00188
00189
00190 CVertexBuffer &rVB = _CloudScape->_VertexBuffer;
00191 uint32 nVSize = rVB.getVertexSize ();
00192 CVector *pVertices = (CVector*)rVB.getVertexCoordPointer (0);
00193 *pVertices = CVector((float)0.0f, (float)0.0f, 0.0f); pVertices = (CVector*)( ((uint8*)pVertices) + nVSize );
00194 *pVertices = CVector((float)_Width, (float)0.0f, 0.0f); pVertices = (CVector*)( ((uint8*)pVertices) + nVSize );
00195 *pVertices = CVector((float)_Width, (float)_Height, 0.0f); pVertices = (CVector*)( ((uint8*)pVertices) + nVSize );
00196 *pVertices = CVector((float)0.0f, (float)_Height, 0.0f);
00197
00198
00199 CloudDiffuse.A = 255;
00200 _CloudScape->_MatClear.setColor (CloudDiffuse);
00201 _Driver->activeVertexBuffer (rVB);
00202 _Driver->renderQuads (_CloudScape->_MatClear, 0, 1);
00203
00204 CUV *pUV;
00205
00206 float oneOverNbW = 1.0f/_NbW;
00207 float oneOverNbH = 1.0f/_NbH;
00208 uint32 previ, prevj;
00209 _Driver->activeVertexBuffer (rVB);
00210 for (j = 0; j < _NbH; ++j)
00211 {
00212 for (i = 0; i < _NbW; ++i)
00213 {
00214
00215 if ((i+j) > 0)
00216 {
00217 _Driver->setColorMask (true, true, true, false);
00218 pUV = (CUV*)rVB.getTexCoordPointer (0, 0);
00219 pUV->U = previ*oneOverNbW; pUV->V = prevj*oneOverNbH; pUV = (CUV*)( ((uint8*)pUV) + nVSize );
00220 pUV->U = (previ+1)*oneOverNbW; pUV->V = prevj*oneOverNbH; pUV = (CUV*)( ((uint8*)pUV) + nVSize );
00221 pUV->U = (previ+1)*oneOverNbW; pUV->V = (prevj+1)*oneOverNbH; pUV = (CUV*)( ((uint8*)pUV) + nVSize );
00222 pUV->U = previ*oneOverNbW; pUV->V = (prevj+1)*oneOverNbH;
00223
00224 _CloudTexTmp->ToLight.setBlend (true);
00225 _Driver->renderQuads (_CloudTexTmp->ToLight, 0, 1);
00226 }
00227
00228 _Driver->setColorMask (false, false, false, true);
00229
00230 pUV = (CUV*)rVB.getTexCoordPointer (0, 0);
00231 pUV->U = i*oneOverNbW; pUV->V = j*oneOverNbH; pUV = (CUV*)( ((uint8*)pUV) + nVSize );
00232 pUV->U = (i+1)*oneOverNbW; pUV->V = j*oneOverNbH; pUV = (CUV*)( ((uint8*)pUV) + nVSize );
00233 pUV->U = (i+1)*oneOverNbW; pUV->V = (j+1)*oneOverNbH; pUV = (CUV*)( ((uint8*)pUV) + nVSize );
00234 pUV->U = i*oneOverNbW; pUV->V = (j+1)*oneOverNbH;
00235
00236 _CloudTexTmp->ToLight.setBlend (false);
00237 _Driver->renderQuads (_CloudTexTmp->ToLight, 0, 1);
00238
00239
00240 _Driver->copyFrameBufferToTexture(_CloudTexTmp->Tex, 0, i*_Width, j*_Height, 0, 0, _Width, _Height);
00241 previ = i;
00242 prevj = j;
00243 }
00244 }
00245 _Driver->setColorMask (true, true, true, true);
00246
00247 _CloudTexTmp->Tex->setFilterMode (ITexture::Linear, ITexture::LinearMipMapOff);
00248 }
00249
00250
00251 void CCloud::reset (NL3D::CCamera *pViewer)
00252 {
00253 if (_BillSize != 4)
00254 {
00255 _BillSize = 4;
00256 _MemBill = new uint8[4*_BillSize*_BillSize];
00257 _TexBill = new CTextureMem (_MemBill, 4*_BillSize*_BillSize, true, false, _BillSize, _BillSize);
00258 _TexBill->setWrapS (ITexture::Clamp);
00259 _TexBill->setWrapT (ITexture::Clamp);
00260 _TexBill->setFilterMode (ITexture::Linear, ITexture::LinearMipMapOff);
00261 _TexBill->generate();
00262 _TexBill->setReleasable (false);
00263 }
00264 if (_OldBillSize != 4)
00265 {
00266 _OldBillSize = 4;
00267 _MemOldBill = new uint8[4*_OldBillSize*_OldBillSize];
00268 _TexOldBill = new CTextureMem (_MemOldBill, 4*_OldBillSize*_OldBillSize, true, false, _OldBillSize, _OldBillSize);
00269 _TexOldBill->setWrapS (ITexture::Clamp);
00270 _TexOldBill->setWrapT (ITexture::Clamp);
00271 _TexOldBill->setFilterMode (ITexture::Linear, ITexture::LinearMipMapOff);
00272 _TexOldBill->generate();
00273 _TexOldBill->setReleasable (false);
00274 }
00275 setMode2D ();
00276
00277
00278 CVertexBuffer &rVB = _CloudScape->_VertexBuffer;
00279 uint32 nVSize = rVB.getVertexSize ();
00280 CVector *pVertices = (CVector*)rVB.getVertexCoordPointer (0);
00281 *pVertices = CVector(0.0f, 0.0f, 0.0f); pVertices = (CVector*)( ((uint8*)pVertices) + nVSize );
00282 *pVertices = CVector(5.0f, 0.0f, 0.0f); pVertices = (CVector*)( ((uint8*)pVertices) + nVSize );
00283 *pVertices = CVector(5.0f, 5.0f, 0.0f); pVertices = (CVector*)( ((uint8*)pVertices) + nVSize );
00284 *pVertices = CVector(0.0f, 5.0f, 0.0f);
00285 _CloudScape->_MatClear.setColor (CRGBA(0,0,0,0));
00286 _Driver->activeVertexBuffer (rVB);
00287 _Driver->renderQuads (_CloudScape->_MatClear, 0, 1);
00288
00289 _Driver->copyFrameBufferToTexture (_TexBill, 0, 0, 0, 0, 0, 4, 4);
00290 _Driver->copyFrameBufferToTexture (_TexOldBill, 0, 0, 0, 0, 0, 4, 4);
00291
00292
00293
00294 CVector Viewer = CVector(0,0,0);
00295 CVector Center = CVector (_Pos.x+_Size.x/2, _Pos.y+_Size.y/2, _Pos.z+_Size.z/2);
00296 CVector Size = _Size;
00297 CVector I, J, K;
00298 float Left, Right, Top, Bottom, Near, Far;
00299
00300 calcBill (Viewer, Center, Size, I, J, K, Left, Right, Top, Bottom, Near, Far);
00301
00302 _BillOldCenter = _BillCenter;
00303 _BillViewer = Viewer;
00304 _BillCenter = Center;
00305
00306 calcBill (Viewer, Center, Size, I, J, K, Left, Right, Top, Bottom, Near, Far);
00307
00308 _BillOldCenter = _BillCenter;
00309 _BillViewer = Viewer;
00310 _BillCenter = Center;
00311
00312 }
00313
00314
00315 void CCloud::anim (double dt, double dt2)
00316 {
00317 for (uint32 nOct = 0; nOct < _NbOctave; ++nOct)
00318 {
00319 _UStart[nOct] += dt*(1<<nOct) / 5000.0;
00320 _VStart[nOct] += dt*(1<<nOct) / 5000.0;
00321 _WStart[nOct] += dt*(1<<nOct) / 5000.0;
00322 }
00323
00324
00325 }
00326
00327
00328 void CCloud::disp ()
00329 {
00330 CQuadUV qc;
00331 qc.Uv0 = CUV(0.0f, 0.0f);
00332 qc.Uv1 = CUV(1.0f, 0.0f);
00333 qc.Uv2 = CUV(1.0f, 1.0f);
00334 qc.Uv3 = CUV(0.0f, 1.0f);
00335
00337 CScissor s;
00338 s.initFullScreen();
00339 _Driver->setupScissor (s);
00340 _Driver->setupViewport (CViewport());
00341 _Driver->setFrustum (0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, false);
00342 CVector I(1,0,0);
00343 CVector J(0,0,1);
00344 CVector K(0,-1,0);
00345 CMatrix ViewMatrix;
00346 ViewMatrix.identity();
00347 ViewMatrix.setRot(I,J,K, true);
00348 _Driver->setupViewMatrix(ViewMatrix);
00349 _Driver->setupModelMatrix(CMatrix::Identity);
00351
00352 uint32 w = _NbW*_Width;
00353 uint32 h = _NbH*_Height;
00354 uint32 i = 0;
00355 qc.V0 = CVector(0.0f/800.0f, 0.0f/600.0f, 0.0f);
00356 qc.V1 = CVector(w/800.0f, 0.0f/600.0f, 0.0f);
00357 qc.V2 = CVector(w/800.0f, h/600.0f, 0.0f);
00358 qc.V3 = CVector(0.0f/800.0f, h/600.0f, 0.0f);
00359 static CMaterial *dispMat = NULL;
00360 if (dispMat == NULL)
00361 {
00362 dispMat = new CMaterial;
00363 dispMat->initUnlit();
00364 dispMat->setTexture(0, _CloudTexTmp->Tex);
00365 dispMat->texEnvOpRGB(0, CMaterial::Replace);
00366
00367 dispMat->texEnvArg0RGB(0, CMaterial::Texture, CMaterial::SrcColor);
00368 dispMat->setZFunc(CMaterial::always);
00369 dispMat->setZWrite(false);
00370 dispMat->setDoubleSided(true);
00371 dispMat->setBlend (false);
00372 }
00373
00374 CVertexBuffer &rVB = _CloudScape->_VertexBuffer;
00375 rVB.setVertexCoord (0, qc.V0);
00376 rVB.setVertexCoord (1, qc.V1);
00377 rVB.setVertexCoord (2, qc.V2);
00378 rVB.setVertexCoord (3, qc.V3);
00379 rVB.setTexCoord (0, 0, qc.Uv0);
00380 rVB.setTexCoord (1, 0, qc.Uv1);
00381 rVB.setTexCoord (2, 0, qc.Uv2);
00382 rVB.setTexCoord (3, 0, qc.Uv3);
00383 _Driver->activeVertexBuffer (rVB);
00384 _Driver->renderQuads (*dispMat, 0, 1);
00385 }
00386
00387
00388 void CCloud::dispXYZ (CMaterial *pMat)
00389 {
00390 CQuadUV qc;
00391 uint32 i,j;
00392
00393 float oneOverNbW = 1.0f / _NbW;
00394 float oneOverNbH = 1.0f / _NbH;
00395 float oneOverNbWNbH = 1.0f / (_NbW*_NbH);
00396 CVertexBuffer &rVB = _CloudScape->_VertexBuffer;
00397 uint32 nVSize = rVB.getVertexSize ();
00398 CVector *pVertices;
00399 CUV *pUV;
00400 _Driver->activeVertexBuffer (rVB);
00401
00402 if (pMat == NULL)
00403 return;
00404
00405 for (j = 0; j < _NbH; ++j)
00406 {
00407 for (i = 0; i < _NbW; ++i)
00408 {
00409 uint32 d = i+j*_NbW;
00410
00411 pVertices = (CVector*)rVB.getVertexCoordPointer (0);
00412 *pVertices = CVector(_Pos.x, _Pos.y, _Pos.z+_Size.z*(_NbW*_NbH-d)*oneOverNbWNbH); pVertices = (CVector*)( ((uint8*)pVertices) + nVSize );
00413 *pVertices = CVector(_Pos.x+_Size.x, _Pos.y, _Pos.z+_Size.z*(_NbW*_NbH-d)*oneOverNbWNbH); pVertices = (CVector*)( ((uint8*)pVertices) + nVSize );
00414 *pVertices = CVector(_Pos.x+_Size.x, _Pos.y+_Size.y, _Pos.z+_Size.z*(_NbW*_NbH-d)*oneOverNbWNbH); pVertices = (CVector*)( ((uint8*)pVertices) + nVSize );
00415 *pVertices = CVector(_Pos.x, _Pos.y+_Size.y, _Pos.z+_Size.z*(_NbW*_NbH-d)*oneOverNbWNbH);
00416
00417 pUV = (CUV*)rVB.getTexCoordPointer (0, 0);
00418 pUV->U = i*oneOverNbW; pUV->V = j*oneOverNbH; pUV = (CUV*)( ((uint8*)pUV) + nVSize );
00419 pUV->U = (i+1)*oneOverNbW; pUV->V = j*oneOverNbH; pUV = (CUV*)( ((uint8*)pUV) + nVSize );
00420 pUV->U = (i+1)*oneOverNbW; pUV->V = (j+1)*oneOverNbH; pUV = (CUV*)( ((uint8*)pUV) + nVSize );
00421 pUV->U = i*oneOverNbW; pUV->V = (j+1)*oneOverNbH;
00422
00423 pUV = (CUV*)rVB.getTexCoordPointer (0, 1);
00424 pUV->U = i*oneOverNbW; pUV->V = j*oneOverNbH; pUV = (CUV*)( ((uint8*)pUV) + nVSize );
00425 pUV->U = (i+1)*oneOverNbW; pUV->V = j*oneOverNbH; pUV = (CUV*)( ((uint8*)pUV) + nVSize );
00426 pUV->U = (i+1)*oneOverNbW; pUV->V = (j+1)*oneOverNbH; pUV = (CUV*)( ((uint8*)pUV) + nVSize );
00427 pUV->U = i*oneOverNbW; pUV->V = (j+1)*oneOverNbH;
00428
00429 _Driver->renderQuads (*pMat, 0, 1);
00430 }
00431 }
00432 }
00433
00434
00435
00436
00437 void CCloud::calcBill (const CVector &Viewer, const CVector &Center, const CVector &Size, CVector &I, CVector &J, CVector &K,
00438 float &Left, float &Right, float &Top, float &Bottom, float &Near, float &Far)
00439 {
00440 CVector ViewDir = Center - Viewer;
00441 float ViewDist = ViewDir.norm();
00442 ViewDir.normalize();
00443
00444 Left = 1000.0f;
00445 Right = -1000.0f;
00446 Top = -1000.0f;
00447 Bottom = 1000.0f;
00448 Near = 1000.0f;
00449 Far = -1000.0f;
00450
00451 if (fabsf(Center.y-Viewer.y) > fabsf(Center.z-Viewer.z))
00452 {
00453 K.set(0, 0, 1);
00454 J= ViewDir;
00455 I= J^K;
00456 K= I^J;
00457 }
00458 else
00459 {
00460 K.set(0, 1, 0);
00461 J= ViewDir;
00462 I= J^K;
00463 K= I^J;
00464 }
00465 I.normalize();
00466 J.normalize();
00467 K.normalize();
00468
00469 CMatrix mat;
00470 mat.identity();
00471 mat.setRot(I,J,K, true);
00472 mat.setPos(CVector(Viewer.x, Viewer.y, Viewer.z));
00473 mat.invert();
00474
00475 uint32 i, j, k;
00476 for (i = 0; i < 2; ++i)
00477 for (j = 0; j < 2; ++j)
00478 for (k = 0; k < 2; ++k)
00479 {
00480 CVector v;
00481 if (i == 0) v.x = Center.x-Size.x/2; else v.x = Center.x+Size.x/2;
00482 if (j == 0) v.y = Center.y-Size.y/2; else v.y = Center.y+Size.y/2;
00483 if (k == 0) v.z = Center.z-Size.z/2; else v.z = Center.z+Size.z/2;
00484 v = mat.mulPoint(v);
00485 if (v.y < Near) Near = v.y;
00486 if (v.y > Far) Far = v.y;
00487 }
00488
00489 for (i = 0; i < 2; ++i)
00490 for (j = 0; j < 2; ++j)
00491 for (k = 0; k < 2; ++k)
00492 {
00493 CVector v;
00494 if (i == 0) v.x = Center.x-Size.x/2; else v.x = Center.x+Size.x/2;
00495 if (j == 0) v.y = Center.y-Size.y/2; else v.y = Center.y+Size.y/2;
00496 if (k == 0) v.z = Center.z-Size.z/2; else v.z = Center.z+Size.z/2;
00497 v = mat.mulPoint(v);
00498 v.x = v.x / (v.y/Near);
00499 v.z = v.z / (v.y/Near);
00500 if (v.x < Left) Left = v.x;
00501 if (v.x > Right) Right = v.x;
00502 if (v.z < Bottom) Bottom = v.z;
00503 if (v.z > Top) Top = v.z;
00504 }
00505 }
00506
00507
00508
00509 void CCloud::genBill (CCamera *pCam, uint32 nBillSize)
00510 {
00511 uint32 sizeTMP = _OldBillSize;
00512 uint8 *MemTMP = _MemOldBill;
00513 CSmartPtr<CTextureMem> TexTMP = _TexOldBill;
00514
00515 _OldBillSize = _BillSize;
00516 _MemOldBill = _MemBill;
00517 _TexOldBill = _TexBill;
00518 _BillSize = sizeTMP;
00519 _MemBill = MemTMP;
00520 _TexBill = TexTMP;
00521
00522
00523 if (nBillSize != _BillSize)
00524 {
00525 _BillSize = nBillSize;
00526 _MemBill = new uint8[4*_BillSize*_BillSize];
00527 _TexBill = new CTextureMem (_MemBill, 4*_BillSize*_BillSize, true, false, _BillSize, _BillSize);
00528
00529 _TexBill->setWrapS (ITexture::Clamp);
00530 _TexBill->setWrapT (ITexture::Clamp);
00531 _TexBill->setFilterMode (ITexture::Linear, ITexture::LinearMipMapOff);
00532 _TexBill->setReleasable (false);
00533 _TexBill->generate();
00534 }
00535
00536 CViewport viewport, viewportOLD;
00537 viewportOLD.initFullScreen();
00538 uint32 nScreenW, nScreenH;
00539 _Driver->getWindowSize (nScreenW, nScreenH);
00540 viewport.init(0.0f, 0.0f, ((float)_BillSize+1)/((float)nScreenW), ((float)_BillSize+1)/((float)nScreenH));
00541 _Driver->setupViewport (viewport);
00542
00543
00544
00545 CVector Viewer = CVector (0,0,0);
00546 CVector Center = CVector (_Pos.x+_Size.x/2, _Pos.y+_Size.y/2, _Pos.z+_Size.z/2);
00547 CVector Size = _Size;
00548 CVector I, J, K;
00549 float Left, Right, Top, Bottom, Near, Far;
00550
00551 calcBill (Viewer, Center, Size, I, J, K, Left, Right, Top, Bottom, Near, Far);
00552
00553 CMatrix mat;
00554 mat.identity();
00555 mat.setRot(I,J,K, true);
00556 mat.setPos(CVector(Viewer.x, Viewer.y, Viewer.z));
00557 mat.invert();
00558
00559
00560 _Driver->setFrustum(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, false);
00561 _Driver->setupViewMatrix (CMatrix::Identity);
00562 _Driver->setupModelMatrix (CMatrix::Identity);
00563
00564 CVertexBuffer &rVB = _CloudScape->_VertexBuffer;
00565 uint32 nVSize = rVB.getVertexSize ();
00566 CVector *pVertices = (CVector*)rVB.getVertexCoordPointer (0);
00567 *pVertices = CVector(0.0f, 0.0f, 0.0f); pVertices = (CVector*)( ((uint8*)pVertices) + nVSize );
00568 *pVertices = CVector(1.0f, 0.0f, 0.0f); pVertices = (CVector*)( ((uint8*)pVertices) + nVSize );
00569 *pVertices = CVector(1.0f, 0.0f, 1.0f); pVertices = (CVector*)( ((uint8*)pVertices) + nVSize );
00570 *pVertices = CVector(0.0f, 0.0f, 1.0f);
00571
00572 _CloudScape->_MatClear.setColor (CRGBA(0,0,0,0));
00573 _Driver->activeVertexBuffer (rVB);
00574 _Driver->renderQuads (_CloudScape->_MatClear, 0, 1);
00575
00576
00577 _Driver->setFrustum(Left, Right, Bottom, Top, Near, Far);
00578 _Driver->setupViewMatrix(mat);
00579 _Driver->setupModelMatrix (CMatrix::Identity);
00580
00581 _CloudTexTmp->ToBill.setColor (CloudAmbient);
00582 dispXYZ (&_CloudTexTmp->ToBill);
00583
00584 _Driver->copyFrameBufferToTexture (_TexBill, 0, 0, 0, 0, 0, _BillSize, _BillSize);
00585
00586
00587 _Driver->setupViewport (viewportOLD);
00588
00589 _BillOldCenter = _BillCenter;
00590 _BillViewer = Viewer;
00591 _BillCenter = Center;
00592
00593 if (_WaitState > 0)
00594 _WaitState = _WaitState - 1;
00595
00596 _LastX = _Pos.x;
00597 }
00598
00599
00600 void CCloud::dispBill (CCamera *pCam)
00601 {
00602
00603
00604 CVector Viewer = CVector (0,0,0);
00605 CVector Center = CVector (_Pos.x+_Size.x/2, _Pos.y+_Size.y/2, _Pos.z+_Size.z/2);
00606 CVector Size = _Size;
00607
00608
00609 CQuadUV qc;
00610
00611 CVector I, J, K;
00612 float Left, Right, Top, Bottom, Near, Far;
00613
00614 if ((_MemBill == NULL) || (_MemOldBill == NULL))
00615 return;
00616
00617 if (_WaitState > 0)
00618 return;
00619
00620 if (Time > FuturTime)
00621 Time = FuturTime;
00622
00623
00624 Viewer= _BillViewer;
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637 Center= _BillCenter;
00638 calcBill (Viewer, Center, Size, I, J, K, Left, Right, Top, Bottom, Near, Far);
00639 CVector lct = Viewer + J*Near;
00640 CQuadUV qc0;
00641 qc0.V0 = lct + I*Left + K*Bottom;
00642 qc0.V1 = lct + I*Right + K*Bottom;
00643 qc0.V2 = lct + I*Right + K*Top;
00644 qc0.V3 = lct + I*Left + K*Top;
00645
00646 Center= _BillOldCenter;
00647 calcBill (Viewer, Center, Size, I, J, K, Left, Right, Top, Bottom, Near, Far);
00648 lct = Viewer + J*Near;
00649 CQuadUV qc1;
00650 qc1.V0 = lct + I*Left + K*Bottom;
00651 qc1.V1 = lct + I*Right + K*Bottom;
00652 qc1.V2 = lct + I*Right + K*Top;
00653 qc1.V3 = lct + I*Left + K*Top;
00654
00655 float a0= ((float)(Time)/(float)FuturTime);
00656 float a1= (float)(FuturTime-Time)/(float)FuturTime;
00657 qc.V0= qc0.V0*a0 + qc1.V0*a1;
00658 qc.V1= qc0.V1*a0 + qc1.V1*a1;
00659 qc.V2= qc0.V2*a0 + qc1.V2*a1;
00660 qc.V3= qc0.V3*a0 + qc1.V3*a1;
00661
00662 qc.Uv0 = CUV(0, 0);
00663 qc.Uv1 = CUV(1, 0);
00664 qc.Uv2 = CUV(1, 1);
00665 qc.Uv3 = CUV(0, 1);
00666
00667
00668
00669
00670 _CloudScape->_MatBill.setTexture (0, _TexOldBill);
00671 _CloudScape->_MatBill.setTexture (1, _TexBill);
00672 _CloudScape->_MatBill.setColor (CRGBA(255, 255, 255, (uint8)(255*((float)Time/(float)FuturTime))));
00673 CVertexBuffer &rVB = _CloudScape->_VertexBuffer;
00674 uint32 nVSize = rVB.getVertexSize ();
00675 CVector *pVertices = (CVector*)rVB.getVertexCoordPointer (0);
00676 *pVertices = qc.V0; pVertices = (CVector*)( ((uint8*)pVertices) + nVSize );
00677 *pVertices = qc.V1; pVertices = (CVector*)( ((uint8*)pVertices) + nVSize );
00678 *pVertices = qc.V2; pVertices = (CVector*)( ((uint8*)pVertices) + nVSize );
00679 *pVertices = qc.V3;
00680
00681 CUV *pUV = (CUV*)rVB.getTexCoordPointer (0, 0);
00682 pUV->U = 0; pUV->V = 0; pUV = (CUV*)( ((uint8*)pUV) + nVSize );
00683 pUV->U = 1; pUV->V = 0; pUV = (CUV*)( ((uint8*)pUV) + nVSize );
00684 pUV->U = 1; pUV->V = 1; pUV = (CUV*)( ((uint8*)pUV) + nVSize );
00685 pUV->U = 0; pUV->V = 1;
00686
00687 pUV = (CUV*)rVB.getTexCoordPointer (0, 1);
00688 pUV->U = 0; pUV->V = 0; pUV = (CUV*)( ((uint8*)pUV) + nVSize );
00689 pUV->U = 1; pUV->V = 0; pUV = (CUV*)( ((uint8*)pUV) + nVSize );
00690 pUV->U = 1; pUV->V = 1; pUV = (CUV*)( ((uint8*)pUV) + nVSize );
00691 pUV->U = 0; pUV->V = 1;
00692
00693 _Driver->activeVertexBuffer (rVB);
00694 _Driver->renderQuads (_CloudScape->_MatBill, 0, 1);
00695
00696
00697
00698
00699
00700 if (_CloudScape->isDebugQuadEnabled())
00701 {
00702 static CMaterial *mTmp = NULL;
00703 if (mTmp == NULL)
00704 {
00705 mTmp = new CMaterial();
00706 mTmp->setBlend(false);
00707 mTmp->setDoubleSided(true);
00708 }
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724 if (FuturTime <= 4)
00725 mTmp->setColor(CRGBA(0,127,0,255));
00726 else if (FuturTime <= 8)
00727 mTmp->setColor(CRGBA(0,255,0,255));
00728 else if (FuturTime <= 12)
00729 mTmp->setColor(CRGBA(127,255,0,255));
00730 else if (FuturTime <= 16)
00731 mTmp->setColor(CRGBA(255,255,0,255));
00732 else if (FuturTime <= 20)
00733 mTmp->setColor(CRGBA(255,127,0,255));
00734 else
00735 mTmp->setColor(CRGBA(255,0,0,255));
00736
00737 _Driver->setPolygonMode(IDriver::Line);
00738 _Driver->renderQuads (*mTmp, 0, 1);
00739 _Driver->setPolygonMode(IDriver::Filled);
00740 }
00741
00742 }
00743
00744
00745 void CCloud::setMode2D ()
00746 {
00747 CVector I(1,0,0), J(0,0,1), K(0,-1,0);
00748 CMatrix ViewMatrix;
00749 ViewMatrix.identity ();
00750 ViewMatrix.setRot (I,J,K, true);
00751 CScissor Scissor;
00752 Scissor.initFullScreen();
00753 _Driver->setupScissor (Scissor);
00754 _Driver->setupViewport (CViewport());
00755 uint32 nScreenW, nScreenH;
00756 _Driver->getWindowSize (nScreenW, nScreenH);
00757 _Driver->setFrustum (0, (float)nScreenW, 0, (float)nScreenH, -1, 1, false);
00758 _Driver->setupViewMatrix (ViewMatrix);
00759 _Driver->setupModelMatrix (CMatrix::Identity);
00760 }
00761
00762 }
00763