Coloring units

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
badday
Posts: 102
Joined: Mon Aug 16, 2010 1:14 pm

Coloring units

Post by badday »

Hi guys,

I´m currently trying to colorize my units the following way:

Taking the original texture/material:

Code: Select all

video::SMaterial text = node->getMaterial(0);
text.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
text.setFlag(video::EMF_LIGHTING, false);
As a background I create a solid color texture like the following:

Code: Select all

video::SMaterial solid;
solid.MaterialType = video::EMT_SOLID;
video::IImage *img = Device->getVideoDriver()->createImage(video::ECF_A8R8G8B8, core::dimension2du(1,1));
img->setPixel(0,0, video::SColor(0, 0, 0, 255));        
solid.setTexture(0, Device->getVideoDriver()->addTexture("bla", img));
solid.setFlag(video::EMF_LIGHTING, false);
Finally I use those two materials at the node:

Code: Select all

node->setMaterialTexture(0, solid.getTexture(0));
node->setMaterialTexture(1, text.getTexture(0));
But as a result, not only the transparent part of my .png texture (currently I only use values 0 and 255 and nothing in between) seems to be transparent, but all parts. Therefore the hole model seems to be dip-painted in blue in this example.

What am I doing wrong? I further information is required, please give a shout.


Best wishes,

badday
Klunk
Posts: 264
Joined: Mon Jan 10, 2011 5:21 pm

Re: Coloring units

Post by Klunk »

scolor is alpha red green blue not red green blue alpha
badday
Posts: 102
Joined: Mon Aug 16, 2010 1:14 pm

Re: Coloring units

Post by badday »

You´re right, the solid color should therefore be video::SColor(255, 0, 0, 255) meaning not transparent at all. Anyway, this doesn´t solve the problem (it doesn´t even have any obvious effect at all)
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Coloring units

Post by hybrid »

The proper material would be EMT_TRANSPARENT_ALPHA_CHANNEL. Otherwise you get transparency on black (0,0,0) colors.
badday
Posts: 102
Joined: Mon Aug 16, 2010 1:14 pm

Re: Coloring units

Post by badday »

Hm... I made the MaterialType of text video::EMT_TRANSPARENT_ALPHA_CHANNEL. However, the problem remains.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Coloring units

Post by hybrid »

Well, looking over the code in more detail: Why do you need two textures? All the materials you mentioned don't even support two textures. From what I see you probably want to change the background color independently of the text. I'd probably change the vertex color to solid blue and use the transparent text on top. But you can also use two meshes overlaid, or the two texture materials. However, the two texture solid material seems to use vertex alpha only, lightmap and detailmap might have disturbing visual effects, and reflection materials distort the reflected texture (although this would be invisible on the plain blue texture). So don't know if any of these options really helps. Guess you have to try them all
badday
Posts: 102
Joined: Mon Aug 16, 2010 1:14 pm

Re: Coloring units

Post by badday »

Hm... It all results in almost the same unfortunately, even with video::EMT_TRANSPARENT_REFLECTION_2_LAYER or video::EMT_LIGHTMAP like this:
Image
What I do not understand is why this can´t be easily made as by default it does colorize the background with white:
Image

So isn´t it just possible to change this "default" color or is this a totally different mechanism?

Thanks.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Coloring units

Post by hybrid »

I still don't really get what you want to achieve. But the white color comes from the vertex color, which you can change on a per-mesh base (not per scene node). You might need to enable lighting for the meshes, though. Also note that you seem to mix texture and material in your code example. You talk about text material and solid material, but use only textures in the end.
badday
Posts: 102
Joined: Mon Aug 16, 2010 1:14 pm

Re: Coloring units

Post by badday »

I still don't really get what you want to achieve
I would like to have some background in the color I choose and to put the texture on top of it. According to the alpha-value of this texture, you should see the background or not.
But the white color comes from the vertex color, which you can change on a per-mesh base (not per scene node). You might need to enable lighting for the meshes, though.
Alright, so you thought about

Code: Select all

Device->getSceneManager()->getMeshManipulator()->setVertexColors(mesh, SColor(255,0,0,255));
mesh->setMaterialFlag(video::EMF_LIGHTING, true);
This results in the first image above. Do I need to set the MaterialType of the scene node to some other value maybe? Does it mix the vertex color and the texture color? What exactly does vertex color mean? I this just the default color of all vertices?
Also note that you seem to mix texture and material in your code example. You talk about text material and solid material, but use only textures in the end.
OK, you´re right, this it doesn´t make sense to play around with the materials which are not used at all (as only textures are used from those materials).


Thanks again for spending ur time on helping me :)
badday
Posts: 102
Joined: Mon Aug 16, 2010 1:14 pm

Re: Coloring units

Post by badday »

Alright, I finally made it by hand. This way should be driver-independent, therefore it might be useful for others as well:

Code: Select all

core::dimension2du size = node->getMaterial(0).getTexture(0)->getSize();
 
video::ITexture *texture = node->getMaterial(0).getTexture(0);
char* pixels = (char*)texture->lock();
        
unsigned long offset = 0;
unsigned long fractionColor = 0x000000FF;
unsigned short r2, g2, b2;
unsigned short r1,g1,b1;
r1 = (unsigned short)((fractionColor & 0x00FF0000) >> 16);
g1 = (unsigned short)((fractionColor & 0x0000FF00) >> 8);
b1 = (unsigned short)(fractionColor & 0x000000FF);
unsigned long PointColor;
unsigned int size1D = size.Width * size.Height;
 
size_t sizeOf_ul = sizeof(unsigned long);
 
for(s32 counter = 0; counter < size1D; ++counter)
{
        memcpy(&PointColor, pixels + offset, sizeOf_ul);
 
        if((PointColor & 0xFF000000) != 0xFF000000)
        {
                        unsigned short r2,g2,b2;
                        float a2, a1;
                        a2 = (unsigned short)((PointColor & 0xFF000000) >> 32);
                        a2 = a2/255.0;
                        a1 = 255 - (unsigned short)((PointColor & 0xFF000000) >> 32);
                        a1 = a1/255.0;
                        r2 = (unsigned short)((PointColor & 0x00FF0000) >> 16);
                        g2 = (unsigned short)((PointColor & 0x0000FF00) >> 8);
                        b2 = (unsigned short)(PointColor & 0x000000FF);
 
                        r2 = (r2*a2) + r1*a1;
                        g2 = (g2*a2) + g1*a1;
                        b2 = (b2*a2) + b1*a1;
 
                        
                        if(r2 > 0xFF) r2 = 0xFF;
                        if(g2 > 0xFF) g2 = 0xFF;
                        if(b2 > 0xFF) b2 = 0xFF;
 
                        PointColor = 0xFF000000 | (r2 << 16) | (g2 << 8) | b2;
 
                        
                        memcpy(pixels + offset, &PointColor, sizeOf_ul);
        }
 
        offset += sizeOf_ul;
}
texture->unlock();
texture->regenerateMipMapLevels();
Which results in:
Image

I didn´t test the algo for other alpha-values than 0 and 255, therefore it might be possible that there is some mistake somewhere ;)
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Coloring units

Post by hendu »

Why not use a shader? Certainly should be faster and less code than generating textures on the cpu.
Post Reply