XNA Game Development Forums
2012/05/18 06:14:13 *
Welcome, Guest. Please login or register.

Login with username, password and session length
 
   Home   Help Search Calendar Login Register  
Pages: [1]
  Print  
Author Topic: Strange Problem ( Advice/Assistance Needed Please :-) )  (Read 1778 times)
DaphydTheBard
Jr. Member
**
Offline Offline

Posts: 55


View Profile
« on: 2007/02/28 05:49:30 »

This is really bizzare.

I have 2 point sprites, one at (0,0,0) and the other at (0,0,1).

The first one is red, the second blue.  The are both being rendered to the screen as textured quads, that face the camera (point sprites).

The red one is being rendered first, then the blue one second.



As you can see, this looks cool, and everything is working as expected.

However, if I then fly my ship round the other side of the sprites, I get this:



With the red quad "obscuring" the blue one, but nothing else in the scene.

How can I get around this bizzare problem?  I'm guessing it's something to do with the Z-Buffer - but I don't know how to turn it on/off.

My Textured Quad Handler, in case this is of any help.

Code:

#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 XNAHandler_TexturedQuad
    {
        private GraphicsDevice objDevice = null;
        private XNAViewPort objViewPort = null;
        private Effect objEffect;       
        private VertexBuffer myVertices;
        private IndexBuffer myIndices;

        public XNAHandler_TexturedQuad(ref XNAGame XNAGame, ref XNAViewPort XNAViewPort)
        {
            objDevice = XNAGame.Device;
            objViewPort = XNAViewPort;
            objEffect = XNAGame.Content.Load<Effect>(FolderHelper.ShadersFolder() + "TexturedQuad");

            VertexPositionTexture[] verts = {
        new VertexPositionTexture(new Vector3(-0.5f, 0.5f, 0), new Vector2(0, 0)),
        new VertexPositionTexture(new Vector3(0.5f, 0.5f, 0), new Vector2(1, 0)),
        new VertexPositionTexture(new Vector3(-0.5f, -0.5f, 0), new Vector2(0, 1)),
        new VertexPositionTexture(new Vector3(0.5f, -0.5f, 0), new Vector2(1, 1))};

            int[] inds = { 0, 1, 2, 1, 3, 2 };

            myVertices = new VertexBuffer(XNAGame.Device,
                   typeof(VertexPositionTexture), 4,
                   ResourceUsage.WriteOnly,
                   ResourceManagementMode.Automatic);

            myVertices.SetData<VertexPositionTexture>(verts, 0, 4, SetDataOptions.None);

            myIndices = new IndexBuffer(objDevice, typeof(int), 6,
                ResourceUsage.WriteOnly, ResourceManagementMode.Automatic);

            myIndices.SetData<int>(inds, 0, 6, SetDataOptions.None);
        }

        public void Render(ref XNAObject obj, Texture2D tex, Vector3 lookat)
        {
            XNAObject o = new XNAObject();
            o.Position = obj.Position;
            o.Rotation = obj.Rotation;
            o.LookAt(lookat, 1.0f);
            o.PitchDown(180.0f);
            Render(ref o, tex);
           
        }

        public void Render(ref XNAObject obj, Texture2D tex)
        {

            objEffect.CurrentTechnique = objEffect.Techniques["TransformTexture"];

            objEffect.Parameters["WorldViewProject"].SetValue(Matrix.CreateScale(obj.Scale)
                * Matrix.CreateFromQuaternion(obj.Rotation)
                * Matrix.CreateTranslation(obj.Position) *
                objViewPort.MatrixView *
                objViewPort.MatrixProjection);

            objEffect.Begin();
            foreach (EffectPass pass in objEffect.CurrentTechnique.Passes)
            {
                pass.Begin();
                using (VertexDeclaration declaration = new VertexDeclaration(objDevice, VertexPositionTexture.VertexElements))
                {

                    objDevice.VertexDeclaration = declaration;
                    objDevice.Textures[0] = tex;
                    objDevice.Vertices[0].SetSource(myVertices, 0, VertexPositionTexture.SizeInBytes);
                    objDevice.Indices = myIndices;
                    objDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 4, 0, 2);
                   
                }
                pass.End();
            }

            objEffect.End(); 

        }
    }
}


And here's the Shader I'm using:

Code:

float4x4 WorldViewProject;
sampler TextureSampler;

struct VS_INPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;
};

struct VS_OUTPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;
};

VS_OUTPUT Transform(VS_INPUT Input)
{
VS_OUTPUT Output;

Output.Position = mul(Input.Position, WorldViewProject);
Output.Texcoord = Input.Texcoord;

return Output;
}

struct PS_INPUT
{
float2 Texcoord : TEXCOORD0;
};

float4 Texture(PS_INPUT Input) : COLOR0
{
return tex2D(TextureSampler, Input.Texcoord);
};

technique TransformTexture
{
pass P0
{
VertexShader = compile vs_2_0 Transform();
PixelShader  = compile ps_2_0 Texture();
}
}


Any help appreciated....

UPDATE:

I've noticed that I can turn off the depth buffer at shader level by adding the following line to my pass:

ZENABLE = FALSE;

However, this means that point sprites that should appear behind other objects, don't.  Wink

I've also noted that if I render the two point sprites the other way round, then the reverse happens.  I.e. when the game first starts, the sprites appear obscured, and then moving round the other side makes it look normal again.

 Embarrassed
« Last Edit: 2007/02/28 05:55:29 by DaphydTheBard » Logged
mikeschuld
Administrator
Sr. Member
*****
Offline Offline

Posts: 389


View Profile WWW
« Reply #1 on: 2007/02/28 08:00:40 »

You have to depth sort the point sprites every frame to get this to work. Depth is based on their distance from the camera. Farther away sprites MUST be rendered first for the alpha blending to work correctly.
Logged
DaphydTheBard
Jr. Member
**
Offline Offline

Posts: 55


View Profile
« Reply #2 on: 2007/02/28 08:11:34 »

Thanks Mike

I thought as much.  Sad

I've been experimenting today with various other possible solutions, but to no avail.  I've tried disabling the DepthBuffer whilst rendering the sprites, and then enabling it again for the rest of the scene.  This however produced unwanted results as the the sprites were always "on top of" everything else.

Hmmm...looks like I'll have to have a re-think about my engine structure.  Thanks for clarifying this for me Mike.
Logged
Tiago
Newbie
*
Offline Offline

Posts: 42


View Profile
« Reply #3 on: 2007/03/08 22:14:09 »

are there any prefered ways for sorting those objects? i mean, should a quick-sort be used (i gess bubble sort would nt be a good idea) or is there a special way to handle that sorting?
Logged
DaphydTheBard
Jr. Member
**
Offline Offline

Posts: 55


View Profile
« Reply #4 on: 2007/03/17 10:23:52 »

I've sussed this out now, and got it implemented and working.

Here's my complete Textured Quad code, in case it's of any use to anyone.  It has three classes, a TexturedQuad class, a TexturedQuadManager, and a TexturerQuadRenderer (which does the sorting):

