1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #include "environment/VolumetricFog.h"
- #include "windowManager/platformWindowMgr.h"
- #include "gfx/gfxTransformSaver.h"
- #include "renderInstance/renderPassManager.h"
- #include "math/mathIO.h"
- #include "materials/shaderData.h"
- #include "math/util/matrixSet.h"
- #include "core/resourceManager.h"
- #include "core/stream/bitStream.h"
- #include "T3D/gameBase/gameConnection.h"
- #include "T3D/shapeBase.h"
- #include "ts/tsShapeInstance.h"
- #include "console/engineAPI.h"
- #include "gui/core/guiCanvas.h"
- #include "VolumetricFogRTManager.h"
- #include "lighting/lightInfo.h"
- #include "lighting/lightManager.h"
- #define COLBOX_SCALE Point3F(1.02f, 1.02f, 1.02f)
- IMPLEMENT_CO_NETOBJECT_V1(VolumetricFog);
- ConsoleDocClass(VolumetricFog,
- "@brief Volumetric Fog Object class. Main class defining the Volumetric\n"
- "Fog objects in the scene. Used in conjunction with the VolumetricFogRTManager\n"
- "class which is responsible for the required rendertargets.\n\n"
- "Methods (exposed to script):\n"
- " setFogColorF(color) Changes the overall fog color (color.rgba range 0.0 - 1.0).\n;"
- " setFogColor(color) Changes the overall fog color color.rgba range 0 - 255).\n;"
- " setFogDensity(density) Changes the overall fog density.\n"
- " setFogModulation(strength, speed1, speed2) changes the strength\n"
- " and the speeds of the 2 animation layers.\n\n"
- "Callbacks:\n"
- "onEnterFog triggered whenever the controlobject (Player or Camera) enters the Fog.\n"
- " (current Fog object and the controlobject are exposed to script.\n"
- "onLeaveFog triggered whenever the controlobject (Player or Camera) left the Fog.\n"
- " (current Fog object and the controlobject are exposed to script.\n\n"
- "@tsexample\n"
- " new VolumetricFog()\n"
- " {\n"
- " shapeName = \"art/environment/FogRCube.dts\";\n"
- " fogColor = \"200 200 200 128\";\n"
- " fogDensity = \"0.2\";\n"
- " ignoreWater = \"0\";\n"
- " MinSize = \"250\";\n"
- " FadeSize = \"750\";\n"
- " texture = \"art/environment/FogMod_heavy.dds\";\n"
- " tiles = \"1.5\";\n"
- " modStrength = \"0.2\";\n"
- " PrimSpeed = \"-0.01 0.04\";\n"
- " SecSpeed = \"0.02 -0.02\";\n"
- " position = \"748.644 656.371 65.3506\"; \n"
- " rotation = \"0 0 1 20.354\";\n"
- " scale = \"40 30 6\";\n"
- " };\n"
- "@endtsexample\n"
- );
- IMPLEMENT_CALLBACK(VolumetricFog, onEnterFog, void, (SimObjectId obj), (obj),
- "@brief Called when an object enters the volume of the Fog instance.\n\n"
- "@param obj the controlobject entering the fog.");
- IMPLEMENT_CALLBACK(VolumetricFog, onLeaveFog, void, (SimObjectId obj), (obj),
- "@brief Called when an object left the volume of the Fog instance.\n\n"
- "@param obj the controlobject leaving the fog.");
- VolumetricFog::VolumetricFog()
- {
- AssertFatal(VFRTM != NULL, "VolumetricFog Fatal Error: No Manager found");
- if (!VFRTM->IsInitialized())
- VFRTM->Init();
- mNetFlags.set(Ghostable | ScopeAlways);
- mTypeMask |= EnvironmentObjectType | StaticObjectType;
- mDeferredTarget = NULL;
- mDepthBufferTarget = NULL;
- mFrontBufferTarget = NULL;
- z_buf = NULL;
- mTexture = NULL;
- mIsVBDirty = false;
- mIsPBDirty = false;
- mFogColor.set(200, 200, 200, 255);
- mFogDensity = 0.3f;
- mIgnoreWater = false;
- mReflect = false;
- mCamInFog = false;
- mResizing = false;
- mFogReflStrength = 20.0;
- mUseGlow = false;
- mGlowStrength = 0.3f;
- mGlowing = 0;
- mModifLightRays = false;
- mLightRayMod = 1.0f;
- mOldLightRayStrength = 0.1f;
- mShapeLoaded = false;
- mMinDisplaySize = 10.0f;
- mFadeSize = 0.0f;
- mCurDetailLevel = 0;
- mNumDetailLevels = 0;
- det_size.clear();
- mIsTextured = false;
- mStrength = 0.5f;
- mTexTiles = 1.0f;
- mSpeed1.set(0.5f, 0.0f);
- mSpeed2.set(0.1f, 0.1f);
- INIT_ASSET(Shape);
- INIT_ASSET(Texture);
- }
- VolumetricFog::~VolumetricFog()
- {
- if (!isClientObject())
- return;
- for (S32 i = 0; i < det_size.size(); i++)
- {
- if (det_size[i].indices != NULL)
- delete(det_size[i].indices);
- if (det_size[i].piArray != NULL)
- delete(det_size[i].piArray);
- if (det_size[i].verts != NULL)
- delete [] (det_size[i].verts);
- }
- det_size.clear();
- z_buf = NULL;
- if (!mTexture.isNull())
- mTexture.free();
- }
- void VolumetricFog::initPersistFields()
- {
- docsURL;
- Parent::initPersistFields();
- addGroup("Shapes");
- INITPERSISTFIELD_SHAPEASSET(Shape, VolumetricFog, "The source shape asset.");
- endGroup("Shapes");
- addGroup("VolumetricFogData");
- addField("FogColor", TypeColorI, Offset(mFogColor, VolumetricFog),
- "Fog color RGBA (Alpha is ignored)");
- addField("FogDensity", TypeF32, Offset(mFogDensity, VolumetricFog),
- "Overal fog density value (0 disables the fog).");
- addField("IgnoreWater", TypeBool, Offset(mIgnoreWater, VolumetricFog),
- "Set to true if volumetric fog should continue while submerged.");
- addField("MinSize", TypeF32, Offset(mMinDisplaySize, VolumetricFog),
- "Min size (in pixels) for fog to be rendered.");
- addField("FadeSize", TypeF32, Offset(mFadeSize, VolumetricFog),
- "Object size in pixels at which the FX-fading kicks in (0 disables fading).");
- endGroup("VolumetricFogData");
- addGroup("VolumetricFogModulation");
- INITPERSISTFIELD_IMAGEASSET(Texture, VolumetricFog, "A texture which contains Fogdensity modulator in the red channel and color with 1-green channel. No texture disables modulation.");
- addField("tiles", TypeF32, Offset(mTexTiles, VolumetricFog),
- "How many times the texture is mapped to the object.");
- addField("modStrength", TypeF32, Offset(mStrength, VolumetricFog),
- "Overall strength of the density modulation (0 disables modulation).");
- addField("PrimSpeed", TypePoint2F, Offset(mSpeed1, VolumetricFog),
- "Overall primary speed of the density modulation (x-speed(u) y-speed(v))");
- addField("SecSpeed", TypePoint2F, Offset(mSpeed2, VolumetricFog),
- "Overall secundary speed of the density modulation (x-speed(u) y-speed(v))");
- endGroup("VolumetricFogModulation");
- addGroup("Reflections");
- addField("Reflectable", TypeBool, Offset(mReflect, VolumetricFog),
- "Set to true if volumetric fog should be reflected.");
- addField("ReflectStrength", TypeF32, Offset(mFogReflStrength, VolumetricFog),
- "Strength of the reflections (0 disables the fog).");
- endGroup("Reflections");
- addGroup("PostFX");
- addField("useGlow", TypeBool, Offset(mUseGlow, VolumetricFog),
- "Set to true if volumetric fog should use glow PostFX.");
- addField("glowStrength", TypeF32, Offset(mGlowStrength, VolumetricFog),
- "Overall strength of the glow PostFX.");
- addField("modLightRay", TypeBool, Offset(mModifLightRays, VolumetricFog),
- "Set to true if volumetric fog should modify the brightness of the Lightrays.");
- addField("lightRayMod", TypeF32, Offset(mLightRayMod, VolumetricFog),
- "Modifier for LightRay PostFX when inside Fog.");
- endGroup("PostFX");
- }
- bool VolumetricFog::_setShapeAsset(void* obj, const char* index, const char* data)
- {
- VolumetricFog* fog = static_cast<VolumetricFog*>(obj);// ->setFile(FileName(data));
- fog->setShapeAsset(StringTable->insert(data));
- return false;
- }
- void VolumetricFog::inspectPostApply()
- {
- Parent::inspectPostApply();
- mSpeed.set(mSpeed1.x, mSpeed1.y, mSpeed2.x, mSpeed2.y);
- setMaskBits(VolumetricFogMask | FogColorMask | FogDensityMask | FogModulationMask | FogPostFXMask | FogShapeMask);
- }
- bool VolumetricFog::onAdd()
- {
- if (!Parent::onAdd())
- return false;
- if (!VFRTM->IsInitialized())
- {
- Con::errorf("No VolumetricFogRTManager present!!");
- return false;
- }
- resetWorldBox();
- mShapeLoaded = LoadShape();
- setRenderTransform(mObjToWorld);
- addToScene();
- ColBox.set(getTransform(), (mObjBox.getExtents() * getScale() * COLBOX_SCALE));
- mObjSize = mWorldBox.getGreatestDiagonalLength();
- mObjScale = getScale();
- mTexTiles = mAbs(mTexTiles);
- mSpeed.set(mSpeed1.x, mSpeed1.y, mSpeed2.x, mSpeed2.y);
- mInvScale = (1.0f / getMax(getMax(mObjScale.x, mObjScale.y), mObjScale.z));
- VFRTM->IncFogObjects();
- if (isClientObject())
- {
- conn = GameConnection::getConnectionToServer();
- if (!conn)
- {
- Con::errorf("VolumetricFog::onAdd - No Serverconnection");
- return false;
- }
- glowFX = static_cast<PostEffect*>(Sim::findObject("VolFogGlowPostFx"));
- mOldLightRayStrength = Con::getFloatVariable("$LightRayPostFX::brightScalar",1.0f);
- GuiCanvas* cv = dynamic_cast<GuiCanvas*>(Sim::findObject("Canvas"));
- if (cv == NULL)
- {
- Con::errorf("VolumetricFog::onAdd - Canvas not found!!");
- return false;
- }
- mPlatformWindow = cv->getPlatformWindow();
- VolumetricFogRTManager::getVolumetricFogRTMResizeSignal().notify(this, &VolumetricFog::handleResize);
- GuiCanvas::getCanvasSizeChangeSignal().notify(this, &VolumetricFog::handleCanvasResize);
- InitTexture();
- return setupRenderer();
- }
-
- return true;
- }
- void VolumetricFog::onRemove()
- {
- if (isClientObject())
- {
- if (isTicking())
- {
- setProcessTick(false);
- if (mGlowing != 0)
- {
- mGlowing = 0;
- glowFX->disable();
- }
- _leaveFog(dynamic_cast<ShapeBase*>(conn->getControlObject()));
- }
- VolumetricFogRTManager::getVolumetricFogRTMResizeSignal().remove(this, &VolumetricFog::handleResize);
- GuiCanvas::getCanvasSizeChangeSignal().remove(this, &VolumetricFog::handleCanvasResize);
- }
- removeFromScene();
- VFRTM->DecFogObjects();
- Parent::onRemove();
- }
- void VolumetricFog::handleCanvasResize(GuiCanvas* canvas)
- {
- UpdateBuffers(0,true);
- }
- void VolumetricFog::handleResize(VolumetricFogRTManager *RTM, bool resize)
- {
- if (resize)
- {
- mResizing = true;
- RTM->FogAnswered();
- }
- else
- mResizing = false;
- if (mIsTextured)
- {
- F32 width = (F32)mPlatformWindow->getClientExtent().x;
- F32 height = (F32)mPlatformWindow->getClientExtent().y;
- mTexScale.x = 2.0f - ((F32)mTexture.getWidth() / width);
- mTexScale.y = 2.0f - ((F32)mTexture.getHeight() / height);
- }
- UpdateBuffers(0,true);
- }
- //-----------------------------------------------------------------------------
- // Loadshape extracted from TSMesh and TSShapeInstance
- //-----------------------------------------------------------------------------
- bool VolumetricFog::setShapeAsset(const StringTableEntry shapeAssetId)
- {
- mShapeAssetId = shapeAssetId;
- LoadShape();
- return true;
- }
- bool VolumetricFog::LoadShape()
- {
- GFXPrimitiveType GFXdrawTypes[] = { GFXTriangleList, GFXTriangleStrip };
- if (mShapeAsset.isNull())
- {
- Con::errorf("[VolumetricFog] Failed to load shape asset.");
- return false;
- }
- if (!mShape)
- {
- Con::errorf("VolumetricFog::_createShape() - Shape Asset had no valid shape!");
- return false;
- }
- mObjBox = mShape->mBounds;
- mRadius = mShape->mRadius;
- resetWorldBox();
- if (!isClientObject())
- return false;
- TSShapeInstance *mShapeInstance = new TSShapeInstance(mShape, false);
- meshes mesh_detail;
- for (S32 i = 0; i < det_size.size(); i++)
- {
- if (det_size[i].indices != NULL)
- delete(det_size[i].indices);
- if (det_size[i].piArray != NULL)
- delete(det_size[i].piArray);
- if (det_size[i].verts != NULL)
- delete [] (det_size[i].verts);
- }
- det_size.clear();
- // browsing model for detail levels
- for (U32 i = 0; i < mShape->details.size(); i++)
- {
- const TSDetail *detail = &mShape->details[i];
- mesh_detail.det_size = detail->size;
- mesh_detail.sub_shape = detail->subShapeNum;
- mesh_detail.obj_det = detail->objectDetailNum;
- mesh_detail.verts = NULL;
- mesh_detail.piArray = NULL;
- mesh_detail.indices = NULL;
- if (detail->size >= 0.0f && detail->subShapeNum >= 0)
- det_size.push_back(mesh_detail);
- }
- for (U32 i = 0; i < det_size.size(); i++)
- {
- const S32 ss = det_size[i].sub_shape;
- if (ss >= 0)
- {
- const S32 start = mShape->subShapeFirstObject[ss];
- const S32 end = start + mShape->subShapeNumObjects[ss];
- for (S32 j = start; j < end; j++)
- {
- // Loading shape, only the first mesh for each detail will be used!
- TSShapeInstance::MeshObjectInstance *meshObj = &mShapeInstance->mMeshObjects[j];
- if (!meshObj)
- continue;
- TSMesh *mesh = meshObj->getMesh(det_size[i].obj_det);
- if (mesh != NULL)
- {
- const U32 numNrms = mesh->mNumVerts;
- GFXVertexPNTT *tmpVerts = NULL;
- tmpVerts = new GFXVertexPNTT[numNrms];
- mIsVBDirty = true;
- for (U32 k = 0; k < numNrms; k++)
- {
- const TSMesh::__TSMeshVertexBase &vd = mesh->mVertexData.getBase(k);
- Point3F norm = vd.normal();
- Point3F vert = vd.vert();
- Point2F uv = vd.tvert();
- tmpVerts[k].point = vert;
- tmpVerts[k].texCoord = uv;
- tmpVerts[k].normal = norm;
- }
- det_size[i].verts = tmpVerts;
- det_size[i].num_verts = numNrms;
- det_size[i].piArray = new Vector<GFXPrimitive>();
- GFXPrimitive pInfo;
- det_size[i].indices = new Vector<U32>();
- for (U32 k = 0; k < mesh->mIndices.size(); k++)
- det_size[i].indices->push_back(mesh->mIndices[k]);
- U32 primitivesSize = mesh->mPrimitives.size();
- for (U32 k = 0; k < primitivesSize; k++)
- {
- const TSDrawPrimitive & draw = mesh->mPrimitives[k];
- GFXPrimitiveType drawType = GFXdrawTypes[draw.matIndex >> 30];
- switch (drawType)
- {
- case GFXTriangleList:
- pInfo.type = drawType;
- pInfo.numPrimitives = draw.numElements / 3;
- pInfo.startIndex = draw.start;
- // Use the first index to determine which 16-bit address space we are operating in
- pInfo.startVertex = mesh->mIndices[draw.start] & 0xFFFF0000;
- pInfo.minIndex = pInfo.startVertex;
- pInfo.numVertices = getMin((U32)0x10000, mesh->mNumVerts - pInfo.startVertex);
- break;
- case GFXTriangleStrip:
- pInfo.type = drawType;
- pInfo.numPrimitives = draw.numElements - 2;
- pInfo.startIndex = draw.start;
- // Use the first index to determine which 16-bit address space we are operating in
- pInfo.startVertex = mesh->mIndices[draw.start] & 0xFFFF0000;
- pInfo.minIndex = pInfo.startVertex;
- pInfo.numVertices = getMin((U32)0x10000, mesh->mNumVerts - pInfo.startVertex);
- break;
- default:
- Con::errorf("VolumetricFog::LoadShape Unknown drawtype!?!");
- return false;
- break;
- }
- det_size[i].piArray->push_back(pInfo);
- j = end;
- }
- }
- else
- {
- Con::errorf("VolumetricFog::LoadShape Error loading mesh from shape!");
- delete mShapeInstance;
- return false;
- }
- mIsVBDirty = true;
- mIsPBDirty = true;
- }
- }
- }
- mNumDetailLevels = det_size.size();
- mCurDetailLevel = 0;
- UpdateBuffers(mCurDetailLevel);
- delete mShapeInstance;
- return true;
- }
- //-----------------------------------------------------------------------------
- // UpdateBuffers called whenever detaillevel changes (LOD)
- //-----------------------------------------------------------------------------
- bool VolumetricFog::UpdateBuffers(U32 dl, bool force)
- {
- if (mVB.isNull() || mIsVBDirty || dl != mCurDetailLevel || force)
- {
- mVB.set(GFX, det_size[dl].num_verts, GFXBufferTypeDynamic);
- mIsVBDirty = false;
- }
- GFXVertexPNTT *vertPtr = mVB.lock();
- if (!vertPtr)
- {
- mVB.unlock();
- return false;
- }
- dMemcpy(vertPtr, det_size[dl].verts, sizeof (GFXVertexPNTT)* det_size[dl].num_verts);
- mVB.unlock();
- if (mIsPBDirty || mPB.isNull() || dl != mCurDetailLevel || force)
- {
- #ifdef TORQUE_DEBUG
- mPB.set(GFX, det_size[dl].indices->size(), det_size[dl].piArray->size(), GFXBufferTypeDynamic, avar("%s() - VolFogPrimBuffer (line %d)", __FUNCTION__, __LINE__));
- #else
- mPB.set(GFX, det_size[dl].indices->size(), det_size[dl].piArray->size(), GFXBufferTypeDynamic);
- #endif
- U16 *ibIndices = NULL;
- GFXPrimitive *piInput = NULL;
- mPB.lock(&ibIndices, &piInput);
- dCopyArray(ibIndices, det_size[dl].indices->address(), det_size[dl].indices->size());
- dMemcpy(piInput, det_size[dl].piArray->address(), det_size[dl].piArray->size() * sizeof(GFXPrimitive));
- mPB.unlock();
- mIsPBDirty = false;
- }
- mCurDetailLevel = dl;
- return true;
- }
- U32 VolumetricFog::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
- {
- U32 retMask = Parent::packUpdate(con, mask, stream);
- if (stream->writeFlag(mask & FogColorMask))
- stream->write(mFogColor);
- if (stream->writeFlag(mask & FogDensityMask))
- stream->write(mFogDensity);
- if (stream->writeFlag(mask & FogModulationMask))
- {
- PACK_ASSET(con, Texture);
- mTexTiles = mFabs(mTexTiles);
- stream->write(mTexTiles);
- stream->write(mStrength);
- mathWrite(*stream, mSpeed);
- }
- if (stream->writeFlag(mask & FogPostFXMask))
- {
- stream->writeFlag(mUseGlow);
- stream->write(mGlowStrength);
- stream->writeFlag(mModifLightRays);
- stream->write(mLightRayMod);
- }
- if (stream->writeFlag(mask & VolumetricFogMask))
- {
- stream->writeFlag(mIgnoreWater);
- stream->writeFlag(mReflect);
- stream->write(mFogReflStrength);
- stream->writeFlag(mResizing);
- stream->write(mMinDisplaySize);
- stream->write(mFadeSize);
- }
- if (stream->writeFlag(mask & FogShapeMask))
- {
- PACK_ASSET(con, Shape);
- mathWrite(*stream, getTransform());
- mathWrite(*stream, getScale());
- if (mShapeAsset.notNull())
- {
- mObjBox = mShapeAsset->getShapeResource()->mBounds;
- mRadius = mShapeAsset->getShapeResource()->mRadius;
- }
- else
- {
- return retMask;
- }
- resetWorldBox();
- mObjSize = mWorldBox.getGreatestDiagonalLength();
- mObjScale = getScale();
- mInvScale = (1.0f / getMax(getMax(mObjScale.x, mObjScale.y), mObjScale.z));
- }
- return retMask;
- }
- void VolumetricFog::unpackUpdate(NetConnection *con, BitStream *stream)
- {
- Parent::unpackUpdate(con, stream);
- MatrixF mat;
- VectorF scale;
- VectorF mOldScale = getScale();
- StringTableEntry oldTextureName = mTextureAssetId;
- StringTableEntry oldShapeAsset = mShapeAssetId;
- StringTableEntry oldShape = mShapeName;
- if (stream->readFlag())// Fog color
- stream->read(&mFogColor);
- if (stream->readFlag())// Fog Density
- {
- stream->read(&mFogDensity);
- if (isTicking())
- {
- char buf[20];
- dSprintf(buf, sizeof(buf), "%3.7f", mFogDensity);
- Con::setVariable("$VolumetricFog::density", buf);
- }
- }
- if (stream->readFlag())// Fog Modulation
- {
- UNPACK_ASSET(con, Texture);
- stream->read(&mTexTiles);
- mTexTiles = mFabs(mTexTiles);
- stream->read(&mStrength);
- mathRead(*stream, &mSpeed);
- mSpeed1.set(mSpeed.x, mSpeed.y);
- mSpeed2.set(mSpeed.z, mSpeed.w);
- if (isProperlyAdded())
- {
- if (oldTextureName != mTextureAssetId)
- InitTexture();
- if (oldTextureName != StringTable->EmptyString() && mTextureAssetId == StringTable->EmptyString())
- {
- mIsTextured = false;
- mTexture.free();
- }
- }
- }
- if (stream->readFlag())//Fog PostFX
- {
- mUseGlow = stream->readFlag();
- stream->read(&mGlowStrength);
- mModifLightRays = stream->readFlag();
- stream->read(&mLightRayMod);
- if (isTicking())
- {
- char glowStrBuf[20];
- dSprintf(glowStrBuf, sizeof(glowStrBuf), "%3.7f", mGlowStrength);
- Con::setVariable("$VolFogGlowPostFx::glowStrength", glowStrBuf);
- if (mUseGlow && !glowFX->isEnabled())
- glowFX->enable();
- if (!mUseGlow && glowFX->isEnabled())
- glowFX->disable();
- F32 rayStrength = mOldLightRayStrength;
- if (mModifLightRays)
- rayStrength *= mLightRayMod;
- char rayStrBuf[20];
- dSprintf(rayStrBuf, sizeof(rayStrBuf), "%3.7f", rayStrength);
- Con::setVariable("$LightRayPostFX::brightScalar", rayStrBuf);
- }
- }
- if (stream->readFlag())//Volumetric Fog
- {
- mIgnoreWater = stream->readFlag();
- mReflect = stream->readFlag();
- stream->read(&mFogReflStrength);
- mResizing = stream->readFlag();
- stream->read(&mMinDisplaySize);
- stream->read(&mFadeSize);
- }
- if (stream->readFlag())//Fog shape
- {
- UNPACK_ASSET(con, Shape);
- mathRead(*stream, &mat);
- mathRead(*stream, &scale);
- if (strcmp(oldShapeAsset, mShapeAssetId) != 0 || strcmp(oldShape, mShapeName) != 0)
- {
- mIsVBDirty = true;
- mShapeLoaded = LoadShape();
- }
- setScale(scale);
- setTransform(mat);
- ColBox.set(getTransform(), (mObjBox.getExtents() * getScale() * COLBOX_SCALE));
- mObjSize = mWorldBox.getGreatestDiagonalLength();
- mObjScale = getScale();
- mInvScale = (1.0f / getMax(getMax(mObjScale.x, mObjScale.y), mObjScale.z));
- }
- }
- void VolumetricFog::processTick(const Move* move)
- {
- Parent::processTick(move);
- mCounter++;
- if ( mGlowing==1 && mCurGlow < mGlowStrength )
- {
- mCurGlow += (mGlowStrength / 10.0);
- char buf[20];
- dSprintf(buf, sizeof(buf), "%3.7f", mCurGlow);
- Con::setVariable("$VolFogGlowPostFx::glowStrength", buf);
- }
- else if ( mGlowing == 2 && mCurGlow > 0.0f )
- {
- mCurGlow -= (mGlowStrength / 5.0f);
- if (mCurGlow <= 0.0f)
- {
- glowFX->disable();
- mGlowing = 0;
- setProcessTick(false);
- return;
- }
- else
- {
- char buf[20];
- dSprintf(buf, sizeof(buf), "%3.7f", mCurGlow);
- Con::setVariable("$VolFogGlowPostFx::glowStrength", buf);
- }
- }
- if (mCounter == 3)
- {
- ShapeBase* control = dynamic_cast<ShapeBase*>(conn->getControlObject());
- if (!control)
- return;
- MatrixF xfm;
- control->getRenderEyeTransform(&xfm);
- Point3F pos = xfm.getPosition();
- if (!ColBox.isContained(pos))
- _leaveFog(control);
- mCounter = 0;
- }
- }
- void VolumetricFog::_enterFog(ShapeBase *control)
- {
- if (mUseGlow)
- {
- if (glowFX)
- {
- mCurGlow = 0.0f;
- Con::setVariable("$VolFogGlowPostFx::glowStrength", "0.0");
- glowFX->enable();
- mGlowing = 1;
- }
- }
- if (mModifLightRays)
- {
- char buf[20];
- dSprintf(buf, sizeof(buf), "%3.7f", mOldLightRayStrength * mLightRayMod);
- Con::setVariable("$LightRayPostFX::brightScalar", buf);
- }
- mCounter = 0;
- char buf[20];
- dSprintf(buf, sizeof(buf), "%3.7f", mFogDensity);
- Con::setVariable("$VolumetricFog::density", buf);
- setProcessTick(true);
- if (control)
- onEnterFog_callback(control->getId());
- }
- void VolumetricFog::_leaveFog(ShapeBase *control)
- {
- mCamInFog = false;
- Con::setVariable("$VolumetricFog::density", "0.0");
- if (mModifLightRays)
- {
- char buf[20];
- dSprintf(buf, sizeof(buf), "%3.7f", mOldLightRayStrength);
- Con::setVariable("$LightRayPostFX::brightScalar", buf);
- }
- if (mUseGlow)
- {
- if (glowFX && mGlowing != 2)
- {
- mCurGlow = mGlowStrength;
- mGlowing = 2;
- if (control)
- onLeaveFog_callback(control->getId());
- }
- }
- else
- {
- setProcessTick(false);
- if (control)
- onLeaveFog_callback(control->getId());
- }
- }
- //-----------------------------------------------------------------------------
- // Setting up the renderers
- //-----------------------------------------------------------------------------
- bool VolumetricFog::setupRenderer()
- {
- // Search for the deferred rendertarget and shadermacros.
- mDeferredTarget = NamedTexTarget::find("deferred");
- if (!mDeferredTarget.isValid())
- {
- Con::errorf("VolumetricFog::setupRenderer - could not find DeferredTarget");
- return false;
- }
- Vector<GFXShaderMacro> macros;
- if (mDeferredTarget)
- mDeferredTarget->getShaderMacros(¯os);
- // Search the depth and frontbuffers which are created by the VolumetricFogRTManager
- mDepthBufferTarget = NamedTexTarget::find("volfogdepth");
- if (!mDepthBufferTarget.isValid())
- {
- Con::errorf("VolumetricFog::setupRenderer - could not find depthbuffer");
- return false;
- }
- mFrontBufferTarget = NamedTexTarget::find("volfogfront");
- if (!mFrontBufferTarget.isValid())
- {
- Con::errorf("VolumetricFog::setupRenderer - could not find frontbuffer");
- return false;
- }
- // Find and setup the deferred Shader
- ShaderData *shaderData;
- mDeferredShader = Sim::findObject("VolumetricFogDeferredShader", shaderData) ?
- shaderData->getShader() : NULL;
- if (!mDeferredShader)
- {
- Con::errorf("VolumetricFog::setupRenderer - could not find VolumetricFogDeferredShader");
- return false;
- }
- // Create ShaderConstBuffer and Handles
- mPPShaderConsts = mDeferredShader->allocConstBuffer();
- if (mPPShaderConsts.isNull())
- {
- Con::errorf("VolumetricFog::setupRenderer - could not allocate ShaderConstants 1.");
- return false;
- }
- mPPModelViewProjSC = mDeferredShader->getShaderConstHandle("$modelView");
- // Find and setup the VolumetricFog Shader
- shaderData = NULL;
- mShader = Sim::findObject("VolumetricFogShader", shaderData) ?
- shaderData->getShader(macros) : NULL;
- if (!mShader)
- {
- Con::errorf("VolumetricFog::setupRenderer - could not find VolumetricFogShader");
- return false;
- }
- // Create ShaderConstBuffer and Handles
- mShaderConsts = mShader->allocConstBuffer();
- if (mShaderConsts.isNull())
- {
- Con::errorf("VolumetricFog::setupRenderer - could not allocate ShaderConstants 2.");
- return false;
- }
- mModelViewProjSC = mShader->getShaderConstHandle("$modelView");
- mFadeSizeSC = mShader->getShaderConstHandle("$fadesize");
- mFogColorSC = mShader->getShaderConstHandle("$fogColor");
- mFogDensitySC = mShader->getShaderConstHandle("$fogDensity");
- mPreBias = mShader->getShaderConstHandle("$preBias");
- mAccumTime = mShader->getShaderConstHandle("$accumTime");
- mIsTexturedSC = mShader->getShaderConstHandle("$textured");
- mTexTilesSC = mShader->getShaderConstHandle("$numtiles");
- mModStrengthSC = mShader->getShaderConstHandle("$modstrength");
- mModSpeedSC = mShader->getShaderConstHandle("$modspeed");
- mViewPointSC = mShader->getShaderConstHandle("$viewpoint");
- mTexScaleSC = mShader->getShaderConstHandle("$texscale");
- mAmbientColorSC = mShader->getShaderConstHandle("$ambientColor");
- // Find and setup the reflection Shader
- shaderData = NULL;
- mReflectionShader = Sim::findObject("VolumetricFogReflectionShader", shaderData) ?
- shaderData->getShader() : NULL;
- if (!mReflectionShader)
- {
- Con::errorf("VolumetricFog::setupRenderer - could not find VolumetricFogReflectionShader");
- return false;
- }
- mReflShaderConsts = mReflectionShader->allocConstBuffer();
- if (mReflShaderConsts.isNull())
- {
- Con::errorf("VolumetricFog::setupRenderer - could not allocate ShaderConstants for VolumetricFogReflectionShader.");
- return false;
- }
- mReflModelViewProjSC = mReflectionShader->getShaderConstHandle("$modelView");
- mReflFogColorSC = mReflectionShader->getShaderConstHandle("$fogColor");
- mReflFogDensitySC = mReflectionShader->getShaderConstHandle("$fogDensity");
- mReflFogStrengthSC = mReflectionShader->getShaderConstHandle("$reflStrength");
- // Create the deferred StateBlock
- desc_preD.setCullMode(GFXCullCW);
- desc_preD.setBlend(true);
- desc_preD.setZReadWrite(false, false);
- desc_preD.stencilEnable = false;
- desc_preF.setCullMode(GFXCullCCW);
- desc_preF.setBlend(true);
- desc_preF.setZReadWrite(true, false);
- desc_preF.stencilEnable = false;
-
- // Create the VolumetricFog StateBlock
- descD.setCullMode(GFXCullCW);
- descD.setBlend(true);
- descD.setZReadWrite(false, false);// desc.setZReadWrite(true, false);
- // deferredBuffer sampler
- descD.samplersDefined = true;
- descD.samplers[0].addressModeU = GFXAddressClamp;
- descD.samplers[0].addressModeV = GFXAddressClamp;
- descD.samplers[0].addressModeW = GFXAddressClamp;
- descD.samplers[0].magFilter = GFXTextureFilterLinear;
- descD.samplers[0].minFilter = GFXTextureFilterLinear;
- descD.samplers[0].mipFilter = GFXTextureFilterLinear;
- // DepthBuffer sampler
- descD.samplers[1].addressModeU = GFXAddressClamp;
- descD.samplers[1].addressModeV = GFXAddressClamp;
- descD.samplers[1].addressModeW = GFXAddressClamp;
- descD.samplers[1].magFilter = GFXTextureFilterLinear;
- descD.samplers[1].minFilter = GFXTextureFilterLinear;
- descD.samplers[1].mipFilter = GFXTextureFilterLinear;
- // FrontBuffer sampler
- descD.samplers[2].addressModeU = GFXAddressClamp;
- descD.samplers[2].addressModeV = GFXAddressClamp;
- descD.samplers[2].addressModeW = GFXAddressClamp;
- descD.samplers[2].magFilter = GFXTextureFilterLinear;
- descD.samplers[2].minFilter = GFXTextureFilterLinear;
- descD.samplers[2].mipFilter = GFXTextureFilterLinear;
- // animated density modifier map sampler
- descD.samplers[3].addressModeU = GFXAddressWrap;
- descD.samplers[3].addressModeV = GFXAddressWrap;
- descD.samplers[3].addressModeW = GFXAddressWrap;
- descD.samplers[3].magFilter = GFXTextureFilterLinear;
- descD.samplers[3].minFilter = GFXTextureFilterLinear;
- descD.samplers[3].mipFilter = GFXTextureFilterLinear;
- dMemcpy(&descF, &descD, sizeof(GFXStateBlockDesc));
- descF.setCullMode(GFXCullCCW);
- descF.setBlend(true);
- descF.setZReadWrite(true, false);
- desc_refl.setCullMode(GFXCullCCW);
- desc_refl.setBlend(true);
- desc_refl.setZReadWrite(true, false);
- mStateblock_preD = GFX->createStateBlock(desc_preD);
- mStateblock_preF = GFX->createStateBlock(desc_preF);
- mStateblockD = GFX->createStateBlock(descD);
- mStateblockF = GFX->createStateBlock(descF);
- mStateblock_refl = GFX->createStateBlock(desc_refl);
- // Create Rendertarget
- z_buf = GFX->allocRenderToTextureTarget();
- if (z_buf == NULL)
- {
- Con::errorf("VolumetricFog::setupRenderer - Could not create Render Target");
- return false;
- }
- return true;
- }
- void VolumetricFog::prepRenderImage(SceneRenderState *state)
- {
- if (!mShapeLoaded || mFogDensity <= 0.0f || mResizing)
- return;
- if (!state->isDiffusePass())
- {
- if (!state->isReflectPass())
- return;
- }
-
- PROFILE_SCOPE(VolumetricFog_prepRenderImage);
- ShapeBase* control = dynamic_cast<ShapeBase*>(conn->getControlObject());
- if (!control || (control->getWaterCoverage() >= 0.9f && !mIgnoreWater))
- return;
- camPos = state->getCameraPosition();
- F32 dist = (camPos - getBoxCenter()).len();
- F32 scaleFactor = dist * mInvScale;
- if (scaleFactor <= 0.0f)
- {
- if (mCurDetailLevel != 0)
- UpdateBuffers(0);
- }
- const F32 pixelScale = state->getViewport().extent.y / 300.0f;
- mPixelSize = (mRadius / scaleFactor) * state->getWorldToScreenScale().y * pixelScale;
- if (mPixelSize < mMinDisplaySize)
- return;
- if (mNumDetailLevels > 1)
- {
- if ((mCurDetailLevel < mNumDetailLevels - 1) && (det_size[mCurDetailLevel].det_size > mPixelSize))
- UpdateBuffers(mCurDetailLevel + 1);
- else if (mCurDetailLevel > 0)
- {
- if (mPixelSize >= det_size[mCurDetailLevel - 1].det_size)
- UpdateBuffers(mCurDetailLevel - 1);
- }
- }
- if (state->isReflectPass() && mReflect)
- {
- ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();
- ri->renderDelegate.bind(this, &VolumetricFog::reflect_render);
- ri->type = RenderPassManager::RIT_VolumetricFog;
- ri->translucentSort = true;
- ri->sortDistSq = getRenderWorldBox().getSqDistanceToPoint(camPos);
- if (dist < 1.0f)
- ri->defaultKey = 1;
- else
- ri->defaultKey = U32(dist);
- state->getRenderPass()->addInst(ri);
- return;
- }
- else if (state->isDiffusePass())
- {
- viewDist = state->getFarPlane();
- mFOV = state->getCameraFrustum().getFov() / M_PI_F;
- Point3F mEyeVec = state->getVectorEye() * viewDist;
- mViewPoint.x = ((mAtan2(mEyeVec.x, mEyeVec.y) / M_PI_F) + 1.0f) * mTexTiles;
- mViewPoint.y = (0.5f - (mAsin(mEyeVec.z) / M_PI_F)) * mTexTiles;
- bool isInside = ColBox.isContained(camPos);
- if (isInside && !mCamInFog)
- {
- mCamInFog = true;
- _enterFog(control);
- }
- else if (!isInside && mCamInFog)
- mCamInFog = false;
- ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();
- ri->renderDelegate.bind(this, &VolumetricFog::render);
- ri->type = RenderPassManager::RIT_VolumetricFog;
- ri->translucentSort = true;
- ri->sortDistSq = getRenderWorldBox().getSqDistanceToPoint(camPos);
- if (dist < 1.0f)
- ri->defaultKey = 1;
- else
- ri->defaultKey = U32(dist);
- state->getRenderPass()->addInst(ri);
- return;
- }
- return;
- }
- void VolumetricFog::render(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat)
- {
- if (overrideMat || !mShapeLoaded || !isClientObject() || mResizing)
- return;
- PROFILE_SCOPE(VolumetricFog_Render);
- GFXTransformSaver saver;
- GFX->setVertexBuffer(mVB);
- GFX->setPrimitiveBuffer(mPB);
- MatrixF mat = getRenderTransform();
- mat.scale(mObjScale);
- GFX->multWorld(mat);
- GFX->setShader(mDeferredShader);
- GFX->setShaderConstBuffer(mPPShaderConsts);
- GFX->setStateBlock(mStateblock_preD);
- // Set all the shader consts...
- MatrixF xform(GFX->getProjectionMatrix());
- xform *= GFX->getViewMatrix();
- xform *= GFX->getWorldMatrix();
- mPPShaderConsts->setSafe(mPPModelViewProjSC, xform);
- const LinearColorF &sunlight = state->getAmbientLightColor();
- Point3F ambientColor(sunlight.red, sunlight.green, sunlight.blue);
- mShaderConsts->setSafe(mAmbientColorSC, ambientColor);
- GFXTextureObject *mDepthBuffer = mDepthBufferTarget ? mDepthBufferTarget->getTexture(0) : NULL;
- GFXTextureObject *mFrontBuffer = mFrontBufferTarget ? mFrontBufferTarget->getTexture(0) : NULL;
- GFX->pushActiveRenderTarget();
- //render backside to target mDepthBuffer
- z_buf->attachTexture(GFXTextureTarget::DepthStencil, GFXTextureTarget::sDefaultDepthStencil);
- z_buf->attachTexture(GFXTextureTarget::Color0, mDepthBuffer);
- GFX->setActiveRenderTarget(z_buf);
- GFX->clear(GFXClearStencil | GFXClearTarget , ColorI(0,0,0,0), 1.0f, 0);
- GFX->drawPrimitive(0);
- z_buf->resolve();
- //render frontside to target mFrontBuffer
- z_buf->attachTexture(GFXTextureTarget::DepthStencil, GFXTextureTarget::sDefaultDepthStencil);
- z_buf->attachTexture(GFXTextureTarget::Color0, mFrontBuffer);
- GFX->clear(GFXClearStencil | GFXClearTarget, ColorI(0, 0, 0, 0), 1.0f, 0);
- GFX->setStateBlock(mStateblock_preF);
- GFX->drawPrimitive(0);
- z_buf->resolve();
- GFX->popActiveRenderTarget();
- z_buf->attachTexture(GFXTextureTarget::Color0, NULL);
- //render Volumetric Fog
- GFX->setShader(mShader);
- GFX->setShaderConstBuffer(mShaderConsts);
- mShaderConsts->setSafe(mModelViewProjSC, xform);
- if (mFadeSize > 0.0f)
- mShaderConsts->setSafe(mFadeSizeSC, mClampF(mPixelSize / mFadeSize, 0.0f, 1.0f));
- else
- mShaderConsts->setSafe(mFadeSizeSC, 1.0f);
- mShaderConsts->setSafe(mFogColorSC, mFogColor);
- mShaderConsts->setSafe(mFogDensitySC, mFogDensity);
- mShaderConsts->setSafe(mPreBias, viewDist);
- mShaderConsts->setSafe(mAccumTime, (F32)Sim::getCurrentTime() / 1000.0f);
- mShaderConsts->setSafe(mModStrengthSC, mStrength);
- mShaderConsts->setSafe(mModSpeedSC, mSpeed);
- mShaderConsts->setSafe(mViewPointSC, mViewPoint);
- mShaderConsts->setSafe(mTexScaleSC, mTexScale * mFOV);
- mShaderConsts->setSafe(mTexTilesSC, mTexTiles);
- GFXTextureObject *deferredtex = mDeferredTarget ? mDeferredTarget->getTexture(0) : NULL;
- GFX->setTexture(0, deferredtex);
- GFX->setTexture(1, mDepthBuffer);
- GFX->setTexture(2, mFrontBuffer);
- if (mIsTextured && mStrength > 0.0f)
- {
- GFX->setTexture(3, mTexture);
- mShaderConsts->setSafe(mIsTexturedSC, 1.0f);
- }
- else
- mShaderConsts->setSafe(mIsTexturedSC, 0.0f);
- if (mCamInFog)
- {
- /*GFXLockedRect *rect=mDepthBuffer->lock();
- U32 pixoffset = 0;// 1572864 + (512 * 4);
- U8 red = rect->bits[pixoffset];
- U8 green = rect->bits[pixoffset+1];
- U8 blue = rect->bits[pixoffset+2];
- U8 alpha = rect->bits[pixoffset+3];
- mDepthBuffer->unlock();
- S32 lval = ((alpha << 24) + (blue << 16) + (green << 8) + (red));
- F32 fval = ((F32)lval / S32_MAX);
- Con::printf("Color %d %d %d %d %d %f", red, green, blue, alpha, lval, fval);*/
- GFX->setStateBlock(mStateblockD);
- }
- else
- GFX->setStateBlock(mStateblockF);
- GFX->drawPrimitive(0);
- // Ensure these two textures are NOT bound to the pixel shader input on the second run as they are used as pixel shader outputs (render targets).
- GFX->clearTextureStateImmediate(1); //mDepthBuffer
- GFX->clearTextureStateImmediate(2); //mFrontBuffer
- }
- void VolumetricFog::reflect_render(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat)
- {
- if (overrideMat || !mShapeLoaded || !isClientObject() || mResizing || (mFogReflStrength==0.0f))
- return;
- GFXTransformSaver saver;
- GFX->setVertexBuffer(mVB);
- GFX->setPrimitiveBuffer(mPB);
- MatrixF mat = getRenderTransform();
- mat.scale(mObjScale);
- GFX->multWorld(mat);
- GFX->setShader(mReflectionShader);
- GFX->setShaderConstBuffer(mReflShaderConsts);
- GFX->setStateBlock(mStateblock_refl);
- // Set all the shader consts...
- MatrixF xform(GFX->getProjectionMatrix());
- xform *= GFX->getViewMatrix();
- xform *= GFX->getWorldMatrix();
- mReflShaderConsts->setSafe(mReflModelViewProjSC, xform);
- mReflShaderConsts->setSafe(mReflFogColorSC, mFogColor);
- mReflShaderConsts->setSafe(mReflFogDensitySC, mFogDensity);
- mReflShaderConsts->setSafe(mReflFogStrengthSC, mFogReflStrength);
- GFX->drawPrimitive(0);
- }
- //-----------------------------------------------------------------------------
- // InitTexture is called whenever a modulation texture is added to the object
- //-----------------------------------------------------------------------------
- void VolumetricFog::InitTexture()
- {
- mIsTextured = false;
- if (mTextureAsset.isNull())
- return;
- if (!mTexture.isNull())
- {
- mIsTextured = true;
- F32 width = (F32)mPlatformWindow->getClientExtent().x;
- F32 height = (F32)mPlatformWindow->getClientExtent().y;
- mTexScale.x = 2.0f - ((F32)mTexture.getWidth() / width);
- mTexScale.y = 2.0f - ((F32)mTexture.getHeight() / height);
- }
- }
- void VolumetricFog::setFogColor(LinearColorF color)
- {
- mFogColor.set(255 * color.red,255 * color.green,255 * color.blue);
- setMaskBits(FogColorMask);
- }
- void VolumetricFog::setFogColor(ColorI color)
- {
- mFogColor = color;
- setMaskBits(FogColorMask);
- }
- void VolumetricFog::setFogDensity(F32 density)
- {
- if (density < 0.0f)
- density = 0.0f;
- mFogDensity = density;
- setMaskBits(FogDensityMask);
- }
- void VolumetricFog::setFogModulation(F32 strength,Point2F speed1,Point2F speed2)
- {
- mStrength = strength;
- mSpeed1 = speed1;
- mSpeed2 = speed2;
- mSpeed.set(speed1.x, speed1.y, speed2.x, speed2.y);
- setMaskBits(FogModulationMask);
- }
- void VolumetricFog::setFogGlow(bool on_off, F32 strength)
- {
- mUseGlow = on_off;
- mGlowStrength = strength;
- setMaskBits(FogPostFXMask);
- }
- void VolumetricFog::setFogLightray(bool on_off, F32 strength)
- {
- mModifLightRays = on_off;
- mLightRayMod = strength;
- setMaskBits(FogPostFXMask);
- }
- bool VolumetricFog::isInsideFog()
- {
- return mCamInFog;
- }
- DefineEngineMethod(VolumetricFog, SetFogColorF, void, (LinearColorF new_color), ,
- "@brief Changes the color of the fog\n\n."
- "@params new_color the new fog color (rgb 0.0 - 1.0, a is ignored.")
- {
- object->setFogColor(new_color);
- }
- DefineEngineMethod(VolumetricFog, SetFogColor, void, (ColorI new_color), ,
- "@brief Changes the color of the fog\n\n."
- "@params new_color the new fog color (rgb 0-255, a is ignored.")
- {
- object->setFogColor(new_color);
- }
- DefineEngineMethod(VolumetricFog, SetFogDensity, void, (F32 new_density), ,
- "@brief Changes the density of the fog\n\n."
- "@params new_density the new fog density.")
- {
- object->setFogDensity(new_density);
- }
- DefineEngineMethod(VolumetricFog, SetFogModulation, void, (F32 new_strenght, Point2F new_speed1, Point2F new_speed2), ,
- "@brief Changes the modulation of the fog\n\n."
- "@params new_strenght the new strength of the modulation.\n"
- "@params new_speed1 the new speed (x y) of the modulation layer 1.\n"
- "@params new_speed2 the new speed (x y) of the modulation layer 2.\n")
- {
- object->setFogModulation(new_strenght, new_speed1, new_speed2);
- }
- DefineEngineMethod(VolumetricFog, SetFogGlow, void, (bool on_off,F32 strength), ,
- "@brief Changes the glow postfx when inside the fog\n\n."
- "@params on_off set to true to enable glow.\n"
- "@params strength glow strength.\n")
- {
- object->setFogGlow(on_off, strength);
- }
- DefineEngineMethod(VolumetricFog, SetFogLightray, void, (bool on_off, F32 strength), ,
- "@brief Changes the lightrays postfx when inside the fog\n\n."
- "@params on_off set to true to modification of the lightray postfx.\n"
- "@params strength lightray strength.\n")
- {
- object->setFogLightray(on_off, strength);
- }
- DefineEngineMethod(VolumetricFog, isInsideFog, bool, (), ,
- "@brief returns true if control object is inside the fog\n\n.")
- {
- return object->isInsideFog();
- }
|