Jump to content


non-FVF VertexBuffer [MDX]


5 replies to this topic

#1 alexndr

    New Member

  • Members
  • PipPip
  • 28 posts

Posted 31 May 2006 - 06:59 PM

How to create Mesh with non-FVF VertexBuffer on Managed DirectX?

10% luck, 20% skill, 15% concentrated power of will, 5% pleasure, 50% pain
and 100% reason to remember the name

My Weblog "Project Delta" » http://project-delta.blogspot.com/

#2 Mjolnir

    Member

  • Members
  • PipPip
  • 42 posts

Posted 01 June 2006 - 09:18 AM

You could use vertex declarations - an even more flexible method (I think FVF is actually internally converted to a vd). You can describe a vd by declaring an array of VertexElement - each one of them used for a component of a vertex.

For example:

private static readonly VertexElement[] elements = new VertexElement[] 

{

	new VertexElement(0, 0,  DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0), 

	new VertexElement(0, 12, DeclarationType.Color, DeclarationMethod.Default, DeclarationUsage.Color, 0),

	VertexElement.VertexDeclarationEnd // must end with this

};


// Helper struct:

public struct MyVD

{

	public float X, Y, Z;

	public int Color;

	public MyVD( float X, float Y, float Z, int Color )

	{

		this.X = X; this.Y = Y; this.Z = Z; this.Color = Color;

	}

}


Then:

Mesh mesh = new Mesh(numberVerts * 3, numberVerts, MeshFlags.Managed, elements, device);


using (VertexBuffer vb = mesh.VertexBuffer)

{

	GraphicsStream data = vb.Lock(0, 0, LockFlags.None);

		

	data.Write(new MyVD(-1.0f, 1.0f, 1.0f, 0x00ff0000));

	...

	data.Write(new MyVD(1.0f, -1.0f, -1.0f, 0x00ff0000));


	vb.Unlock();

}


using (IndexBuffer ib = mesh.IndexBuffer)

{

	ib.SetData(indices, 0, LockFlags.None); // indices set somewhere

}



#3 alexndr

    New Member

  • Members
  • PipPip
  • 28 posts

Posted 01 June 2006 - 10:58 AM

Actually, I tried vertex declaration, but it didn't help (MDX v2.0):


VertexElement[] elements = new VertexElement[] {

	new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0), 

	new VertexElement(0, 12, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Normal, 0), 

	new VertexElement(0, 24, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0), 

	VertexElement.VertexDeclarationEnd };


dxDevice.VertexDeclaration = new VertexDeclaration(dxDevice, elements);

dxDevice.VertexFormat = VertexFormats.None;


dxMesh = new Mesh(dxDevice, d3dfile.TotalFaces, d3dfile.Vertices.Count, MeshFlags.Managed, elements);


The result will be (look at FVF):

Quote

Call: DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
BaseVertexIndex: 0,
MinVertexIndex: 0,
NumVertices: 16641,
startIndex: 0,
primCount: 32768)


*********************************************
Vertex Declaration
*********************************************

Stream: 0, Offset: 0, Type: D3DDECLTYPE_FLOAT3,
Method: D3DDECLMETHOD_DEFAULT,
Usage: D3DDECLUSAGE_POSITION,
UsageIndex: 0

Stream: 0, Offset: 12, Type: D3DDECLTYPE_FLOAT3,
Method: D3DDECLMETHOD_DEFAULT,
Usage: D3DDECLUSAGE_NORMAL,
UsageIndex: 0

Stream: 0, Offset: 24, Type: D3DDECLTYPE_FLOAT2,
Method: D3DDECLMETHOD_DEFAULT,
Usage: D3DDECLUSAGE_TEXCOORD,
UsageIndex: 0

Total elements: 4


*********************************************
FVF
*********************************************

FVF = D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1


*********************************************
Vertex streams
*********************************************

StreamIndex: 3958160,
VertexBuffer: 0x04f74c60,
OffsetInBytes: 0,
Stride: 32,
Format: D3DFMT_VERTEXDATA,
Usage: 0,
Pool: D3DPOOL_MANAGED,
Size: 532512,
FVF: D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1


*********************************************
Index stream
*********************************************

IndexBuffer: 0x0024c040,
Format: D3DFMT_INDEX16,
Usage: 0,
Pool: D3DPOOL_MANAGED,
Size: 196608


