⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fxlight.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 4 页
字号:

	// Reset Last Render Time.
	mLastRenderTime = Platform::getRealMilliseconds();

	// 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 = getRenderTransform();
	RXF.getColumn(3, &Position);

	// Translate transform to absolute position.
	Position.x = mAnimationPosition.x;
	Position.y = mAnimationPosition.y;
	Position.z = mAnimationPosition.z;

	// Set new Position.
	RXF.setColumn(3, Position);
	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);
	glDisable(GL_DEPTH_TEST);

	// Select User Blend Mode.
	switch(mDataBlock->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("fxLight: Invalid Blend Mode Selected!");
			glBlendFunc(GL_SRC_ALPHA, GL_ONE); break;
	}

	// Is the Flare On?
	if (mDataBlock->mFlareOn && mEnable)
	{
		// Flare On ...

		// Modulate Texture.
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

		Point3F ScreenPoint;
		Point3F ObjectPoint;

		// Get Animation Position.
		ObjectPoint = mAnimationPosition;


		//
		// Calculate screen point, on screen?
		if (dglPointToScreen(ObjectPoint, ScreenPoint))
		{
			// Fetch Eye Position.
			Point3F	eyePos = state->getCameraPosition();
			
			// Calculate Distance from Light.
			F32 Distance = (ObjectPoint - eyePos).len();

			// Reset Billboard Radius.
			BBRadius = 1.0f;

			// Are we using Constant Size?
			if (mDataBlock->mConstantSizeOn)
			{
				// Yes, so simply size to Constant Size.
				BBRadius *= mDataBlock->mConstantSize;
			}
			else
			{
				// No, so calculate current size (in world units) according to distance.
				
				// Are we below the near size distance?
				if (Distance <= mDataBlock->mNearDistance)
				{
					// Yes, so clamp at near size.
					BBRadius *= mDataBlock->mNearSize;
				}
				// Are we above the far size distance?
				else if (Distance >= mDataBlock->mFarDistance)
				{
					// Yes, so clamp at far size.
					BBRadius *= mDataBlock->mFarSize;
				}
				else
				{
					// In the ramp so calculate current size according to distance.
					BBRadius = mDataBlock->mNearSize + ((Distance - mDataBlock->mNearDistance) * ((mDataBlock->mFarSize - mDataBlock->mNearSize) / ( mDataBlock->mFarDistance - mDataBlock->mNearDistance )));
				}
			}
		}
		else
		{
			// Console Warning.
			//Con::warnf("Flare point off screen!  How did this happen huh?");

			// Calculate Billboard Radius.
			BBRadius = 0;
		}

		// Do we have Line-of-sight?
		if (TestLOS(mAnimationPosition, mAttached?mpAttachedObject:NULL))
		{
			// Yes, so are we fully showing?
			if (mFlareScale < 1.0f)
			{
				// No, so calculate new scale.
				mFlareScale += mElapsedTime / mDataBlock->mFadeTime;

				// Check new scale.
				if (mFlareScale > 1.0f) mFlareScale = 1.0f;
			}
		}
		else
		{
			// No, so are we fully hidden?
			if (mFlareScale > 0.0f)
			{
				// No, so calculate new scale.
				mFlareScale -= mElapsedTime / mDataBlock->mFadeTime;

				// Check new scale.
				if (mFlareScale < 0.0f) mFlareScale = 0.0f;
			}
		}

		// Scale BB Size.
		BBRadius *= mFlareScale;

		// Are we linking flare size?
		if (mDataBlock->mLinkFlareSize)
		{
			// Yes, so Scale by LUMINANCE (better for modern colour monitors).
			BBRadius *= (mAnimationColour.red * 0.212671f) +
						(mAnimationColour.green * 0.715160f) +
						(mAnimationColour.blue * 0.072169f);
		}

		// Select Icon Texture.
		glBindTexture(GL_TEXTURE_2D, mFlareTextureHandle.getGLName());

		// Are we linking the flare?
		if (mDataBlock->mLinkFlare)
		{
			// Yes, so set Flare Colour to animation.
			glColor3f(mAnimationColour.red, mAnimationColour.green, mAnimationColour.blue);
		}
		else
		{
			// No, so set it to constant flare colour.
			glColor3f(mDataBlock->mFlareColour.red, mDataBlock->mFlareColour.green, mDataBlock->mFlareColour.blue);
		}
	}
	else
	{
		// Icon On ...

		// Icon Blend Function.
		glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
		// Replace Texture.
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

		// Calculate Billboard Radius.
		BBRadius = mIconSize / 2;

		// Select Icon Texture.
		glBindTexture(GL_TEXTURE_2D, mIconTextureHandle.getGLName());
	}

	// Only draw if needed.
	if (BBRadius > 0)
	{
		// 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.
	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 fxLight::TestLOS(const Point3F& ObjectPosition, SceneObject* AttachedObj)
{
	// Valid Control Object types (for now).
	const U32 ObjectMask = PlayerObjectType | VehicleObjectType | CameraObjectType;

	// Get Server Connection.
	GameConnection* con = GameConnection::getConnectionToServer();
	// Problem?
	if (!con) return false;

	// Get the Control Object.
	ShapeBase* ControlObj = con->getControlObject();
	// Valid Control Objects?
	if (!ControlObj || !(ControlObj->getType() & ObjectMask)) return false;
	// Kill flare if Third-person not available.
	if (!ControlObj->isFirstPerson() && !mDataBlock->mFlareTP) return false;

	// Fetch Eye Position.
	Point3F eyePos;
	MatrixF eye;
	con->getControlCameraTransform(0, &eye);
	eye.getColumn(3, &eyePos);

	// Get our object center.
    Point3F endPos = ObjectPosition;

	// LOS Mask.
	static U32 losMask =	STATIC_COLLISION_MASK |
							ShapeBaseObjectType |
							StaticTSObjectType |
							PlayerObjectType;

	// Stop Collisions with our Control Object (in first person).
	if (ControlObj->isFirstPerson()) ControlObj->disableCollision();
	// If we are attached to an object then disable it's collision.
	if (AttachedObj) AttachedObj->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();

	// 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();

	// If we are attached to an object then enable it's collision.
	if (AttachedObj) AttachedObj->enableCollision();
	// Continue Collisions with our Control Object (in first person).
	if (ControlObj->isFirstPerson()) ControlObj->enableCollision();

	// Return LOS result.
	return los;
};

//------------------------------------------------------------------------------

U32 fxLight::packUpdate(NetConnection * con, U32 mask, BitStream * stream)
{
	// Pack Parent.
	U32 retMask = Parent::packUpdate(con, mask, stream);

	// Write Attach Flag.
	if (stream->writeFlag((mask & fxLightAttachChange) && mAttachValid))
	{
		// Get Attached Object.
		GameBase* Obj = getProcessAfter();

		// Write Object Attach/Detach Flag.
		if (stream->writeFlag(Obj != NULL))
		{
/*
			// Get Server Connection.
			GameConnection* conn = GameConnection::getLocalClientConnection();
			// Problem?
			if (!conn)
			{
				// Invalidate Attachment.
				mAttachValid = false;
				// Return here.
				return(retMask);
			}
*/
			// Get the GhostID of the object.
			S32 GhostID = con->getGhostIndex(Obj);
			// Send it to the client.
            stream->writeRangedU32(U32(GhostID), 0, GhostConnection::MaxGhostCount);
		}

		// Invalidate Attachment.
		mAttachValid = false;
	}

	// Write Config Change Flag.
	if (stream->writeFlag(mask & fxLightConfigChangeMask))
	{
		// Position.
		stream->writeAffineTransform(mObjToWorld);

		// Enable.
		stream->write(mEnable);

		// Basis Light.
		stream->write(mIconSize);
	}

	// Were done ...
	return(retMask);
}

//------------------------------------------------------------------------------

void fxLight::unpackUpdate(NetConnection * con, BitStream * stream)
{
	// Unpack Parent.
	Parent::unpackUpdate(con, stream);

	// Read Attach Position.
	if (stream->readFlag())
	{
		// Read Attach/Detach Flag.
		mAttached = stream->readFlag();

		// Read Position.
		if (mAttached)
		{
			// Get the ObjectID.
			S32 ObjectID = stream->readRangedU32(0, GhostConnection::MaxGhostCount);
			// Resolve it.
			NetObject* pObject = con->resolveGhost(ObjectID);
			if (pObject != NULL)
			{
				// Get the object.
				mpAttachedObject = dynamic_cast<GameBase*>(pObject);

				// Make sure we know if it's deleted.
				deleteNotify(mpAttachedObject);

				//Con::warnf(ConsoleLogEntry::General, "fxLight::unpack: attached to object.");
			}
			else
			{
				//Con::warnf(ConsoleLogEntry::General, "fxLight::unpack: could not resolve attachment targetID!");
				//Con::warnf(ConsoleLogEntry::General, "fxLight::unpack: recovering by detaching object.");
				mAttached = false;
			}
		}
		else
		{
			// Reset Any Attachment.
			mAttached = false;
		}
	}

	// Read Config Change Details?
	if(stream->readFlag())
	{
		MatrixF		ObjectMatrix;

		// Position.
		stream->readAffineTransform(&ObjectMatrix);

		// Enable.
		stream->read(&mEnable);

		// Basis Light.
		stream->read(&mIconSize);

		// Set Transform.
		setTransform(ObjectMatrix);

		// Reset Animation.
		ResetAnimation();
	}
}

//------------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -