Jump to content
  • Advertisement
Sign in to follow this  
deadlydog

Point Sprites being drawn as pixels in XNA

This topic is 3654 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm using C# and XNA and am trying to draw some point sprites from my particle system, but they simply show up as colored pixels instead of a texture. I am following the example given on Riemer's tutorial website. I am also using Reimers effect file. I have defined my own vertex format:
/// <summary>
    /// Structure used to hold a Particle Vertex's properties to be used by the Vertex Buffer
    /// </summary>
    struct DPSFParticleVertex
    {
        public Vector3 cPosition;               // The Position of the Particle in 3D space
        public float fSize;                     // The Size of the Particle

        public void Set(Vector3 cPosition, float fSize)
        {
            this.cPosition = cPosition;
            this.fSize = fSize;
        }

        // Describe the vertex structure used to display a Particle
        public static readonly VertexElement[] VertexElements =
        {
            new VertexElement(0, 0, VertexElementFormat.Vector3,
                                    VertexElementMethod.Default,
                                    VertexElementUsage.Position, 0),

            new VertexElement(0, 12, VertexElementFormat.Single, 
                                     VertexElementMethod.Default, 
                                     VertexElementUsage.PointSize, 0)
        };

        // The size of the vertex structure in bytes
        public const int SizeInBytes = 16;
    }









My Particles are then stored as an array of DPSFParticleVertex's, called mcParticleVertices. Here is my Draw function:
/// <summary>
        /// Draws all of the Active Particles to the screen
        /// </summary>
        public virtual void Draw(Matrix cWorld, Matrix cView, Matrix cProjection)
        {
            // If there are no Particles to draw
            if (mcActiveParticlesList.Count <= 0)
            {
                // Exit without drawing anything
                return;
            }

            // Set the Render State for drawing Sprites
            mcGame.GraphicsDevice.RenderState.PointSpriteEnable = true;
            mcGame.GraphicsDevice.RenderState.DepthBufferWriteEnable = false;

            // Specify the Vertex Buffer to use
            mcGame.GraphicsDevice.VertexDeclaration = mcVertexDeclaration;

            // Specity the World, View, and Projection Matrices
            mcEffect.Parameters["xWorld"].SetValue(cWorld);
            mcEffect.Parameters["xView"].SetValue(cView);
            mcEffect.Parameters["xProjection"].SetValue(cProjection);

            // Begin the Effect
            mcEffect.Begin();

            // Loop through each Pass of the Current Technique
            foreach (EffectPass cPass in mcEffect.CurrentTechnique.Passes)
            {
                // Begin the Pass
                cPass.Begin();

                // Draw the point sprites
                mcGame.GraphicsDevice.DrawUserPrimitives<DPSFParticleVertex>(PrimitiveType.PointList, 
mcParticleVertices, 0, mcActiveParticlesList.Count);

                // End the Pass
                cPass.End();
            }

            // End the Effect
            mcEffect.End();

            // Reset a couple of the more unusual Render States that we changed,
            // so as not to mess up any other subsequent drawing
            mcGame.GraphicsDevice.RenderState.PointSpriteEnable = false;
            mcGame.GraphicsDevice.RenderState.DepthBufferWriteEnable = true;
        }









I also set the "xTexture" effect parameter when the particle system is initialized And here is Riemer's effect file that I am using (I am using the PointSprites technique at the bottom):
//------------------------------------------------------
//--                                                	--
//--				www.riemers.net			--
//--				Basic shaders			--
//--			Use/modify as you like              --
//--                                                	--
//------------------------------------------------------

struct VertexToPixel
{
    float4 Position   	: POSITION;    
    float4 Color		: COLOR0;
    float LightingFactor: TEXCOORD0;
    float2 TextureCoords: TEXCOORD1;
};

struct PixelToFrame
{
    float4 Color : COLOR0;
};

//------- XNA-to-HLSL variables --------
float4x4 xView;
float4x4 xProjection;
float4x4 xWorld;
float3 xLightDirection;
float xAmbient;
bool xEnableLighting;
bool xShowNormals;

//------- Texture Samplers --------

Texture xTexture;
sampler TextureSampler = sampler_state { texture = <xTexture>; magfilter = LINEAR; minfilter = LINEAR;
 mipfilter=LINEAR; AddressU = mirror; AddressV = mirror;};

//------- Technique: Pretransformed --------

VertexToPixel PretransformedVS( float4 inPos : POSITION, float4 inColor: COLOR)
{	
	VertexToPixel Output = (VertexToPixel)0;
	
	Output.Position = inPos;
	Output.Color = inColor;
    
	return Output;    
}

PixelToFrame PretransformedPS(VertexToPixel PSIn) 
{
	PixelToFrame Output = (PixelToFrame)0;		
	
	Output.Color = PSIn.Color;

	return Output;
}

technique Pretransformed_2_0
{
	pass Pass0
	{   
		VertexShader = compile vs_2_0 PretransformedVS();
		PixelShader  = compile ps_2_0 PretransformedPS();
	}
}

technique Pretransformed
{
	pass Pass0
	{   
		VertexShader = compile vs_1_1 PretransformedVS();
		PixelShader  = compile ps_1_1 PretransformedPS();
	}
}

//------- Technique: Colored --------

VertexToPixel ColoredVS( float4 inPos : POSITION, float4 inColor: COLOR, float3 inNormal: NORMAL)
{	
	VertexToPixel Output = (VertexToPixel)0;
	float4x4 preViewProjection = mul (xView, xProjection);
	float4x4 preWorldViewProjection = mul (xWorld, preViewProjection);
    
	Output.Position = mul(inPos, preWorldViewProjection);
	Output.Color = inColor;
	
	float3 Normal = normalize(mul(normalize(inNormal), xWorld));	
	Output.LightingFactor = 1;
	if (xEnableLighting)
		Output.LightingFactor = saturate(dot(Normal, -xLightDirection));
    
	return Output;    
}

PixelToFrame ColoredPS(VertexToPixel PSIn) 
{
	PixelToFrame Output = (PixelToFrame)0;		
    
	Output.Color = PSIn.Color;
	Output.Color.rgb *= saturate(PSIn.LightingFactor + xAmbient);
	
	return Output;
}

technique Colored_2_0
{
	pass Pass0
	{   
		VertexShader = compile vs_2_0 ColoredVS();
		PixelShader  = compile ps_2_0 ColoredPS();
	}
}

technique Colored
{
	pass Pass0
	{   
		VertexShader = compile vs_1_1 ColoredVS();
		PixelShader  = compile ps_1_1 ColoredPS();
	}
}


//------- Technique: Textured --------

VertexToPixel TexturedVS( float4 inPos : POSITION, float3 inNormal: NORMAL, float2 inTexCoords: TEXCOORD0)
{	
	VertexToPixel Output = (VertexToPixel)0;
	float4x4 preViewProjection = mul (xView, xProjection);
	float4x4 preWorldViewProjection = mul (xWorld, preViewProjection);
    
	Output.Position = mul(inPos, preWorldViewProjection);	
	Output.TextureCoords = inTexCoords;
	
	float3 Normal = normalize(mul(normalize(inNormal), xWorld));	
	Output.LightingFactor = 1;
	if (xEnableLighting)
		Output.LightingFactor = saturate(dot(Normal, -xLightDirection));
    
	return Output;    
}

PixelToFrame TexturedPS(VertexToPixel PSIn) 
{
	PixelToFrame Output = (PixelToFrame)0;		
	
	Output.Color = tex2D(TextureSampler, PSIn.TextureCoords);
	Output.Color.rgb *= saturate(PSIn.LightingFactor + xAmbient);

	return Output;
}

technique Textured_2_0
{
	pass Pass0
	{   
		VertexShader = compile vs_2_0 TexturedVS();
		PixelShader  = compile ps_2_0 TexturedPS();
	}
}

technique Textured
{
	pass Pass0
	{   
		VertexShader = compile vs_1_1 TexturedVS();
		PixelShader  = compile ps_1_1 TexturedPS();
	}
}

//------- Technique: PointSprites --------

struct SpritesVertexOut
{
    float4 Position		: POSITION0;
    float1 Size 		: PSIZE;
};

struct SpritesPixelIn
{
    #ifdef XBOX
		float4 TexCoord : SPRITETEXCOORD;
	#else
		float2 TexCoord : TEXCOORD0;
	#endif
};

SpritesVertexOut PointSpritesVS (float4 Position : POSITION, float4 Color : COLOR0, float1 Size : PSIZE)
{
    SpritesVertexOut Output = (SpritesVertexOut)0;
     
    float4x4 preViewProjection = mul (xView, xProjection);
	float4x4 preWorldViewProjection = mul (xWorld, preViewProjection); 
    Output.Position = mul(Position, preWorldViewProjection);    
    Output.Size = 1/(pow(Output.Position.z,2)+1	) * Size;
    
    return Output;    
}

PixelToFrame PointSpritesPS(SpritesPixelIn PSIn)
{ 
    PixelToFrame Output = (PixelToFrame)0;    

    #ifdef XBOX
		float2 texCoord = abs(PSIn.TexCoord.zw);
    #else
		float2 texCoord = PSIn.TexCoord.xy;
    #endif

    Output.Color = tex2D(TextureSampler, texCoord);
    
    return Output;
}

technique PointSprites_2_0
{
	pass Pass0
	{   
		PointSpriteEnable = true;
		VertexShader = compile vs_2_0 PointSpritesVS();
		PixelShader  = compile ps_2_0 PointSpritesPS();
	}
}

technique PointSprites
{
	pass Pass0
	{   
		PointSpriteEnable = true;
		VertexShader = compile vs_1_1 PointSpritesVS();
		PixelShader  = compile ps_1_1 PointSpritesPS();
	}
}









Can anybody see what I am doing wrong for the point sprites to be drawn as pixels. The pixels aren't all the same color either. The texture that I am using is red and yellow, so there are both red and yellow pixels. Setting the RenderState.PointSpriteEnable to false (and commenting out PointSpriteEnable = true from the effect file technique) draws all of the pixels as yellow. Also, declaring mcGame.GraphicsDevice.RenderState.PointSize = 128; also does not have any effect, if that's a helpful clue. Any ideas or suggestions would be appreciated. Thanks.

Share this post


Link to post
Share on other sites
Advertisement
I found the problem; it was in Riemer's vertex shader. He has:
Output.Size = 1/(pow(Output.Position.z,2)+1) * Size;
but I think he meant to put:
Output.Size = (1/pow(Output.Position.z,2)+1) * Size;
so everything is working now.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!