Code:
#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
{
    /// <summary>
    /// Textured Quad Object - Manager
    /// </summary>
    public class XNATexturedQuadManager
    {
        #region Variables

        protected Dictionary<string, XNATexturedQuad> objDictionary = new Dictionary<string, XNATexturedQuad>();
        protected XNATexturedQuad[] objItems = new XNATexturedQuad[1];
        protected int pItemCount = 0;

        public void Create(string objKey)
        {
            pItemCount++;
            objItems = (XNATexturedQuad[])ArrayHelper.ReDimPreserve(objItems, pItemCount);
            objItems[pItemCount - 1] = new XNATexturedQuad();
            objDictionary.Add(objKey, objItems[pItemCount - 1]);
        }

        public void Remove(string objKey)
        {
            int i = 0;
            foreach (KeyValuePair<string, XNATexturedQuad> kvp in objDictionary)
            {
                if (kvp.Key == objKey)
                {
                    objDictionary.Remove(objKey);
                    ArrayHelper.RemoveElement(objItems, i);
                    return;
                }
                i++;
            }
        }

        public XNATexturedQuad Item(string objKey)
        {
            if (objDictionary.ContainsKey(objKey) == true)
            { return objDictionary[objKey]; }
            else { return null; }
        }

        public XNATexturedQuad Item(int index)
        {
            if (index <= objItems.GetUpperBound(0))
            { return objItems[index]; }
            else { return null; }
        }

        #endregion
    }

    /// <summary>
    /// Textured Quad Object
    /// </summary>
    public class XNATexturedQuad : XNAObject
    {
        private string textureID;
        private bool faceCamera;

        /// <summary>
        /// The Colour to be used for Alpha-Blending
        /// </summary>
        private Color blendColour = new Color(255, 255, 255);

        public string TextureID
        {
            get { return textureID; }
            set { textureID = value; }
        }

        public bool FaceCamera
        {
            get { return faceCamera; }
            set { faceCamera = value; }
        }

        /// <summary>
        /// The Colour to be used for Alpha-Blending
        /// </summary>
        public Color BlendColour
        {
            get { return blendColour; }
            set { blendColour = value; }
        }
    }

    /// <summary>
    /// Textured Quad Object - Renderer
    /// </summary>
    public class XNATexturedQuadRenderer
    {
        private XNAGame objGame = null;
        private GraphicsDevice objDevice = null;
        private XNATexture2DManager objTextureManager = null;
        private XNATexturedQuadManager objTexturedQuadManager = null;
        private XNAViewPort objViewPort = null;
        private XNACamera objCamera = null;
        private Effect objEffect;       
        private VertexBuffer myVertices;
        private IndexBuffer myIndices;

        private float[] fDistance = new float[1];
        private string[] texturedQuadID = new string[1];
        protected int pItemCount = 0;

        public XNATexturedQuadRenderer(ref XNAGame XNAGame, ref XNAViewPort XNAViewPort, ref XNACamera xnaCamera, ref XNATexture2DManager xnaTexture2DManager, ref XNATexturedQuadManager xnaTexturedQuadManager)
        {
            objGame = XNAGame;
            objDevice = XNAGame.Device;
            objViewPort = XNAViewPort;
            objCamera = xnaCamera;
            objTextureManager = xnaTexture2DManager;
            objTexturedQuadManager = xnaTexturedQuadManager;
            objEffect = XNAGame.Content.Load<Effect>(FolderHelper.ShadersFolder() + "TexturedQuad");

            VertexPositionTexture[] verts = {
        new VertexPositionTexture(new Vector3(-0.5f, 0.5f, 0), new Vector2(0, 0)),
        new VertexPositionTexture(new Vector3(0.5f, 0.5f, 0), new Vector2(1, 0)),
        new VertexPositionTexture(new Vector3(-0.5f, -0.5f, 0), new Vector2(0, 1)),
        new VertexPositionTexture(new Vector3(0.5f, -0.5f, 0), new Vector2(1, 1))};

            int[] inds = { 0, 1, 2, 1, 3, 2 };

            myVertices = new VertexBuffer(XNAGame.Device,
                   typeof(VertexPositionTexture), 4,
                   ResourceUsage.WriteOnly,
                   ResourceManagementMode.Automatic);

            myVertices.SetData<VertexPositionTexture>(verts, 0, 4, SetDataOptions.None);

            myIndices = new IndexBuffer(objDevice, typeof(int), 6,
                ResourceUsage.WriteOnly, ResourceManagementMode.Automatic);

            myIndices.SetData<int>(inds, 0, 6, SetDataOptions.None);
        }

        public void QueueClear()
        {
            pItemCount = 0;
        }

        public void QueueAdd(string objKey)
        {
            pItemCount++;
            fDistance = (float[])ArrayHelper.ReDimPreserve(fDistance, pItemCount);
            texturedQuadID = (string[])ArrayHelper.ReDimPreserve(texturedQuadID, pItemCount);
            fDistance[pItemCount - 1] = 0.0f;
            texturedQuadID[pItemCount - 1] = objKey;           
        }

        public void RenderQueue()
        {
            if (pItemCount == 0) return;

            Color tempCol = objGame.BlendColour;

            for (int i = 0; i <= texturedQuadID.GetUpperBound(0); i++)
            { fDistance[i] = Vector3.Distance(objTexturedQuadManager.Item(texturedQuadID[i]).Position, objCamera.Position); }
            Array.Sort(fDistance, texturedQuadID);

            for (int i = texturedQuadID.GetUpperBound(0); i >= 0; i--)
            {
                objGame.BlendColour = objTexturedQuadManager.Item(texturedQuadID[i]).BlendColour;
                Render(objTexturedQuadManager.Item(texturedQuadID[i]));
            }

            objGame.BlendColour = tempCol;
        }

        public void Render(XNATexturedQuad obj)
        {
            XNAObject o = new XNAObject();
            o.Position = obj.Position;
            o.Rotation = obj.Rotation;
            o.Scale = obj.Scale;
           
            if (obj.FaceCamera == true)
            {
                o.LookAt(objCamera.Position, 1.0f);
                o.PitchDown(180.0f);
            }

            objEffect.CurrentTechnique = objEffect.Techniques["Default"];

            objEffect.Parameters["WorldViewProject"].SetValue(Matrix.CreateScale(o.Scale)
                * Matrix.CreateFromQuaternion(o.Rotation)
                * Matrix.CreateTranslation(o.Position) *
                objViewPort.MatrixView *
                objViewPort.MatrixProjection);

            objEffect.Begin();
            foreach (EffectPass pass in objEffect.CurrentTechnique.Passes)
            {
                pass.Begin();
                using (VertexDeclaration declaration = new VertexDeclaration(objDevice, VertexPositionTexture.VertexElements))
                {

                    objDevice.VertexDeclaration = declaration;
                    objDevice.Textures[0] = objTextureManager.Item(obj.TextureID);
                    objDevice.Vertices[0].SetSource(myVertices, 0, VertexPositionTexture.SizeInBytes);
                    objDevice.Indices = myIndices;
                    objDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 4, 0, 2);
                   
                }
                pass.End();
            }

            objEffect.End(); 

        }
    }
}

