[Done] Rendering opaque and transparent separately

If you found a bug in our library or on our website, please report it in this section. In this forum you can also make concrete suggestions or feature requests.

Moderators: CEGUI MVP, CEGUI Team

YaronCT
CEGUI Team
Posts: 448
Joined: Fri Jun 19, 2015 12:18
Location: Kiryat-Bialik, Israel

Re: Rendering opaque and transparent separately

Postby YaronCT » Sun Aug 28, 2016 11:10

@Ident: Sorry, I was mistaken then.

User avatar
Ident
CEGUI Team
Posts: 1998
Joined: Sat Oct 31, 2009 13:57
Location: Austria

Re: Rendering opaque and transparent separately

Postby Ident » Sun Aug 28, 2016 11:43

@yaronct here is my version:
https://bitbucket.org/cegui/cegui/commi ... c0bb317b89

I did not store it as an integer as String because i find the conversion problematic. Instead I act as if it was read from XML and turn the serialised enum into a regular enum using PropertyHelper. Feels clener to me.

It works now just like any other property and the functions are exposed too. Pretty optimal imo.

There is only one thing that bothers me now: What meaning do the "Opaque" and "Non-Opaque" modes actually have? All they do is allow windows of the same mode to be drawn. It could as well just be a "QueueNumber" or something like that. That would of course mean that we cant include multiple drawmodes into one draw call, for that we would need a bitmask.

So my suggestion is that we turn this into a bitmask. The OPAQUE and NON-OPAQUE bit flags would then be fully user specifyable. What do you think?
CrazyEddie: "I don't like GUIs"

niello
Quite a regular
Quite a regular
Posts: 76
Joined: Tue May 24, 2011 05:54
Contact:

Re: Rendering opaque and transparent separately

Postby niello » Sun Aug 28, 2016 13:39

Oh, I really didn't expect such a fast and active feedback. Thank you all. Tell me when you finish. I will prioritize this feature testing over all other work.

User avatar
Ident
CEGUI Team
Posts: 1998
Joined: Sat Oct 31, 2009 13:57
Location: Austria

Re: Rendering opaque and transparent separately

Postby Ident » Sun Aug 28, 2016 17:13

Here: now based on a bitmask https://bitbucket.org/cegui/cegui/commi ... d1a7292203

Evidently it must be stored as an integer (uint32) now so yaron got nothing on me now. There is two predefined values for drawmodes, as described in the docu of RenderingSurface::draw(uint32 drawMode);

Dunno how to document that better


EDIT: use this https://bitbucket.org/cegui/cegui/commi ... ebbeb3322e

EDIT2: @niello, I tested this in the samples while developing and it worked fine for me but I didn't use complex setups. What I am unsure about is if clipping works properly. Like if parents that are not drawn are properly having their children clipped as they would if rendered usually. If you could test that it would be awesome. Otherwise this seems pretty final to me in the state iti s now.
CrazyEddie: "I don't like GUIs"

YaronCT
CEGUI Team
Posts: 448
Joined: Fri Jun 19, 2015 12:18
Location: Kiryat-Bialik, Israel

Re: Rendering opaque and transparent separately

Postby YaronCT » Tue Aug 30, 2016 12:41

@Ident: Using a bitmask seems like a good idea, other of course than the fact I got nothing on u now.

And another thing, I know I've already mentioned it and plz don't get angry.. I must urge all forum users to not edit their posts unless it's a tiny unimportant fix. When u update your posts, it is only sometimes by chance that I notice the edit. Posting in the forums is (still) free of charge, even posting 10 times in a row, if u really r senile.

User avatar
Ident
CEGUI Team
Posts: 1998
Joined: Sat Oct 31, 2009 13:57
Location: Austria

Re: Rendering opaque and transparent separately

Postby Ident » Tue Aug 30, 2016 19:38

Posting multiple times in a row without any other people posting is really looked down upon in many forums and I really got used to this "rule". That's the pure reason I do edits - internalised this "rule". I will try to stop myself in the future ;) just keep reminding me if I do wrong.

