mirror of https://github.com/buggins/dlangui.git
#183 light bindings
This commit is contained in:
parent
846c25c652
commit
97cf194319
|
@ -48,10 +48,23 @@ class Light : RefCountedObject {
|
||||||
@property void range(float v) { assert(false); }
|
@property void range(float v) { assert(false); }
|
||||||
@property float rangeInverse() const { return 1.0; }
|
@property float rangeInverse() const { return 1.0; }
|
||||||
|
|
||||||
|
@property float innerAngle() const { assert(false); }
|
||||||
|
@property float innerAngleCos() const { assert(false); }
|
||||||
|
@property float outerAngle() const { assert(false); }
|
||||||
|
@property float outerAngleCos() const { assert(false); }
|
||||||
|
|
||||||
/// create new directional light
|
/// create new directional light
|
||||||
static Light createDirectional(vec3 color) {
|
static Light createDirectional(vec3 color) {
|
||||||
return new DirectionalLight(color);
|
return new DirectionalLight(color);
|
||||||
}
|
}
|
||||||
|
/// create new point light
|
||||||
|
static Light createPoint(vec3 color, float range) {
|
||||||
|
return new PointLight(color, range);
|
||||||
|
}
|
||||||
|
/// create new point light
|
||||||
|
static Light createSpot(vec3 color, float range, float innerAngle, float outerAngle) {
|
||||||
|
return new SpotLight(color, range, innerAngle, outerAngle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected class DirectionalLight : Light {
|
protected class DirectionalLight : Light {
|
||||||
|
@ -63,7 +76,7 @@ protected class DirectionalLight : Light {
|
||||||
protected class PointLight : Light {
|
protected class PointLight : Light {
|
||||||
protected float _range = 1;
|
protected float _range = 1;
|
||||||
protected float _rangeInverse = 1;
|
protected float _rangeInverse = 1;
|
||||||
protected this(vec3 color, float range = 1) {
|
protected this(vec3 color, float range) {
|
||||||
super(color);
|
super(color);
|
||||||
_range = range;
|
_range = range;
|
||||||
_rangeInverse = 1 / range;
|
_rangeInverse = 1 / range;
|
||||||
|
@ -79,6 +92,28 @@ protected class PointLight : Light {
|
||||||
override @property float rangeInverse() const { return _rangeInverse; }
|
override @property float rangeInverse() const { return _rangeInverse; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected class SpotLight : PointLight {
|
||||||
|
protected float _innerAngle;
|
||||||
|
protected float _innerAngleCos;
|
||||||
|
protected float _outerAngle;
|
||||||
|
protected float _outerAngleCos;
|
||||||
|
protected this(vec3 color, float range, float innerAngle, float outerAngle) {
|
||||||
|
import std.math;
|
||||||
|
super(color, range);
|
||||||
|
_innerAngle = innerAngle;
|
||||||
|
_outerAngle = outerAngle;
|
||||||
|
_innerAngleCos = cos(innerAngle);
|
||||||
|
_outerAngleCos = cos(outerAngle);
|
||||||
|
}
|
||||||
|
|
||||||
|
override @property LightType type() const { return LightType.spot; }
|
||||||
|
|
||||||
|
override @property float innerAngle() const { return _innerAngle; }
|
||||||
|
override @property float innerAngleCos() const { return _innerAngleCos; }
|
||||||
|
override @property float outerAngle() const { return _outerAngle; }
|
||||||
|
override @property float outerAngleCos() const { return _outerAngleCos; }
|
||||||
|
}
|
||||||
|
|
||||||
alias LightCounts = int[3];
|
alias LightCounts = int[3];
|
||||||
|
|
||||||
/// light collection
|
/// light collection
|
||||||
|
@ -87,11 +122,11 @@ struct Lights {
|
||||||
Light[] point;
|
Light[] point;
|
||||||
Light[] spot;
|
Light[] spot;
|
||||||
void reset() {
|
void reset() {
|
||||||
directional = null;
|
directional.length = 0;
|
||||||
point = null;
|
point.length = 0;
|
||||||
spot = null;
|
spot.length = 0;
|
||||||
}
|
}
|
||||||
@property bool empty() { return directional.length + point.length + spot.length > 0; }
|
@property bool empty() const { return directional.length + point.length + spot.length > 0; }
|
||||||
/// returns point types by type
|
/// returns point types by type
|
||||||
@property LightCounts counts() const { return [cast(int)directional.length, cast(int)point.length, cast(int)spot.length]; }
|
@property LightCounts counts() const { return [cast(int)directional.length, cast(int)point.length, cast(int)spot.length]; }
|
||||||
@property int directionalCount() const { return cast(int)directional.length; }
|
@property int directionalCount() const { return cast(int)directional.length; }
|
||||||
|
@ -191,6 +226,58 @@ struct Lights {
|
||||||
struct LightParams {
|
struct LightParams {
|
||||||
Lights _lights;
|
Lights _lights;
|
||||||
|
|
||||||
|
@property bool empty() const { return _lights.empty; }
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
_lights.reset();
|
||||||
|
u_directionalLightDirection.length = 0;
|
||||||
|
u_directionalLightColor.length = 0;
|
||||||
|
|
||||||
|
u_pointLightPosition.length = 0;
|
||||||
|
u_pointLightColor.length = 0;
|
||||||
|
u_pointLightRangeInverse.length = 0;
|
||||||
|
|
||||||
|
u_spotLightPosition.length = 0;
|
||||||
|
u_spotLightDirection.length = 0;
|
||||||
|
u_spotLightColor.length = 0;
|
||||||
|
u_spotLightRangeInverse.length = 0;
|
||||||
|
u_spotLightInnerAngleCos.length = 0;
|
||||||
|
u_spotLightOuterAngleCos.length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset(ref LightParams params) {
|
||||||
|
reset();
|
||||||
|
if (params._lights.directional.length)
|
||||||
|
_lights.directional ~= params._lights.directional;
|
||||||
|
if (params._lights.point.length)
|
||||||
|
_lights.point ~= params._lights.point;
|
||||||
|
if (params._lights.spot.length)
|
||||||
|
_lights.spot ~= params._lights.spot;
|
||||||
|
|
||||||
|
u_directionalLightDirection ~= params.u_directionalLightDirection;
|
||||||
|
u_directionalLightColor ~= params.u_directionalLightColor;
|
||||||
|
|
||||||
|
u_pointLightPosition ~= params.u_pointLightPosition;
|
||||||
|
u_pointLightColor ~= params.u_pointLightColor;
|
||||||
|
u_pointLightRangeInverse ~= params.u_pointLightRangeInverse;
|
||||||
|
|
||||||
|
u_spotLightPosition ~= params.u_spotLightPosition;
|
||||||
|
u_spotLightDirection ~= params.u_spotLightDirection;
|
||||||
|
u_spotLightColor ~= params.u_spotLightColor;
|
||||||
|
u_spotLightRangeInverse ~= params.u_spotLightRangeInverse;
|
||||||
|
u_spotLightInnerAngleCos ~= params.u_spotLightInnerAngleCos;
|
||||||
|
u_spotLightOuterAngleCos ~= params.u_spotLightOuterAngleCos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void add(ref Lights lights) {
|
||||||
|
foreach(light; lights.directional)
|
||||||
|
add(light);
|
||||||
|
foreach(light; lights.point)
|
||||||
|
add(light);
|
||||||
|
foreach(light; lights.spot)
|
||||||
|
add(light);
|
||||||
|
}
|
||||||
|
|
||||||
/// returns true if light is added (not a duplicate, and enabled)
|
/// returns true if light is added (not a duplicate, and enabled)
|
||||||
bool add(Light light) {
|
bool add(Light light) {
|
||||||
if (!light.node || !light.enabled || !_lights.add(light))
|
if (!light.node || !light.enabled || !_lights.add(light))
|
||||||
|
@ -206,7 +293,12 @@ struct LightParams {
|
||||||
u_pointLightRangeInverse ~= light.rangeInverse;
|
u_pointLightRangeInverse ~= light.rangeInverse;
|
||||||
return true;
|
return true;
|
||||||
case LightType.spot:
|
case LightType.spot:
|
||||||
// TODO
|
u_spotLightPosition ~= light.position;
|
||||||
|
u_spotLightDirection ~= light.direction;
|
||||||
|
u_spotLightColor ~= light.color;
|
||||||
|
u_spotLightRangeInverse ~= light.rangeInverse;
|
||||||
|
u_spotLightInnerAngleCos ~= light.innerAngleCos;
|
||||||
|
u_spotLightOuterAngleCos ~= light.outerAngleCos;
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -87,7 +87,7 @@ class Material : RefCountedObject {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bind(Node3d node) {
|
void bind(Node3d node, LightParams * lights = null) {
|
||||||
assert(!effect.isNull);
|
assert(!effect.isNull);
|
||||||
effect.bind();
|
effect.bind();
|
||||||
if (!texture.isNull) {
|
if (!texture.isNull) {
|
||||||
|
@ -109,6 +109,36 @@ class Material : RefCountedObject {
|
||||||
_effect.setUniform(DefaultUniform.u_modulateColor, _modulateColor);
|
_effect.setUniform(DefaultUniform.u_modulateColor, _modulateColor);
|
||||||
if (_effect.hasUniform(DefaultUniform.u_modulateAlpha))
|
if (_effect.hasUniform(DefaultUniform.u_modulateAlpha))
|
||||||
_effect.setUniform(DefaultUniform.u_modulateAlpha, _modulateAlpha);
|
_effect.setUniform(DefaultUniform.u_modulateAlpha, _modulateAlpha);
|
||||||
|
if (lights && !lights.empty) {
|
||||||
|
if (lights.u_directionalLightDirection.length) {
|
||||||
|
if (_effect.hasUniform(DefaultUniform.u_directionalLightDirection))
|
||||||
|
_effect.setUniform(DefaultUniform.u_directionalLightDirection, lights.u_directionalLightDirection);
|
||||||
|
if (_effect.hasUniform(DefaultUniform.u_directionalLightColor))
|
||||||
|
_effect.setUniform(DefaultUniform.u_directionalLightColor, lights.u_directionalLightColor);
|
||||||
|
}
|
||||||
|
if (lights.u_pointLightPosition.length) {
|
||||||
|
if (_effect.hasUniform(DefaultUniform.u_pointLightPosition))
|
||||||
|
_effect.setUniform(DefaultUniform.u_pointLightPosition, lights.u_pointLightPosition);
|
||||||
|
if (_effect.hasUniform(DefaultUniform.u_pointLightColor))
|
||||||
|
_effect.setUniform(DefaultUniform.u_pointLightColor, lights.u_pointLightColor);
|
||||||
|
if (_effect.hasUniform(DefaultUniform.u_pointLightRangeInverse))
|
||||||
|
_effect.setUniform(DefaultUniform.u_pointLightRangeInverse, lights.u_pointLightRangeInverse);
|
||||||
|
}
|
||||||
|
if (lights.u_spotLightPosition.length) {
|
||||||
|
if (_effect.hasUniform(DefaultUniform.u_spotLightPosition))
|
||||||
|
_effect.setUniform(DefaultUniform.u_spotLightPosition, lights.u_spotLightPosition);
|
||||||
|
if (_effect.hasUniform(DefaultUniform.u_spotLightDirection))
|
||||||
|
_effect.setUniform(DefaultUniform.u_spotLightDirection, lights.u_spotLightDirection);
|
||||||
|
if (_effect.hasUniform(DefaultUniform.u_spotLightColor))
|
||||||
|
_effect.setUniform(DefaultUniform.u_spotLightColor, lights.u_spotLightColor);
|
||||||
|
if (_effect.hasUniform(DefaultUniform.u_spotLightRangeInverse))
|
||||||
|
_effect.setUniform(DefaultUniform.u_spotLightRangeInverse, lights.u_spotLightRangeInverse);
|
||||||
|
if (_effect.hasUniform(DefaultUniform.u_spotLightInnerAngleCos))
|
||||||
|
_effect.setUniform(DefaultUniform.u_spotLightInnerAngleCos, lights.u_spotLightInnerAngleCos);
|
||||||
|
if (_effect.hasUniform(DefaultUniform.u_spotLightOuterAngleCos))
|
||||||
|
_effect.setUniform(DefaultUniform.u_spotLightOuterAngleCos, lights.u_spotLightOuterAngleCos);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawMesh(Mesh mesh) {
|
void drawMesh(Mesh mesh) {
|
||||||
|
|
|
@ -35,9 +35,28 @@ class Model : DrawableObject {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static __gshared LightParams _lightParamsBuffer;
|
||||||
|
@property protected LightParams * lights(Node3d node) {
|
||||||
|
if (!node.scene)
|
||||||
|
return null;
|
||||||
|
if (_lights.empty) {
|
||||||
|
if (node.scene.boundLights.empty)
|
||||||
|
return null;
|
||||||
|
return node.scene.boundLightsPtr;
|
||||||
|
}
|
||||||
|
if (node.scene.boundLights.empty) {
|
||||||
|
_lightParamsBuffer.reset();
|
||||||
|
_lightParamsBuffer.add(_lights);
|
||||||
|
} else {
|
||||||
|
_lightParamsBuffer.reset(node.scene.boundLights);
|
||||||
|
_lightParamsBuffer.add(_lights);
|
||||||
|
}
|
||||||
|
return &_lightParamsBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
override void draw(Node3d node, bool wireframe) {
|
override void draw(Node3d node, bool wireframe) {
|
||||||
/// override it
|
/// override it
|
||||||
_material.bind(node);
|
_material.bind(node, lights(node));
|
||||||
_material.drawMesh(_mesh);
|
_material.drawMesh(_mesh);
|
||||||
_material.unbind();
|
_material.unbind();
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,11 +69,15 @@ class Scene3d : Node3d {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Lights _lights;
|
protected LightParams _lights;
|
||||||
|
|
||||||
@property ref const(Lights) boundLights() {
|
@property ref LightParams boundLights() {
|
||||||
return _lights;
|
return _lights;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@property LightParams * boundLightsPtr() {
|
||||||
|
return _lights.empty ? null : &_lights;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// depth-first recursive node traversion, stops if visitor returns true
|
/// depth-first recursive node traversion, stops if visitor returns true
|
||||||
|
|
Loading…
Reference in New Issue