diff options
author | Ulysse Martin <you.le@live.fr> | 2016-01-17 20:41:37 +0300 |
---|---|---|
committer | Thomas Szepe <HG1_public@gmx.net> | 2016-01-17 20:47:14 +0300 |
commit | c4c2bd1350a52e18f973bba7e52e929f94ff6496 (patch) | |
tree | cb0bba24307411a8a601373806b781d49d2343c3 | |
parent | a5c419f4ccb19b0c01f3cbf5929f8a43bc503eff (diff) |
BGE: Allow access to light shadow settings with python
This patch adds a new API which allow us to access light shadow settings from python. The new API can be used to write custom GLSL materials with shadows.
Reviewers: brecht, kupoman, agoose77, panzergame, campbellbarton, moguri, hg1
Reviewed By: agoose77, panzergame, campbellbarton, moguri, hg1
Projects: #game_engine
Differential Revision: https://developer.blender.org/D1690
-rw-r--r-- | doc/python_api/rst/bge_types/bge.types.KX_LightObject.rst | 72 | ||||
-rw-r--r-- | source/blender/gpu/GPU_material.h | 2 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_material.c | 10 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_BlenderDataConversion.cpp | 9 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_Light.cpp | 70 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_Light.h | 10 | ||||
-rw-r--r-- | source/gameengine/Rasterizer/RAS_ILightObject.h | 10 | ||||
-rw-r--r-- | source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.cpp | 20 | ||||
-rw-r--r-- | source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.h | 2 |
9 files changed, 205 insertions, 0 deletions
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_LightObject.rst b/doc/python_api/rst/bge_types/bge.types.KX_LightObject.rst index 2b2bdf76b4f..f4d5b114372 100644 --- a/doc/python_api/rst/bge_types/bge.types.KX_LightObject.rst +++ b/doc/python_api/rst/bge_types/bge.types.KX_LightObject.rst @@ -48,6 +48,78 @@ base class --- :class:`KX_GameObject` :type: float + .. attribute:: shadowClipStart + + The shadowmap clip start, below which objects will not generate shadows. + + :type: float (read only) + + .. attribute:: shadowClipEnd + + The shadowmap clip end, beyond which objects will not generate shadows. + + :type: float (read only) + + ..attribute:: shadowFrustumSize + + Size of the frustum used for creating the shadowmap. + + :type: float (read only) + + ..attribute:: shadowBindId + + The OpenGL shadow texture bind number/id. + + :type: int (read only) + + ..attribute:: shadowMapType + + The shadow shadow map type (0 -> Simple; 1 -> Variance) + + :type: int (read only) + + ..attribute:: shadowBias + + The shadow buffer sampling bias. + + :type: float (read only) + + ..attribute:: shadowBleedBias + + The bias for reducing light-bleed on variance shadow maps. + + :type: float (read only) + + ..attribute:: useShadow + + Returns True if the light has Shadow option activated, else returns False. + + :type: boolean (read only) + + .. attribute:: shadowColor + + The color of this light shadows. Black = (0.0, 0.0, 0.0), White = (1.0, 1.0, 1.0). + + :type: :class:`mathutils.Color` (read only) + + .. attribute:: shadowMatrix + + Matrix that converts a vector in camera space to shadow buffer depth space. + + Computed as: + mat4_perspective_to_depth * mat4_lamp_to_perspective * mat4_world_to_lamp * mat4_cam_to_world. + + mat4_perspective_to_depth is a fixed matrix defined as follow: + + 0.5 0.0 0.0 0.5 + 0.0 0.5 0.0 0.5 + 0.0 0.0 0.5 0.5 + 0.0 0.0 0.0 1.0 + Note: + There is one matrix of that type per lamp casting shadow in the scene. + + :type: Matrix4x4 (read only) + .. attribute:: distance The maximum distance this light can illuminate. (SPOT and NORMAL lights only). diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 40b32862e9f..25788c26fea 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -306,6 +306,8 @@ void GPU_lamp_update_buffer_mats(GPULamp *lamp); void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4]); void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp); int GPU_lamp_shadow_buffer_type(GPULamp *lamp); +int GPU_lamp_shadow_bind_code(GPULamp *lamp); +float *GPU_lamp_dynpersmat(GPULamp *lamp); void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4]); void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy); diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 2c5054c0d62..29e49ca89d3 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -2275,6 +2275,16 @@ int GPU_lamp_shadow_buffer_type(GPULamp *lamp) return lamp->la->shadowmap_type; } +int GPU_lamp_shadow_bind_code(GPULamp *lamp) +{ + return lamp->tex ? GPU_texture_opengl_bindcode(lamp->tex) : -1; +} + +float *GPU_lamp_dynpersmat(GPULamp *lamp) +{ + return lamp->dynpersmat ? (float *)lamp->dynpersmat : NULL; +} + int GPU_lamp_shadow_layer(GPULamp *lamp) { if (lamp->fb && lamp->tex && (lamp->mode & (LA_LAYER | LA_LAYER_SHADOW))) diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index f542525dd1e..0f55438ecf6 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1432,6 +1432,15 @@ static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int l lightobj->m_color[2] = la->b; lightobj->m_distance = la->dist; lightobj->m_energy = la->energy; + lightobj->m_shadowclipstart = la->clipsta; + lightobj->m_shadowclipend = la->clipend; + lightobj->m_shadowbias = la->bias; + lightobj->m_shadowbleedbias = la->bleedbias; + lightobj->m_shadowmaptype = la->shadowmap_type; + lightobj->m_shadowfrustumsize = la->shadow_frustum_size; + lightobj->m_shadowcolor[0] = la->shdwr; + lightobj->m_shadowcolor[1] = la->shdwg; + lightobj->m_shadowcolor[2] = la->shdwb; lightobj->m_layer = layerflag; lightobj->m_spotblend = la->spotblend; lightobj->m_spotsize = la->spotsize; diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index b681f10804a..9ccf60b15ce 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -158,6 +158,16 @@ PyAttributeDef KX_LightObject::Attributes[] = { KX_PYATTRIBUTE_RW_FUNCTION("quad_attenuation", KX_LightObject, pyattr_get_quad_attenuation, pyattr_set_quad_attenuation), KX_PYATTRIBUTE_RW_FUNCTION("spotsize", KX_LightObject, pyattr_get_spotsize, pyattr_set_spotsize), KX_PYATTRIBUTE_RW_FUNCTION("spotblend", KX_LightObject, pyattr_get_spotblend, pyattr_set_spotblend), + KX_PYATTRIBUTE_RO_FUNCTION("shadowClipStart", KX_LightObject, pyattr_get_shadow_clip_start), + KX_PYATTRIBUTE_RO_FUNCTION("shadowClipEnd", KX_LightObject, pyattr_get_shadow_clip_end), + KX_PYATTRIBUTE_RO_FUNCTION("shadowFrustumSize", KX_LightObject, pyattr_get_shadow_frustum_size), + KX_PYATTRIBUTE_RO_FUNCTION("shadowBias", KX_LightObject, pyattr_get_shadow_bias), + KX_PYATTRIBUTE_RO_FUNCTION("shadowBleedBias", KX_LightObject, pyattr_get_shadow_bleed_bias), + KX_PYATTRIBUTE_RO_FUNCTION("shadowBindId", KX_LightObject, pyattr_get_shadow_bind_code), + KX_PYATTRIBUTE_RO_FUNCTION("shadowMapType", KX_LightObject, pyattr_get_shadow_map_type), + KX_PYATTRIBUTE_RO_FUNCTION("shadowColor", KX_LightObject, pyattr_get_shadow_color), + KX_PYATTRIBUTE_RO_FUNCTION("useShadow", KX_LightObject, pyattr_get_shadow_active), + KX_PYATTRIBUTE_RO_FUNCTION("shadowMatrix", KX_LightObject, pyattr_get_shadow_matrix), KX_PYATTRIBUTE_RO_FUNCTION("SPOT", KX_LightObject, pyattr_get_typeconst), KX_PYATTRIBUTE_RO_FUNCTION("SUN", KX_LightObject, pyattr_get_typeconst), KX_PYATTRIBUTE_RO_FUNCTION("NORMAL", KX_LightObject, pyattr_get_typeconst), @@ -219,6 +229,66 @@ int KX_LightObject::pyattr_set_energy(void *self_v, const KX_PYATTRIBUTE_DEF *at return PY_SET_ATTR_FAIL; } +PyObject *KX_LightObject::pyattr_get_shadow_clip_start(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_LightObject *self = static_cast<KX_LightObject *>(self_v); + return PyFloat_FromDouble(self->m_lightobj->m_shadowclipstart); +} + +PyObject *KX_LightObject::pyattr_get_shadow_clip_end(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_LightObject *self = static_cast<KX_LightObject *>(self_v); + return PyFloat_FromDouble(self->m_lightobj->m_shadowclipend); +} + +PyObject *KX_LightObject::pyattr_get_shadow_frustum_size(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_LightObject *self = static_cast<KX_LightObject *>(self_v); + return PyFloat_FromDouble(self->m_lightobj->m_shadowfrustumsize); +} + +PyObject *KX_LightObject::pyattr_get_shadow_bind_code(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_LightObject *self = static_cast<KX_LightObject *>(self_v); + return PyLong_FromLong(self->m_lightobj->GetShadowBindCode()); +} + +PyObject *KX_LightObject::pyattr_get_shadow_bias(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_LightObject *self = static_cast<KX_LightObject *>(self_v); + return PyFloat_FromDouble(self->m_lightobj->m_shadowbias); +} + +PyObject *KX_LightObject::pyattr_get_shadow_bleed_bias(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_LightObject *self = static_cast<KX_LightObject *>(self_v); + return PyFloat_FromDouble(self->m_lightobj->m_shadowbleedbias); +} + +PyObject *KX_LightObject::pyattr_get_shadow_map_type(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_LightObject *self = static_cast<KX_LightObject *>(self_v); + return PyLong_FromLong(self->m_lightobj->m_shadowmaptype); +} + +PyObject *KX_LightObject::pyattr_get_shadow_matrix(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_LightObject *self = static_cast<KX_LightObject *>(self_v); + return PyObjectFrom(self->m_lightobj->GetShadowMatrix()); +} + +PyObject *KX_LightObject::pyattr_get_shadow_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_LightObject *self = static_cast<KX_LightObject *>(self_v); + return PyColorFromVector(MT_Vector3(self->m_lightobj->m_shadowcolor)); +} + +PyObject *KX_LightObject::pyattr_get_shadow_active(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_LightObject *self = static_cast<KX_LightObject *>(self_v); + return PyBool_FromLong(self->m_lightobj->HasShadowBuffer()); +} + PyObject *KX_LightObject::pyattr_get_distance(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_LightObject* self = static_cast<KX_LightObject*>(self_v); diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h index 3a58584223d..b446acd6e63 100644 --- a/source/gameengine/Ketsji/KX_Light.h +++ b/source/gameengine/Ketsji/KX_Light.h @@ -70,6 +70,16 @@ public: static int pyattr_set_layer(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static PyObject* pyattr_get_energy(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_energy(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); + static PyObject *pyattr_get_shadow_clip_start(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject *pyattr_get_shadow_clip_end(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject *pyattr_get_shadow_frustum_size(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject *pyattr_get_shadow_bind_code(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject *pyattr_get_shadow_bias(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject *pyattr_get_shadow_bleed_bias(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject *pyattr_get_shadow_map_type(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject *pyattr_get_shadow_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject *pyattr_get_shadow_active(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject *pyattr_get_shadow_matrix(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_distance(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_distance(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static PyObject* pyattr_get_color(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Rasterizer/RAS_ILightObject.h b/source/gameengine/Rasterizer/RAS_ILightObject.h index f087f3bbb70..59475200a73 100644 --- a/source/gameengine/Rasterizer/RAS_ILightObject.h +++ b/source/gameengine/Rasterizer/RAS_ILightObject.h @@ -38,6 +38,7 @@ class KX_Camera; class KX_Scene; class MT_Transform; +class MT_Matrix4x4; struct Image; @@ -56,6 +57,13 @@ public: float m_energy; float m_distance; + float m_shadowclipstart; + float m_shadowfrustumsize; + float m_shadowclipend; + float m_shadowbias; + float m_shadowbleedbias; + short m_shadowmaptype; + float m_shadowcolor[3]; float m_color[3]; @@ -74,6 +82,8 @@ public: virtual RAS_ILightObject* Clone() = 0; virtual bool HasShadowBuffer() = 0; + virtual int GetShadowBindCode() = 0; + virtual MT_Matrix4x4 GetShadowMatrix() = 0; virtual int GetShadowLayer() = 0; virtual void BindShadowBuffer(RAS_ICanvas *canvas, KX_Camera *cam, MT_Transform& camtrans) = 0; virtual void UnbindShadowBuffer() = 0; diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.cpp index 8319b75331f..beb2d67f9f5 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.cpp @@ -177,6 +177,26 @@ bool RAS_OpenGLLight::HasShadowBuffer() return false; } +int RAS_OpenGLLight::GetShadowBindCode() +{ + GPULamp *lamp; + + if ((lamp = GetGPULamp())) + return GPU_lamp_shadow_bind_code(lamp); + return -1; +} + +MT_Matrix4x4 RAS_OpenGLLight::GetShadowMatrix() +{ + GPULamp *lamp; + + if ((lamp = GetGPULamp())) + return MT_Matrix4x4(GPU_lamp_dynpersmat(lamp)); + MT_Matrix4x4 mat; + mat.setIdentity(); + return mat; +} + int RAS_OpenGLLight::GetShadowLayer() { GPULamp *lamp; diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.h index 0c4e5bf41c4..a520b18c434 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.h @@ -46,6 +46,8 @@ public: RAS_OpenGLLight* Clone() { return new RAS_OpenGLLight(*this); } bool HasShadowBuffer(); + int GetShadowBindCode(); + MT_Matrix4x4 GetShadowMatrix(); int GetShadowLayer(); void BindShadowBuffer(RAS_ICanvas *canvas, KX_Camera *cam, MT_Transform& camtrans); void UnbindShadowBuffer(); |