@niello, tested it?
CrazyEddie: "I don't like GUIs"

niello
Quite a regular
Quite a regular
Posts: 76
Joined: Tue May 24, 2011 05:54
Contact:

Re: Rendering opaque and transparent separately

Postby niello » Wed Aug 31, 2016 08:57

My input system is currently broken, so I can't control the camera :) Hope to fix this in a day or two. I will post my results here.

niello
Quite a regular
Quite a regular
Posts: 76
Joined: Tue May 24, 2011 05:54
Contact:

Re: Rendering opaque and transparent separately

Postby niello » Fri Sep 02, 2016 05:46

It seems that GUIContext::d_isDirty is cleared incorrectly. When I call GUIContext::draw(4) for opaque, it skips all possibly transparent windows (1 & 2, regular & cursor) inside a drawWindowContentToTarget(drawModeMask). But context doesn't count as dirty anymore, and when I call GUIContext::draw(3), it doesn't call drawWindowContentToTarget and therefore draws nothing, except the cursor, which, I think, is never cached.

User avatar
Ident
CEGUI Team
Posts: 1998
Joined: Sat Oct 31, 2009 13:57
Location: Austria

Re: Rendering opaque and transparent separately

Postby Ident » Fri Sep 02, 2016 20:18

Ok I think I now see what is happening here. As warned about, I didnt test it enough and in the way I tested this the problem could not possibly show up.

The thing is that the GUIContext has a cache as you said, so the way to go here would be to additionally check if the last drawmode has changed (if so, we mark ourselves dirty). For v0-8 we cant add this due to ABI compatibility, so for now I fixed this by always marking dirty if a drawmode was used:
https://bitbucket.org/cegui/cegui/commi ... 7dac977c6c

Please test again. The performance impact btw is neglectable, whenever you move a window the GUIContext would be dirtified anyways, and I really doubt you change so little in the GUI in a real production setup as that you would be able to render the same stuff each frame :)
CrazyEddie: "I don't like GUIs"

niello
Quite a regular
Quite a regular
Posts: 76
Joined: Tue May 24, 2011 05:54
Contact:

Re: Rendering opaque and transparent separately

Postby niello » Sat Sep 03, 2016 07:06

It finally works! Thanks.
I will describe implementation details there for others who may want to use a new feature.

1. I had to add 'OpaqueMode' flag to my renderer, otherwise I can't get information about draw mode inside a GeometryBuffer::draw(). Possibly this may be reworked in future versions to make mixed rendering possible, but it requires internal changes in CEGUI. Now it is like:

Code: Select all

   pRenderer->beginRendering();

   if (Mode & DrawMode_Opaque)
   {
      ((CEGUI::CDEMRenderer*)pRenderer)->setOpaqueMode(true);
      pGUIContext->draw(DrawModeFlagWindowOpaque);
   }

   if (Mode & DrawMode_Transparent)
   {
      ((CEGUI::CDEMRenderer*)pRenderer)->setOpaqueMode(false);
      pGUIContext->draw(CEGUI::Window::DrawModeFlagWindowRegular | CEGUI::Window::DrawModeFlagMouseCursor);
   }

   pRenderer->endRendering();


2. I added 2 opaque (clipped & unclipped) render states to existing 4 regular states. In opaque states:
- alpha blending is disabled
- depth test is enabled
- depth func is 'always'
- depth write is enabled
- other pixel shader used, see below

3. Vertex shader writes 0.0f into a z component of transformed position to occupy near plane in a depth buffer, so that it will occlude any other geometry except child windows, which are rendered without depth test when regular or with 'always' depth func when opaque. I think it is possible to change ProjectionMatrix to achieve the same effect without VS changes.

Code: Select all

PSSceneIn VSMain(VSSceneIn In)
{
   PSSceneIn Out = (PSSceneIn)0.0;

   Out.Pos = mul(float4(In.Pos, 1), WorldMatrix);
   Out.Pos = mul(Out.Pos, ProjectionMatrix);
   Out.Pos.z = 0; // ADDED: Render to the near plane
   Out.Tex = In.Tex;
   Out.Colour.rgba = In.Colour.bgra;

   return Out;
}


