|
DaphydTheBard
|
 |
« on: 2007/02/15 13:46:25 » |
|
Hi again folks.
Firstly a big thanks to everyone who's helped me so far.
My own game engine is now growing steadily thanks to the help and support I've received here.
I have a little issue I can't seem to get my head around and was hoping someone might be able to point me in the right direction.
I've recenty added Point Sprites to my engine so I can do laser bolts, explosions, smoke, etc. It's working well, with the exception that the point sprites are *always* in front of everything else (although they do scale correctly).
I wanted to use this effect for engine exhaust flares on spaceships, but if I turn the ship to face the camera, you can see the point sprite "through" the ship....there must be a way to determine that the point sprite is obscured from the camera's view - but I haven't got a clue how to do it.
Anyone got any ideas? Any help would be appreciated.
Here's my PointSprite Class:
#region Using Directives
using System; using System.Collections.Generic; using System.Text;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Storage;
using XNACore.Graphics; using XNACore.Helpers;
#endregion
namespace XNACore.Graphics { class XNAPointSprite { #region Structures
private struct pointSpriteVertexFormat { private Vector3 position; private float pointSize;
public pointSpriteVertexFormat(Vector3 position, float pointSize) { this.position = position; this.pointSize = pointSize; }
public static VertexElement[] Elements = { new VertexElement(0, 0, VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Position, 0), new VertexElement(0, sizeof(float)*3, VertexElementFormat.Single, VertexElementMethod.Default, VertexElementUsage.PointSize, 0), };
public static int SizeInBytes = sizeof(float) * (3 + 1); }
#endregion
#region Variables
private GraphicsDevice objDevice = null; private XNAViewPort objViewPort = null; private Effect objEffect;
#endregion
#region Constructor
public XNAPointSprite(ref XNAGame XNAGame, ref XNAViewPort XNAViewPort) { objDevice = XNAGame.Device; objViewPort = XNAViewPort; objEffect = XNAGame.Content.Load<Effect>(FolderHelper.ShadersFolder() + "PointSprite"); }
#endregion
#region Public Methods
public void RenderSprite(Texture2D texture, Vector3 position, float scale) { pointSpriteVertexFormat[] objPoint = new pointSpriteVertexFormat[1];
objPoint[0] = new pointSpriteVertexFormat(position, scale);
objEffect.CurrentTechnique = objEffect.Techniques["PointSprites"]; Matrix worldMatrix = Matrix.Identity; objEffect.Parameters["xWorld"].SetValue(worldMatrix); objEffect.Parameters["xView"].SetValue(objViewPort.MatrixView); objEffect.Parameters["xProjection"].SetValue(objViewPort.MatrixProjection); objEffect.Parameters["xTexture"].SetValue(texture);
objDevice.RenderState.AlphaBlendEnable = true; objDevice.RenderState.SourceBlend = Blend.One; objDevice.RenderState.DestinationBlend = Blend.One;
objEffect.Begin(); foreach (EffectPass pass in objEffect.CurrentTechnique.Passes) { pass.Begin(); objDevice.VertexDeclaration = new VertexDeclaration(objDevice, pointSpriteVertexFormat.Elements); objDevice.DrawUserPrimitives(PrimitiveType.PointList, objPoint, 0, 1); pass.End(); } objEffect.End();
objDevice.RenderState.AlphaBlendEnable = false; }
#endregion
} }
and here's the shader I'm using:
//------- Technique: PointSprites --------
struct SpritesVertexToPixel { float4 Position : POSITION; float4 Color : COLOR0; float1 Size : PSIZE; };
SpritesVertexToPixel PointSpritesVS (float4 Position : POSITION, float4 Color : COLOR0, float1 Size : PSIZE) { SpritesVertexToPixel Output = (SpritesVertexToPixel)0; float4x4 preViewProjection = mul (xView, xProjection); float4x4 preWorldViewProjection = mul (xWorld, preViewProjection); Output.Position = mul(Position, preWorldViewProjection); Output.Color = Color; Output.Size = 1/(pow(Output.Position.z,2)+1 ) * Size; return Output; }
PixelToFrame PointSpritesPS(SpritesVertexToPixel PSIn, float2 TexCoords : TEXCOORD0) { PixelToFrame Output = (PixelToFrame)0;
Output.Color = tex2D(TextureSampler, TexCoords); return Output; }
technique PointSprites { pass Pass0 { PointSpriteEnable = true; VertexShader = compile vs_1_1 PointSpritesVS(); PixelShader = compile ps_1_1 PointSpritesPS(); } }
|