12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331 |
- //-----------------------------------------------------------------------------
- // 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()
- {
- addGroup("VolumetricFogData");
- INITPERSISTFIELD_SHAPEASSET(Shape, VolumetricFog, "The source shape asset.");
- 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");
- Parent::initPersistFields();
- }
- 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();
- }
|