4. Opaque pixel shader added. Disabling alpha-blending breaks text rendering and non-straight edges, but texkill/clip/discard comes to the resque:

Code: Select all

float4 PSMain(PSSceneIn In): SV_Target
{
   return BoundTexture.Sample(LinearSampler, In.Tex) * In.Colour;
}

// ADDED: Pixel shader variation with manual alpha testing
float4 PSMainOpaque(PSSceneIn In): SV_Target
{
   float4 TexColour = BoundTexture.Sample(LinearSampler, In.Tex);
   clip(TexColour.a - 0.5);
   return TexColour * In.Colour;
}


All changes in shaders are supported in both sm3.0 (DX9) and USM (DX10+).

User avatar
Ident
CEGUI Team
Posts: 1998
Joined: Sat Oct 31, 2009 13:57
Location: Austria

Re: Rendering opaque and transparent separately

Postby Ident » Sat Sep 03, 2016 08:00

Are you saying we should somehow add a way for GeometryBuffers to know what drawMode they are being rendered in, for the custom renderers?

I agree that this would makes sense.

I would prefer to do it the way that the GeometryBuffer would call a getter on a static variable of the RenderingSurface(GUIContext) for now, this would simply be storing the last state, as set by the initial draw call on the GUIContext. Every other draw call will have to reset this state. In v0 we can solve this more elegantly with a getter on a member variable.

Sounds good?
CrazyEddie: "I don't like GUIs"

niello
Quite a regular
Quite a regular
Posts: 76
Joined: Tue May 24, 2011 05:54
Contact:

Re: Rendering opaque and transparent separately

Postby niello » Sat Sep 03, 2016 08:46

Yes, when we render a geometry buffer it is crucial to know whether it is rendered opaque or not to setup render state accordingly. What you suggest will work per GUIContext::draw(), not per GeometryBuffer::draw(), but for now it is a solution.

User avatar
Ident
CEGUI Team
Posts: 1998
Joined: Sat Oct 31, 2009 13:57
Location: Austria

Re: Rendering opaque and transparent separately

Postby Ident » Sat Sep 03, 2016 09:17

niello wrote:Yes, when we render a geometry buffer it is crucial to know whether it is rendered opaque or not to setup render state accordingly. What you suggest will work per GUIContext::draw(), not per GeometryBuffer::draw(), but for now it is a solution.

In what case would you call a GeomtryBuffer::draw() function directly?
CrazyEddie: "I don't like GUIs"

User avatar
Ident
CEGUI Team
Posts: 1998
Joined: Sat Oct 31, 2009 13:57
Location: Austria

Re: Rendering opaque and transparent separately

Postby Ident » Sat Sep 03, 2016 09:26

Window has a public getGeometryBuffers() function so I guess in theory someone might do something. It should be added to the function as param then, i ll do that.
CrazyEddie: "I don't like GUIs"

niello
Quite a regular
Quite a regular
Posts: 76
Joined: Tue May 24, 2011 05:54
Contact:

Re: Rendering opaque and transparent separately

Postby niello » Sat Sep 03, 2016 09:50

Ident wrote:In what case would you call a GeomtryBuffer::draw() function directly?


I never do that, but if you call GUIContext::draw(opaque | transparent), then in GeometryBuffer::draw() you don't know is this particular buffer opaque or transparent, and therefore you can't select appropriate rendering params. It leads to calling GUIContext::draw(opaque) and then GUIContext::draw(transparent), remembering passed flag globally. It is completely acceptable in a case of rendering opaque/transparent, but you implemented drawMode as a bit field with idea that user may define bits as he wants and for what purpose he wants, and GUIContext::draw() can be called with a bit mask. User might need to know exactly what bits are set in a particular buffer during its rendering. But we can't obtain this info because geometry buffer has no reference to its owning CEGUI::Window.


Return to “Bug Reports, Suggestions, Feature Requests”

Who is online

Users browsing this forum: No registered users and 7 guests