10% luck, 20% skill, 15% concentrated power of will, 5% pleasure, 50% pain
and 100% reason to remember the name

My Weblog "Project Delta" » http://project-delta.blogspot.com/

#4 Mjolnir

    Member

  • Members
  • PipPip
  • 42 posts

Posted 02 June 2006 - 10:51 AM

Unless you've solved the problem in the meantime, check a bit of this code. I got something running with your vertex specs (though I'm not quite sure what was the issue initially).


using System;

using System.Drawing;

using System.Windows.Forms;

using Microsoft.DirectX;

using Microsoft.DirectX.Direct3D;

using Microsoft.DirectX.Generic;


namespace SpinningSquare

{

    public class SpinningSquare : Form

    {

        const int numberVerts = 6;        


        Device device = null;

        PresentParameters presentParams = new PresentParameters();

        VertexDeclaration vertexDecl = null;

        bool pause = false;

        Mesh mesh = null;

        Texture texture = null;


        private static readonly VertexElement[] elements = new VertexElement[] 

        {

	        new VertexElement(0, 0,  DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0), 

	        new VertexElement(0, 12, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Normal, 0), 

	        new VertexElement(0, 24, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0),	

	        VertexElement.VertexDeclarationEnd

        };


        public struct MyVD

        {

            public Vector3 Position;

            public Vector3 Normal;

            public float U, V;

        }


        public SpinningSquare()

        {

            this.ClientSize = new System.Drawing.Size(400, 300);

            this.Text = "Spinning Square - MDX 2.0";

        }


        public bool InitializeGraphics()

        {

            try

            {

                presentParams.IsWindowed = true;

                presentParams.SwapEffect = SwapEffect.Discard;

                presentParams.EnableAutoDepthStencil = true;

                presentParams.AutoDepthStencilFormat = DepthFormat.D24X8;

                device = new Device(0, DeviceType.Hardware, this.Handle, CreateFlags.SoftwareVertexProcessing, new PresentParameters[] { presentParams });

                device.DeviceReset += new System.EventHandler(this.OnResetDevice);

                this.OnCreateDevice(device, null);

                this.OnResetDevice(device, null);

                pause = false;

                return true;

            }

            catch ( DirectXException )

            {

                return false;

            }

        }


        public void OnCreateDevice( object sender, EventArgs e )

        {

            Device dev = (Device) sender;

            vertexDecl = new VertexDeclaration(dev, elements);


            mesh = new Mesh(device, 2, numberVerts, MeshFlags.Managed, elements);


            using ( VertexBuffer vb = mesh.VertexBuffer )

            {

                GraphicsBuffer<MyVD> data = vb.Lock<MyVD>(0, 0, LockFlags.None);


                MyVD[] verts = new MyVD[numberVerts];

                int i = 0;

                verts[i].Position = new Vector3(-1.0f, 0.0f, 1.0f);

                verts[i].Normal = new Vector3(0.0f, 1.0f, 0.0f);

                verts[i].U = 0.0f;

                verts[i++].V = 0.0f;


                verts[i].Position = new Vector3(1.0f, 0.0f, 1.0f);

                verts[i].Normal = new Vector3(0.0f, 1.0f, 0.0f);

                verts[i].U = 1.0f;

                verts[i++].V = 0.0f;


                verts[i].Position = new Vector3(1.0f, 0.0f, -1.0f);

                verts[i].Normal = new Vector3(0.0f, 1.0f, 0.0f);

                verts[i].U = 1.0f;

                verts[i++].V = 1.0f;


                verts[i].Position = new Vector3(-1.0f, 0.0f, 1.0f);

                verts[i].Normal = new Vector3(0.0f, 1.0f, 0.0f);

                verts[i].U = 0.0f;

                verts[i++].V = 0.0f;


                verts[i].Position = new Vector3(1.0f, 0.0f, -1.0f);

                verts[i].Normal = new Vector3(0.0f, 1.0f, 0.0f);

                verts[i].U = 1.0f;

                verts[i++].V = 1.0f;


                verts[i].Position = new Vector3(-1.0f, 0.0f, -1.0f);

                verts[i].Normal = new Vector3(0.0f, 1.0f, 0.0f);

                verts[i].U = 0.0f;

                verts[i++].V = 1.0f;


                data.Write(verts);


                vb.Unlock();

                data.Dispose();

            }


            using ( IndexBuffer ib = mesh.IndexBuffer )

            {

                GraphicsBuffer<short> gb = ib.Lock<short>(0, 0, LockFlags.None);


                short[] indices =

                {

                    0,1,2,

                    3,4,5

                };

                gb.Write(indices);


                ib.Unlock();

                gb.Dispose();

            }

        }

