hbraun wrote:I solved the problem using Color Mask (material properties)
hybrid wrote:For the rest, yes, colormask is the best way here.
Can you elaborate, please?
I think I'm having a similar problem with a transparent texture. I have two scene nodes: one with a transparent texture (blue circle) on top of another one with a opaque texture (square wall). Depending on their positions, they get randomly rendered in the wrong Z order. Some screenshots:
1.
2. With "smgr->getParameters()->setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true);". The circle is now on top but with a gray background.
And here's the code (you can move the circle with the W A S D keys:
Code: Select all
#include <irrlicht.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
class MyEventReceiver : public IEventReceiver {
public:
virtual bool OnEvent(const SEvent& event) {
if (event.EventType == irr::EET_KEY_INPUT_EVENT)
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
virtual bool IsKeyDown(EKEY_CODE keyCode) const {
return KeyIsDown[keyCode];
}
MyEventReceiver() {
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
KeyIsDown[i] = false;
}
private:
bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
SMesh* CreateBoxMesh(f32 width, f32 height) {
f32 halfWidth = width / 2,
halfHeight = height / 2;
video::S3DVertex Vertices[4];
Vertices[0] = video::S3DVertex(-halfWidth, halfHeight, 0, 0, 0, 0, video::SColor(0,255,255,255), 0, 0);
Vertices[1] = video::S3DVertex(halfWidth, halfHeight, 0, 0, 0, 0, video::SColor(0,255,255,255), 1, 0);
Vertices[2] = video::S3DVertex(halfWidth, -halfHeight, 0, 0, 0, 0, video::SColor(0,255,255,255), 1, 1);
Vertices[3] = video::S3DVertex(-halfWidth, -halfHeight, 0, 0, 0, 0, video::SColor(0,255,255,255), 0, 1);
u16 indices[] = {0,1,2, 2,3,0};
SMeshBuffer *buffer = new SMeshBuffer;
buffer->append(Vertices, 4, indices, 6);
SMesh *mesh = new SMesh;
mesh->addMeshBuffer(buffer);
buffer->drop();
aabbox3d<f32> Box;
Box.reset(Vertices[0].Pos);
for (int i = 1; i < 4; ++i) {
Box.addInternalPoint(buffer->Vertices[i].Pos);
}
mesh->setBoundingBox(Box);
return mesh;
}
int main() {
SMesh *tempMesh;
ISceneNode *box1, *box2;
SMaterial myMaterial;
vector3df pos;
MyEventReceiver receiver;
IrrlichtDevice* device = createDevice(EDT_DIRECT3D9, dimension2d<u32>(640, 480), 16, false, false, false, &receiver);
if (device == 0)
return 1;
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
smgr->getParameters()->setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true);
ICameraSceneNode *irrCamera = smgr->addCameraSceneNode();
matrix4 ortho;
ortho.buildProjectionMatrixOrthoLH(640.f, 480.f, 0.f, 1100.f);
irrCamera->setProjectionMatrix(ortho, true);
irrCamera->setPosition(vector3df(0, 0, -100));
irrCamera->setTarget(vector3df(0, 0, 0));
irrCamera->updateAbsolutePosition();
// Setup material
myMaterial.MaterialType = EMT_TRANSPARENT_ALPHA_CHANNEL;
myMaterial.Lighting = false;
// Create 1st box
tempMesh = CreateBoxMesh(200, 200);
box1 = smgr->addMeshSceneNode(tempMesh);
tempMesh->drop();
box1->setAutomaticCulling(EAC_BOX);
box1->setPosition(vector3df(0, 0, 0));
myMaterial.setTexture(0, device->getVideoDriver()->getTexture("square_wall.png"));
box1->getMaterial(0) = myMaterial;
// Create 2nd box
tempMesh = CreateBoxMesh(150, 150);
box2 = smgr->addMeshSceneNode(tempMesh);
tempMesh->drop();
box2->setAutomaticCulling(EAC_BOX);
box2->setPosition(vector3df(0, 0, -2));
myMaterial.setTexture(0, device->getVideoDriver()->getTexture("blue_circle.png"));
box2->getMaterial(0) = myMaterial;
u32 nextStepTime = 0;
while (device->run()) {
u32 currentTime = device->getTimer()->getTime();
if (currentTime >= nextStepTime) {
nextStepTime = currentTime + u32(1000.f / 60.f);
pos = box2->getPosition();
if (receiver.IsKeyDown(KEY_KEY_W)) pos.Y += 1.f;
if (receiver.IsKeyDown(KEY_KEY_A)) pos.X -= 1.f;
if (receiver.IsKeyDown(KEY_KEY_S)) pos.Y -= 1.f;
if (receiver.IsKeyDown(KEY_KEY_D)) pos.X += 1.f;
box2->setPosition(pos);
driver->beginScene(true, true, video::SColor(255,113,113,133));
smgr->drawAll();
driver->endScene();
}
}
device->drop();
return 0;
}
Thank you in advance!