Design log 3: GUI system in 3D games
In 3D games, the standard GUI of the operating system is often unavailable, mainly because GDI and 3D are completely different acceleration modules. If they are put together, there will be flickering, an invisible, and other uncertain results. On the other hand, there are also reasons why games are generally used in a different system's personalized GUI. The in-game GUI can be simple or complex, but in any case, it is always more complex than expected.
Because of the complexity, it is difficult to complete, and we often prefer to use the existing complete system, one of which is flash. The best way to use flash is that it has excellent design and production tools. The worst thing is that it is purely software-based Grating, which is very slow when the resolution is high. Although Adobe claims to be developing a version that uses hardware acceleration, it is at least a pie chart. Another option is WPF, which provides the ability to integrate d3d surfaces in. Net 3.5 SP1. But most people will not consider this system. The remaining options include finding an open-source GUI engine, such as cegui. Unfortunately, for the Chinese, these GUI engines almost all have a big problem-lack of support for Chinese. Therefore, we often have to make our own GUI system or transform the existing system. This is a big topic. Here we will only discuss one or two of them.
[Text]
Start with the basic text. The traditional method of rendering text is to arrange the ASCII letters neatly on one texture, and then draw the area corresponding to each character in the string. Later, in order to support font with different character widths, another file needs to be added to record the texture coordinate range of each character and the offset of moving the output reference point to the next character position. This offset is required because the spacing between two English characters is not necessarily equal to the character width, and strictly speaking, this offset is only an approximate solution, because the English kerning is actually different in the spacing between different character combinations. So the text we draw on 3D is not as good as that of GDI.
For Chinese, there is a qualitative change caused by quantitative changes. Extended ASCII 256 symbols are enough for Western languages, while modern commonly used Chinese characters have more than 3000, gb2312 standard Chinese characters have more than 6000, GB18030-2000 contains more than 27000 Chinese characters. In contrast, there are generally more than 1000 commonly used Chinese characters. If all these characters are used to generate textures, a large amount of Memory is wasted, and 80% of textures are rarely used. However, if we only generate textures for a few commonly used characters, the user will encounter a situation where words cannot be typed. In addition, if you want to support traditional Chinese characters, you need a larger texture because there are many strokes and you cannot see them clearly. There will be many more interesting questions if you want to consider internationalization. For example, in Arabic and some Western languages, the combination of some characters should be changed, rather than the simple link of characters.
Further, we may encounter text layout problems. English words, numbers, and so on cannot be cut off when the line is folded. Chinese sentences cannot place punctuation marks at the beginning of the next line when the line is folded, the break and ellipsis cannot be broken when being folded ...... (Thousands of words are omitted here)
It is self-evident that the rendering of text requires special optimization. If you want to be lazy, id3dxfont is a good stuff. It will generate a texture and cache the recently used characters, it also dealt with the problem of Arabic and some western language fonts, even though it sacrificed some speed. Another easy way is to draw the entire text to be rendered on the texture, but the disadvantage is that the texture needs to be updated frequently for dynamically changed texts. Therefore, id3dxfont is used for the moment.
Window System]
The window system is very easy to think of, that is, the layer-by-layer nesting of windows. The good thing about this stuff is that it is easy to understand. The bad thing is that it has to be implemented very complicated to make it so simple.
First, the top-level window has a special case called topmost, such as tooltip, menu, and the main menu displayed by pressing ESC in the game at any time. Second, the focus of mouse input and keyboard input is different. Generally, mouse events are processed in a word window that is just right under the mouse, but there is a special case called Mouse capture, which typically appears when a scroll bar is dragged. Keyboard Input always goes directly to a focal point subwindow, but there is a special case that the shortcut key must be blocked when there is a focal point input. Thirdly, Windows. There are also issues such as the hover and drag effects. You can select the supported quantity as needed.
[Layout System]
Early games basically ignored this issue, because at that time, most of the display resolutions were 640xlarge or 800x600. Later, some increase was made, but all of them were 4-3. But now there are various types such as, and. As a result, layout has to be considered.
Currently, the game's GUI system uses two positioning Methods: absolute coordinate and proportional positioning. Proportional positioning is used to determine the coordinates. For example, the coordinates of the role information window are x = 10%, y = 20%, width = 40%, Height = 60%, that is to say, the screen width is 10% on the left, the top edge is 20% on the screen height, the width is 40% on the screen width, and the height is 60% on the screen height. Proportional positioning can adapt to resolution, but it is not always appropriate, so it is often combined with absolute coordinates. For example, x = 10%, y = 20%, width = 300, Height = 600. Of course, this is just a simplified design of the problem. If you have used winform and WPF, you should be able to understand the efforts of the program framework to solve the layout problem. Sometimes we need a control to keep a fixed distance from one side of the parent window. Sometimes we need the control to always fill a certain area of the parent window. When narrowing down, some controls have the minimum limit and some have the maximum limit. There are also some special controls that provide special layout modes, such as stream layout and table layout.
After all, our goal is to play games, rather than a good GUI system, as long as we choose the simplest solution that can meet our needs. However, individuals do not like proportional positioning, because most GUI elements are not suitable for proportional stretching. For example, if the resolution of a button changes, we do not want the aspect ratio of the button to be changed. For example, when the role window is displayed at 10% on the left half of the screen, it looks good at, and the position may be strange. Therefore, I plan to use the simplified winform Layout mode to dock at the relative positions of the Four-direction Boundary, so that the layout can be very flexible and sufficiently fidelity. In addition, the difference between high and low resolutions can be solved by adding an overall shrinkage coefficient.
[Text input]
Text input is a small problem or a big problem, because the input window cannot be displayed in full screen mode. After playing World of Warcraft, You should have noticed that in full screen mode, there will be a very different input method selection window, rather than a self-installed input method selection window. Microsoft's Win32 API has a special set of IME APIs. If you want to enter Chinese in the exclusive full-screen mode like Warcraft, you can only learn IME APIs and draw the input method selection window by yourself. I am simply lazy, without having to exclusively occupy the full screen mode. I sacrifice a little speed and save a lot of effort.