And, here's my ArrayHelper Class:

Code:
#region Using Directives

using System;
using System.Collections.Generic;
using System.Text;

#endregion

namespace XNACore.Helpers
{
    public static class ArrayHelper
    {
        /// <summary>
        /// Re-dimensions an Array, and preserves existing Elements
        /// Example:
        /// a=(int[])ArrayHelper.ReDimArrayPreserve(a, 32);
        /// </summary>       
        public static Array ReDimPreserve(Array input, int size)
        {
            Array result = (Array)Activator.CreateInstance(input.GetType(), new object[] { size });
            Array.Copy(input, result, Math.Min(input.Length, result.Length));
            return result;           
        }

        /// <summary>
        /// Removes an Array Element and resizes the Array automatically
        /// </summary>
        /// <param name="input"></param>
        /// <param name="element"></param>
        /// <returns></returns>
        public static Array RemoveElement(Array input, int element)
        {
            for (int k = element; k < input.GetUpperBound(0); k++)
            {
                input.SetValue(input.GetValue(k + 1), k);
            }
            return ReDimPreserve(input, input.GetUpperBound(0));

        }


    }
}
Logged
Pages: [1]
  Print  
 
Jump to:  

Related Topics
Subject Started by Replies Views Last post
Got a problem with an .x file Hazy Mind XNA Engine bobbie_dache 8 2784 Last post 2007/01/16 12:26:30
by bobbie_dache
Animations! But one problem... Hazy Mind XNA Engine EclipsE 2 1412 Last post 2007/04/12 02:42:27
by EclipsE
tutorial 4 problem Hazy Mind 3D Engine precious roy 3 2495 Last post 2007/08/03 12:24:26
by mikeschuld
Interface problem. Help!! General Discussion XNASorcerer 5 2111 Last post 2007/05/09 09:46:36
by CarlosFreitas
ObjectManagers problem Hazy Mind XNA Engine Jonotron 1 1339 Last post 2007/08/03 12:29:19
by mikeschuld
Camera problem Hazy Mind XNA Engine Montynis 2 1685 Last post 2007/08/02 09:54:14
by Montynis
Problem with the pick Hazy Mind 3D Engine Zandman26 0 1420 Last post 2007/08/06 15:04:06
by Zandman26
Post Tutorial 8 - advice needed! Hazy Mind XNA Engine solthar 5 2241 Last post 2008/09/03 20:47:57
by solthar
Powered by MySQL Powered by PHP Powered by SMF 1.1.12 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Page created in 0.278 seconds with 18 queries.