forked from Mirrorlandia_minetest/irrlicht
Merging r6468 through r6486 from trunk to ogl-es branch
Also updating ES&ES2 interface to work with removal of IMaterialRendererServices::setBasicRenderStates git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@6487 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
parent
e4bb544079
commit
1670db617b
@ -11,6 +11,8 @@ Changes in ogl-es (not yet released - will be merged with trunk at some point)
|
||||
--------------------------
|
||||
Changes in 1.9 (not yet released)
|
||||
|
||||
- Add IMeshSceneNode::setNodeRegistration to allow registering MeshSceneNodes to the SceneManager per buffer instead of per node
|
||||
- Add SMaterialLayer::hasSetTextureMatrix and SMaterialLayer::resetTextureMatrix
|
||||
- Add IShaderConstantSetCallBack::OnCreate to allow earlier access to IMaterialRendererServices
|
||||
- CIrrDeviceWin32::yield() now uses Sleep(0) instead of Sleep(1).
|
||||
We had Sleep(1) to allow yielding to all processes back in Windows XP time.
|
||||
|
@ -255,7 +255,7 @@ void loadModel(const io::path& filename)
|
||||
// that's not so simple. so we do it brute force
|
||||
gui::IGUIContextMenu* menu = (gui::IGUIContextMenu*)Device->getGUIEnvironment()->getRootGUIElement()->getElementFromId(GUI_ID_TOGGLE_DEBUG_INFO, true);
|
||||
if (menu)
|
||||
for(int item = 1; item < 6; ++item)
|
||||
for(int item = 1; item < 7; ++item)
|
||||
menu->setItemChecked(item, false);
|
||||
updateScaleInfo(Model);
|
||||
}
|
||||
|
@ -17,7 +17,11 @@ namespace scene
|
||||
//! Only transform the position of the node transformation matrix
|
||||
//! by the parent transformation matrix.
|
||||
//! Parent will not affect the rotation/scale of the node transformation.
|
||||
ESNUA_TRANSFORM_POSITION
|
||||
ESNUA_TRANSFORM_POSITION,
|
||||
|
||||
//! Use the relative matrix as absolute transformation matrix
|
||||
//! Parent node transformation is ignored just like when the parent is set to 0
|
||||
ESNUA_RELATIVE
|
||||
};
|
||||
|
||||
//! Names for culling type
|
||||
@ -25,6 +29,7 @@ namespace scene
|
||||
{
|
||||
"matrix",
|
||||
"pos",
|
||||
"relative",
|
||||
0
|
||||
};
|
||||
|
||||
|
@ -24,20 +24,6 @@ public:
|
||||
//! Destructor
|
||||
virtual ~IMaterialRendererServices() {}
|
||||
|
||||
//! Can be called by an IMaterialRenderer to make its work easier.
|
||||
/** Sets all basic renderstates if needed.
|
||||
Basic render states are diffuse, ambient, specular, and emissive color,
|
||||
specular power, bilinear and trilinear filtering, wireframe mode,
|
||||
gouraudshading, lighting, zbuffer, zwriteenable, backfaceculling and
|
||||
fog enabling.
|
||||
\param material The new material to be used.
|
||||
\param lastMaterial The material used until now.
|
||||
\param resetAllRenderstates Set to true if all renderstates should be
|
||||
set, regardless of their current state. */
|
||||
virtual void setBasicRenderStates(const SMaterial& material,
|
||||
const SMaterial& lastMaterial,
|
||||
bool resetAllRenderstates) = 0;
|
||||
|
||||
//! Return an index constant for the vertex shader based on a name.
|
||||
virtual s32 getVertexShaderConstantID(const c8* name) = 0;
|
||||
|
||||
|
@ -15,6 +15,20 @@ namespace scene
|
||||
class IShadowVolumeSceneNode;
|
||||
class IMesh;
|
||||
|
||||
//! Option for nodes how to register themeselves at the SceneManager
|
||||
enum ENodeRegistration
|
||||
{
|
||||
//! Each node registers once and renders all it's mesh-buffers
|
||||
ENR_DEFAULT,
|
||||
|
||||
//! Register a new node per mesh-buffer at the SceneManager
|
||||
//! It allows the SceneManager to sort in each render stage per buffer instead of per node.
|
||||
//! This can be useful when having several transparent buffers in a mesh.
|
||||
//! Depending on the scene (and hardware) this can have a positive or negative effect on performance.
|
||||
//! It can avoid texture-switches, but adds nodes to sort and more matrix transformations are set.
|
||||
ENR_PER_MESH_BUFFER
|
||||
};
|
||||
|
||||
|
||||
//! A scene node displaying a static mesh
|
||||
class IMeshSceneNode : public ISceneNode
|
||||
@ -28,9 +42,11 @@ public:
|
||||
const core::vector3df& position = core::vector3df(0,0,0),
|
||||
const core::vector3df& rotation = core::vector3df(0,0,0),
|
||||
const core::vector3df& scale = core::vector3df(1,1,1))
|
||||
: ISceneNode(parent, mgr, id, position, rotation, scale) {}
|
||||
: ISceneNode(parent, mgr, id, position, rotation, scale)
|
||||
, NodeRegistration(ENR_DEFAULT)
|
||||
{}
|
||||
|
||||
//! Sets a new mesh to display
|
||||
//! Sets a new mesh to display or update mesh when it changed
|
||||
/** \param mesh Mesh to display. */
|
||||
virtual void setMesh(IMesh* mesh) = 0;
|
||||
|
||||
@ -73,6 +89,23 @@ public:
|
||||
/** This flag can be set by setReadOnlyMaterials().
|
||||
\return Whether the materials are read-only. */
|
||||
virtual bool isReadOnlyMaterials() const = 0;
|
||||
|
||||
//! Set how the node registers itself to the SceneManager
|
||||
/** Note: Derived classes can ignore this flag, so think of it as a hint. */
|
||||
virtual void setNodeRegistration(ENodeRegistration nodeRegistration)
|
||||
{
|
||||
NodeRegistration = nodeRegistration;
|
||||
}
|
||||
|
||||
//! How does a node register itself to the SceneManager
|
||||
/** Note: Derived classes may ignore this flag */
|
||||
virtual ENodeRegistration getNodeRegistration() const
|
||||
{
|
||||
return NodeRegistration;
|
||||
}
|
||||
|
||||
protected:
|
||||
ENodeRegistration NodeRegistration;
|
||||
};
|
||||
|
||||
} // end namespace scene
|
||||
|
@ -66,7 +66,7 @@ namespace scene
|
||||
//! In this pass, lights are transformed into camera space and added to the driver
|
||||
ESNRP_LIGHT =2,
|
||||
|
||||
//! This is used for sky boxes.
|
||||
//! This is mostly used for sky boxes. Stage between light and solid.
|
||||
ESNRP_SKY_BOX =4,
|
||||
|
||||
//! All normal objects can use this for registering themselves.
|
||||
|
@ -79,7 +79,7 @@ namespace scene
|
||||
|
||||
//! This method is called just before the rendering process of the whole scene.
|
||||
/** Nodes may register themselves in the render pipeline during this call,
|
||||
precalculate the geometry which should be rendered, and prevent their
|
||||
pre-calculate the geometry which should be rendered, and prevent their
|
||||
children from being able to register themselves if they are clipped by simply
|
||||
not calling their OnRegisterSceneNode method.
|
||||
If you are implementing your own scene node, you should overwrite this method
|
||||
@ -95,7 +95,7 @@ namespace scene
|
||||
{
|
||||
if (IsVisible)
|
||||
{
|
||||
ISceneNodeList::Iterator it = Children.begin();
|
||||
ISceneNodeList::ConstIterator it = Children.begin();
|
||||
for (; it != Children.end(); ++it)
|
||||
(*it)->OnRegisterSceneNode();
|
||||
}
|
||||
@ -114,7 +114,7 @@ namespace scene
|
||||
{
|
||||
// animate this node with all animators
|
||||
|
||||
ISceneNodeAnimatorList::Iterator ait = Animators.begin();
|
||||
ISceneNodeAnimatorList::ConstIterator ait = Animators.begin();
|
||||
while (ait != Animators.end())
|
||||
{
|
||||
// continue to the next node before calling animateNode()
|
||||
@ -133,7 +133,7 @@ namespace scene
|
||||
|
||||
// perform the post render process on all children
|
||||
|
||||
ISceneNodeList::Iterator it = Children.begin();
|
||||
ISceneNodeList::ConstIterator it = Children.begin();
|
||||
for (; it != Children.end(); ++it)
|
||||
(*it)->OnAnimate(timeMs);
|
||||
}
|
||||
@ -543,7 +543,7 @@ namespace scene
|
||||
|
||||
|
||||
//! Set a culling style or disable culling completely.
|
||||
/** Box cullling (EAC_BOX) is set by default. Note that not
|
||||
/** Box culling (EAC_BOX) is set by default. Note that not
|
||||
all SceneNodes support culling and that some nodes always cull
|
||||
their geometry because it is their only reason for existence,
|
||||
for example the OctreeSceneNode.
|
||||
@ -682,16 +682,24 @@ namespace scene
|
||||
{
|
||||
if (Parent)
|
||||
{
|
||||
if ( AbsPosUpdateBehavior == ESNUA_TRANSFORM_MATRIX )
|
||||
switch ( AbsPosUpdateBehavior )
|
||||
{
|
||||
case ESNUA_TRANSFORM_MATRIX:
|
||||
{
|
||||
AbsoluteTransformation =
|
||||
Parent->getAbsoluteTransformation() * getRelativeTransformation();
|
||||
}
|
||||
else if ( AbsPosUpdateBehavior == ESNUA_TRANSFORM_POSITION )
|
||||
break;
|
||||
case ESNUA_TRANSFORM_POSITION:
|
||||
{
|
||||
AbsoluteTransformation = getRelativeTransformation();
|
||||
Parent->getAbsoluteTransformation().transformVect(reinterpret_cast<irr::core::vector3df&>(AbsoluteTransformation[12]));
|
||||
}
|
||||
break;
|
||||
case ESNUA_RELATIVE:
|
||||
AbsoluteTransformation = getRelativeTransformation();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
AbsoluteTransformation = getRelativeTransformation();
|
||||
@ -821,7 +829,7 @@ namespace scene
|
||||
|
||||
// clone children
|
||||
|
||||
ISceneNodeList::Iterator it = toCopyFrom->Children.begin();
|
||||
ISceneNodeList::ConstIterator it = toCopyFrom->Children.begin();
|
||||
for (; it != toCopyFrom->Children.end(); ++it)
|
||||
(*it)->clone(this, newManager);
|
||||
|
||||
|
@ -45,7 +45,7 @@ namespace video
|
||||
"texture_clamp_mirror_clamp_to_border", 0};
|
||||
|
||||
//! Struct for holding material parameters which exist per texture layer
|
||||
// Note for implementors: Serialization is in CNullDriver
|
||||
// Note for implementers: Serialization is in CNullDriver
|
||||
class SMaterialLayer
|
||||
{
|
||||
public:
|
||||
@ -153,6 +153,25 @@ namespace video
|
||||
*TextureMatrix = mat;
|
||||
}
|
||||
|
||||
//! Check if we have set a custom texture matrix
|
||||
//! Note that otherwise we get an IdentityMatrix as default
|
||||
inline bool hasSetTextureMatrix() const
|
||||
{
|
||||
return TextureMatrix != 0;
|
||||
}
|
||||
|
||||
//! Reset texture matrix to identity matrix
|
||||
//! Releases memory, which is expensive, but ver rarely useful for optimizations
|
||||
void resetTextureMatrix()
|
||||
{
|
||||
if ( TextureMatrix )
|
||||
{
|
||||
MatrixAllocator.destruct(TextureMatrix);
|
||||
MatrixAllocator.deallocate(TextureMatrix);
|
||||
TextureMatrix = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//! Inequality operator
|
||||
/** \param b Layer to compare to.
|
||||
\return True if layers are different, else false. */
|
||||
|
185
source/Irrlicht/CBufferRenderNode.h
Normal file
185
source/Irrlicht/CBufferRenderNode.h
Normal file
@ -0,0 +1,185 @@
|
||||
// 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
|
||||
|
||||
#include "IMeshSceneNode.h"
|
||||
#include "IVideoDriver.h"
|
||||
#include "ISceneManager.h"
|
||||
#include "ISceneNode.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene
|
||||
{
|
||||
|
||||
// A node which helps rendering a single buffer of an IMeshSceneNode
|
||||
// It solves several problems:
|
||||
// - Allowing the scene manager to sort meshbuffers. Currently it only sorts nodes, so we have to put each meshbuffer in an extra node to allow that
|
||||
// The reason we want that is
|
||||
// a) Better sorting when a node has several transparent buffers (without it they will be just drawn in original order)
|
||||
// b) It can allow to avoid texture changes in the render-pipeline which can make quite a bit of a performance difference
|
||||
// - It buffers the RenderPass. Bit of an abuse of this interface maybe?
|
||||
// Strangely the check for finding out the correct render pass constantly shows up in profilers.
|
||||
// Not exactly sure why as the check looks pretty cheap. My best guess is that there are some cache misses going on due to several virtual
|
||||
// function pointers being involved in the transparency check.
|
||||
//
|
||||
// For now (added pre Irrlicht 1.9) this interface is still a bit experimental. Maybe could go into public headers later, not sure yet.
|
||||
// Or maybe the SceneManager shouldn't work with nodes at all but a simplified interface to render buffers from which Nodes can derive?
|
||||
// CBufferRenderNode isn't really a node - it has to work around nearly all the ISceneNode functions, it only has to be one because
|
||||
// the SceneManager can't sort anything else but nodes.
|
||||
class CBufferRenderNode : public ISceneNode
|
||||
{
|
||||
public:
|
||||
CBufferRenderNode(irr::scene::IMeshSceneNode& parent, irr::scene::ISceneManager* mgr, irr::u32 bufferIdx)
|
||||
: ISceneNode(0, mgr) // we don't want it in the scenegraph
|
||||
, MeshNodeParent(parent)
|
||||
, BufferIdx(bufferIdx)
|
||||
, RenderPass(ESNRP_NONE)
|
||||
, ParentDoesRender(true)
|
||||
{
|
||||
// While it's not the parent in the SceneGraph, we still want to allow accessing it
|
||||
// That can be useful p.E. in a light manager
|
||||
// Arguably if it's a good idea as it's a bit going against the ISceneNode interface - having a parent which doesn't have this node as child.
|
||||
// But the alternative is adding another member to the ISceneNode or having SceneManager not use the ISceneNode for rendering
|
||||
// So for now it should be fine, but if that interface ever get's public... we might have to reconsider
|
||||
Parent = &MeshNodeParent;
|
||||
}
|
||||
|
||||
u32 prepareRendering(E_SCENE_NODE_RENDER_PASS pass, bool parentDoesRender)
|
||||
{
|
||||
RenderPass = pass;
|
||||
ParentDoesRender = parentDoesRender;
|
||||
if ( !ParentDoesRender )
|
||||
return SceneManager->registerNodeForRendering(this, pass);
|
||||
return 0;
|
||||
}
|
||||
|
||||
E_SCENE_NODE_RENDER_PASS getRenderPass() const
|
||||
{
|
||||
return RenderPass;
|
||||
}
|
||||
|
||||
// When true render() this node hasn't registered itself for rendering, but expects it's owner to do the rendering
|
||||
bool getDoesParentRender() const
|
||||
{
|
||||
return ParentDoesRender;
|
||||
}
|
||||
|
||||
// Render meshbuffer, but don't set transformation
|
||||
// It's assumed that this function is only called from within the correct render stage
|
||||
void renderBuffer(video::IVideoDriver* driver)
|
||||
{
|
||||
const IMeshBuffer* mb = MeshNodeParent.getMesh()->getMeshBuffer(BufferIdx);
|
||||
if (mb)
|
||||
{
|
||||
const video::SMaterial& material = MeshNodeParent.getMaterial(BufferIdx);
|
||||
driver->setMaterial(material);
|
||||
driver->drawMeshBuffer(mb);
|
||||
}
|
||||
}
|
||||
|
||||
//! Renders the node.
|
||||
virtual void render() IRR_OVERRIDE
|
||||
{
|
||||
video::IVideoDriver* driver = SceneManager->getVideoDriver();
|
||||
driver->setTransform(video::ETS_WORLD, MeshNodeParent.getAbsoluteTransformation());
|
||||
renderBuffer(driver);
|
||||
|
||||
// resetting each time so direct calls to render() for parent node continue to work
|
||||
RenderPass = ESNRP_NONE;
|
||||
ParentDoesRender = true;
|
||||
}
|
||||
|
||||
virtual const core::aabbox3d<f32>& getBoundingBox() const IRR_OVERRIDE
|
||||
{
|
||||
return MeshNodeParent.getMesh()->getMeshBuffer(BufferIdx)->getBoundingBox();
|
||||
}
|
||||
|
||||
virtual video::SMaterial& getMaterial(u32 num) IRR_OVERRIDE
|
||||
{
|
||||
return MeshNodeParent.getMaterial(BufferIdx);
|
||||
}
|
||||
|
||||
virtual u32 getMaterialCount() const IRR_OVERRIDE
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual const core::matrix4& getAbsoluteTransformation() const IRR_OVERRIDE
|
||||
{
|
||||
return MeshNodeParent.getAbsoluteTransformation();
|
||||
}
|
||||
|
||||
virtual const core::aabbox3d<f32> getTransformedBoundingBox() const IRR_OVERRIDE
|
||||
{
|
||||
core::aabbox3d<f32> box = getBoundingBox();
|
||||
getAbsoluteTransformation().transformBoxEx(box);
|
||||
return box;
|
||||
}
|
||||
|
||||
virtual void getTransformedBoundingBoxEdges(core::array< core::vector3d<f32> >& edges) const IRR_OVERRIDE
|
||||
{
|
||||
edges.set_used(8);
|
||||
getBoundingBox().getEdges( edges.pointer() );
|
||||
for ( u32 i=0; i<8; ++i )
|
||||
getAbsoluteTransformation().transformVect( edges[i] );
|
||||
}
|
||||
|
||||
virtual core::matrix4 getRelativeTransformation() const IRR_OVERRIDE
|
||||
{
|
||||
return MeshNodeParent.getRelativeTransformation();
|
||||
}
|
||||
|
||||
virtual s32 getID() const IRR_OVERRIDE
|
||||
{
|
||||
return MeshNodeParent.getID();
|
||||
}
|
||||
|
||||
virtual const core::vector3df& getScale() const IRR_OVERRIDE
|
||||
{
|
||||
return MeshNodeParent.getScale();
|
||||
}
|
||||
|
||||
virtual const core::vector3df& getRotation() const IRR_OVERRIDE
|
||||
{
|
||||
return MeshNodeParent.getRotation();
|
||||
}
|
||||
|
||||
virtual const core::vector3df& getPosition() const IRR_OVERRIDE
|
||||
{
|
||||
return MeshNodeParent.getPosition();
|
||||
}
|
||||
|
||||
virtual core::vector3df getAbsolutePosition() const IRR_OVERRIDE
|
||||
{
|
||||
return MeshNodeParent.getAbsolutePosition();
|
||||
}
|
||||
|
||||
virtual ITriangleSelector* getTriangleSelector() const IRR_OVERRIDE
|
||||
{
|
||||
return MeshNodeParent.getTriangleSelector();
|
||||
}
|
||||
|
||||
// Not allowing any of that stuff
|
||||
virtual void OnRegisterSceneNode()IRR_OVERRIDE {}
|
||||
virtual void OnAnimate(u32 timeMs) IRR_OVERRIDE {}
|
||||
virtual void addChild(ISceneNode* child) IRR_OVERRIDE {}
|
||||
virtual void addAnimator(ISceneNodeAnimator* animator) IRR_OVERRIDE {}
|
||||
virtual void setScale(const core::vector3df& scale) IRR_OVERRIDE {}
|
||||
virtual void setRotation(const core::vector3df& rotation) IRR_OVERRIDE {}
|
||||
virtual void setPosition(const core::vector3df& newpos) IRR_OVERRIDE {}
|
||||
virtual void setParent(ISceneNode* newParent) IRR_OVERRIDE {}
|
||||
virtual void setTriangleSelector(ITriangleSelector* selector) IRR_OVERRIDE {}
|
||||
virtual void updateAbsolutePosition() IRR_OVERRIDE {}
|
||||
virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const IRR_OVERRIDE {}
|
||||
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) IRR_OVERRIDE {}
|
||||
|
||||
private:
|
||||
irr::scene::IMeshSceneNode& MeshNodeParent;
|
||||
irr::u32 BufferIdx; // Note: Not saving the meshbuffer pointer as meshes can add/remove buffers and we don't want to keep track of that
|
||||
E_SCENE_NODE_RENDER_PASS RenderPass;
|
||||
bool ParentDoesRender;
|
||||
};
|
||||
|
||||
} // end namespace scene
|
||||
} // end namespace irr
|
@ -20,11 +20,12 @@
|
||||
#include "IAttributes.h"
|
||||
#include "IMeshCache.h"
|
||||
#include "IMeshSceneNode.h"
|
||||
#include "SMeshBufferLightMap.h"
|
||||
#include "CDynamicMeshBuffer.h"
|
||||
#include "irrMap.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define COLLADA_READER_DEBUG
|
||||
// Lots of messages, with how slow some consoles are loading can then take minutes
|
||||
// #define COLLADA_READER_DEBUG
|
||||
#endif
|
||||
namespace irr
|
||||
{
|
||||
@ -2123,16 +2124,16 @@ void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
|
||||
{
|
||||
// standard mesh buffer
|
||||
|
||||
scene::SMeshBuffer* mbuffer = new SMeshBuffer();
|
||||
scene::CDynamicMeshBuffer* mbuffer = new CDynamicMeshBuffer(video::EVT_STANDARD, IndexTypeHint == EITH_16BIT ? video::EIT_16BIT : video::EIT_32BIT);
|
||||
buffer = mbuffer;
|
||||
|
||||
core::map<video::S3DVertex, int> vertMap;
|
||||
|
||||
for (u32 i=0; i<polygons.size(); ++i)
|
||||
{
|
||||
core::array<u16> indices;
|
||||
core::array<u32> indices;
|
||||
const u32 vertexCount = polygons[i].Indices.size() / maxOffset;
|
||||
mbuffer->Vertices.reallocate(mbuffer->Vertices.size()+vertexCount);
|
||||
mbuffer->getVertexBuffer().reallocate(mbuffer->getVertexBuffer().size()+vertexCount);
|
||||
|
||||
// for all index/semantic groups
|
||||
for (u32 v=0; v<polygons[i].Indices.size(); v+=maxOffset)
|
||||
@ -2208,7 +2209,7 @@ void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
|
||||
else
|
||||
{
|
||||
indices.push_back(mbuffer->getVertexCount());
|
||||
mbuffer->Vertices.push_back(vtx);
|
||||
mbuffer->getVertexBuffer().push_back(vtx);
|
||||
vertMap.insert(vtx, mbuffer->getVertexCount()-1);
|
||||
}
|
||||
} // end for all vertices
|
||||
@ -2221,9 +2222,9 @@ void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
|
||||
// as full tessellation is problematic
|
||||
for (u32 ind = 0; ind+2 < indices.size(); ++ind)
|
||||
{
|
||||
mbuffer->Indices.push_back(indices[0]);
|
||||
mbuffer->Indices.push_back(indices[ind+2]);
|
||||
mbuffer->Indices.push_back(indices[ind+1]);
|
||||
mbuffer->getIndexBuffer().push_back(indices[0]);
|
||||
mbuffer->getIndexBuffer().push_back(indices[ind+2]);
|
||||
mbuffer->getIndexBuffer().push_back(indices[ind+1]);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -2231,25 +2232,30 @@ void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
|
||||
// it's just triangles
|
||||
for (u32 ind = 0; ind < indices.size(); ind+=3)
|
||||
{
|
||||
mbuffer->Indices.push_back(indices[ind+2]);
|
||||
mbuffer->Indices.push_back(indices[ind+1]);
|
||||
mbuffer->Indices.push_back(indices[ind+0]);
|
||||
mbuffer->getIndexBuffer().push_back(indices[ind+2]);
|
||||
mbuffer->getIndexBuffer().push_back(indices[ind+1]);
|
||||
mbuffer->getIndexBuffer().push_back(indices[ind+0]);
|
||||
}
|
||||
}
|
||||
|
||||
} // end for all polygons
|
||||
|
||||
if ( getIndexTypeHint() == EITH_OPTIMAL && mbuffer->getVertexCount() <= 65536 )
|
||||
{
|
||||
mbuffer->getIndexBuffer().setType(video::EIT_16BIT); // from 32 to 16 bit
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// lightmap mesh buffer
|
||||
|
||||
scene::SMeshBufferLightMap* mbuffer = new SMeshBufferLightMap();
|
||||
scene::CDynamicMeshBuffer* mbuffer = new CDynamicMeshBuffer(video::EVT_2TCOORDS, IndexTypeHint == EITH_16BIT ? video::EIT_16BIT : video::EIT_32BIT);
|
||||
buffer = mbuffer;
|
||||
|
||||
for (u32 i=0; i<polygons.size(); ++i)
|
||||
{
|
||||
const u32 vertexCount = polygons[i].Indices.size() / maxOffset;
|
||||
mbuffer->Vertices.reallocate(mbuffer->Vertices.size()+vertexCount);
|
||||
mbuffer->getVertexBuffer().reallocate(mbuffer->getVertexBuffer().size()+vertexCount);
|
||||
// for all vertices in array
|
||||
for (u32 v=0; v<polygons[i].Indices.size(); v+=maxOffset)
|
||||
{
|
||||
@ -2321,31 +2327,34 @@ void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader,
|
||||
}
|
||||
}
|
||||
|
||||
mbuffer->Vertices.push_back(vtx);
|
||||
mbuffer->getVertexBuffer().push_back(vtx);
|
||||
|
||||
} // end for all vertices
|
||||
|
||||
// add vertex indices
|
||||
const u32 oldVertexCount = mbuffer->Vertices.size() - vertexCount;
|
||||
const u32 oldVertexCount = mbuffer->getVertexBuffer().size() - vertexCount;
|
||||
for (u32 face=0; face<vertexCount-2; ++face)
|
||||
{
|
||||
mbuffer->Indices.push_back(oldVertexCount + 0);
|
||||
mbuffer->Indices.push_back(oldVertexCount + 1 + face);
|
||||
mbuffer->Indices.push_back(oldVertexCount + 2 + face);
|
||||
mbuffer->getIndexBuffer().push_back(oldVertexCount + 0);
|
||||
mbuffer->getIndexBuffer().push_back(oldVertexCount + 1 + face);
|
||||
mbuffer->getIndexBuffer().push_back(oldVertexCount + 2 + face);
|
||||
}
|
||||
|
||||
} // end for all polygons
|
||||
|
||||
if ( getIndexTypeHint() == EITH_OPTIMAL && mbuffer->getVertexCount() <= 65536 )
|
||||
{
|
||||
mbuffer->getIndexBuffer().setType(video::EIT_16BIT); // from 32 to 16 bit
|
||||
}
|
||||
}
|
||||
|
||||
const SColladaMaterial* m = findMaterial(materialName);
|
||||
if (m)
|
||||
{
|
||||
buffer->getMaterial() = m->Mat;
|
||||
SMesh tmpmesh;
|
||||
tmpmesh.addMeshBuffer(buffer);
|
||||
SceneManager->getMeshManipulator()->setVertexColors(&tmpmesh,m->Mat.DiffuseColor);
|
||||
SceneManager->getMeshManipulator()->setVertexColors(buffer,m->Mat.DiffuseColor);
|
||||
if (m->Transparency != 1.0f)
|
||||
SceneManager->getMeshManipulator()->setVertexColorAlpha(&tmpmesh,core::floor32(m->Transparency*255.0f));
|
||||
SceneManager->getMeshManipulator()->setVertexColorAlpha(buffer,core::floor32(m->Transparency*255.0f));
|
||||
}
|
||||
// add future bind reference for the material
|
||||
core::stringc meshbufferReference = geometryId+"/"+materialName;
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "IVideoDriver.h"
|
||||
#include "irrString.h"
|
||||
#include "SMesh.h"
|
||||
#include "SMeshBuffer.h"
|
||||
#include "ISceneManager.h"
|
||||
#include "irrMap.h"
|
||||
#include "CAttributes.h"
|
||||
|
@ -222,8 +222,8 @@ namespace video
|
||||
virtual void OnResize(const core::dimension2d<u32>& size) IRR_OVERRIDE;
|
||||
|
||||
//! Can be called by an IMaterialRenderer to make its work easier.
|
||||
virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
bool resetAllRenderstates) IRR_OVERRIDE;
|
||||
void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
bool resetAllRenderstates);
|
||||
|
||||
//! Returns type of video driver
|
||||
virtual E_DRIVER_TYPE getDriverType() const IRR_OVERRIDE;
|
||||
|
@ -275,11 +275,6 @@ bool CD3D9HLSLMaterialRenderer::createHLSLPixelShader(const char* pixelShaderPro
|
||||
return false;
|
||||
}
|
||||
|
||||
void CD3D9HLSLMaterialRenderer::setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates)
|
||||
{
|
||||
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
}
|
||||
|
||||
s32 CD3D9HLSLMaterialRenderer::getVertexShaderConstantID(const c8* name)
|
||||
{
|
||||
return getVariableID(true, name);
|
||||
|
@ -47,7 +47,6 @@ public:
|
||||
bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) IRR_OVERRIDE;
|
||||
|
||||
// implementations for IMaterialRendererServices
|
||||
virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates) IRR_OVERRIDE;
|
||||
virtual s32 getVertexShaderConstantID(const c8* name) IRR_OVERRIDE;
|
||||
virtual s32 getPixelShaderConstantID(const c8* name) IRR_OVERRIDE;
|
||||
virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1) IRR_OVERRIDE;
|
||||
|
@ -82,7 +82,7 @@ public:
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
bool resetAllRenderstates, IMaterialRendererServices* services) IRR_OVERRIDE
|
||||
{
|
||||
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
|
||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
||||
{
|
||||
@ -105,7 +105,7 @@ public:
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
bool resetAllRenderstates, IMaterialRendererServices* services) IRR_OVERRIDE
|
||||
{
|
||||
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
|
||||
// if (material.MaterialType != lastMaterial.MaterialType ||
|
||||
// material.MaterialTypeParam != lastMaterial.MaterialTypeParam ||
|
||||
@ -175,7 +175,7 @@ public:
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
bool resetAllRenderstates, IMaterialRendererServices* services) IRR_OVERRIDE
|
||||
{
|
||||
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
|
||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
||||
{
|
||||
@ -199,7 +199,7 @@ public:
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
bool resetAllRenderstates, IMaterialRendererServices* services) IRR_OVERRIDE
|
||||
{
|
||||
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
|
||||
Driver->getBridgeCalls()->setBlend(true);
|
||||
Driver->getBridgeCalls()->setBlendFunc(D3DBLEND_ONE, D3DBLEND_INVSRCCOLOR);
|
||||
@ -238,7 +238,7 @@ public:
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
bool resetAllRenderstates, IMaterialRendererServices* services) IRR_OVERRIDE
|
||||
{
|
||||
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
|
||||
Driver->getBridgeCalls()->setBlend(true);
|
||||
Driver->getBridgeCalls()->setBlendFunc(D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
|
||||
@ -278,7 +278,7 @@ public:
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
bool resetAllRenderstates, IMaterialRendererServices* services) IRR_OVERRIDE
|
||||
{
|
||||
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
|
||||
Driver->getBridgeCalls()->setBlend(true);
|
||||
Driver->getBridgeCalls()->setBlendFunc(D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
|
||||
@ -325,7 +325,7 @@ public:
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
bool resetAllRenderstates, IMaterialRendererServices* services) IRR_OVERRIDE
|
||||
{
|
||||
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
|
||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
||||
{
|
||||
@ -367,7 +367,7 @@ public:
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
bool resetAllRenderstates, IMaterialRendererServices* services) IRR_OVERRIDE
|
||||
{
|
||||
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
|
||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
||||
{
|
||||
@ -411,7 +411,7 @@ public:
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
bool resetAllRenderstates, IMaterialRendererServices* services) IRR_OVERRIDE
|
||||
{
|
||||
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
|
||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
||||
{
|
||||
@ -436,7 +436,7 @@ public:
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
bool resetAllRenderstates, IMaterialRendererServices* services) IRR_OVERRIDE
|
||||
{
|
||||
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
|
||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
||||
{
|
||||
@ -471,7 +471,7 @@ public:
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
bool resetAllRenderstates, IMaterialRendererServices* services) IRR_OVERRIDE
|
||||
{
|
||||
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
|
||||
if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
|
||||
{
|
||||
@ -507,7 +507,7 @@ public:
|
||||
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
|
||||
bool resetAllRenderstates, IMaterialRendererServices* services) IRR_OVERRIDE
|
||||
{
|
||||
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
|
||||
Driver->getBridgeCalls()->setBlend(true);
|
||||
Driver->getBridgeCalls()->setBlendFunc(D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
|
||||
|
@ -132,7 +132,7 @@ void CD3D9ShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& material
|
||||
}
|
||||
}
|
||||
|
||||
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
|
||||
if (BaseMaterial)
|
||||
BaseMaterial->OnSetMaterial(material, lastMaterial, resetAllRenderstates, services);
|
||||
|
@ -3,6 +3,7 @@
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
|
||||
#include "CMeshSceneNode.h"
|
||||
#include "CBufferRenderNode.h"
|
||||
#include "IVideoDriver.h"
|
||||
#include "ISceneManager.h"
|
||||
#include "S3DVertex.h"
|
||||
@ -22,14 +23,12 @@ namespace irr
|
||||
namespace scene
|
||||
{
|
||||
|
||||
|
||||
|
||||
//! constructor
|
||||
CMeshSceneNode::CMeshSceneNode(IMesh* mesh, ISceneNode* parent, ISceneManager* mgr, s32 id,
|
||||
const core::vector3df& position, const core::vector3df& rotation,
|
||||
const core::vector3df& scale)
|
||||
: IMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0), Shadow(0),
|
||||
PassCount(0), ReadOnlyMaterials(false)
|
||||
: IMeshSceneNode(parent, mgr, id, position, rotation, scale)
|
||||
, Mesh(0), Shadow(0), ReadOnlyMaterials(false)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("CMeshSceneNode");
|
||||
@ -42,6 +41,7 @@ CMeshSceneNode::CMeshSceneNode(IMesh* mesh, ISceneNode* parent, ISceneManager* m
|
||||
//! destructor
|
||||
CMeshSceneNode::~CMeshSceneNode()
|
||||
{
|
||||
setUsedBufferRenderNodes(0);
|
||||
if (Shadow)
|
||||
Shadow->drop();
|
||||
if (Mesh)
|
||||
@ -54,39 +54,60 @@ void CMeshSceneNode::OnRegisterSceneNode()
|
||||
{
|
||||
if (IsVisible && Mesh)
|
||||
{
|
||||
// because this node supports rendering of mixed mode meshes consisting of
|
||||
Box = Mesh->getBoundingBox(); // in case mesh was modified, as clipping happens when registering nodes for rendering
|
||||
|
||||
// Because this node supports rendering of mixed mode meshes consisting of
|
||||
// transparent and solid material at the same time, we need to go through all
|
||||
// materials, check of what type they are and register this node for the right
|
||||
// render pass according to that.
|
||||
// Also some buffers might register into their own render node
|
||||
|
||||
video::IVideoDriver* driver = SceneManager->getVideoDriver();
|
||||
|
||||
PassCount = 0;
|
||||
int transparentCount = 0;
|
||||
int solidCount = 0;
|
||||
|
||||
// count transparent and solid materials in this scene node
|
||||
const u32 numMaterials = ReadOnlyMaterials ? Mesh->getMeshBufferCount() : Materials.size();
|
||||
for (u32 i=0; i<numMaterials; ++i)
|
||||
if ( !(DebugDataVisible & scene::EDS_HALF_TRANSPARENCY) )
|
||||
{
|
||||
const video::SMaterial& material = ReadOnlyMaterials ? Mesh->getMeshBuffer(i)->getMaterial() : Materials[i];
|
||||
// count transparent and solid materials in this scene node
|
||||
const u32 numMaterials = ReadOnlyMaterials ? Mesh->getMeshBufferCount() : Materials.size();
|
||||
const bool parentRenders = NodeRegistration == ENR_DEFAULT || numMaterials < 2;
|
||||
for (u32 i=0; i<numMaterials; ++i)
|
||||
{
|
||||
const video::SMaterial& material = ReadOnlyMaterials ? Mesh->getMeshBuffer(i)->getMaterial() : Materials[i];
|
||||
|
||||
if ( driver->needsTransparentRenderPass(material) )
|
||||
++transparentCount;
|
||||
else
|
||||
++solidCount;
|
||||
|
||||
if (solidCount && transparentCount)
|
||||
break;
|
||||
if ( driver->needsTransparentRenderPass(material) )
|
||||
{
|
||||
BufferRenderNodes[i]->prepareRendering(ESNRP_TRANSPARENT, parentRenders);
|
||||
if ( parentRenders )
|
||||
{
|
||||
++transparentCount;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferRenderNodes[i]->prepareRendering(ESNRP_SOLID, parentRenders);
|
||||
if ( parentRenders )
|
||||
{
|
||||
++solidCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// register according to material types counted
|
||||
|
||||
if (solidCount)
|
||||
SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID);
|
||||
SceneManager->registerNodeForRendering(this, ESNRP_SOLID);
|
||||
|
||||
if (transparentCount)
|
||||
SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT);
|
||||
SceneManager->registerNodeForRendering(this, ESNRP_TRANSPARENT);
|
||||
|
||||
if (Shadow) // update (not render) shadow node after lights have been set up
|
||||
SceneManager->registerNodeForRendering(this, ESNRP_SKY_BOX);
|
||||
|
||||
if (DebugDataVisible) // debug data has it's own render-stage between solid and transparence
|
||||
SceneManager->registerNodeForRendering(this, ESNRP_SHADOW);
|
||||
|
||||
ISceneNode::OnRegisterSceneNode();
|
||||
}
|
||||
@ -96,109 +117,110 @@ void CMeshSceneNode::OnRegisterSceneNode()
|
||||
//! renders the node.
|
||||
void CMeshSceneNode::render()
|
||||
{
|
||||
video::IVideoDriver* driver = SceneManager->getVideoDriver();
|
||||
|
||||
if (!Mesh || !driver)
|
||||
if (!Mesh )
|
||||
return;
|
||||
|
||||
const bool isTransparentPass =
|
||||
SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT;
|
||||
const E_SCENE_NODE_RENDER_PASS renderPass = SceneManager->getSceneNodeRenderPass();
|
||||
|
||||
++PassCount;
|
||||
|
||||
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
|
||||
Box = Mesh->getBoundingBox();
|
||||
|
||||
if (Shadow && PassCount==1)
|
||||
Shadow->updateShadowVolumes();
|
||||
|
||||
// for debug purposes only:
|
||||
|
||||
bool renderMeshes = true;
|
||||
video::SMaterial mat;
|
||||
if (DebugDataVisible && PassCount==1)
|
||||
if ( renderPass == ESNRP_SKY_BOX )
|
||||
{
|
||||
// overwrite half transparency
|
||||
if (DebugDataVisible & scene::EDS_HALF_TRANSPARENCY)
|
||||
{
|
||||
for (u32 g=0; g<Mesh->getMeshBufferCount(); ++g)
|
||||
{
|
||||
mat = Materials[g];
|
||||
mat.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
|
||||
driver->setMaterial(mat);
|
||||
driver->drawMeshBuffer(Mesh->getMeshBuffer(g));
|
||||
}
|
||||
renderMeshes = false;
|
||||
}
|
||||
if (Shadow )
|
||||
Shadow->updateShadowVolumes();
|
||||
}
|
||||
|
||||
// render original meshes
|
||||
if (renderMeshes)
|
||||
else if ( renderPass == ESNRP_SHADOW )
|
||||
{
|
||||
for (u32 i=0; i<Mesh->getMeshBufferCount(); ++i)
|
||||
// for debug purposes only
|
||||
if ( DebugDataVisible )
|
||||
{
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
if (mb)
|
||||
video::IVideoDriver* driver = SceneManager->getVideoDriver();
|
||||
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
|
||||
|
||||
// render with half transparency
|
||||
if (DebugDataVisible & scene::EDS_HALF_TRANSPARENCY)
|
||||
{
|
||||
const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i];
|
||||
|
||||
const bool transparent = driver->needsTransparentRenderPass(material);
|
||||
|
||||
// only render transparent buffer if this is the transparent render pass
|
||||
// and solid only in solid pass
|
||||
if (transparent == isTransparentPass)
|
||||
for (u32 g=0; g<Mesh->getMeshBufferCount(); ++g)
|
||||
{
|
||||
driver->setMaterial(material);
|
||||
driver->drawMeshBuffer(mb);
|
||||
irr::video::SMaterial mat = Materials[g];
|
||||
mat.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
|
||||
driver->setMaterial(mat);
|
||||
driver->drawMeshBuffer(Mesh->getMeshBuffer(g));
|
||||
}
|
||||
}
|
||||
|
||||
video::SMaterial m;
|
||||
m.Lighting = false;
|
||||
m.AntiAliasing=0;
|
||||
driver->setMaterial(m);
|
||||
|
||||
if (DebugDataVisible & scene::EDS_BBOX)
|
||||
{
|
||||
driver->draw3DBox(Box, video::SColor(255,255,255,255));
|
||||
}
|
||||
if (DebugDataVisible & scene::EDS_BBOX_BUFFERS)
|
||||
{
|
||||
for (u32 g=0; g<Mesh->getMeshBufferCount(); ++g)
|
||||
{
|
||||
driver->draw3DBox(
|
||||
Mesh->getMeshBuffer(g)->getBoundingBox(),
|
||||
video::SColor(255,190,128,128));
|
||||
}
|
||||
}
|
||||
|
||||
if (DebugDataVisible & scene::EDS_NORMALS)
|
||||
{
|
||||
// draw normals
|
||||
const f32 debugNormalLength = SceneManager->getParameters()->getAttributeAsFloat(DEBUG_NORMAL_LENGTH);
|
||||
const video::SColor debugNormalColor = SceneManager->getParameters()->getAttributeAsColor(DEBUG_NORMAL_COLOR);
|
||||
const u32 count = Mesh->getMeshBufferCount();
|
||||
|
||||
for (u32 i=0; i != count; ++i)
|
||||
{
|
||||
driver->drawMeshBufferNormals(Mesh->getMeshBuffer(i), debugNormalLength, debugNormalColor);
|
||||
}
|
||||
}
|
||||
|
||||
// show mesh
|
||||
if (DebugDataVisible & scene::EDS_MESH_WIRE_OVERLAY)
|
||||
{
|
||||
m.Wireframe = true;
|
||||
driver->setMaterial(m);
|
||||
|
||||
for (u32 g=0; g<Mesh->getMeshBufferCount(); ++g)
|
||||
{
|
||||
driver->drawMeshBuffer(Mesh->getMeshBuffer(g));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for debug purposes only:
|
||||
if (DebugDataVisible && PassCount==1)
|
||||
else // solid, transparent or unknown (none when render is called without SceneManager) render stages
|
||||
{
|
||||
video::SMaterial m;
|
||||
m.Lighting = false;
|
||||
m.AntiAliasing=0;
|
||||
driver->setMaterial(m);
|
||||
video::IVideoDriver* driver = SceneManager->getVideoDriver();
|
||||
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
|
||||
|
||||
if (DebugDataVisible & scene::EDS_BBOX)
|
||||
// render buffers, or at least those which don't render in their own node
|
||||
for (u32 i=0; i<BufferRenderNodes.size(); ++i)
|
||||
{
|
||||
driver->draw3DBox(Box, video::SColor(255,255,255,255));
|
||||
}
|
||||
if (DebugDataVisible & scene::EDS_BBOX_BUFFERS)
|
||||
{
|
||||
for (u32 g=0; g<Mesh->getMeshBufferCount(); ++g)
|
||||
CBufferRenderNode* bufRenderNode = BufferRenderNodes[i];
|
||||
if ( bufRenderNode->getDoesParentRender())
|
||||
{
|
||||
driver->draw3DBox(
|
||||
Mesh->getMeshBuffer(g)->getBoundingBox(),
|
||||
video::SColor(255,190,128,128));
|
||||
}
|
||||
}
|
||||
E_SCENE_NODE_RENDER_PASS bufferRenderPass = bufRenderNode->getRenderPass();
|
||||
|
||||
if (DebugDataVisible & scene::EDS_NORMALS)
|
||||
{
|
||||
// draw normals
|
||||
const f32 debugNormalLength = SceneManager->getParameters()->getAttributeAsFloat(DEBUG_NORMAL_LENGTH);
|
||||
const video::SColor debugNormalColor = SceneManager->getParameters()->getAttributeAsColor(DEBUG_NORMAL_COLOR);
|
||||
const u32 count = Mesh->getMeshBufferCount();
|
||||
// render() called without OnRegisterSceneNode, but still wants to render in a specific render stage
|
||||
// Note: Not checking transparency every time, as check got slightly expensive (I think it's prone to cache-misses)
|
||||
if ( bufferRenderPass == ESNRP_NONE && renderPass > ESNRP_NONE )
|
||||
{
|
||||
if ( driver->needsTransparentRenderPass(getMaterial(i)) )
|
||||
{
|
||||
bufferRenderPass = ESNRP_TRANSPARENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
bufferRenderPass = ESNRP_SOLID;
|
||||
}
|
||||
}
|
||||
|
||||
for (u32 i=0; i != count; ++i)
|
||||
{
|
||||
driver->drawMeshBufferNormals(Mesh->getMeshBuffer(i), debugNormalLength, debugNormalColor);
|
||||
}
|
||||
}
|
||||
|
||||
// show mesh
|
||||
if (DebugDataVisible & scene::EDS_MESH_WIRE_OVERLAY)
|
||||
{
|
||||
m.Wireframe = true;
|
||||
driver->setMaterial(m);
|
||||
|
||||
for (u32 g=0; g<Mesh->getMeshBufferCount(); ++g)
|
||||
{
|
||||
driver->drawMeshBuffer(Mesh->getMeshBuffer(g));
|
||||
if ( bufRenderNode->getRenderPass() == renderPass )
|
||||
bufRenderNode->renderBuffer(driver);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -207,7 +229,7 @@ void CMeshSceneNode::render()
|
||||
|
||||
//! Removes a child from this scene node.
|
||||
//! Implemented here, to be able to remove the shadow properly, if there is one,
|
||||
//! or to remove attached childs.
|
||||
//! or to remove attached children.
|
||||
bool CMeshSceneNode::removeChild(ISceneNode* child)
|
||||
{
|
||||
if (child && Shadow == child)
|
||||
@ -256,6 +278,22 @@ u32 CMeshSceneNode::getMaterialCount() const
|
||||
return Materials.size();
|
||||
}
|
||||
|
||||
void CMeshSceneNode::setUsedBufferRenderNodes(irr::u32 num)
|
||||
{
|
||||
if ( BufferRenderNodes.size() > num )
|
||||
{
|
||||
for ( irr::u32 i=num; i<BufferRenderNodes.size(); ++i )
|
||||
BufferRenderNodes[i]->drop();
|
||||
BufferRenderNodes.erase(num, BufferRenderNodes.size()-num);
|
||||
}
|
||||
else if ( BufferRenderNodes.size() < num )
|
||||
{
|
||||
for ( irr::u32 i=BufferRenderNodes.size(); i < num; ++i )
|
||||
{
|
||||
BufferRenderNodes.push_back( new CBufferRenderNode(*this, SceneManager, i) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! Sets a new mesh
|
||||
void CMeshSceneNode::setMesh(IMesh* mesh)
|
||||
@ -264,10 +302,16 @@ void CMeshSceneNode::setMesh(IMesh* mesh)
|
||||
{
|
||||
mesh->grab();
|
||||
if (Mesh)
|
||||
{
|
||||
Mesh->drop();
|
||||
}
|
||||
|
||||
Mesh = mesh;
|
||||
|
||||
// Note: Mesh can change amount of meshbuffers later and we don't handle that so far so that would cause trouble
|
||||
// For now assuming users call setMesh again in that case
|
||||
copyMaterials();
|
||||
setUsedBufferRenderNodes(Mesh ? Mesh->getMeshBufferCount() : 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ namespace irr
|
||||
{
|
||||
namespace scene
|
||||
{
|
||||
class CBufferRenderNode;
|
||||
|
||||
class CMeshSceneNode : public IMeshSceneNode
|
||||
{
|
||||
@ -83,6 +84,7 @@ namespace scene
|
||||
|
||||
protected:
|
||||
|
||||
void setUsedBufferRenderNodes(irr::u32 num);
|
||||
void copyMaterials();
|
||||
|
||||
core::array<video::SMaterial> Materials;
|
||||
@ -92,8 +94,9 @@ namespace scene
|
||||
IMesh* Mesh;
|
||||
IShadowVolumeSceneNode* Shadow;
|
||||
|
||||
s32 PassCount;
|
||||
bool ReadOnlyMaterials;
|
||||
|
||||
core::array<scene::CBufferRenderNode*> BufferRenderNodes;
|
||||
};
|
||||
|
||||
} // end namespace scene
|
||||
|
@ -207,7 +207,7 @@ namespace video
|
||||
virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const IRR_OVERRIDE;
|
||||
|
||||
//! Can be called by an IMaterialRenderer to make its work easier.
|
||||
virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial, bool resetAllRenderstates) IRR_OVERRIDE;
|
||||
void setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial, bool resetAllRenderstates);
|
||||
|
||||
//! Compare in SMaterial doesn't check texture parameters, so we should call this on each OnRender call.
|
||||
void setTextureRenderStates(const SMaterial& material, bool resetAllRenderstates);
|
||||
|
@ -340,14 +340,6 @@ bool COGLES2MaterialRenderer::linkProgram()
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void COGLES2MaterialRenderer::setBasicRenderStates(const SMaterial& material,
|
||||
const SMaterial& lastMaterial,
|
||||
bool resetAllRenderstates)
|
||||
{
|
||||
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
}
|
||||
|
||||
void COGLES2MaterialRenderer::startUseProgram()
|
||||
{
|
||||
Driver->getCacheHandler()->setProgram(Program);
|
||||
|
@ -53,8 +53,6 @@ public:
|
||||
|
||||
virtual s32 getRenderCapability() const IRR_OVERRIDE;
|
||||
|
||||
virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates) IRR_OVERRIDE;
|
||||
|
||||
virtual void startUseProgram() IRR_OVERRIDE;
|
||||
|
||||
virtual s32 getVertexShaderConstantID(const c8* name) IRR_OVERRIDE;
|
||||
|
@ -201,8 +201,8 @@ namespace video
|
||||
virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const IRR_OVERRIDE;
|
||||
|
||||
//! Can be called by an IMaterialRenderer to make its work easier.
|
||||
virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial,
|
||||
bool resetAllRenderstates) IRR_OVERRIDE;
|
||||
void setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial,
|
||||
bool resetAllRenderstates);
|
||||
|
||||
//! Compare in SMaterial doesn't check texture parameters, so we should call this on each OnRender call.
|
||||
virtual void setTextureRenderStates(const SMaterial& material, bool resetAllRenderstates);
|
||||
|
@ -272,8 +272,8 @@ namespace video
|
||||
virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const IRR_OVERRIDE;
|
||||
|
||||
//! Can be called by an IMaterialRenderer to make its work easier.
|
||||
virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial,
|
||||
bool resetAllRenderstates) IRR_OVERRIDE;
|
||||
void setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial,
|
||||
bool resetAllRenderstates);
|
||||
|
||||
//! Compare in SMaterial doesn't check texture parameters, so we should call this on each OnRender call.
|
||||
virtual void setTextureRenderStates(const SMaterial& material, bool resetAllRenderstates);
|
||||
|
@ -563,15 +563,6 @@ bool COpenGLSLMaterialRenderer::linkProgram()
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void COpenGLSLMaterialRenderer::setBasicRenderStates(const SMaterial& material,
|
||||
const SMaterial& lastMaterial,
|
||||
bool resetAllRenderstates)
|
||||
{
|
||||
// forward
|
||||
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
}
|
||||
|
||||
void COpenGLSLMaterialRenderer::startUseProgram()
|
||||
{
|
||||
if (Program2)
|
||||
|
@ -72,7 +72,6 @@ public:
|
||||
}
|
||||
|
||||
// implementations for IMaterialRendererServices
|
||||
virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates) IRR_OVERRIDE;
|
||||
virtual void startUseProgram() IRR_OVERRIDE;
|
||||
virtual void stopUseProgram() IRR_OVERRIDE;
|
||||
virtual s32 getVertexShaderConstantID(const c8* name) IRR_OVERRIDE;
|
||||
|
@ -264,9 +264,9 @@ namespace video
|
||||
|
||||
//IMaterialRendererService
|
||||
|
||||
virtual void setBasicRenderStates(const SMaterial& material,
|
||||
void setBasicRenderStates(const SMaterial& material,
|
||||
const SMaterial& lastMaterial,
|
||||
bool resetAllRenderstates) IRR_OVERRIDE;
|
||||
bool resetAllRenderstates);
|
||||
|
||||
//pass BaseMaterialID
|
||||
void setFallback_Material(E_MATERIAL_TYPE fallback_MaterialType
|
||||
|
@ -299,7 +299,7 @@ void IBurningShader::OnSetMaterial(const SMaterial& material, const SMaterial& l
|
||||
{
|
||||
if (Driver)
|
||||
Driver->setFallback_Material(BaseMaterial, VertexShaderProgram_buildin);
|
||||
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
if (CallBack)
|
||||
CallBack->OnSetMaterial(material);
|
||||
|
||||
@ -331,13 +331,6 @@ IShaderConstantSetCallBack* IBurningShader::getShaderConstantSetCallBack() const
|
||||
return CallBack;
|
||||
}
|
||||
|
||||
// implementations for the render services
|
||||
void IBurningShader::setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates)
|
||||
{
|
||||
// forward
|
||||
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
|
||||
}
|
||||
|
||||
static BurningUniform _empty = { "null",BL_VERTEX_FLOAT,{0.f,0.f,0.f,0.f} };
|
||||
const f32* IBurningShader::getUniform(const c8* name, EBurningUniformFlags flags) const
|
||||
{
|
||||
|
@ -334,7 +334,6 @@ public:
|
||||
virtual IShaderConstantSetCallBack* getShaderConstantSetCallBack() const IRR_OVERRIDE;
|
||||
|
||||
// implementations for the render services
|
||||
virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates) IRR_OVERRIDE;
|
||||
virtual s32 getVertexShaderConstantID(const c8* name) IRR_OVERRIDE;
|
||||
virtual s32 getPixelShaderConstantID(const c8* name) IRR_OVERRIDE;
|
||||
virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount = 1) IRR_OVERRIDE;
|
||||
|
@ -1038,6 +1038,7 @@
|
||||
<ClInclude Include="burning_shader_compile_verify.h" />
|
||||
<ClInclude Include="CB3DMeshWriter.h" />
|
||||
<ClInclude Include="CBlit.h" />
|
||||
<ClInclude Include="CBufferRenderNode.h" />
|
||||
<ClInclude Include="CD3D9RenderTarget.h" />
|
||||
<ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />
|
||||
<ClInclude Include="CDefaultSceneNodeFactory.h" />
|
||||
|
@ -1489,6 +1489,9 @@
|
||||
<ClInclude Include="..\..\include\ESceneNodeUpdateAbs.h">
|
||||
<Filter>include\scene</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CBufferRenderNode.h">
|
||||
<Filter>Irrlicht\scene\sceneNodes</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\changes.txt">
|
||||
|
@ -776,6 +776,7 @@
|
||||
<ClInclude Include="burning_shader_compile_verify.h" />
|
||||
<ClInclude Include="CB3DMeshWriter.h" />
|
||||
<ClInclude Include="CBlit.h" />
|
||||
<ClInclude Include="CBufferRenderNode.h" />
|
||||
<ClInclude Include="CD3D9RenderTarget.h" />
|
||||
<ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />
|
||||
<ClInclude Include="CDefaultSceneNodeFactory.h" />
|
||||
|
@ -1438,6 +1438,9 @@
|
||||
<ClInclude Include="..\..\include\EDeviceTypes.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CBufferRenderNode.h">
|
||||
<Filter>Irrlicht\scene\sceneNodes</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\changes.txt">
|
||||
|
@ -1,4 +1,4 @@
|
||||
Tests finished. 72 tests of 72 passed.
|
||||
Compiled as DEBUG
|
||||
Test suite pass at GMT Fri Apr 21 14:37:22 2023
|
||||
Test suite pass at GMT Fri May 05 18:39:44 2023
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user