Page 1 of 1

GUI elements and MRT

Posted: Sat Sep 28, 2019 11:25 pm
by TheyCrashAroundMe
Hi at all! I'm working on my game made with Irrlicht 1.8.4.

I implemented multiple render targets. I use OpenGL as a back-end.
I can control in which render target should the fragment go.
In every shader I output the albedo color in gl_FragData[0] and another color buffer in gl_FragData[1]. You should get the idea.

Now there is the problem:
I succeded to render texts and images created with methods from IGUIEnvironment to a specific render target, but I cannot specify the "index" in the case of MRT, since you can't apply a material to a IGUIText or IGUIImage.
They seem to render on a specific layer of the current render target. I cannot tell what happens in the case of GUI elements.

Can someone help me?

Thanks in advance.

Re: GUI elements and MRT

Posted: Sun Sep 29, 2019 11:14 pm
by CuteAlien
Not something I did so far. But you can override the material used for UI elements in IVideoDriver with IVideoDriver::enableMaterial2D and IVideoDriver::getMaterial2D (returns a reference so you can change it). Maybe that helps?

Re: GUI elements and MRT

Posted: Tue Oct 01, 2019 10:22 am
by TheyCrashAroundMe
Hi, and thanks for the answer! This surely helps, but I can't override the material without knowing what the original one does. I mean, I think vertex and fragment shaders do something not trivial, like transformations and so on... I should look at Irrlicht source code.
Do you have some clue about this? Maybe I'm missing something...

Re: GUI elements and MRT

Posted: Tue Oct 01, 2019 2:16 pm
by CuteAlien
I think the only driver which uses a shader for 2d is the ogl-es 2 driver in the ogl-es branch (branches\ogl-es in svn). There it can be found in media/Shaders/COGLES2Renderer2D.fsh & vsh- (ignore the COGLES2Renderer2D_noTex.fsh variant, that was a quick hack to get it working on WebGL).

Re: GUI elements and MRT

Posted: Sat Oct 05, 2019 11:56 am
by TheyCrashAroundMe
Thanks!!

Re: GUI elements and MRT

Posted: Tue Nov 12, 2019 11:27 pm
by TheyCrashAroundMe
Hi! I tried to do the following:

Code: Select all

 
driver = device->getVideoDriver();
driver->getMaterial2D().MaterialType = (E_MATERIAL_TYPE)renderer2DMaterial;
driver->getMaterial2D().TextureLayer[0].BilinearFilter = true;
driver->getMaterial2D().AntiAliasing = EAAM_FULL_BASIC;
driver->enableMaterial2D(true);
 
But it basically does nothing. The GUI elements are drawn exactly as they do normally. I am using IGUIEnvironment to draw GUI elements.

This thing is kinda important to me, because in the main RTT I should have the ordinary scene, and in another RTT I have some kind of mask which represents the zone to be affected by some kind of post processing effect.

For example, I managed to do a nice heat wave effect, but since I have only colors do "detect" the zone to be affected by a certain post processing effect, it happens that coloured texts are affected by the post processing effect as well!

It would be very nice to solve this problem, because it means that I could apply the same effects on GUI elements, without creating additional RTTs! Just to say.

Re: GUI elements and MRT

Posted: Wed Nov 13, 2019 2:26 pm
by CuteAlien
Ah yes, surprise - shader material support for 2d only got implemented for d3d and gles. On OpenGL it only supports fixed function materials. *<insert swearword>*

I can try to fix this in svn trunk, but not keen on backporting it to 1.8 as on first view it looks like some stuff changed in there. And no promise yet on svn trunk - I'll take a look, but as original coder didn't implement it I guess there might be something not trivial about this which I don't see yet *sigh*.

edit: OK, this is also not implemented for D3D. So basically - currently 2D materials can't be shaders :-( Sorry, I didn't know about that.

Re: GUI elements and MRT

Posted: Wed Nov 13, 2019 2:54 pm
by TheyCrashAroundMe
Don't worry. I managed to render all the GUI elements on a separate, but common, render target. Then I pass it to my shader which renders the scene in the window, so it's not affected by post-processing effects.
Thanks anyway!

Re: GUI elements and MRT

Posted: Wed Nov 13, 2019 3:05 pm
by CuteAlien
Glad you found a way around it for now.

I just noticed the documentation of getMaterial2D even mentions that MaterialType is ignored (noticed it when I tried to add this info... yeah, I also don't read docs first).
As I got too many open tasks for Irrlicht 1.9 right now, I'll put it on my todo for another year.
Thanks for reporting, at least now I know.

Re: GUI elements and MRT

Posted: Wed Nov 13, 2019 4:43 pm
by TheyCrashAroundMe
Where did you read that?
Here is NOT specified:
http://irrlicht.sourceforge.net/docu/cl ... 1e8a26109c
Nor in the SDK!

Also it's "enableMaterial2D", not "enableInitMaterial2D"

Re: GUI elements and MRT

Posted: Wed Nov 13, 2019 4:45 pm
by CuteAlien
Says "Not all members of SMaterial are honored, especially not MaterialType and Textures."
(in getMaterial2D docu).

Re: GUI elements and MRT

Posted: Wed Nov 13, 2019 4:48 pm
by CuteAlien
Ooops yes, should be enableMaterial2D (fixed now in 1.8 branch, will merge to trunk later).

Re: GUI elements and MRT

Posted: Sat Nov 16, 2019 2:29 pm
by TheyCrashAroundMe
Thanks for all! You are very kind person.

I encoutered another problem, which seems to be a bug:

- I have a irr::core::array of IRenderTarget, called sceneRtts.
- I have a ITexture* where I render the GUI coming from IGUIEnvironment, called guiRtt.

All of the above textures comes from addRenderTargetTexture.

Also, the docs says that if you do setRenderTarget(0), the previous render target is set.

So, if you do:

Code: Select all

 
driver->setRenderTarget(sceneRtts);
// draw and render 3D geometry here
driver->setRenderTarget(guiRtt);
// draw and render GUI stuff here
driver->setRenderTarget(0);
// draw and render other 3D geometry here
 
The array of IRenderTarget will not be bound.

But if you do:

Code: Select all

 
driver->setRenderTarget(sceneRtts[0].RenderTexture);
// draw and render 3D geometry here
driver->setRenderTarget(guiRtt);
// draw and render GUI stuff here
driver->setRenderTarget(0);
// draw and render other 3D geometry here
 
This will work as expected.

Also, I think it should be noted in the docs that texture created from addRenderTargetTexture should be destroyed if not needed anymore (in my case, when you resize the application window), otherwise it will result in a severe memory leak through the life of application.

Re: GUI elements and MRT

Posted: Sun Nov 17, 2019 11:30 am
by CuteAlien
I've added a comment to addRenderTargetTexture.

Not sure about the other one, checking the sources just leaves me more confused. On OpenGL it doesn't seem to try to set previous render target on 0 but the framebuffer. On D3D9 it seems to try get/set a previous render target, but not sure how it handles mrt's.

This seems to have changed in svn trunk where it now also restores a previous rt on OpenGL. But setting an array of images like that is no longer possible in trunk, instead you can set the image array in the rendertarget. Thought I haven't tested yet multi render targets myself (edit: I checked now and they still work).