Tal's picture

[help]Directinal light is changed by distance

I try to use directional light(primitive) on a simple triangle. The light does works, but for some reason, the amount light is changed when I change the viewpoint(AKA eye vector). Here is part of the code(under LGPLv3 license):

protected override void OnStartDrawing ()
		Vector4 baseAmbient = BaseAmbientLight;
		GL.LightModel(LightModelParameter.LightModelAmbient, &baseAmbient.X);
		ILinkedItem<ILight> lights = ambientLights;
		for(byte i = 0; i < ambientCount; ++i, lights = lights.Next)
			Vector4 amount;
			((IAmbientLight)lights.Current).GetAmount (out amount);
			GL.Light (LightName.Light0 + i, LightParameter.Ambient, &amount.X);
		lights = directLights;
		for(byte i = 0; i < directCount; ++i, lights = lights.Next)
			IDirectionalLight current = (IDirectionalLight)lights.Current;
			Vector3 temp; float alpha = 0f;
			Vector4 temp4;
			current.GetUnitSource (out temp);
			temp4 = new Vector4(temp, alpha);
			GL.Light (LightName.Light0 + i, LightParameter.Position, &temp4.X);
			alpha = 1f;
			current.GetDiffuse (out temp);
			temp4 = new Vector4(temp, alpha);
			GL.Light (LightName.Light0 + i, LightParameter.Diffuse, &temp4.X);
			temp4 = Vector4.Zero;
			GL.Light (LightName.Light0 + i, LightParameter.Specular, &temp4.X);

I checked in a debbuger each var, and it seems right(but not visually...).
By the way: Is it matter(performance) if I use a more global(big content) unsafe block as I did here, or it does not matter and I shell use unsafe block only and every time I use "&temp4.X"(in this code it is twice) ?


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

From the FAQ on opengl.org:


How can I make my light stay fixed relative to my scene? How can I put a light in the corner and make it stay there while I change my view?

As your view changes, your ModelView matrix also changes. This means you'll need to respecify the light position, usually at the start of every frame. A typical application will display a frame with the following pseudocode:

  1. Set the view transform.
  2. Set the light position //glLightfv(GL_LIGHT_POSITION,…)
  3. Send down the scene or model geometry.
  4. Swap buffers.

I'd suggest keeping unsafe regions as small as possible as there's no performance penalty in doing that.

Tal's picture

Thanks fiddler!
I have just remembered you told me that sometimes(primitive lights) I'll shell use both MatrixMode.Projection and MatrixMode.Modelview instead of multiply matrix for each object and use only the later...
And for the unsafe block: I though that the only performance problem is managed<->unmanaged(aka. content switch), therefore calling GL.X methods(which they make contents switch) before using pointers in "&temp4.X", is slow.