Jump to content

  • Log In with Google      Sign In   
  • Create Account

Opt7ons

Member Since 17 Apr 2008
Offline Last Active Yesterday, 01:49 PM

Topics I've Started

DirectX 9 Instancing (with SharpDX)

11 July 2012 - 08:48 AM

I am having some trouble getting instancing to work with DX9 and Sharpdx.

My test triangle appears only in the first frame and then it disappears or fails to render for every loop after the first.

Here is what I have currently:


	 [StructLayout(LayoutKind.Sequential)]
	public struct VertexPositionColor
	{
		public Vector4 Position;
		public int Color;

		public VertexPositionColor(Vector4 position, int color)
		{
			this.Position = position;
			this.Color = color;
		}
	}

	public class Program
	{
		public static void Main(String[] args)
		{
			RenderForm form = new RenderForm("SharpDXTest Window");
			Direct3D d3d = new Direct3D();
			Device device = new Device(d3d, 0, DeviceType.Hardware, form.Handle, CreateFlags.HardwareVertexProcessing,
				new PresentParameters(form.ClientSize.Width, form.ClientSize.Height));

			device.SetRenderState(RenderState.Lighting, false);
			device.SetRenderState<Cull>(RenderState.CullMode, Cull.None);

			var effect = Effect.FromFile(device, "MiniCube.fx", ShaderFlags.None);
			var technique = effect.GetTechnique(0);
			var pass = effect.GetPass(technique, 0);

			// Prepare the vertex declaration
			var vertexElems = new[] {
		 new VertexElement(0, 0, DeclarationType.Float4, DeclarationMethod.Default, DeclarationUsage.Position, 0),
		 new VertexElement(0, 12, DeclarationType.Color, DeclarationMethod.Default, DeclarationUsage.Color, 0),
				new VertexElement(1, 0,  DeclarationType.Float4, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate,  1),
				new VertexElement(1, 16, DeclarationType.Float4, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate,  2),
				new VertexElement(1, 32, DeclarationType.Float4, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate,  3),
				new VertexElement(1, 48, DeclarationType.Float4, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate,  4),
VertexElement.VertexDeclarationEnd
		 };
			var vertexDecl = new VertexDeclaration(device, vertexElems);

			// Prepare matrices
			var view = Matrix.LookAtRH(new Vector3(0, 0, 10), new Vector3(0, 0, 0), Vector3.UnitY);
			var proj = Matrix.OrthoRH(form.ClientSize.Width, form.ClientSize.Height, 0.1f, 1000000000.0f);
			device.SetRenderState(RenderState.Lighting, false);
			device.SetRenderState<Cull>(RenderState.CullMode, Cull.None);
			effect.SetValue("proj", proj);
			effect.SetValue("view", view);

			VertexBuffer vertices = new VertexBuffer(device, 3 * 20, Usage.WriteOnly, VertexFormat.None, Pool.Managed);
			vertices.Lock(0, 0, LockFlags.None).WriteRange(new[] {
				new VertexPositionColor() {Position = new Vector4(0, 0, 1.0f, 1), Color = Color.Red.ToArgb()},
				new VertexPositionColor() {Position = new Vector4(110, 110, 1.0f, 1), Color = Color.Red.ToArgb()},
				new VertexPositionColor() {Position = new Vector4(110, 0, 1.0f, 1), Color = Color.Red.ToArgb()},
			});
			vertices.Unlock();

			Matrix mat = Matrix.Identity;
			//mat.Transpose();
			VertexBuffer instances = new VertexBuffer(device, 1 * 64, Usage.WriteOnly, VertexFormat.None, Pool.Managed);
			instances.Lock(0, 0, LockFlags.None).WriteRange(new[] {
				mat
			});
			instances.Unlock();

			IndexBuffer indices = new IndexBuffer(device, 6, Usage.WriteOnly, Pool.Managed, true);
			indices.Lock(0, 0, LockFlags.None).WriteRange(new short[] {
				(short)0, (short)1, (short)2,
			});
			indices.Unlock();

			var world = Matrix.Translation(100, 100, 0);

			effect.Technique = technique;
			effect.SetValue("proj", proj);
			effect.SetValue("view", view);
			effect.SetValue("world", world);

			RenderLoop.Run(form, () =>
			{
				device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, (Color4)Color.CornflowerBlue, 1.0f, 0);

				device.BeginScene();

				effect.Begin(0);
				effect.BeginPass(0);

				effect.SetValue("proj", proj);
				effect.SetValue("view", view);
				effect.SetValue("world", world);
				device.SetStreamSourceFrequency(0, 3, StreamSource.IndexedData);
				device.SetStreamSource(0, vertices, 0, 20);
				device.SetStreamSourceFrequency(1, 1, StreamSource.InstanceData);
				device.SetStreamSource(1, instances, 0, 64);
				
				device.VertexDeclaration = vertexDecl;
				device.Indices = indices;

				device.DrawIndexedPrimitive(PrimitiveType.TriangleList, 0, 0, 3, 0, 1);

				device.ResetStreamSourceFrequency(0);
				device.ResetStreamSourceFrequency(1);

				effect.EndPass();

				effect.End();

				device.EndScene();
				device.Present();
			});
		}


