package min3d.vos;
import java.nio.FloatBuffer;
import min3d.Utils;
import min3d.interfaces.IDirtyParent;
/**
* Consists of three main components - ambient color, diffuse color, and position.
*
* Must be added to Scene to take effect.
* Eg, "scene.lights().add(myLight);"
*
* WARNING: Positional light type does not work in v1.5 emulator.
* But is nevertheless the default type.
*/
public class Light extends AbstractDirtyManaged implements IDirtyParent
{
private BooleanManaged _isVisible;
public Number3dManaged position;
public Number3dManaged direction;
public Color4Managed ambient;
public Color4Managed diffuse;
public Color4Managed specular;
public Color4Managed emissive;
private LightType _type;
private Number3dManaged _attenuation; // (using the 3 properties of N3D for the 3 attenuation properties)
private FloatBuffer _positionAndTypeFloatBuffer;
public Light()
{
super(null);
ambient = new Color4Managed(128,128,128, 255, this);
diffuse = new Color4Managed(255,255,255, 255, this);
specular = new Color4Managed(0,0,0,255, this);
emissive = new Color4Managed(0,0,0,255, this);
position = new Number3dManaged(0f, 0f, 5f, this);
direction = new Number3dManaged(0f, 0f, -1f, this);
_attenuation = new Number3dManaged(1f,0f,0f, this); // (OpenGL default attenuation values)
_isVisible = new BooleanManaged(true, this);
type(LightType.DIRECTIONAL);
_positionAndTypeFloatBuffer = Utils.makeFloatBuffer4(0,0,0,0);
setDirtyFlag();
}
//
public boolean isVisible()
{
return _isVisible.get();
}
public void isVisible(Boolean $b)
{
_isVisible.set($b);
}
//
/**
* type can be either POSITIONAL or DIRECTIONAL.
* Default is DIRECTIONAL.
*
* POSITIONAL does not work correctly with v1.5 emulator, which
* appears to be a known bug. It does not work corrctly for me
* with the v2.2 emulator either.
*/
public LightType type()
{
return _type;
}
public void type(LightType $type)
{
_type = $type;
position.setDirtyFlag(); // .. because position and 'type' go together in OGL data structure
}
//
public float attenuationConstant()
{
return _attenuation.getX();
}
public void attenuationConstant(float $normalizedValue)
{
_attenuation.setX($normalizedValue);
setDirtyFlag();
}
public float attenuationLinear()
{
return _attenuation.getY();
}
public void attenuationLinear(float $normalizedValue)
{
_attenuation.setY($normalizedValue);
setDirtyFlag();
}
public float attenuationQuadratic()
{
return _attenuation.getZ();
}
public void attenuationQuadratic(float $normalizedValue)
{
_attenuation.setZ($normalizedValue);
setDirtyFlag();
}
public void attenuationSetAll(float $constant, float $linear, float $quadratic)
{
_attenuation.setAll($constant, $linear, $quadratic);
setDirtyFlag();
}
//
public void setAllDirty()
{
position.setDirtyFlag();
ambient.setDirtyFlag();
diffuse.setDirtyFlag();
specular.setDirtyFlag();
emissive.setDirtyFlag();
direction.setDirtyFlag();
_attenuation.setDirtyFlag();
_isVisible.setDirtyFlag();
}
public void onDirty()
{
setDirtyFlag();
}
/**
* Used by Renderer
*/
public Number3dManaged attenuation()
{
return _attenuation;
}
/**
* Used by Renderer
*/
public BooleanManaged isVisibleBm()
{
return _isVisible;
}
/**
* Used by Renderer
*/
public FloatBuffer positionAndTypeBuffer()
{
return _positionAndTypeFloatBuffer;
}
/**
* Used by Renderer
*/
public void commitPositionAndTypeBuffer()
{
// GL_POSITION takes 4 arguments, the first 3 being x/y/z position,
// and the 4th being what we're calling 'type' (positional or directional)
_positionAndTypeFloatBuffer.position(0);
_positionAndTypeFloatBuffer.put(position.getX());
_positionAndTypeFloatBuffer.put(position.getY());
_positionAndTypeFloatBuffer.put(position.getZ());
_positionAndTypeFloatBuffer.put(_type.glValue());
_positionAndTypeFloatBuffer.position(0);
}
}