aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/ESceneNodeTypes.h6
-rw-r--r--include/IAnimatedMeshSceneNode.h27
-rw-r--r--include/ILightSceneNode.h86
-rw-r--r--include/IMeshSceneNode.h26
-rw-r--r--include/ISceneManager.h31
-rw-r--r--include/IShadowVolumeSceneNode.h64
-rw-r--r--include/IVideoDriver.h70
-rw-r--r--include/irrlicht.h1
8 files changed, 311 insertions, 0 deletions
diff --git a/include/ESceneNodeTypes.h b/include/ESceneNodeTypes.h
index 2573ca0..f9442f3 100644
--- a/include/ESceneNodeTypes.h
+++ b/include/ESceneNodeTypes.h
@@ -21,9 +21,15 @@ namespace scene
//! of type CSceneManager (note that ISceneManager is not(!) an ISceneNode)
ESNT_SCENE_MANAGER = MAKE_IRR_ID('s','m','n','g'),
+ //! Shadow Volume Scene Node
+ ESNT_SHADOW_VOLUME = MAKE_IRR_ID('s','h','d','w'),
+
//! Mesh Scene Node
ESNT_MESH = MAKE_IRR_ID('m','e','s','h'),
+ //! Light Scene Node
+ ESNT_LIGHT = MAKE_IRR_ID('l','g','h','t'),
+
//! Empty Scene Node
ESNT_EMPTY = MAKE_IRR_ID('e','m','t','y'),
diff --git a/include/IAnimatedMeshSceneNode.h b/include/IAnimatedMeshSceneNode.h
index ef16dd8..f3d3f7b 100644
--- a/include/IAnimatedMeshSceneNode.h
+++ b/include/IAnimatedMeshSceneNode.h
@@ -13,6 +13,8 @@ namespace irr
{
namespace scene
{
+ class IShadowVolumeSceneNode;
+
enum E_JOINT_UPDATE_ON_RENDER
{
//! do nothing
@@ -85,6 +87,31 @@ namespace scene
/** \return Frames per second played. */
virtual f32 getAnimationSpeed() const =0;
+ /** The shadow can be rendered using the ZPass or the zfail
+ method. ZPass is a little bit faster because the shadow volume
+ creation is easier, but with this method there occur ugly
+ looking artifacts when the camera is inside the shadow volume.
+ These error do not occur with the ZFail method, but it can
+ have trouble with clipping to the far-plane (it usually works
+ well in OpenGL and fails with other drivers).
+ \param shadowMesh: Optional custom mesh for shadow volume.
+ \param id: Id of the shadow scene node. This id can be used to
+ identify the node later.
+ \param zfailmethod: If set to true, the shadow will use the
+ zfail method, if not, zpass is used.
+ \param infinity: Value used by the shadow volume algorithm to
+ scale the shadow volume. For zfail shadow volumes on some drivers
+ only support finite shadows, so camera zfar must be larger than
+ shadow back cap,which is depending on the infinity parameter).
+ Infinity value also scales by the scaling factors of the model.
+ If shadows don't show up with zfail then try reducing infinity.
+ If shadows are cut-off then try increasing infinity.
+ \return Pointer to the created shadow scene node. This pointer
+ should not be dropped. See IReferenceCounted::drop() for more
+ information. */
+ virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(const IMesh* shadowMesh=0,
+ s32 id=-1, bool zfailmethod=true, f32 infinity=1000.0f) = 0;
+
//! Get a pointer to a joint in the mesh (if the mesh is a bone based mesh).
/** With this method it is possible to attach scene nodes to
joints for example possible to attach a weapon to the left hand
diff --git a/include/ILightSceneNode.h b/include/ILightSceneNode.h
new file mode 100644
index 0000000..ccf7cdb
--- /dev/null
+++ b/include/ILightSceneNode.h
@@ -0,0 +1,86 @@
+// Copyright (C) 2002-2012 Nikolaus Gebhardt
+// This file is part of the "Irrlicht Engine".
+// For conditions of distribution and use, see copyright notice in irrlicht.h
+
+#ifndef IRR_I_LIGHT_SCENE_NODE_H_INCLUDED
+#define IRR_I_LIGHT_SCENE_NODE_H_INCLUDED
+
+#include "ISceneNode.h"
+#include "SLight.h"
+
+namespace irr
+{
+namespace scene
+{
+
+//! Scene node which is a dynamic light.
+/** You can switch the light on and off by making it visible or not. It can be
+animated by ordinary scene node animators. If the light type is directional or
+spot, the direction of the light source is defined by the rotation of the scene
+node (assuming (0,0,1) as the local direction of the light).
+*/
+class ILightSceneNode : public ISceneNode
+{
+public:
+
+ //! constructor
+ ILightSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,
+ const core::vector3df& position = core::vector3df(0,0,0))
+ : ISceneNode(parent, mgr, id, position) {}
+
+ //! Sets the light data associated with this ILightSceneNode
+ /** \param light The new light data. */
+ virtual void setLightData(const video::SLight& light) = 0;
+
+ //! Gets the light data associated with this ILightSceneNode
+ /** \return The light data. */
+ virtual const video::SLight& getLightData() const = 0;
+
+ //! Gets the light data associated with this ILightSceneNode
+ /** \return The light data. */
+ virtual video::SLight& getLightData() = 0;
+
+ //! Sets if the node should be visible or not.
+ /** All children of this node won't be visible either, when set
+ to true.
+ \param isVisible If the node shall be visible. */
+ virtual void setVisible(bool isVisible) = 0;
+
+ //! Sets the light's radius of influence.
+ /** Outside this radius the light won't lighten geometry and cast no
+ shadows. Setting the radius will also influence the attenuation, setting
+ it to (0,1/radius,0). If you want to override this behavior, set the
+ attenuation after the radius.
+ NOTE: On OpenGL only the attenuation is set, there's no hard range.
+ \param radius The new radius. */
+ virtual void setRadius(f32 radius) = 0;
+
+ //! Gets the light's radius of influence.
+ /** \return The current radius. */
+ virtual f32 getRadius() const = 0;
+
+ //! Sets the light type.
+ /** \param type The new type. */
+ virtual void setLightType(video::E_LIGHT_TYPE type) = 0;
+
+ //! Gets the light type.
+ /** \return The current light type. */
+ virtual video::E_LIGHT_TYPE getLightType() const = 0;
+
+ //! Sets whether this light casts shadows.
+ /** Enabling this flag won't automatically cast shadows, the meshes
+ will still need shadow scene nodes attached. But one can enable or
+ disable distinct lights for shadow casting for performance reasons.
+ \param shadow True if this light shall cast shadows. */
+ virtual void enableCastShadow(bool shadow=true) = 0;
+
+ //! Check whether this light casts shadows.
+ /** \return True if light would cast shadows, else false. */
+ virtual bool getCastShadow() const = 0;
+};
+
+} // end namespace scene
+} // end namespace irr
+
+
+#endif
diff --git a/include/IMeshSceneNode.h b/include/IMeshSceneNode.h
index d4f6fff..e4b3b05 100644
--- a/include/IMeshSceneNode.h
+++ b/include/IMeshSceneNode.h
@@ -12,6 +12,7 @@ namespace irr
namespace scene
{
+class IShadowVolumeSceneNode;
class IMesh;
@@ -37,6 +38,31 @@ public:
/** \return Pointer to mesh which is displayed by this node. */
virtual IMesh* getMesh(void) = 0;
+ /** The shadow can be rendered using the ZPass or the zfail
+ method. ZPass is a little bit faster because the shadow volume
+ creation is easier, but with this method there occur ugly
+ looking artifacts when the camera is inside the shadow volume.
+ These error do not occur with the ZFail method, but it can
+ have trouble with clipping to the far-plane (it usually works
+ well in OpenGL and fails with other drivers).
+ \param shadowMesh: Optional custom mesh for shadow volume.
+ \param id: Id of the shadow scene node. This id can be used to
+ identify the node later.
+ \param zfailmethod: If set to true, the shadow will use the
+ zfail method, if not, zpass is used.
+ \param infinity: Value used by the shadow volume algorithm to
+ scale the shadow volume. For zfail shadow volumes on some drivers
+ only suppport finite shadows, so camera zfar must be larger than
+ shadow back cap,which is depending on the infinity parameter).
+ Infinity value also scales by the scaling factors of the model.
+ If shadows don't show up with zfail then try reducing infinity.
+ If shadows are cut-off then try increasing infinity.
+ \return Pointer to the created shadow scene node. This pointer
+ should not be dropped. See IReferenceCounted::drop() for more
+ information. */
+ virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(const IMesh* shadowMesh=0,
+ s32 id=-1, bool zfailmethod=true, f32 infinity=1000.0f) = 0;
+
//! Sets if the scene node should not copy the materials of the mesh but use them in a read only style.
/** In this way it is possible to change the materials of a mesh
causing all mesh scene nodes referencing this mesh to change, too.
diff --git a/include/ISceneManager.h b/include/ISceneManager.h
index 9379a9c..4cd31e2 100644
--- a/include/ISceneManager.h
+++ b/include/ISceneManager.h
@@ -102,6 +102,7 @@ namespace scene
class IBillboardSceneNode;
class ICameraSceneNode;
class IDummyTransformationSceneNode;
+ class ILightSceneNode;
class IMesh;
class IMeshBuffer;
class IMeshCache;
@@ -112,6 +113,7 @@ namespace scene
class IMeshWriter;
class ISceneNode;
class ISceneNodeFactory;
+ class IShadowVolumeSceneNode;
//! The Scene Manager manages scene nodes, mesh resources, cameras and all the other stuff.
/** All Scene nodes can be created only here.
@@ -392,6 +394,24 @@ namespace scene
const core::vector3df& lookat = core::vector3df(0,0,100),
s32 id=-1, bool makeActive=true) = 0;
+ //! Adds a dynamic light scene node to the scene graph.
+ /** The light will cast dynamic light on all
+ other scene nodes in the scene, which have the material flag video::MTF_LIGHTING
+ turned on. (This is the default setting in most scene nodes).
+ \param parent: Parent scene node of the light. Can be null. If the parent moves,
+ the light will move too.
+ \param position: Position of the space relative to its parent where the light will be placed.
+ \param color: Diffuse color of the light. Ambient or Specular colors can be set manually with
+ the ILightSceneNode::getLightData() method.
+ \param radius: Radius of the light.
+ \param id: id of the node. This id can be used to identify the node.
+ \return Pointer to the interface of the light if successful, otherwise NULL.
+ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
+ virtual ILightSceneNode* addLightSceneNode(ISceneNode* parent = 0,
+ const core::vector3df& position = core::vector3df(0,0,0),
+ video::SColorf color = video::SColorf(1.0f, 1.0f, 1.0f),
+ f32 radius=100.0f, s32 id=-1) = 0;
+
//! Adds a billboard scene node to the scene graph.
/** A billboard is like a 3d sprite: A 2d element,
which always looks to the camera. It is usually used for things
@@ -493,6 +513,17 @@ namespace scene
\param camera: The new camera which should be active. */
virtual void setActiveCamera(ICameraSceneNode* camera) = 0;
+ //! Sets the color of stencil buffers shadows drawn by the scene manager.
+ virtual void setShadowColor(video::SColor color = video::SColor(150,0,0,0)) = 0;
+
+ //! Get the current color of shadows.
+ virtual video::SColor getShadowColor() const = 0;
+
+ //! Create a shadow volume scene node to be used with custom nodes
+ /** Use this if you implement your own SceneNodes and need shadow volumes in them.
+ Otherwise you should generally use addShadowVolumeSceneNode functions from IMeshSceneNode or IAnimatedMeshSceneNode.*/
+ virtual IShadowVolumeSceneNode* createShadowVolumeSceneNode(const IMesh* shadowMesh, ISceneNode* parent, s32 id, bool zfailmethod, f32 infinity) = 0;
+
//! Registers a node for rendering it at a specific time.
/** This method should only be used by SceneNodes when they get a
ISceneNode::OnRegisterSceneNode() call.
diff --git a/include/IShadowVolumeSceneNode.h b/include/IShadowVolumeSceneNode.h
new file mode 100644
index 0000000..7f661cd
--- /dev/null
+++ b/include/IShadowVolumeSceneNode.h
@@ -0,0 +1,64 @@
+// Copyright (C) 2002-2012 Nikolaus Gebhardt
+// This file is part of the "Irrlicht Engine".
+// For conditions of distribution and use, see copyright notice in irrlicht.h
+
+#ifndef IRR_I_SHADOW_VOLUME_SCENE_NODE_H_INCLUDED
+#define IRR_I_SHADOW_VOLUME_SCENE_NODE_H_INCLUDED
+
+#include "ISceneNode.h"
+
+namespace irr
+{
+namespace scene
+{
+ class IMesh;
+
+ enum ESHADOWVOLUME_OPTIMIZATION
+ {
+ //! Create volumes around every triangle
+ ESV_NONE,
+
+ //! Create volumes only around the silhouette of the mesh
+ /** This can reduce the number of volumes drastically,
+ but will have an upfront-cost where it calculates adjacency of
+ triangles. Also it will not work with all models. Basically
+ if you see strange black shadow lines then you have a model
+ for which it won't work.
+ We get that information about adjacency by comparing the positions of
+ all edges in the mesh (even if they are in different meshbuffers). */
+ ESV_SILHOUETTE_BY_POS
+ };
+
+ //! Scene node for rendering a shadow volume into a stencil buffer.
+ class IShadowVolumeSceneNode : public ISceneNode
+ {
+ public:
+
+ //! constructor
+ IShadowVolumeSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id)
+ : ISceneNode(parent, mgr, id) {}
+
+ //! Sets the mesh from which the shadow volume should be generated.
+ /** To optimize shadow rendering, use a simpler mesh for shadows.
+ */
+ virtual void setShadowMesh(const IMesh* mesh) = 0;
+
+ //! Updates the shadow volumes for current light positions.
+ virtual void updateShadowVolumes() = 0;
+
+ //! Set optimization used to create shadow volumes
+ /** Default is ESV_SILHOUETTE_BY_POS. If the shadow
+ looks bad then give ESV_NONE a try (which will be slower).
+ Alternatively you can try to fix the model, it's often
+ because it's not closed (aka if you'd put water in it then
+ that would leak out). */
+ virtual void setOptimization(ESHADOWVOLUME_OPTIMIZATION optimization) = 0;
+
+ //! Get currently active optimization used to create shadow volumes
+ virtual ESHADOWVOLUME_OPTIMIZATION getOptimization() const = 0;
+ };
+
+} // end namespace scene
+} // end namespace irr
+
+#endif
diff --git a/include/IVideoDriver.h b/include/IVideoDriver.h
index ef8e38e..b2d0004 100644
--- a/include/IVideoDriver.h
+++ b/include/IVideoDriver.h
@@ -41,6 +41,7 @@ namespace video
struct S3DVertex;
struct S3DVertex2TCoords;
struct S3DVertexTangents;
+ struct SLight;
class IImageLoader;
class IImageWriter;
class IMaterialRenderer;
@@ -844,6 +845,48 @@ namespace video
const core::position2d<s32>& end,
SColor color=SColor(255,255,255,255)) =0;
+ //! Draws a shadow volume into the stencil buffer.
+ /** To draw a stencil shadow, do this: First, draw all geometry.
+ Then use this method, to draw the shadow volume. Then, use
+ IVideoDriver::drawStencilShadow() to visualize the shadow.
+ Please note that the code for the opengl version of the method
+ is based on free code sent in by Philipp Dortmann, lots of
+ thanks go to him!
+ \param triangles Array of 3d vectors, specifying the shadow
+ volume.
+ \param zfail If set to true, zfail method is used, otherwise
+ zpass.
+ \param debugDataVisible The debug data that is enabled for this
+ shadow node
+ */
+ virtual void drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail=true, u32 debugDataVisible=0) =0;
+
+ //! Fills the stencil shadow with color.
+ /** After the shadow volume has been drawn into the stencil
+ buffer using IVideoDriver::drawStencilShadowVolume(), use this
+ to draw the color of the shadow.
+ Please note that the code for the opengl version of the method
+ is based on free code sent in by Philipp Dortmann, lots of
+ thanks go to him!
+ \param clearStencilBuffer Set this to false, if you want to
+ draw every shadow with the same color, and only want to call
+ drawStencilShadow() once after all shadow volumes have been
+ drawn. Set this to true, if you want to paint every shadow with
+ its own color.
+ \param leftUpEdge Color of the shadow in the upper left corner
+ of screen.
+ \param rightUpEdge Color of the shadow in the upper right
+ corner of screen.
+ \param leftDownEdge Color of the shadow in the lower left
+ corner of screen.
+ \param rightDownEdge Color of the shadow in the lower right
+ corner of screen. */
+ virtual void drawStencilShadow(bool clearStencilBuffer=false,
+ video::SColor leftUpEdge = video::SColor(255,0,0,0),
+ video::SColor rightUpEdge = video::SColor(255,0,0,0),
+ video::SColor leftDownEdge = video::SColor(255,0,0,0),
+ video::SColor rightDownEdge = video::SColor(255,0,0,0)) =0;
+
//! Draws a mesh buffer
/** \param mb Buffer to draw */
virtual void drawMeshBuffer(const scene::IMeshBuffer* mb) =0;
@@ -912,6 +955,33 @@ namespace video
\return Amount of primitives drawn in the last frame. */
virtual u32 getPrimitiveCountDrawn( u32 mode =0 ) const =0;
+ //! Deletes all dynamic lights which were previously added with addDynamicLight().
+ virtual void deleteAllDynamicLights() =0;
+
+ //! adds a dynamic light, returning an index to the light
+ //! \param light: the light data to use to create the light
+ //! \return An index to the light, or -1 if an error occurs
+ virtual s32 addDynamicLight(const SLight& light) =0;
+
+ //! Returns the maximal amount of dynamic lights the device can handle
+ /** \return Maximal amount of dynamic lights. */
+ virtual u32 getMaximalDynamicLightAmount() const =0;
+
+ //! Returns amount of dynamic lights currently set
+ /** \return Amount of dynamic lights currently set */
+ virtual u32 getDynamicLightCount() const =0;
+
+ //! Returns light data which was previously set by IVideoDriver::addDynamicLight().
+ /** \param idx Zero based index of the light. Must be 0 or
+ greater and smaller than IVideoDriver::getDynamicLightCount.
+ \return Light data. */
+ virtual const SLight& getDynamicLight(u32 idx) const =0;
+
+ //! Turns a dynamic light on or off
+ //! \param lightIndex: the index returned by addDynamicLight
+ //! \param turnOn: true to turn the light on, false to turn it off
+ virtual void turnLightOn(s32 lightIndex, bool turnOn) =0;
+
//! Gets name of this video driver.
/** \return Returns the name of the video driver, e.g. in case
of the Direct3D8 driver, it would return "Direct3D 8.1". */
diff --git a/include/irrlicht.h b/include/irrlicht.h
index 359f810..37b961d 100644
--- a/include/irrlicht.h
+++ b/include/irrlicht.h
@@ -105,6 +105,7 @@
#include "ISceneManager.h"
#include "ISceneNode.h"
#include "IShaderConstantSetCallBack.h"
+#include "IShadowVolumeSceneNode.h"
#include "ISkinnedMesh.h"
#include "ITexture.h"
#include "ITimer.h"