Hiya CEGUI folks,
I have an unusual coding problem.
The game I'm working on now has a day/night cycle. At nighttime, the UI looks way too bright against the backdrop of the darkened game. What I'd like to do is slightly darken the UI at night.
I was hoping to find a simple way of doing this, without having to do something like iterate over every UI element and adjust the color manually.
I'm using CEGUI 0.8.2 (and will update to 0.8.4 or the latest sometime before launch).
I'm using the GLRenderer. (GL3Renderer is broken in 0.8.2, but I'll switch to that in 0.8.4, which appears to have a fix).
My only lead so far is here:
file: cegui-0.8.2\cegui\src\RendererModules\OpenGL\GLGeometryBuffer.cpp
function: OpenGLGeometryBuffer::draw()
Is this function responsible for drawing everything in CEGUI?
If so, maybe I can muck around with the values fed into glColorPointer?
Anyway, I don't really expect a bunch of help with this very one-off issue. But in case anybody has any thoughts, I'd very much appreciate it.
Thanks!
Darken the entire UI
Moderators: CEGUI MVP, CEGUI Team
- Jabberwocky
- Quite a regular
- Posts: 86
- Joined: Wed Oct 31, 2007 18:16
- Location: Canada
- Contact:
Darken the entire UI
The Salvation Prophecy
Space Combat. Planet Exploration. Strategic Domination.
Space Combat. Planet Exploration. Strategic Domination.
Re: Darken the entire UI
Hah, that is a very interesting situation. Never thought about that one but it completely makes sense for a use-case such as yours (day-night cycle).
First of all, let's try the "right"(tm) way, then I will get to your suggestion. CEGUI provides ColourRects for LookNFeels, which basically just multiply a a colour onto all existing colours for a single window. If you set such a ColourRect in your LNF (similar to "ImageColours" in current StaticImage windows) and tie a property to it (to be able to adjust it in run-time), you can darken this window with the property in run-time without issues. That requires you to cycle through all of them, since properties are not inherited. You said you do not want this...
...in that case the simplest thing you can do is to alter the glsl fragment shader by adding a single uniform variable. But that requires the OpenGL 3 Core Profile renderer I wrote. I don't know how these things work in the archaic OpenGL 2.X way, but I assume there is some way to do this there as well. So basically what you want is to add a uniform variable for example:
on top of the glsl shader where the other uniforms linger.
you may set this to an initial default value if you want:
You will see that somewhere the frag shader outputs a colour (I am not sure what variable is used for this or if the default var is used, you should be able to recognise this easily). Now you alter this colour in the following way after a value is assigned:
The colour should now be 30% darker than it was before. Don't alter the alpha value of ColourRect (the first 2 characters in <= CEGUI 0.8.X)!
Now you wanna be able to change the uniform variable. When the shader is bound you can use gluniform to upload a float. You will need to know the location of the shader variable for this purpose. This can be retriev in GL3Shader or some class like that internally in CEGUI. You won't get around altering CEGUI for this purpose and making a custom function that allows you to change the variable this way in run-time.
I could create a modification for you but not as part of my volunteer time, because I don't think we should add this to CEGUI Core - it would impose a small overhead on every user but only very very few would actually need this feature. If you are interested in http://cegui.org.uk/paid-support you can contact me.
However, I think you could manage to do this on your own as well, especially in case you got some basic OpenGL knowledge you should definitely be able to get this done. Just look up the OpenGL manual, check the Shader-related classes out in the GL3 Renderer and also I will be here to answer any specific questions.
First of all, let's try the "right"(tm) way, then I will get to your suggestion. CEGUI provides ColourRects for LookNFeels, which basically just multiply a a colour onto all existing colours for a single window. If you set such a ColourRect in your LNF (similar to "ImageColours" in current StaticImage windows) and tie a property to it (to be able to adjust it in run-time), you can darken this window with the property in run-time without issues. That requires you to cycle through all of them, since properties are not inherited. You said you do not want this...
...in that case the simplest thing you can do is to alter the glsl fragment shader by adding a single uniform variable. But that requires the OpenGL 3 Core Profile renderer I wrote. I don't know how these things work in the archaic OpenGL 2.X way, but I assume there is some way to do this there as well. So basically what you want is to add a uniform variable for example:
Code: Select all
uniform float darkness;
on top of the glsl shader where the other uniforms linger.
you may set this to an initial default value if you want:
Code: Select all
uniform float darkness = 0.7;
You will see that somewhere the frag shader outputs a colour (I am not sure what variable is used for this or if the default var is used, you should be able to recognise this easily). Now you alter this colour in the following way after a value is assigned:
Code: Select all
colourVar.rgb *= darkness;
The colour should now be 30% darker than it was before. Don't alter the alpha value of ColourRect (the first 2 characters in <= CEGUI 0.8.X)!
Now you wanna be able to change the uniform variable. When the shader is bound you can use gluniform to upload a float. You will need to know the location of the shader variable for this purpose. This can be retriev in GL3Shader or some class like that internally in CEGUI. You won't get around altering CEGUI for this purpose and making a custom function that allows you to change the variable this way in run-time.
I could create a modification for you but not as part of my volunteer time, because I don't think we should add this to CEGUI Core - it would impose a small overhead on every user but only very very few would actually need this feature. If you are interested in http://cegui.org.uk/paid-support you can contact me.
However, I think you could manage to do this on your own as well, especially in case you got some basic OpenGL knowledge you should definitely be able to get this done. Just look up the OpenGL manual, check the Shader-related classes out in the GL3 Renderer and also I will be here to answer any specific questions.
CrazyEddie: "I don't like GUIs"
- Jabberwocky
- Quite a regular
- Posts: 86
- Joined: Wed Oct 31, 2007 18:16
- Location: Canada
- Contact:
Re: Darken the entire UI
Hi Ident -
Thanks for the response!
Re: the "right"(tm) way:
One of the reasons I wanted to avoid iterating is that the transition from day to night is gradual. Throughout this gradual transition, I'd need to iterate quite often (perhaps every frame, or close to it), such that the UI gradually became darker as the world became darker. I don't want the UI to noticeably jump from one colour to another, which would happen if I updated the UI darkness too infrequently.
That iteration in itself might be a bit expensive, but I also assume you would need to invalidate every window each time you changed the colour, which would add to the perf hit.
The final concern was that I didn't want to overwrite any existing (pre-darkened) colours on a window. For example, maybe I already have a StaticImage which is tinted red. I don't want to override that tint, but rather multiply it. Maybe your LooknFeel approach solves this? Either way, there are the other problems mentioned above, as well.
Re: glsl fragment shader
Cool, this sounds more along the lines of something quick and efficient!
At my soonest opportunity, I'll upgrade to 0.8.4 and migrate to the GL3Renderer, then give it a shot. I'm reasonably competent with shaders (and this shader code change is about as basic as you get), but less so with low level opengl. I'll give it a shot. But if you'd like to PM me with a rough quote for the work, that'll give me an idea of how much time I should spend on trying to get it work myself, vs. hiring an expert.
Thanks!
Thanks for the response!
Re: the "right"(tm) way:
One of the reasons I wanted to avoid iterating is that the transition from day to night is gradual. Throughout this gradual transition, I'd need to iterate quite often (perhaps every frame, or close to it), such that the UI gradually became darker as the world became darker. I don't want the UI to noticeably jump from one colour to another, which would happen if I updated the UI darkness too infrequently.
That iteration in itself might be a bit expensive, but I also assume you would need to invalidate every window each time you changed the colour, which would add to the perf hit.
The final concern was that I didn't want to overwrite any existing (pre-darkened) colours on a window. For example, maybe I already have a StaticImage which is tinted red. I don't want to override that tint, but rather multiply it. Maybe your LooknFeel approach solves this? Either way, there are the other problems mentioned above, as well.
Re: glsl fragment shader
Cool, this sounds more along the lines of something quick and efficient!
At my soonest opportunity, I'll upgrade to 0.8.4 and migrate to the GL3Renderer, then give it a shot. I'm reasonably competent with shaders (and this shader code change is about as basic as you get), but less so with low level opengl. I'll give it a shot. But if you'd like to PM me with a rough quote for the work, that'll give me an idea of how much time I should spend on trying to get it work myself, vs. hiring an expert.
Thanks!
Re: Darken the entire UI
Jabberwocky wrote:One of the reasons I wanted to avoid iterating is that the transition from day to night is gradual. Throughout this gradual transition, I'd need to iterate quite often (perhaps every frame, or close to it), such that the UI gradually became darker as the world became darker. I don't want the UI to noticeably jump from one colour to another, which would happen if I updated the UI darkness too infrequently.
That iteration in itself might be a bit expensive, but I also assume you would need to invalidate every window each time you changed the colour, which would add to the perf hit.
Yea, I thought about it that way already and the reasons you stated are part of why I didn't elaborate this direction further - it is not feasible. If the colour was inheritable it would be less of an issue. However, in current CEGUI the Colours are baked into vertices, not something I would have designed that way but that is from fixed-function times I assume. Changing this is very high on my Todo list, since it bloats the vbos and requires useless vbo regens. I already fully planned out how to change it, just haven't done it yet, but the change will only be in 1.0 (current default branch). But even if you were using 1.0 this wouldn't be optimal: the LNFs would need to be altered and you would still need to edit properties - a lot. So even though this is the "right" way it is by far not the optimal or recommended one. Even if we had global properties this would be an issue internally, since all geometry (in 0.8 ) still would have to be recreated on every change - invalidating all windows and resending all data to the GPU every time. I recommend going by the other route.
Jabberwocky wrote:The final concern was that I didn't want to overwrite any existing (pre-darkened) colours on a window. For example, maybe I already have a StaticImage which is tinted red. I don't want to override that tint, but rather multiply it. Maybe your LooknFeel approach solves this? Either way, there are the other problems mentioned above, as well.
If the other colours of the LNF are not correctly taken into account then this is a bug that should be fixed in upcoming versions. I would expect things to work the way you described them. I haven't encountered problems so far but I also did not specifically play around with this feature yet. In either case it should not be of concern regarding your problem.
So in any case I suggest doing this via the general shader program. I sent you a pm.
CrazyEddie: "I don't like GUIs"
Re: Darken the entire UI
We solved this in an efficient way using OpenGL3Renderer and shader programs. Since this is not backwards compatible and a rare feature, we won't adopt it into CEGUI source code. This was only applied to the client's code.
CrazyEddie: "I don't like GUIs"
Return to “Modifications / Integrations / Customisations”
Who is online
Users browsing this forum: No registered users and 3 guests