and the shader:

float4x4 world;
float4x4 proj;
float4x4 view;

sampler2D mySampler
{
	MinFilter = Point;
	MagFilter = Point;
};

struct VS_IN
{
float4 pos : POSITION0;
	float4 tex : COLOR0;
	float4 W0 : TEXCOORD0;
	float4 W1 : TEXCOORD1;
	float4 W2 : TEXCOORD2;
	float4 W3 : TEXCOORD3;
};

struct PS_IN
{
	float4 tex : COLOR0;
float4 pos : POSITION0;
};

PS_IN VS( VS_IN input )
{
	//float4x4 wor = float4x4(input.W0, input.W1, input.W2, float4(input.W3.xyz, 1.0f));
	//float4x4 objectworld = mul(wor, world);
	float4x4 worldViewProj = mul(world, mul(view, proj));

PS_IN output = (PS_IN)0;

output.pos = mul(input.pos, worldViewProj);
	output.tex = input.tex;

return output;
}

float4 PS( PS_IN input ) : COLOR
{
	float4 output = input.tex;
	output.a=1;
	output.r=1;
	//output = tex2D(mySampler, input.tex);
return output;
}

technique Main
{
pass P0
	{
VertexShader = compile vs_3_0 VS();
		PixelShader  = compile ps_3_0 PS();
}
}

Any help appreciated Posted Image.

XNA Lighting and Normals

22 June 2008 - 10:17 PM

Hi,

Well, I've been trying to get this working for the last two hours and just can't figure it out. Basically I have generated terrain with a height map and generated normals for it. The terrain shows but I can't get any lighting to work. I havn't sorted out texture coordinates but that shouldn't be the problem (I have tested with lighting off and the colors show etc).

Heres what I have so far (partially based off Reimers tutorials)

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;


namespace CotD
{
    struct MyOwnVertexFormat
    {
        private Vector3 position;
        private Vector2 texCoord;
        private Vector3 normal;

        public MyOwnVertexFormat(Vector3 newPosition, Vector2 newTexCoord, Vector3 newNormal)
        {
            position = newPosition;
            texCoord = newTexCoord;
            normal = newNormal;
        }

        public Vector3 getNormal()
        {
            return normal;
        }

        public Vector3 getPosition()
        {
            return position;
        }

        public void setNormal(Vector3 newNormal)
        {
            normal += newNormal;
            normal.Normalize();
        }

