[Done] Rendering opaque and transparent separately
Moderators: CEGUI MVP, CEGUI Team
Re: Rendering opaque and transparent separately
@Ident: Sorry, I was mistaken then.
Re: Rendering opaque and transparent separately
@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?
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"
Re: Rendering opaque and transparent separately
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.
Re: Rendering opaque and transparent separately
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.
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"
Re: Rendering opaque and transparent separately
@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.
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.
Re: Rendering opaque and transparent separately
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?
@niello, tested it?
CrazyEddie: "I don't like GUIs"
Re: Rendering opaque and transparent separately
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.
Re: Rendering opaque and transparent separately
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.
Re: Rendering opaque and transparent separately
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
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"
Re: Rendering opaque and transparent separately
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:
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.
4. Opaque pixel shader added. Disabling alpha-blending breaks text rendering and non-straight edges, but texkill/clip/discard comes to the resque:
All changes in shaders are supported in both sm3.0 (DX9) and USM (DX10+).
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+).
Re: Rendering opaque and transparent separately
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?
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"
Re: Rendering opaque and transparent separately
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.
Re: Rendering opaque and transparent separately
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"
Re: Rendering opaque and transparent separately
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"
Re: Rendering opaque and transparent separately
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 10 guests