Monday, August 20, 2007

Color themes and gradient power.

Hey!

This time I would like to talk how the shapes are getting drawn using the list of color themes.

The new GUI system includes a color theme support. Generally you define a unique color for each element of the widget shape. All the unique colors are stored in one list. By making another list with the same color names but with different color values, it is possible to apply new color values  to the GUI widgets without making changes within the widget itself.

I made a separate file which is part of the skin. By default it is called themes.cfg .
It holds different themes and each of them can hold different color values. Like this:



<theme>
            name = "default"
            <colors>
                    window_fill                         = RGBA{ 0.4 , 0.4 , 0.4 , 1.0 }
                   button_fill                             = RGBA{ 0.5 , 0.5 , 0.5 , 1.0 }
                   button_hover_start_fill    = RGBA{ 0.0 , 1.0 , 0.0 , 0.1 }
                   button_hover_end_fill       = RGBA{ 0.0 , 1.0 , 0.0 , 0.0 }
      </colors>
</theme>

<theme>
      name = "blue"
      <colors
>
                    window_fill                       = RGBA{ 0.0 , 0.0 , 0.4 , 1.0 }
                    button_fill                          = RGBA{ 0.2 , 0.2 , 0.5 , 1.0 }
                    button_hover_start_fill  = RGBA{ 0.0 , 0.0 , 1.0 , 0.1 }
                    button_hover_end_fill    = RGBA{ 0.0 , 0.0 , 1.0 , 0.0 }
      </colors>
</theme>

 

It is really easy and straightforward to change these values or add another theme.

The gradient effect is created using only 2 colors from the theme table.



As you can see on this picture there are 2 points. Generally they are used for defining the gradient and texture coordinate values. They are referenced in the strokes.cfg file:


<frame>
          gradient = "vertical"
          <point>
                theme = "button_hover_start_fill"
                uv = UV{ 0.0 , 0.0 }
          </point>
          <point>
                theme = "button_hover_end_fill"
                uv = UV{ 1.0 , 1.0 }
          </point>
</frame>




As you can see the shape is defined here using vertical gradient type.
The color values for each vertex are interpolated depending on the initial point color values and the vertex position relative to the point1 and point2.

There are also other different gradient types that can be used for defining shape appearance:

Solid - only point1 color is used:


Horizontal:


Linear - this is where it is possible to define the gradient angle = 0..360 degrees:


This is probably all there is to know about the gradient and colors in the new GUI system.

Friday, August 03, 2007

Finally an update !

It has been a while since I have updated this blog. Well the primary reason is, that I was working on the new GUI system and at that time there wasn't anything that could be shown.

But it is progressing and I can show a few early screenshots.

The old GUI systems worked fairly well, but had a few flaws. I tried to avoid these problems and add more functionality this time.

One of the major problem in the old GUI was the rendering system. The GUI skin was one big file. It included description of how to render each widget and for each different state. There were generally 4 states: normal , disabled , hover , clicked. Each state is drawn by GL_POLYGON and all the points should be specified directly with (Color,Texture coordinate,position on the 2d screen and anchor).

The new GUI however tries to minimize the amount of data that needs to be written. This is achieved by creating one stroke object that would later be used to draw different parts of many widgets, but it only needs to be defined once.

The widget shape is created from the list of these strokes. The stroke itself is made from many 2d primitive shapes like: line , rectangle , round rectangle , circle , ellipse , arc and bezier. The amount of the data that needs to be written to define a stroke is minimum.

Here is an example of the stroke created from 2 bezier curves:



Each bezier curve is defined by 4 points. The GUI also allows to change the quality of shapes.

The previous shape was created from 16 iterations this is created from 8:


Each shape except line and rectangle can have different quality versions.

One of the most important additions to the GUI rendering system is the material system. The GUI uses the same material system that is used in any other engine part.
This makes it possible to create all sorts of animation effects. The texture coordinates , gradient and alpha values are generated automatically:



One of the most annoying issues when making GUI systems, especially with OpenGL is the lack of good line drawing functionality. The standard line drawing implementation is really limited. Not only it doesn't guarantee some line widths to be available, but the width itself is related directly to pixel width. Which makes it looks different on different resolutions. The other problem is antialiasing of the line. It is widely supported by most graphic cards this day, however their implementation depends on the graphic card manufacturer driver version, and can produce different results.

The line drawing system that I am using here is created by two 4 vertex quads. Original drawing with one 4 vertex quad produced really noticeable jagged lines. However by adding additional quad and using blending, made it look really well, without almost any performance impact. It would also work on any OpenGL implementation and on any resolution the same correct way:



I would probably make some more posts soon, if I manage to get something new working :)

Labels: , , , , ,