Problem with overlaying regular texture with RTT.

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
Andrey01
Posts: 57
Joined: Mon Jul 27, 2020 9:08 pm

Problem with overlaying regular texture with RTT.

Post by Andrey01 »

I have a mesh scene node (mirror) with two materials. The second one contains two texture layers. In the first layer I add a render target texture (created using IVideoDriver::addRenderTargetTexture) in which the camera renders from the position of the mirror node and from that direction where the mirror is targeted itself. In the second layer I put a regular texture (created using IVideoDriver::addTexture(const core::dimension2d< u32 > size, const io::path name, ECOLOR_FORMAT format = ECF_A8R8G8B8)) afterwards from which video::IImage is created as a pointer to the data of the video::ITexture. Then I draw some red line at the center of the video::IImage using setPixel() calls. I draw only once before the main loop. However, the total mirror looks like black at the background, but contains a red line at the center:

Image

How the render target texture looks like on the mirror itself (disabling the second layer):

Image

I also tried to load from disk some texture, in my case containing a gloss for the mirror and replaced the IImage in the second layer to that (I selected the semitransparent one purposely to see what's in the background):
Image

The result is almost fine, except the oerkki character is drawn atop the gloss texture:
Image

Ideally it should be vice versa because of the order of the texture layers set for the material.

My code:

Code: Select all

// int main()

core::dimension2du img_size(256, 256);
video::ITexture *overlay_tex = vdrv->addTexture(img_size, "overlay", video::ECF_A8R8G8B8);
-----------------------------------------------------------------------------

// Set two texture layers (first is rtt, second is dynamic texture with red line)
mat.setTexture(0, colorRT);
mat.setTexture(1, overlay_tex);
-----------------------------------------------------------------------------

video::IImage *overlay_img = vdrv->createImageFromData(
	overlay_tex->getColorFormat(),
	overlay_tex->getSize(),
	overlay_tex->lock(),
	true
);
	
// Draw the red line at the center
for (int x = 0; x < img_size.Height; x++)
	for (int y = 0; y < img_size.Width; y++)
		overlay_img->setPixel(128, y, video::SColor(255, 255, 0, 0));
	
overlay_tex->unlock();
CuteAlien
Admin
Posts: 9643
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Problem with overlaying regular texture with RTT.

Post by CuteAlien »

addTexture is not initializing the memory in any way. So can be black - can be random. You only draw one red line, the rest is uninitialized. So fill the image once with some color. If you want it transparent the colors should probably have an alpha of 0.

Multiple textures are not drawn one over the other in the order they are given. How they are combined is defined by the material - especially the MaterialType. Check the documentation for each one to see what it does. Minor note: EMT_SOLID_2_LAYER docs say right now it's not implemented in OpenGL, I gotta check this - could be documentation for this is outdated and that it works at least in Irrlicht trunk.

For more complicated combinations for 2 textures than those offered by E_MATERIAL_TYPE you will need to code shaders.
Sadly I think one of the most common requests needs a shader: Adding second material on first one while using alpha-channel of second texture (or both alpha channels). Using EMT_LIGHTMAP_ADD and black instead of alpha for parts which shouldn't be drawn in second texture maybe works for you if you are lucky (if it's just about adding a bit brightness to mirror).

Maybe BlendOperation allows more options. I think this has to be set anyway as well (or maybe only needs to be set to blend with background and unrelated to 2 textures).

Sorry if I'm a bit uncertain about materials, there's a quite a few flags and combinations and I mostly use shaders by now if it's getting slightly beyond the defaults.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Andrey01
Posts: 57
Joined: Mon Jul 27, 2020 9:08 pm

Re: Problem with overlaying regular texture with RTT.

Post by Andrey01 »

Thanks. I read thoroughly all materials types documented in EMaterialTypes.h file since the doc in the engine itself is more actual than that one which the website says. I really didn't find any suitable type that would just combine two textures (what is very wonderful as other materials can combine diffuse maps with light ones and even reflection maps, but can not overlay simple diffuse maps at each other), except EMT_SOLID_2_LAYER that really doesn't work so far :( As a result I wrote an own very easy shader that just gets two diffuse textures and adds them based on the alpha of the second one and it worked as expected:
Image
CuteAlien
Admin
Posts: 9643
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Problem with overlaying regular texture with RTT.

Post by CuteAlien »

Yeah, EMT_SOLID_2_LAYER is a bit weird. It uses the alpha of the vertices - not the alpha of textures. So basically you can blend the whole second texture, but nothing per pixel with it. edit: Although I tested it and at least it works with OpenGL.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Post Reply