📄 fxfoliagereplicator.cc
字号:
mFrustumRenderSet.CompileVisibleSet(mFoliageQuadTree[0], getRenderTransform(), mFieldData.mUseDebugInfo);
if ( mFieldData.mUseDebugInfo)
{
// Restore rendering state.
glDisable(GL_BLEND);
}
}
else
{
// No, so clear the Render Object Set.
mFrustumRenderSet.mVisObjectSet.clear();
// Handle *all* objects ... potential eeek!
mFrustumRenderSet.mVisObjectSet.merge(mReplicatedFoliage);
}
// Increase Frame Serial ID.
mFrameSerialID++;
// Reset Foliage Processed Counter.
U32 FoliageProcessed = 0;
// Only process if we have any trivially visible objects.
if (mFrustumRenderSet.mVisObjectSet.size() > 0)
{
// Setup Render State.
glEnable ( GL_TEXTURE_2D );
glBindTexture ( GL_TEXTURE_2D, mFieldData.mFoliageTexture.getGLName() );
glEnable ( GL_BLEND );
glBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA );
glTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
glEnable ( GL_ALPHA_TEST );
glEnable ( GL_CULL_FACE );
glAlphaFunc ( GL_GREATER, mFieldData.mAlphaCutoff );
// Step through Foliage.
for (U32 idx = 0; idx < mFrustumRenderSet.mVisObjectSet.size(); idx++)
{
fxFoliageItem* pFoliageItem;
F32 Width, Height;
F32 Distance;
F32 ItemAlpha;
F32 FogAlpha;
// Fetch the Foliage Item.
pFoliageItem = mFrustumRenderSet.mVisObjectSet[idx];
// Check to see if we've already rendered this object.
//
// NOTE:- We need to do this as objects can overlap over quad-tree boundaries and are
// therefore picked up. We don't want to remove these duplicates otherwise the
// overlapping billboards would be contained within a single quad-block only
// and could possibly be culled even though they are visible in the adjacent
// quad-block. In other words, billboards are *not* treated as a point but rather
// a psuedo volume which stops them popping-up when the central point is visible.
//
// We also mark the billboard as rendered even if it results in being culled
// further on as this stops it being rendered further this frame.
//
// Has the item been rendered this frame?
if (pFoliageItem->LastFrameSerialID != mFrameSerialID)
{
// No, so flag as rendered this frame.
pFoliageItem->LastFrameSerialID = mFrameSerialID;
// Increase Foliage Processed Counter.
FoliageProcessed++;
// Is Swaying On and *not* in Sync?
if (mFieldData.mSwayOn && !mFieldData.mSwaySync)
{
// Yes, so calculate Sway Offset.
SwayOffsetX = mFieldData.mSwayMagnitudeSide * mCosTable[(U32)pFoliageItem->SwayPhase];
SwayOffsetY = mFieldData.mSwayMagnitudeFront * mSinTable[(U32)pFoliageItem->SwayPhase];
// Animate Sway Phase (Modulus).
pFoliageItem->SwayPhase = pFoliageItem->SwayPhase + (pFoliageItem->SwayTimeRatio * ElapsedTime);
if (pFoliageItem->SwayPhase >= 720.0f) pFoliageItem->SwayPhase -= 720.0f;
}
// Is Light On and *not* in Sync?
if (mFieldData.mLightOn && !mFieldData.mLightSync)
{
// Yes, so calculate Light Luminance.
Luminance = LuminanceMidPoint + LuminanceMagnitude * mCosTable[(U32)pFoliageItem->LightPhase];
// Animate Light Phase (Modulus).
pFoliageItem->LightPhase = pFoliageItem->LightPhase + (pFoliageItem->LightTimeRatio * ElapsedTime);
if (pFoliageItem->LightPhase >= 720.0f) pFoliageItem->LightPhase -= 720.0f;
}
// Calculate Distance to Item.
Distance = (pFoliageItem->Transform.getPosition() - state->getCameraPosition()).len();
// Trivially reject the billboard if it's beyond the SceneGraphs visible distance.
if (Distance > state->getVisibleDistance()) continue;
// Calculate Fog Alpha.
FogAlpha = 1.0f - state->getHazeAndFog(Distance, pFoliageItem->Transform.getPosition().z - state->getCameraPosition().z);
// Trivially reject the billboard if it's totally transparent.
if (FogAlpha < FXFOLIAGE_ALPHA_EPSILON) continue;
// Can we trivially accept the billboard?
if (Distance >= MinimumViewDistance && Distance <= MaximumViewDistance)
{
// Yes, so are we fading out?
if (Distance < mFieldData.mViewClosest)
{
// Yes, so set fade-out.
ItemAlpha = 1.0f - ((mFieldData.mViewClosest - Distance) * mFadeOutGradient);
}
// No, so are we fading in?
else if (Distance > ClippedViewDistance)
{
// Yes, so set fade-in
ItemAlpha = 1.0f - ((Distance - ClippedViewDistance) * mFadeInGradient);
}
// No, so set full.
else
{
ItemAlpha = 1.0f;
}
// Clamp upper-limit to Fog Alpha.
if (ItemAlpha > FogAlpha) ItemAlpha = FogAlpha;
// Store our Modelview.
glPushMatrix();
// Perform Spherical Billboarding.
dglMultMatrix(&pFoliageItem->Transform);
dglGetModelview(&ModelView);
ModelView.setColumn(0, XRotation);
ModelView.setColumn(1, YRotation);
dglLoadMatrix(&ModelView);
// Fetch Width/Height.
Width = pFoliageItem->Width / 2.0f;
Height = pFoliageItem->Height;
// Fetch Flipped Flag.
LeftTexPos = pFoliageItem->Flipped ? 1.0f : 0.0f;
RightTexPos = 1.0f - LeftTexPos;
// Draw Billboard.
glBegin(GL_QUADS);
// Set Blend Function.
glColor4f(Luminance,Luminance,Luminance, ItemAlpha);
// Draw Top part of billboard.
glTexCoord2f (LeftTexPos,0);
glVertex3f (-Width+SwayOffsetX,SwayOffsetY,Height);
glTexCoord2f (RightTexPos,0);
glVertex3f (+Width+SwayOffsetX,SwayOffsetY,Height);
// Set Ground Blend.
if (mFieldData.mGroundAlpha < 1.0f) glColor4f(Luminance, Luminance, Luminance, mFieldData.mGroundAlpha < ItemAlpha ? mFieldData.mGroundAlpha : ItemAlpha);
// Draw bottom part of billboard.
glTexCoord2f (RightTexPos,1);
glVertex3f (+Width,0,0);
glTexCoord2f (LeftTexPos,1);
glVertex3f (-Width,0,0);
glEnd();
// Restore our Modelview.
glPopMatrix();
}
}
}
// Restore rendering state.
glTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
glDisable ( GL_CULL_FACE );
glDisable ( GL_ALPHA_TEST );
glDisable ( GL_BLEND );
glDisable ( GL_TEXTURE_2D );
}
// Dump Debug Information (Uncomment this if needed).
//
// NOTE:- Here we show the number of objects rendered compared to the potential objects in the viewing frustum.
// Remember that the difference is simply billboards that intersect quad-tree boundaries.
//
//if (mFieldData.mUseDebugInfo) Con::printf("fxFoliageReplicator - %d of %d Foliage Items Processed", FoliageProcessed, mFrustumRenderSet.mVisObjectSet.size());
}
// Restore out nice and friendly canonical state.
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
dglSetViewport(viewport);
// Check we have restored Canonical State.
AssertFatal(dglIsInCanonicalState(), "Error, GL not in canonical state on exit");
}
//------------------------------------------------------------------------------
U32 fxFoliageReplicator::packUpdate(NetConnection * con, U32 mask, BitStream * stream)
{
// Pack Parent.
U32 retMask = Parent::packUpdate(con, mask, stream);
// Write Foliage Replication Flag.
if (stream->writeFlag(mask & FoliageReplicationMask))
{
stream->writeAffineTransform(mObjToWorld); // Foliage Master-Object Position.
stream->writeFlag(mFieldData.mUseDebugInfo); // Foliage Debug Information Flag.
stream->write(mFieldData.mDebugBoxHeight); // Foliage Debug Height.
stream->write(mFieldData.mSeed); // Foliage Seed.
stream->write(mFieldData.mFoliageCount); // Foliage Count.
stream->write(mFieldData.mFoliageRetries); // Foliage Retries.
stream->writeString(mFieldData.mFoliageFile); // Foliage File.
stream->write(mFieldData.mInnerRadiusX); // Foliage Inner Radius X.
stream->write(mFieldData.mInnerRadiusY); // Foliage Inner Radius Y.
stream->write(mFieldData.mOuterRadiusX); // Foliage Outer Radius X.
stream->write(mFieldData.mOuterRadiusY); // Foliage Outer Radius Y.
stream->write(mFieldData.mMinWidth); // Foliage Minimum Width.
stream->write(mFieldData.mMaxWidth); // Foliage Maximum Width.
stream->write(mFieldData.mMinHeight); // Foliage Minimum Height.
stream->write(mFieldData.mMaxHeight); // Foliage Maximum Height.
stream->write(mFieldData.mFixAspectRatio); // Foliage Fix Aspect Ratio.
stream->write(mFieldData.mFixSizeToMax); // Foliage Fix Size to Max.
stream->write(mFieldData.mOffsetZ); // Foliage Offset Z.
stream->write(mFieldData.mRandomFlip); // Foliage Random Flip.
stream->write(mFieldData.mUseCulling); // Foliage Use Culling.
stream->write(mFieldData.mCullResolution); // Foliage Cull Resolution.
stream->write(mFieldData.mViewDistance); // Foliage View Distance.
stream->write(mFieldData.mViewClosest); // Foliage View Closest.
stream->write(mFieldData.mFadeInRegion); // Foliage Fade-In Region.
stream->write(mFieldData.mFadeOutRegion); // Foliage Fade-Out Region.
stream->write(mFieldData.mAlphaCutoff); // Foliage Alpha Cutoff.
stream->write(mFieldData.mGroundAlpha); // Foliage Ground Alpha.
stream->writeFlag(mFieldData.mSwayOn); // Foliage Sway On Flag.
stream->writeFlag(mFieldData.mSwaySync); // Foliage Sway Sync Flag.
stream->write(mFieldData.mSwayMagnitudeSide); // Foliage Sway Magnitude Side2Side.
stream->write(mFieldData.mSwayMagnitudeFront); // Foliage Sway Magnitude Front2Back.
stream->write(mFieldData.mMinSwayTime); // Foliage Minimum Sway Time.
stream->write(mFieldData.mMaxSwayTime); // Foliage Maximum way Time.
stream->writeFlag(mFieldData.mLightOn); // Foliage Light On Flag.
stream->writeFlag(mFieldData.mLightSync); // Foliage Light Sync
stream->write(mFieldData.mMinLuminance); // Foliage Minimum Luminance.
stream->write(mFieldData.mMaxLuminance); // Foliage Maximum Luminance.
stream->write(mFieldData.mLightTime); // Foliage Light Time.
stream->writeFlag(mFieldData.mAllowOnTerrain); // Allow on Terrain.
stream->writeFlag(mFieldData.mAllowOnInteriors); // Allow on Interiors.
stream->writeFlag(mFieldData.mAllowStatics); // Allow on Statics.
stream->writeFlag(mFieldData.mAllowOnWater); // Allow on Water.
stream->writeFlag(mFieldData.mAllowWaterSurface); // Allow on Water Surface.
stream->write(mFieldData.mAllowedTerrainSlope); // Foliage Offset Z.
stream->writeFlag(mFieldData.mHideFoliage); // Hide Foliage.
stream->writeFlag(mFieldData.mShowPlacementArea); // Show Placement Area Flag.
stream->write(mFieldData.mPlacementBandHeight); // Placement Area Height.
stream->write(mFieldData.mPlaceAreaColour); // Placement Area Colour.
}
// Were done ...
return(retMask);
}
//------------------------------------------------------------------------------
void fxFoliageReplicator::unpackUpdate(NetConnection * con, BitStream * stream)
{
// Unpack Parent.
Parent::unpackUpdate(con, stream);
// Read Replication Details.
if(stream->readFlag())
{
MatrixF ReplicatorObjectMatrix;
stream->readAffineTransform(&ReplicatorObjectMatrix); // Foliage Master Object Position.
mFieldData.mUseDebugInfo = stream->readFlag(); // Foliage Debug Information Flag.
stream->read(&mFieldData.mDebugBoxHeight); // Foliage Debug Height.
stream->read(&mFieldData.mSeed); // Foliage Seed.
stream->read(&mFieldData.mFoliageCount); // Foliage Count.
stream->read(&mFieldData.mFoliageRetries); // Foliage Retries.
mFieldData.mFoliageFile = stream->readSTString(); // Foliage File.
stream->read(&mFieldData.mInnerRadiusX); // Foliage Inner Radius X.
stream->read(&mFieldData.mInnerRadiusY); // Foliage Inner Radius Y.
stream->read(&mFieldData.mOuterRadiusX); // Foliage Outer Radius X.
stream->read(&mFieldData.mOuterRadiusY); // Foliage Outer Radius Y.
stream->read(&mFieldData.mMinWidth); // Foliage Minimum Width.
stream->read(&mFieldData.mMaxWidth); // Foliage Maximum Width.
stream->read(&mFieldData.mMinHeight); // Foliage Minimum Height.
stream->read(&mFieldData.mMaxHeight); // Foliage Maximum Height.
stream->read(&mFieldData.mFixAspectRatio); // Foliage Fix Aspect Ratio.
stream->read(&mFieldData.mFixSizeToMax); // Foliage Fix Size to Max.
stream->read(&mFieldData.mOffsetZ); // Foliage Offset Z.
stream->read(&mFieldData.mRandomFlip); // Foliage Random Flip.
stream->read(&mFieldData.mUseCulling); // Foliage Use Culling.
stream->read(&mFieldData.mCullResolution); // Foliage Cull Resolution.
stream->read(&mFieldData.mViewDistance); // Foliage View Distance.
stream->read(&mFieldData.mViewClosest); // Foliage View Closest.
stream->read(&mFieldData.mFadeInRegion); // Foliage Fade-In Region.
stream->read(&mFieldData.mFadeOutRegion); // Foliage Fade-Out Region.
stream->read(&mFieldData.mAlphaCutoff); // Foliage Alpha Cutoff.
stream->read(&mFieldData.mGroundAlpha); // Foliage Ground Alpha.
mFieldData.mSwayOn = stream->readFlag(); // Foliage Sway On Flag.
mFieldData.mSwaySync = stream->readFlag(); // Foliage Sway Sync Flag.
stream->read(&mFieldData.mSwayMagnitudeSide); // Foliage Sway Magnitude Side2Side.
stream->read(&mFieldData.mSwayMagnitudeFront); // Foliage Sway Magnitude Front2Back.
stream->read(&mFieldData.mMinSwayTime); // Foliage Minimum Sway Time.
stream->read(&mFieldData.mMaxSwayTime); // Foliage Maximum way Time.
mFieldData.mLightOn = stream->readFlag(); // Foliage Light On Flag.
mFieldData.mLightSync = stream->readFlag(); // Foliage Light Sync
stream->read(&mFieldData.mMinLuminance); // Foliage Minimum Luminance.
stream->read(&mFieldData.mMaxLuminance); // Foliage Maximum Luminance.
stream->read(&mFieldData.mLightTime); // Foliage Light Time.
mFieldData.mAllowOnTerrain = stream->readFlag(); // Allow on Terrain.
mFieldData.mAllowOnInteriors = stream->readFlag(); // Allow on Interiors.
mFieldData.mAllowStatics = stream->readFlag(); // Allow on Statics.
mFieldData.mAllowOnWater = stream->readFlag(); // Allow on Water.
mFieldData.mAllowWaterSurface = stream->readFlag(); // Allow on Water Surface.
stream->read(&mFieldData.mAllowedTerrainSlope); // Allowed Terrain Slope.
mFieldData.mHideFoliage = stream->readFlag(); // Hide Foliage.
mFieldData.mShowPlacementArea = stream->readFlag(); // Show Placement Area Flag.
stream->read(&mFieldData.mPlacementBandHeight); // Placement Area Height.
stream->read(&mFieldData.mPlaceAreaColour);
// Calculate Fade-In/Out Gradients.
mFadeInGradient = 1.0f / mFieldData.mFadeInRegion;
mFadeOutGradient = 1.0f / mFieldData.mFadeOutRegion;
// Set Transform.
setTransform(ReplicatorObjectMatrix);
// Load Foliage Texture on the client.
mFieldData.mFoliageTexture = TextureHandle( mFieldData.mFoliageFile, MeshTexture );
// Set Quad-Tree Box Height Lerp.
mFrustumRenderSet.mHeightLerp = mFieldData.mDebugBoxHeight;
// Create Foliage (if Replication has begun).
if (mClientReplicationStarted) CreateFoliage();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -