📄 fxsunlight.cc
字号:
// Cannot render without appropriate textures!
if ((!mLocalFlareTextureHandle && LocalSun) ||
(!mRemoteFlareTextureHandle && !LocalSun)) return;
// Screen Viewport.
RectI viewport;
// Setup out the Projection Matrix/Viewport.
glMatrixMode(GL_PROJECTION);
glPushMatrix();
dglGetViewport(&viewport);
state->setupBaseProjection();
// Setup Billboard View.
//
// NOTE:- We need to adjust for any animated offset.
glPushMatrix();
// Get Object Transform.
RXF = getTransform();
RXF.getColumn(3, &Position);
// Set new Position.
RXF.setColumn(3, mSunlightPosition);
dglMultMatrix(&RXF);
// Finish-up billboard.
dglGetModelview(&ModelView);
ModelView.getColumn(3, &Position);
ModelView.identity();
ModelView.setColumn(3, Position);
dglLoadMatrix(&ModelView);
// Setup our rendering state.
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glDepthMask(GL_FALSE);
// Select appropriate depth test for sun.
if (LocalSun)
glDisable(GL_DEPTH_TEST);
else
glEnable(GL_DEPTH_TEST);
// Select User Blend Mode.
switch(mBlendMode)
{
case 0:
glBlendFunc(GL_SRC_ALPHA, GL_ONE); break;
case 1:
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); break;
case 2:
glBlendFunc(GL_ONE,GL_ONE); break;
default:
// Duh, User error.
Con::printf("fxSunLight: Invalid Blend Mode Selected!");
glBlendFunc(GL_SRC_ALPHA, GL_ONE); break;
}
// Modulate Texture.
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
Point3F ScreenPoint;
Point3F ObjectPoint;
// Get Sunlight Position.
ObjectPoint = mSunlightPosition;
// Calculate screen point, on screen?
if (dglPointToScreen(ObjectPoint, ScreenPoint))
{
// Yes, so get Server Connection.
GameConnection* conn = GameConnection::getConnectionToServer();
// Problem?
if (conn)
{
// Get the Control Object.
ShapeBase* ControlObj = conn->getControlObject();
// Fetch Eye Position.
Point3F eyePos;
MatrixF eye;
ControlObj->getEyeTransform(&eye);
eye.getColumn(3, &eyePos);
// Calculate Distance from Light.
F32 Distance = (ObjectPoint - eyePos).len();
// Calculate Billboard Radius (in world units) to be constant independant of distance.
BBRadius = (Distance / dglGetPixelScale()) / 2;
// Set to current Size (or constant).
BBRadius *= mAnimationSize;
}
else
{
// No Billboard.
BBRadius = 0;
}
}
// Is this the Local Sun?
if (LocalSun)
{
// Yes, so do we have Line-of-sight?
if (TestLOS(mSunlightPosition))
{
// Yes, so are we fully showing?
if (mLocalFlareScale < 1.0f)
{
// No, so calculate new scale.
mLocalFlareScale += mElapsedTime / mFadeTime;
// Check new scale.
if (mLocalFlareScale > 1.0f) mLocalFlareScale = 1.0f;
}
}
else
{
// No, so are we fully hidden?
if (mLocalFlareScale > 0.0f)
{
// No, so calculate new scale.
mLocalFlareScale -= mElapsedTime / mFadeTime;
// Check new scale.
if (mLocalFlareScale < 0.0f) mLocalFlareScale = 0.0f;
}
}
}
// If this is the local flare then scale according to current show/hide fade.
if (LocalSun) BBRadius *= mLocalFlareScale;
// Are we linking flare size?
if (mLinkFlareSize)
{
// Yes, so Scale by LUMINANCE.
BBRadius *= (mAnimationColour.red * 0.212671f) +
(mAnimationColour.green * 0.715160f) +
(mAnimationColour.blue * 0.072169f);
}
// Only draw if needed.
if (BBRadius > 0)
{
// Select Flare Texture for sun type.
glBindTexture(GL_TEXTURE_2D, LocalSun ? mLocalFlareTextureHandle.getGLName() : mRemoteFlareTextureHandle.getGLName());
// Set flare colour.
glColor3f(mAnimationColour.red, mAnimationColour.green, mAnimationColour.blue);
// Rotate, if we have a rotation.
if (mAnimationRotation != 0.0f) glRotatef(mAnimationRotation, 0, 1, 0);
// Draw Billboard.
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(-BBRadius, 0, BBRadius);
glTexCoord2f(1, 0);
glVertex3f(BBRadius, 0, BBRadius);
glTexCoord2f(1, 1);
glVertex3f(BBRadius, 0, -BBRadius);
glTexCoord2f(0, 1);
glVertex3f(-BBRadius, 0, -BBRadius);
glEnd();
}
// Restore rendering state.
glDepthMask(GL_TRUE);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glEnable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
// Restore our nice, friendly and dull canonical state.
glPopMatrix();
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");
}
//------------------------------------------------------------------------------
bool fxSunLight::TestLOS(const Point3F& ObjectPosition)
{
// Valid Control Object types (for now).
const U32 ObjectMask = PlayerObjectType | VehicleObjectType | CameraObjectType;
// Get Server Connection.
GameConnection* conn = GameConnection::getConnectionToServer();
// Problem?
if (!conn) return false;
// Get the Control Object.
ShapeBase* ControlObj = conn->getControlObject();
// Valid Control Objects?
if (!ControlObj || !(ControlObj->getType() & ObjectMask)) return false;
// Kill flare if Third-person not available.
if (!ControlObj->isFirstPerson() && !mFlareTP) return false;
// Fetch Eye Position.
Point3F eyePos;
MatrixF eye;
conn->getControlCameraTransform(0, &eye);
eye.getColumn(3, &eyePos);
// Get our object center.
Point3F endPos = ObjectPosition;
// LOS Mask.
static U32 losMask = STATIC_COLLISION_MASK |
ShapeBaseObjectType |
StaticTSObjectType |
ItemObjectType |
PlayerObjectType;
// Stop Collisions with our Control Object (in first person).
if (ControlObj->isFirstPerson()) ControlObj->disableCollision();
// Store old Object Box.
Box3F OldObjBox = mObjBox;
// Set LOS Test Object Box.
mObjBox.min.set( -0.5, -0.5, -0.5 );
mObjBox.max.set( 0.5, 0.5, 0.5 );
// Reset the World Box.
resetWorldBox();
setRenderTransform(mObjToWorld);
// Perform a ray cast on the client container database.
RayInfo info;
bool los = !gClientContainer.castRay(eyePos, endPos, losMask, &info);
// Restore old Object Box.
mObjBox = OldObjBox;
// Reset the World Box.
resetWorldBox();
setRenderTransform(mObjToWorld);
// Continue Collisions with our Control Object (in first person).
if (ControlObj->isFirstPerson()) ControlObj->enableCollision();
// Return LOS result.
return los;
};
//------------------------------------------------------------------------------
U32 fxSunLight::packUpdate(NetConnection * con, U32 mask, BitStream * stream)
{
// Pack Parent.
U32 retMask = Parent::packUpdate(con, mask, stream);
// Write Config Change Flag.
if (stream->writeFlag(mask & fxSunLightConfigChangeMask))
{
// Position.
stream->writeAffineTransform(mObjToWorld);
// Debugging.
stream->write(mEnable);
// Media.
stream->writeString(mLocalFlareTextureName);
stream->writeString(mRemoteFlareTextureName);
// Sun Orbit.
stream->write(mSunAzimuth);
stream->write(mSunElevation);
// Flare.
stream->write(mFlareTP);
stream->write(mFlareColour);
stream->write(mFlareBrightness);
stream->write(mFlareSize);
stream->write(mFadeTime);
stream->write(mBlendMode);
// Animation Options.
stream->writeFlag(mUseColour);
stream->writeFlag(mUseBrightness);
stream->writeFlag(mUseRotation);
stream->writeFlag(mUseSize);
stream->writeFlag(mUseAzimuth);
stream->writeFlag(mUseElevation);
stream->writeFlag(mLerpColour);
stream->writeFlag(mLerpBrightness);
stream->writeFlag(mLerpRotation);
stream->writeFlag(mLerpSize);
stream->writeFlag(mLerpAzimuth);
stream->writeFlag(mLerpElevation);
stream->writeFlag(mLinkFlareSize);
stream->writeFlag(mSingleColourKeys);
// Animation Extents.
stream->write(mMinColour);
stream->write(mMaxColour);
stream->write(mMinBrightness);
stream->write(mMaxBrightness);
stream->write(mMinRotation);
stream->write(mMaxRotation);
stream->write(mMinSize);
stream->write(mMaxSize);
stream->write(mMinAzimuth);
stream->write(mMaxAzimuth);
stream->write(mMinElevation);
stream->write(mMaxElevation);
// Animation Keys.
stream->writeString(mRedKeys);
stream->writeString(mGreenKeys);
stream->writeString(mBlueKeys);
stream->writeString(mBrightnessKeys);
stream->writeString(mRotationKeys);
stream->writeString(mSizeKeys);
stream->writeString(mAzimuthKeys);
stream->writeString(mElevationKeys);
// Animation Times.
stream->write(mColourTime);
stream->write(mBrightnessTime);
stream->write(mRotationTime);
stream->write(mSizeTime);
stream->write(mAzimuthTime);
stream->write(mElevationTime);
// Forgotten!
stream->write(mLockToRealSun);
}
// Were done ...
return(retMask);
}
//------------------------------------------------------------------------------
void fxSunLight::unpackUpdate(NetConnection * con, BitStream * stream)
{
// Unpack Parent.
Parent::unpackUpdate(con, stream);
// Read Config Change Details?
if(stream->readFlag())
{
MatrixF ObjectMatrix;
// Position.
stream->readAffineTransform(&ObjectMatrix);
// Debugging.
stream->read(&mEnable);
// Media.
const char* Local = stream->readSTString();
const char* Remote = stream->readSTString();
setFlareBitmaps(Local, Remote);
// Sun Orbit.
stream->read(&mSunAzimuth);
stream->read(&mSunElevation);
// Flare.
stream->read(&mFlareTP);
stream->read(&mFlareColour);
stream->read(&mFlareBrightness);
stream->read(&mFlareSize);
stream->read(&mFadeTime);
stream->read(&mBlendMode);
// Animation Options.
mUseColour = stream->readFlag();
mUseBrightness = stream->readFlag();
mUseRotation = stream->readFlag();
mUseSize = stream->readFlag();
mUseAzimuth = stream->readFlag();
mUseElevation = stream->readFlag();
mLerpColour = stream->readFlag();
mLerpBrightness = stream->readFlag();
mLerpRotation = stream->readFlag();
mLerpSize = stream->readFlag();
mLerpAzimuth = stream->readFlag();
mLerpElevation = stream->readFlag();
mLinkFlareSize = stream->readFlag();
mSingleColourKeys = stream->readFlag();
// Animation Extents.
stream->read(&mMinColour);
stream->read(&mMaxColour);
stream->read(&mMinBrightness);
stream->read(&mMaxBrightness);
stream->read(&mMinRotation);
stream->read(&mMaxRotation);
stream->read(&mMinSize);
stream->read(&mMaxSize);
stream->read(&mMinAzimuth);
stream->read(&mMaxAzimuth);
stream->read(&mMinElevation);
stream->read(&mMaxElevation);
// Animation Keys.
mRedKeys = stream->readSTString();
mGreenKeys = stream->readSTString();
mBlueKeys = stream->readSTString();
mBrightnessKeys = stream->readSTString();
mRotationKeys = stream->readSTString();
mSizeKeys = stream->readSTString();
mAzimuthKeys = stream->readSTString();
mElevationKeys = stream->readSTString();
// Animation Times.
stream->read(&mColourTime);
stream->read(&mBrightnessTime);
stream->read(&mRotationTime);
stream->read(&mSizeTime);
stream->read(&mAzimuthTime);
stream->read(&mElevationTime);
// Forgotten!
stream->read(&mLockToRealSun);
// Set Transform.
setTransform(ObjectMatrix);
// Reset Animation.
ResetAnimation();
}
}
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -