I gave agamemnus a code snippet and some advice on IRC. It basically boils down to a bit of compositing:
1) Background pass: draw the sea in the skybox pass with z-writes disabled, followed by all the ground nodes as usual.
2) Foreground pass: draw the sea as a skybox with colour writes disabled but z-write on, followed by boats and other units.
This should prevent ordering problems where the sea swallows up the land, yet allow boats to be partially occluded by the sea.
[solved] Some sort of clipping problem.
Yeah, so the realization was that putting the ("solid") nodes in some specific order into the scene doesn't matter... what matters is how close each node is to the camera. When I add and start moving the ship nodes, Irrlicht re-sorts nodes and the order they are drawn in. It somehow recalculates the sea node with a very fast but inaccurate distance algorithm so that it isn't always the first node (because it's not farthest to the camera), and that is why I get these seemingly random "area" node disappearances (they are actually just hidden by the sea node).
Bitplane's code looks good, but I am going to make some slight modifications and I will post my full code later on.
Bitplane's code looks good, but I am going to make some slight modifications and I will post my full code later on.
Ok, here it is.
The current mesh I am passing is just two triangles, making a rectangle -- one material.
I would like to add three modifications, though:
1) Make it work for multiple materials.
2) Make it work for actually dynamic meshes.
3) Add a way to record the addition and removal/deletion of nodes into a global data structure so that I can cleanly automatically drop the custom nodes in my cleanup function.
Edit: I realized the roads are going to flicker too (in and out of areas). Not sure what I am going to do about this, but now that I am more clear on how it works, I am confident I will find a solution.
Code: Select all
class CCustomPassNode : public scene::ISceneNode {
video::SMaterial material;
irr::scene::IMeshBuffer *meshBuffer;
E_SCENE_NODE_RENDER_PASS renderPass;
public:
CCustomPassNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, IMeshBuffer *mb, E_SCENE_NODE_RENDER_PASS pass)
: scene::ISceneNode(parent, mgr, id), meshBuffer(mb), renderPass(pass) {
material = meshBuffer->getMaterial();
}
virtual void OnRegisterSceneNode() {
if (IsVisible) SceneManager->registerNodeForRendering (this, renderPass);
ISceneNode::OnRegisterSceneNode();
}
virtual void render() {
driver->setMaterial(material);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawMeshBuffer(meshBuffer);
}
virtual const core::aabbox3d<f32>& getBoundingBox() const {
return meshBuffer->getBoundingBox();
}
virtual u32 getMaterialCount() const {
return 1;
}
virtual video::SMaterial& getMaterial(u32 i) {
return material;
}
};
// .....
void * DLL_EXPORT IrrAddCustomPassMeshToScene (IAnimatedMesh* mesh, u32 passEnum, s32 id = 0) {
return (new CCustomPassNode(smgr->getRootSceneNode(), smgr, id, mesh->getMesh(0)->getMeshBuffer(0), (irr::scene::E_SCENE_NODE_RENDER_PASS)passEnum));
}
void DLL_EXPORT IrrRemoveCustomPassMeshFromScene (u32* node) {
((CCustomPassNode*)node)->drop();
}
I would like to add three modifications, though:
1) Make it work for multiple materials.
2) Make it work for actually dynamic meshes.
3) Add a way to record the addition and removal/deletion of nodes into a global data structure so that I can cleanly automatically drop the custom nodes in my cleanup function.
Edit: I realized the roads are going to flicker too (in and out of areas). Not sure what I am going to do about this, but now that I am more clear on how it works, I am confident I will find a solution.