        public static VertexElement[] VertexElements =
        {
            new VertexElement(
                0, 
                0, 
                VertexElementFormat.Vector3, 
                VertexElementMethod.Default, 
                VertexElementUsage.Position, 
                0),
            new VertexElement(
                0, 
                sizeof(float)*3, 
                VertexElementFormat.Vector2, 
                VertexElementMethod.Default, 
                VertexElementUsage.TextureCoordinate, 
                0),
            new VertexElement(
                0, 
                sizeof(float)*5, 
                VertexElementFormat.Vector3, 
                VertexElementMethod.Default, 
                VertexElementUsage.Normal, 
                0),
        };

        public static int SizeInBytes = sizeof(float) * (3 + 2+ 3);
    }

    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        GraphicsDevice device;

        Effect effect;
        Matrix viewMatrix;
        Matrix projectionMatrix;

        // Create buffers
        VertexBuffer vertexBuffer;
        IndexBuffer indexBuffer;

        MyOwnVertexFormat[] vertices;
        int[] indices;

        VertexDeclaration vertexDeclaration;
        Vector3 cameraPos;

        Texture2D streetTexture;

        private float[,] heightData;
        private int terrainWidth = 4;
        private int terrainHeight = 3;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            graphics.PreferredBackBufferWidth = 500;
            graphics.PreferredBackBufferHeight = 500;
            graphics.IsFullScreen = false;
            graphics.ApplyChanges();
            Window.Title = "Terrain Test";

            base.Initialize();
        }

        protected override void LoadContent()
        {
            device = GraphicsDevice;

            effect = Content.Load<Effect>("Effects/CustomEffect");

            streetTexture = Content.Load<Texture2D>("Textures/streettexture");

            Texture2D heightMap = Content.Load<Texture2D>("Textures/heightmap");
            LoadHeightData(heightMap);

            SetUpVertices();
            SetUpIndices();
            
            SetUpCamera();

            CalculateNormals();
        }

        private void LoadHeightData(Texture2D heightMap)
        {
            terrainWidth = heightMap.Width;
            terrainHeight = heightMap.Height;

            Color[] heightMapColors = new Color[terrainWidth * terrainHeight];
            heightMap.GetData(heightMapColors);

            heightData = new float[terrainWidth, terrainHeight];
            for (int x = 0; x < terrainWidth; x++)
                for (int y = 0; y < terrainHeight; y++)
                    heightData[x, y] = heightMapColors[x + y * terrainWidth].R / 5.0f;
        }

        private void SetUpVertices()
        {
            vertices = new MyOwnVertexFormat[terrainWidth * terrainHeight];
            for (int x = 0; x < terrainWidth; x++)
            {
                for (int y = 0; y < terrainHeight; y++)
                {
                    vertices[x + y * terrainWidth] = new MyOwnVertexFormat(
                        new Vector3(x, heightData[x, y], -y),
                        new Vector2(0, 0), 
                        new Vector3(0, 0, 0)); 
                }
            }

            vertexBuffer = new VertexBuffer(device, vertices.Length * MyOwnVertexFormat.SizeInBytes, BufferUsage.WriteOnly);
            vertexBuffer.SetData(vertices);

            vertexDeclaration = new VertexDeclaration(device, MyOwnVertexFormat.VertexElements);
        }

        private void CalculateNormals()
        {
            for (int i = 0; i < indices.Length / 3; i++)
            {
                int index1 = indices[i * 3];
                int index2 = indices[i * 3 + 1];
                int index3 = indices[i * 3 + 2];

                Vector3 side1 = vertices[index1].getPosition() - vertices[index3].getPosition();
                Vector3 side2 = vertices[index1].getPosition() - vertices[index2].getPosition();
                Vector3 normal = Vector3.Cross(side1, side2);

                vertices[index1].setNormal(normal);
                vertices[index2].setNormal(normal);
                vertices[index3].setNormal(normal);
            }
        }

        private void SetUpIndices()
        {
            indices = new int[(terrainWidth - 1) * (terrainHeight - 1) * 6];
            int counter = 0;
            for (int y = 0; y < terrainHeight - 1; y++)
            {
                for (int x = 0; x < terrainWidth - 1; x++)
                {
                    int lowerLeft = x + y * terrainWidth;
                    int lowerRight = (x + 1) + y * terrainWidth;
                    int topLeft = x + (y + 1) * terrainWidth;
                    int topRight = (x + 1) + (y + 1) * terrainWidth;

                    indices[counter++] = topLeft;
                    indices[counter++] = lowerRight;
                    indices[counter++] = lowerLeft;

                    indices[counter++] = topLeft;
                    indices[counter++] = topRight;
                    indices[counter++] = lowerRight;
                }
            }

            indexBuffer = new IndexBuffer(device, typeof(int), indices.Length, BufferUsage.WriteOnly);
            indexBuffer.SetData(indices);

            device.Indices = indexBuffer;
        }

        private void SetUpCamera()
        {
            cameraPos = new Vector3(10, 200, 40);
            viewMatrix = Matrix.CreateLookAt(cameraPos, new Vector3(0, 2, -2), new Vector3(0, 1, 0));
            projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, device.Viewport.AspectRatio, 1.0f, 2000.0f);
        }


        protected override void UnloadContent()
        {
        }

        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.DarkSlateBlue, 1.0f, 0);
            //device.RenderState.FillMode = FillMode.WireFrame;

            Matrix worldMatrix = Matrix.CreateTranslation(-terrainWidth / 2.0f, 0, terrainHeight / 2.0f);
            effect.CurrentTechnique = effect.Techniques["Simplest"];
            effect.Parameters["xTexture"].SetValue(streetTexture);
            effect.Parameters["xViewProjection"].SetValue(viewMatrix * projectionMatrix);
            effect.Parameters["xWorld"].SetValue(worldMatrix);


            effect.Parameters["xEnableLighting"].SetValue(true);
            effect.Parameters["xLightDirection"].SetValue(new Vector3(-0.5f, -0.5f, -1));
            effect.Parameters["xAmbient"].SetValue(0.1f);

            effect.Begin();
            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                pass.Begin();
                device.VertexDeclaration = vertexDeclaration;

                device.Vertices[0].SetSource(vertexBuffer, 0, MyOwnVertexFormat.SizeInBytes);
                device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, vertices.Length, 0, indices.Length / 3);


                pass.End();
            }
            effect.End();

            base.Draw(gameTime);
        }
    }
}