        public void OnResetDevice( object sender, EventArgs e )

        {

            Device dev = (Device) sender;

            dev.RenderState.CullMode = Cull.None;

            dev.RenderState.ZBufferEnable = true;

            dev.RenderState.ZBufferWriteEnable = true;

            dev.RenderState.Lighting = true;


            texture = new Texture(dev, "ball.dds");

        }


        private void Render()

        {

            if ( device == null )

                return;


            if ( pause )

                return;


            device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, System.Drawing.Color.Blue, 1.0f, 0);

            device.BeginScene();

                SetupLights();

                SetupMatrices();


                device.SetTextureState(0, TextureStates.ColorArgument1, (int) TextureArgument.Texture);

                device.SetTexture(0, texture);


                device.VertexDeclaration = vertexDecl;


                mesh.DrawSubset(0);

            device.EndScene();

            device.Present();

        }


        private void SetupMatrices()

        {

            device.Transform.World = Matrix.RotationAxis(new Vector3(1, 0, 0), Environment.TickCount / 200.0f);

            device.Transform.View = Matrix.LookAtLeftHanded(new Vector3(0.0f, 3.0f, -5.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));

            device.Transform.Projection = Matrix.PerspectiveFieldOfViewLeftHanded((float) Math.PI / 4.0f, 1.0f, 1.0f, 100.0f);

        }


        private void SetupLights()

        {

            Material material = new Material();

            material.DiffuseColor = ColorValue.FromColor(Color.White);

            material.AmbientColor = ColorValue.FromColor(Color.White);

            device.Material = material;


            device.Lights[0].LightType = LightType.Spot;

            device.Lights[0].Diffuse = Color.White;

            device.Lights[0].Range = 500f;

            device.Lights[0].Direction = new Vector3(0.0f, -1f, 0.0f);

            device.Lights[0].Position = new Vector3(0.0f, 5.0f, 0.0f);

            device.Lights[0].Falloff = 1f;

            device.Lights[0].InnerConeAngle = Geometry.DegreeToRadian(10.0f);

            device.Lights[0].OuterConeAngle = Geometry.DegreeToRadian(40.0f);

            device.Lights[0].Attenuation0 = 1f;

            device.Lights[0].Update();

            device.Lights[0].Enabled = true;                       


            device.RenderState.Ambient = Color.FromArgb(60, 60, 60);

        }


        protected override void OnPaint( System.Windows.Forms.PaintEventArgs e )

        {

            this.Render();

        }


        protected override void OnKeyPress( System.Windows.Forms.KeyPressEventArgs e )

        {

            if ( (int) (byte) e.KeyChar == (int) System.Windows.Forms.Keys.Escape )

                this.Close();

        }

        protected override void OnResize( System.EventArgs e )

        {

            pause = ((this.WindowState == FormWindowState.Minimized) || !this.Visible);

        }


        static void Main()

        {

            using ( SpinningSquare frm = new SpinningSquare() )

            {

                if ( !frm.InitializeGraphics() )

                {

                    MessageBox.Show("Could not initialize Direct3D.");

                    return;

                }


                frm.Show();


                while ( frm.Created )

                {

                    frm.Render();

                    Application.DoEvents();

                }

            }

        }

    }

}



#5 alexndr

    New Member

  • Members
  • PipPip
  • 28 posts

Posted 02 June 2006 - 07:49 PM

Mjolnir, can you check your application with any DX analyze tool? Because with the same code I get FVF vertexbuffer (FVF = D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1).

10% luck, 20% skill, 15% concentrated power of will, 5% pleasure, 50% pain
and 100% reason to remember the name

My Weblog "Project Delta" » http://project-delta.blogspot.com/

#6 Mjolnir

    Member

  • Members
  • PipPip
  • 42 posts

Posted 03 June 2006 - 10:48 AM

Ran it through PIX, says nothing about FVF, just the declarations I used.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users