[MDX] Help! Lighting in Managed DirectX is not working

Started by
8 comments, last by Dave Hunt 18 years, 7 months ago
Hi, I write a very simple Managed DirectX program to show a spinning cube with lighting. However, there is no light at all and all it displays is a black cube. Can anyone help me find out what's wrong?


using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;



namespace DirectX3
{
	/// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class DirectXForm : System.Windows.Forms.Form
	{
		/// <summary>
		/// Required designer variable.
		/// </summary>
		
		private Device device;
		private System.ComponentModel.Container components = null;
		private float angle = 0.0f;
		Mesh mesh = null;


		public DirectXForm()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
		}

		/// <summary>
		/// Initialize the DirectX Device
		/// </summary>
		public void InitializeDevice()
		{
			PresentParameters presentParams = new PresentParameters();

			presentParams.Windowed = true;
			presentParams.SwapEffect = SwapEffect.Discard;
			presentParams.EnableAutoDepthStencil = true;
			presentParams.AutoDepthStencilFormat = DepthFormat.D16;

			device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams);

			Material boxMaterial = new Material();
			boxMaterial.Ambient = Color.White;
			boxMaterial.Diffuse = Color.White;
			device.Material = boxMaterial;
			
			device.Lights[0].Type = LightType.Directional;
			device.Lights[0].Position = new Vector3(0.0f, 3.0f, 3.0f);
			device.Lights[0].Diffuse = Color.DarkBlue;
			device.Lights[0].Enabled = true;
			device.Lights[0].Update();
		}


		private void DrawObject()
		{
			mesh = Mesh.Box(device, 2.0f, 2.0f, 2.0f);
		}


		private void DrawBox(float yaw, float pitch, float roll, float x, float y, float z)
		{
			angle += 0.01f;

			device.Transform.World = Matrix.RotationYawPitchRoll(yaw, pitch, roll) * Matrix.Translation(x, y, z);

			DrawObject();
			mesh.DrawSubset(0);

		}


		protected override void OnPaint(PaintEventArgs e)
		{
			// Set the Camera
			device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, (float)this.Width / (float)this.Height, 1.0f, 100.0f);
			device.Transform.View = Matrix.LookAtLH(new Vector3(0.0f, 0.0f, 10.0f), new Vector3(), new Vector3(0.0f, 1.0f, 0.0f));
				
            // Clear the Scene
			device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.CornflowerBlue, 1.0f, 0);
				
			// Draw the scene
			device.BeginScene();
				DrawBox(angle / (float)Math.PI, angle / (float)Math.PI * 2.0f, angle / (float)Math.PI / 4.0f, 0.0f, 0.0f, 0.0f);
			device.EndScene();

			device.Present();

			this.Invalidate();
		}


		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			// 
			// DirectXForm
			// 
			this.components = new Container();
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(500, 500);
			this.Text = "DirectXForm";

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			using(DirectXForm dxf = new DirectXForm())
			{
				dxf.Show();
				dxf.InitializeDevice();
				Application.Run(dxf);
			}
		}
	}
}


Thanks, ninjaindark
Advertisement
Don't Panic!

You have to enable lighting in the render state manager:
device.RenderState.Lighting = true;

Thanks Dave,

I think the device.RenderState.Lighting is TRUE by default.
I put the line device.RenderState.Lighting = true; in but still doesn't work.

ninjaindark
device.Lights[0].Type = LightType.Directional;

You're using a directional light, and for a directional light it is required that you specify a direction of the light. I assume you want your light shine at 0,0,0, so add this:
device.Lights[0].Direction = new Vector3(0.0f, -3.0f, -3.0f);

Toolmaker

I have no idea, but you might want to check that there are Normals on the meshes produced by the mesh functions. If they don't you will have to add them in yourself.
Turring Machines are better than C++ any day ^_~
Quote:Toolmaker
You're using a directional light, and for a directional light it is required that you specify a direction of the light.


Right. A directional light actually has no position, but must have a direction. Good catch, Toolmaker.
Thanks a lot everyone.
I should use direction instead of position. :)
You need to use BOTH direction and position. Because a light must be at a certain position and direct it's light to another point.

Toolmaker

I don't think that's true for directional lights. You need both for spotlights, but (I'm fairly sure) directional lights don't attenuate and only need a direction.
According to the SDK Docs, a directional light has no position. In addition, the directional lights tutorial does not set a position - only a direction.

This topic is closed to new replies.

Advertisement