And the effect file

//------- Constants --------
float4x4 xViewProjection;
float4x4 xWorld;
float3 xLightDirection;
float xAmbient;
bool xEnableLighting;

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

Texture xTexture;

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

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

struct TexVertexToPixel
{
    float4 Position         : POSITION;    
    float4 Color            : COLOR0;
    float3 Normal            : TEXCOORD0;
    float2 TextureCoords    : TEXCOORD1;
    float4 LightDirection    : TEXCOORD2;

};

struct TexPixelToFrame
{
    float4 Color : COLOR0;
};

TexVertexToPixel TexturedVS( float4 inPos : POSITION, float3 inNormal: NORMAL, float2 inTexCoords: TEXCOORD0)
{
    TexVertexToPixel Output = (TexVertexToPixel)0;
    float4x4 preWorldViewProjection = mul (xWorld, xViewProjection);
    
    Output.Position = mul(inPos, preWorldViewProjection);
    Output.Normal = mul(normalize(inNormal), xWorld);
    Output.TextureCoords = inTexCoords;
    Output.LightDirection.xyz = -xLightDirection;
    Output.LightDirection.w = 1;
    
    return Output;    
}

TexPixelToFrame TexturedPS(TexVertexToPixel PSIn)
{
    TexPixelToFrame Output = (TexPixelToFrame)0;
    
    float lightingFactor = 1;
    if (xEnableLighting)
        lightingFactor = saturate(saturate(dot(PSIn.Normal, PSIn.LightDirection)) + xAmbient);

    Output.Color = tex2D(TextureSampler, PSIn.TextureCoords)*lightingFactor;

    return Output;
}


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

Any help apreciated.

PARTNERS