   [SlimDX] Can't get lighting to work
  I am trying to use a vertex format of Position+normal+Color and I can't seem to get it working.The scene renders as expected with lighting turned off, proper colors and all, just terribly flat looking with no defined edges visible.  I am reasonably sure the normals are ok, the code was ported from openGL and rendered properly there.  Just to be sure, I flipped normals and got the same results.  The results are that the geometry is rendered, and can be seen when I set the background to a lighter shade, but the rendered geometry is black. I am also drawing a grid, and using the PositionColor only fvf with it, and it also renders black, so I don't think vertex normal values are the issue, since the grid doesn't use them.I have 2 lights defined, I have tried various positions and settings, both are 'set' and enabled on the device.What kind of surprises me is the lack of any examples on the net that use those three components in a fvf - I find that very strange since I would think it quite common, and that lead me to believe it is just plain not a valid combination.Can anyone point me in a direction to make this work??This is a screen cap of the openGL/Tao (RIP) version I am trying to move to slimDX;  http://www.spiked3.com/CncGo3_7.swf.html   
  Some code would help.   ;Quote:Original post by adt7Some code would help.Yes it would. Hopefully someone who has done PositionNormalColor FVF can post their lighting code sample that worked.  Or even better someone who struggled with it like I am, and then found the one call they missed (perhaps because it is an obscure call that I missed in the days I have looked myself already) that made it all work. I am working on an smaller example of what is failing for me (reducing a 10,000 line program down to just this), it will take a while. I may find out what I am doing wrong in the process. I will either post my broken code in a while, or what I found to be incorrect.   ;using System;using System.Windows;using System.Drawing;using System.Runtime.InteropServices;using System.ComponentModel;using SlimDX;using SlimDX.Direct3D9;using SlimDX.Wpf;namespace DirectxLighting{    /// &lt;summary&gt;    /// Interaction logic for MainWindow.xaml    /// &lt;/summary&gt;    public partial class MainWindow : Window    {   MyRenderEngine MyRenderEngine;   public MainWindow()   {  InitializeComponent();  Loaded += delegate(object sender, RoutedEventArgs e)  { MyRenderEngine = new MyRenderEngine(); slimDXControl1.SetRenderEngine(MyRenderEngine); DataContext = MyRenderEngine;  };   }   private void button1_Click(object sender, RoutedEventArgs e)   {  MyRenderEngine.UseLighting = !MyRenderEngine.UseLighting;   }    }    class MyRenderEngine : IRenderEngine, INotifyPropertyChanged    {   bool isInitialized = false;   SlimDXControl SlimDXControl;   Light Light_0 = new Light()    {   Type = LightType.Point, Position = new Vector3(2, 2, 2), Diffuse = Color.Red, Attenuation0 = .2f, Attenuation1 = 1000    }; Light Light_1 = new Light()    {   Type = LightType.Point, Position = new Vector3(-2, -2, -2), Diffuse = Color.Blue, Attenuation0 = .2f, Attenuation1 = 1000   };   PositionColorVertex[] SimpleTriangle1; PositionNormalColorVertex[] SimpleTriangle2;   bool _WireFrame = false, _UseLighting = true, _EnableLight_0 = true, _EnableLight_1 = true;   public bool WireFrame { get { return _WireFrame; } set { _WireFrame = value; OnPropertyChanged("WireFrame"); } }   public bool UseLighting { get { return _UseLighting; } set { _UseLighting = value; OnPropertyChanged("UseLighting"); } }   public bool EnableLight_0 { get { return _EnableLight_0; } set { _EnableLight_0 = value; OnPropertyChanged("EnableLight_0"); } }   public bool EnableLight_1 { get { return _EnableLight_1; } set { _EnableLight_1 = value; OnPropertyChanged("EnableLight_1"); } }   public void OnDeviceCreated(object sender, EventArgs e)   {  // +++ never getting called?   }   public void OnDeviceDestroyed(object sender, EventArgs e)   {  //throw new NotImplementedException();   }   public void OnDeviceLost(object sender, EventArgs e)   {  //throw new NotImplementedException();   }   public void OnDeviceReset(object sender, EventArgs e)   {  isInitialized = false;  SlimDXControl = sender as SlimDXControl;  if (SlimDXControl == null) throw new ArgumentNullException("sender");  SimpleTriangle1 = new PositionColorVertex[] { new PositionColorVertex( new Vector3(-0.5f, -0.5f, 0.0f), Color.Red),new PositionColorVertex( new Vector3(0.5f, -0.5f, 0.0f), Color.Blue ),new PositionColorVertex( new Vector3(0.0f, 0.5f, 0.0f), Color.Green),  };  SimpleTriangle2 = new PositionNormalColorVertex[] { new PositionNormalColorVertex( new Vector3(-0.5f, -0.5f, 0.0f), new Vector3(0,0,-1), Color.Red),new PositionNormalColorVertex( new Vector3(0.5f, -0.5f, 0.0f), new Vector3(0,0,-1), Color.Blue ),new PositionNormalColorVertex( new Vector3(0.0f, 0.5f, 0.0f), new Vector3(0,0,-1), Color.Green),  };  SlimDXControl.Device.SetLight(0, Light_1);  SlimDXControl.Device.SetLight(1, Light_1);  SlimDXControl.Device.SetTransform(TransformState.Projection, Matrix.PerspectiveFovRH((float)Math.PI / 4, (float)(SlimDXControl.Width / SlimDXControl.Height), 1, 100));  SlimDXControl.Device.SetTransform(TransformState.View, Matrix.LookAtRH(new Vector3(0, 2, -2), new Vector3(0, 0, 0), new Vector3(0, 1, 0)));  isInitialized = true;   }   DateTime lastTick = DateTime.MaxValue;   public void OnMainLoop(object sender, EventArgs e)   {  if (!isInitialized) return;// we get called before we get created :| (in the voice of eric cartman, "lame")  DateTime NowTime = DateTime.Now;  float elapsedSeconds = (float)(NowTime - lastTick).TotalSeconds;  SlimDXControl.Device.MultiplyTransform(TransformState.World, Matrix.RotationY((float)(elapsedSeconds * Math.PI)));  lastTick = NowTime;  SlimDXControl.Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.FromArgb(255, 100, 100, 100), 1, 0);  SlimDXControl.Device.SetRenderState(RenderState.FillMode, WireFrame ? FillMode.Wireframe : FillMode.Solid);  SlimDXControl.Device.SetRenderState(RenderState.CullMode, Cull.None);  SlimDXControl.Device.EnableLight(0, EnableLight_0);  SlimDXControl.Device.EnableLight(1, EnableLight_1);  SlimDXControl.Device.SetRenderState(RenderState.Lighting, UseLighting);  //SlimDXControl.Device.VertexFormat = PositionColorVertex.VertextFormat;  //SlimDXControl.Device.DrawUserPrimitives&lt;PositionColorVertex&gt;  //    (SlimDX.Direct3D9.PrimitiveType.TriangleList, SimpleTriangle1.Length, SimpleTriangle1);  SlimDXControl.Device.VertexFormat = PositionNormalColorVertex.VertextFormat;  SlimDXControl.Device.DrawUserPrimitives&lt;PositionNormalColorVertex&gt; (SlimDX.Direct3D9.PrimitiveType.TriangleList, SimpleTriangle2.Length / 3, SimpleTriangle2);   }   #region INotifyPropertyChanged Members   public event PropertyChangedEventHandler PropertyChanged;   void OnPropertyChanged(string T)   {  if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(T));   }   #endregion    }    [StructLayout(LayoutKind.Sequential)]    public struct PositionNormalColorVertex : IEquatable&lt;PositionNormalColorVertex&gt;    {   public Vector3 Position;   public Vector3 Normal;   public Int32 Color;   public static VertexFormat VertextFormat { get { return VertexFormat.Position | VertexFormat.Normal | VertexFormat.Diffuse; } }   public PositionNormalColorVertex(Vector3 position, Vector3 normal, Color color)  : this()   {  Position = position;  Normal = normal;  Color = color.ToArgb();   }   #region IEquatable   public static bool operator ==(PositionNormalColorVertex left, PositionNormalColorVertex right)   {  return left.Equals(right);   }   public static bool operator !=(PositionNormalColorVertex left, PositionNormalColorVertex right)   {  return !(left == right);   }   public override int GetHashCode()   {  return Position.GetHashCode() + Color.GetHashCode();   }   public override bool Equals(object obj)   {  if (obj == null) return false;  if (GetType() != obj.GetType()) return false;  return Equals((PositionNormalColorVertex)obj);   }   public bool Equals(PositionNormalColorVertex other)   {  return (Position == other.Position && Color == other.Color && Normal == other.Normal);   }   #endregion    }    [StructLayout(LayoutKind.Sequential)]    public struct PositionColorVertex : IEquatable&lt;PositionColorVertex&gt;    {   public Vector3 Position;   public Int32 Color;   public static VertexFormat VertextFormat { get { return VertexFormat.Position |VertexFormat.Diffuse; } }   public PositionColorVertex(Vector3 position, Color color)  : this()   {  Position = position;  Color = color.ToArgb();   }   #region IEquatable   public static bool operator ==(PositionColorVertex left, PositionColorVertex right)   {  return left.Equals(right);   }   public static bool operator !=(PositionColorVertex left, PositionColorVertex right)   {  return !(left == right);   }   public override int GetHashCode()   {  return Position.GetHashCode() + Color.GetHashCode();   }   public override bool Equals(object obj)   {  if (obj == null) return false;  if (GetType() != obj.GetType()) return false;  return Equals((PositionColorVertex)obj);   }   public bool Equals(PositionColorVertex other)   {  return (Position == other.Position && Color == other.Color);   }   #endregion    }} [Edited by - Promit on April 11, 2010 10:07:50 AM];  Ok, now I am really confused - and I am out of time for now, so I will look more into it later.But commenting out the second set light, and some colors appear - although changing the light parameters has no effect on anything. Very weird, probably something simple and stupid code error wise.   ;  You need to set an appropriate material for FFP lighting to work (device.Material)or at least set the RenderState.DiffuseMaterialSource et. al. to sensible values (these can redirect material properties to your vertex). In the code you provided you never set these properties at all.A test run with some own code showed that the default value (after device creation) of RenderState.DiffuseMaterialSource is actually Color1, though. Then again, the default Material is zero everywhere. But you may have got something different. So playing around with the states and device.Material would be my first attempt.;  Well, I'm not sure exactly what change made it start working, but after changing just about everything I started seeing some light.  The changes that stick out at me are; I added the range parameter to the lights - the example I had seen did not have those. I have not yet found a good explanation showing what light use which parameters - but anyhow, in the version that works now the values are different than the code above.  I also had to revers the normals - no big surprise there. I discovered that when I started rotating things. As I move lights around now and change colors, things appear as I would expect - so now I am going to change the big program to match.Here is a repost of the above, but working now - there may be other significant differences I haven't noticed yet.  BTW - still no material, so that does not seem to be a requirement (and actually I had tried that earlier with no results).If anyone want the full code let me know - since its wpf, this post doesn't cover everything.-----------------------  working version -----------------using System;using System.Windows;using System.Drawing;using System.Runtime.InteropServices;using System.ComponentModel;using SlimDX;using SlimDX.Direct3D9;using SlimDX.Wpf;namespace DirectxLighting{    /// <summary>    /// Interaction logic for MainWindow.xaml    /// </summary>    public partial class MainWindow : Window    {   MyRenderEngine MyRenderEngine;   public MainWindow()   {  InitializeComponent();  Loaded += delegate(object sender, RoutedEventArgs e)  { MyRenderEngine = new MyRenderEngine(); slimDXControl1.SetRenderEngine(MyRenderEngine); DataContext = MyRenderEngine;  };   }    }    class MyRenderEngine : IRenderEngine, INotifyPropertyChanged    {   bool isInitialized = false;   SlimDXControl SlimDXControl;   Light Light_0 = new Light()    {   Type = LightType.Point, Position = new Vector3(4, 2, 10), Diffuse = Color.White, Attenuation0=0, Attenuation1=.1f, Attenuation2=0, Range=100    };    Light Light_1 = new Light()    {   Type = LightType.Point, Position = new Vector3(-4, 2, 10), Diffuse = Color.Blue, Attenuation0=0, Attenuation1=.1f, Attenuation2=0, Range=100    };   PositionColorVertex[] SimpleTriangle1;    PositionNormalColorVertex[] SimpleTriangle2;   bool _WireFrame = false, _UseLighting = true, _EnableLight_0 = true, _EnableLight_1 = true;   public bool WireFrame { get { return _WireFrame; } set { _WireFrame = value; OnPropertyChanged("WireFrame"); } }   public bool UseLighting { get { return _UseLighting; } set { _UseLighting = value; OnPropertyChanged("UseLighting"); } }   public bool EnableLight_0 { get { return _EnableLight_0; } set { _EnableLight_0 = value; OnPropertyChanged("EnableLight_0"); } }   public bool EnableLight_1 { get { return _EnableLight_1; } set { _EnableLight_1 = value; OnPropertyChanged("EnableLight_1"); } }   public void OnDeviceCreated(object sender, EventArgs e)   {  // +++ never getting called?   }   public void OnDeviceDestroyed(object sender, EventArgs e)   {  //throw new NotImplementedException();   }   public void OnDeviceLost(object sender, EventArgs e)   {  //throw new NotImplementedException();   }   public void OnDeviceReset(object sender, EventArgs e)   {  isInitialized = false;  SlimDXControl = sender as SlimDXControl;  if (SlimDXControl == null) throw new ArgumentNullException("sender");  SimpleTriangle1 = new PositionColorVertex[] { new PositionColorVertex( new Vector3(-0.5f, -0.5f, 0.0f), Color.Red),new PositionColorVertex( new Vector3(0.5f, -0.5f, 0.0f), Color.Blue ),new PositionColorVertex( new Vector3(0.0f, 0.5f, 0.0f), Color.Green),  };  SimpleTriangle2 = new PositionNormalColorVertex[] { new PositionNormalColorVertex( new Vector3(-0.5f, -0.5f, 0.0f), new Vector3(0,0,1), Color.Red),new PositionNormalColorVertex( new Vector3(0.5f, -0.5f, 0.0f), new Vector3(0,0,1), Color.Blue ),new PositionNormalColorVertex( new Vector3(0.0f, 0.5f, 0.0f), new Vector3(0,0,1), Color.Green),  };  SlimDXControl.Device.SetLight(0, Light_0);  SlimDXControl.Device.SetLight(1, Light_1);  SlimDXControl.Device.SetTransform(TransformState.Projection, Matrix.PerspectiveFovRH((float)Math.PI / 4, (float)(SlimDXControl.Width / SlimDXControl.Height), 1, 100));  SlimDXControl.Device.SetTransform(TransformState.View, Matrix.LookAtRH(new Vector3(0, 2, -2), new Vector3(0, 0, 0), new Vector3(0, 1, 0)));  isInitialized = true;   }   DateTime lastTick = DateTime.MaxValue;   public void OnMainLoop(object sender, EventArgs e)   {  if (!isInitialized) return;// we get called before we get created :| (in the voice of eric cartman, "lame")  DateTime NowTime = DateTime.Now;  float elapsedSeconds = (float)(NowTime - lastTick).TotalSeconds;  SlimDXControl.Device.MultiplyTransform(TransformState.World, Matrix.RotationY((float)(elapsedSeconds * Math.PI)));  lastTick = NowTime;  SlimDXControl.Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.FromArgb(255, 100, 100, 100), 1, 0);  SlimDXControl.Device.SetRenderState(RenderState.FillMode, WireFrame ? FillMode.Wireframe : FillMode.Solid);  //SlimDXControl.Device.SetRenderState(RenderState.CullMode, Cull.None);  SlimDXControl.Device.EnableLight(0, EnableLight_0);  SlimDXControl.Device.EnableLight(1, EnableLight_1);  SlimDXControl.Device.SetRenderState(RenderState.Lighting, UseLighting);  //SlimDXControl.Device.VertexFormat = PositionColorVertex.VertextFormat;  //SlimDXControl.Device.DrawUserPrimitives<PositionColorVertex>  //    (SlimDX.Direct3D9.PrimitiveType.TriangleList, SimpleTriangle1.Length, SimpleTriangle1);  SlimDXControl.Device.VertexFormat = PositionNormalColorVertex.VertextFormat;  SlimDXControl.Device.DrawUserPrimitives<PositionNormalColorVertex> (SlimDX.Direct3D9.PrimitiveType.TriangleList, SimpleTriangle2.Length / 3, SimpleTriangle2);   }   #region INotifyPropertyChanged Members   public event PropertyChangedEventHandler PropertyChanged;   void OnPropertyChanged(string T)   {  if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(T));   }   #endregion    }    [StructLayout(LayoutKind.Sequential)]    public struct PositionNormalColorVertex : IEquatable<PositionNormalColorVertex>    {   public Vector3 Position;   public Vector3 Normal;   public Int32 Color;   public static VertexFormat VertextFormat { get { return VertexFormat.Position | VertexFormat.Normal | VertexFormat.Diffuse; } }   public PositionNormalColorVertex(Vector3 position, Vector3 normal, Color color)  : this()   {  Position = position;  Normal = normal;  Color = color.ToArgb();   }   #region IEquatable   public static bool operator ==(PositionNormalColorVertex left, PositionNormalColorVertex right)   {  return left.Equals(right);   }   public static bool operator !=(PositionNormalColorVertex left, PositionNormalColorVertex right)   {  return !(left == right);   }   public override int GetHashCode()   {  return Position.GetHashCode() + Color.GetHashCode();   }   public override bool Equals(object obj)   {  if (obj == null) return false;  if (GetType() != obj.GetType()) return false;  return Equals((PositionNormalColorVertex)obj);   }   public bool Equals(PositionNormalColorVertex other)   {  return (Position == other.Position && Color == other.Color && Normal == other.Normal);   }   #endregion    }    [StructLayout(LayoutKind.Sequential)]    public struct PositionColorVertex : IEquatable<PositionColorVertex>    {   public Vector3 Position;   public Int32 Color;   public static VertexFormat VertextFormat { get { return VertexFormat.Position |VertexFormat.Diffuse; } }   public PositionColorVertex(Vector3 position, Color color)  : this()   {  Position = position;  Color = color.ToArgb();   }   #region IEquatable   public static bool operator ==(PositionColorVertex left, PositionColorVertex right)   {  return left.Equals(right);   }   public static bool operator !=(PositionColorVertex left, PositionColorVertex right)   {  return !(left == right);   }   public override int GetHashCode()   {  return Position.GetHashCode() + Color.GetHashCode();   }   public override bool Equals(object obj)   {  if (obj == null) return false;  if (GetType() != obj.GetType()) return false;  return Equals((PositionColorVertex)obj);   }   public bool Equals(PositionColorVertex other)   {  return (Position == other.Position && Color == other.Color);   }   #endregion    }}