Page 1 of 1

.X files and Alpha map

Posted: Sun Dec 17, 2006 5:51 am
by Viniterra
Hi every one,

I have a doubt about transparency on a model. I have made some model in blender, aplied a tga texture with alpha chanel as uv-map, and then exported to .x format. But when I open it on the Irrlicht model viewer, I can't see the transparencies.

So I suppose that when I load this model in my source code, I will have to set the alpha map manually. But the problem is that the model has many materials, that implies it has more than one texture (1 per material). It is possible to aply alpha map texture to each material of a model separatedly? Or is that any other way to have an animated model with alpha map working?

Thanks in advance.

Posted: Sun Dec 17, 2006 8:42 pm
by hybrid
Transparencies seem indeed to be missing for .x files. Maybe you could send me your mesh such that we could add it.

Posted: Mon Dec 18, 2006 3:40 am
by Viniterra
Sorry, but I do not understand right your answer. I just wanna know how to add an alpha map to a model, so it will be visible in the game engine. It is not so simple to just send the mesh and add the transparencies, because there are many models to add to the game, and I don't want to depend someone to do this to me. Does exists any solution? So what is this?
Thanks anyway for the answer...

Posted: Mon Dec 18, 2006 9:31 am
by hybrid
You are probably able to put transparency stuff into your meshes (directly in your modeler). But this has to be supported by the .x loader. I could read the .x specs and hopefully get it right, but it would be much easier if I had a test case at hand. This way you would not need to touch the loaded meshes, but transparencies would be supported automatically.
If you want to make parts of your mesh transparent you have to find the correct mesh buffer. Therefore assign these parts a distinct material and make a trial and error for finding the correct mesh buffer. Then, do a getMaterial and change the material to the transparency you want. But this is far from trivial, especially for many meshes. Moreover, this will probably break when you mesh is changed or when the mesh loader changes.

Posted: Mon Dec 18, 2006 8:08 pm
by Viniterra
Sorry for the way I questioned it. I was thinking that the engine already has some way to simply set this alpha map. Now I understand why would you want the model, to see if the exporter is writing the transparency parts correctly, and maybe implement it, am I rigth? At this link

http://homepages.dcc.ufmg.br/~allonman/worm/worm.zip

I put some model in .X format, with animation and some uv-mapped textures. The alpha map is a channel in the hair.tga. In the Blender viewport I could see this alpha map applied correctly, but in the mesh viewer, I cant.
If you could help me will be great.

Thanks in advance, and sorry for my english...

Posted: Tue Dec 19, 2006 1:06 am
by hybrid
No, the materials used do not have any alpha values. .x files could have an alpha value < 1.0 which would make those faces partially transparent. I'll see if I can put it into the code. But your mesh won't look any different that way :(

Posted: Tue Dec 19, 2006 3:15 am
by Viniterra
It seems to be a trouble of the .x exporter plugin. Do you know any format supported by irrlicht tha I can handle transparencies and animations working?

PS: its not transparencies applied to faces, its based on the alpha map. Isn't that per pixel?

Posted: Tue Dec 19, 2006 8:51 am
by hybrid
But .x does not support alpha maps. At least I did not find any hint in the specification. You can set a per face transparency via the colors. Maybe you could even use an alpha channel of the texture, but not an explicit alpha map. Try b3d or maybe even ms3d, I don't really know which one would be capable of it (oh, and if you really mean an explicit alpha map you might have problems with Irrlicht's material system... You usually use the alpha channel of the texture for transparency).

Posted: Tue Dec 19, 2006 6:13 pm
by Viniterra
hybrid wrote:You usually use the alpha channel of the texture for transparency).
I think that is this that I wanna do. The TGA texture has an alpha channel, how can I use this in the model? Will be easiest if I can use PNG instead of TGA?

Posted: Tue Dec 19, 2006 6:36 pm
by hybrid
Since I don't see support in the direct x format for this natively you might have to do it this way: Search for the texture with the correct filename in the texture cache. Using this pointer you iterate through the mesh buffers of your .x mesh and compare the texture pointer with the one you found in the cache. Then change the settings to EMT_TRANSPARENT_ALPHA_CHANNEL. You might also want to change the material parameter to change the threshold of transparency. This way you won't get any problems if you change your mesh or the loader changes the order of the mesh buffers.

Posted: Wed Dec 20, 2006 10:24 pm
by Viniterra
EDIT: I made this works, thanks for the support.

Posted: Thu Dec 21, 2006 11:59 am
by rimbou
Viniterra wrote:EDIT: I made this works, thanks for the support.
It would be very useful if you could share your code ;).
Thanks
________
Mexico Hotels

Posted: Thu Dec 21, 2006 6:56 pm
by Viniterra
Here it is (just the relevant code):

Code: Select all

IAnimatedMesh* mesh = smgr->getMesh("media/model.x");
IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );
if (node)
{
	node->setAnimationSpeed(30);
	node->setFrameLoop(1, 24);
	node->setMaterialFlag(EMF_BACK_FACE_CULLING, false); //two sided faces
	node->getMaterial(2).MaterialType = EMT_TRANSPARENT_ALPHA_CHANNEL; //hair
}
I have made this by modifying the "Hello World" example. The number of the material with transparencies (2) had been found just by tentatives. There is already some more intelligent way to do that, the way hybrid has told some posts above. But, as I could see, the materials index doesn't change for the same .X, so I suppose I could make it hard-coded.

Posted: Fri Dec 22, 2006 1:36 pm
by rimbou
Viniterra wrote: I have made this by modifying the "Hello World" example. The number of the material with transparencies (2) had been found just by tentatives. There is already some more intelligent way to do that, the way hybrid has told some posts above. But, as I could see, the materials index doesn't change for the same .X, so I suppose I could make it hard-coded.
Oh I see, I was hoping for an implementation of what hybrid suggested. Trying to find the transparent material by hand is not exactly good when you have many meshes :D
But thanks for the code. I guess that for the moment I'll do something similar to this.
________
Iolite vaporizer review

Posted: Fri Dec 22, 2006 2:30 pm
by CuteAlien
I change the material usually directly after loading the meshes, using the texturenames (speed ain't a problem there). My implementation does use the stl, but i guess that's easy to change if it troubles you.

All transpartent textures in my game have the word "alpha" as part of the texturename and i'm looking for that:

Code: Select all

SetMaterialTypeByTextureName(node, video::EMT_TRANSPARENT_ALPHA_CHANNEL, "alpha");
That's just a helper function i need to remove the path from my texturenames:

Code: Select all

void ErasePathFromFilename(std::string &filename_)
{
    std::string::size_type p1 = filename_.rfind("/");
    std::string::size_type p2 = filename_.rfind("\\");
    if ( p1 == std::string::npos || (p2 != std::string::npos && p2 > p1 ) )
        p1 = p2;
    if ( p1 != std::string::npos )
        filename_.erase(0, p1+1);
}
That's the function i use to change the materials:

Code: Select all

void SetMaterialTypeByTextureName(scene::ISceneNode* node_, video::E_MATERIAL_TYPE type_, const char *label_)
{
    if ( !node_ || !label_ || !strlen(label_))
        return;

    for ( s32 i=0; i < node_->getMaterialCount(); ++i )
    {
        video::SMaterial & material = node_->getMaterial(i);
        if ( material.Texture1 )
        {
            std::string textureName(material.Texture1->getName().c_str());
            ErasePathFromFilename(textureName); 
            if ( strstr(textureName.c_str(), label_) )
            {
                material.MaterialType = type_;
            }
        }
    }
}