Mason McCuskey - Developing a GUI in C++ and DirectX

Здесь есть возможность читать онлайн «Mason McCuskey - Developing a GUI in C++ and DirectX» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Жанр: Программирование, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Developing a GUI in C++ and DirectX: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Developing a GUI in C++ and DirectX»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

At first glance, it may seem like I’m reinventing the wheel; Windows already comes with a very complex, very functional GUI. Unfortunately, while the Windows GUI is great for office apps, quite frequently, it’s not suited for many games. Games tend to want a more precise control over the GUI than Windows can provide (for example, games may want to use alpha-blending to implement partially transparent windows - easy if you’ve written your own GUI, but next to impossible using the Windows GUI).
This article will walk you though how to create a GUI using C++ and DirectX. The series is divided into several parts, each dealing with a specific aspect of GUI programming:
Part I: The Basics, and the Mouse
Part II: Windows
Part III: Controls
Part IV: Resource Editors and Other Madness
NOTE: This document was originally four separate articles on www.gamedev.net. I’ve concatenated all four into one for the XGDC, but they remain otherwise unchanged. - Mason

Developing a GUI in C++ and DirectX — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Developing a GUI in C++ and DirectX», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Now that we’ve got some coordinates, we can finally begin to draw our window…

Window Drawing Code

Recursion is a double-edged sword. It makes the window drawing code very easy to follow, but it also ends up touching pixels twice, which can be a significant performance hit (say, for example, you have a stack of fifty windows, all the same size and at the same screen position - the code will run through the drawing loop fifty times, and touch the same set of pixels fifty times). This is a notorious problem. There are certainly hidden-surface elimination algorithms one could apply to this situation - in fact, this is an area I need to spend some time with on my own code - Quaternion’s GUI is most active during the non-game screens (title, closing, etc.), places where it’s perfectly OK for the GUI to be a hog, because there isn’t anything else going on.

But, I am tinkering with it; I’m currently trying to employ the DirectDrawClipper object in my drawing routines. So far, the initial code looks pretty promising. Here’s the way it will work: The desktop window “clears” the clipper object. Each window then draws is subwindows backwards, top one first, bottom one last. After each window is drawn, it adds its screen rectangle to the Clipper, effectively “excluding” that area from the windows below it (yes, this assumes all windows are 100% opaque). This helps to ensure that at the very least, each pixel will be touched only once; granted, the code is still churning through all of the calculations and calls required for GUI rendering, (and the clipper’s probably got its hands full, too), but at least the code isn’t actually drawing redundant pixels. Whether the clipper object operates fast enough to make this worthwhile remains to be seen.

I’m tossing around several other ideas, too - perhaps using the built-in z-buffer on the 3D graphics card, or implementing some sort of dirty rectangle setup. If you’ve got any ideas, let me know; or, try them yourself and let me know what you found.

Most of the bulk of the window drawing code I cut out, because it’s very specific to my situation (it calls my custom sprite classes). Suffice it to say that once you know the exact screen dimensions of where you’re going to draw a window, the actual drawing code is straightforward (and fun) to implement. Fundamentally, my drawing code takes a set of nine sprites - four for the corners, four for the edges, one for the background - and uses those sprites to draw the window.

The color sets deserve a small explanation. I decided that each window would have two unique color sets; one set for when that window is active, one set for when it’s not. Before the drawing code gets started, it makes a call to getappropriatecolorset(), which returns the correct color set for the window’s activation status. Having separate colors for active and inactive windows is a basic principle of GUI design; it was also fairly easy to implement.

Now our windows draw, so it’s time to start looking at messaging…

Window Messages

This section is the core of GUI implementation. Window messages are the events that get sent to a window when the user performs certain actions - clicking the mouse, moving it, hitting a key, etc. Some messages (like wm_keydown) are sent to the active window, some (wm_mousemove) are sent to the window the mouse is over, and some (wm_update) are always sent to the desktop, regardless.

Microsoft Windows has a message queue. My GUI does not - when calcall() figures out that it needs to send a message to a window, it stops right there and “sends” it - it calls the appropriate wm_xxxx() virtual function for that window. I’ve found that this method is just fine for simple GUIs. Unless you have a really good reason, don’t bother with implementing a full-blown message queue, storing things into it, and having separate threads pick up the messages and dispatch them. For most game GUIs, it isn’t worth it.

As much as I’d like to, I can’t go into very much detail about calcall(), the function that polls all the input devices and sends out the messages. It does many things, and implements many behaviors that are specific to my GUI. For example, you might want your GUI to behave like X-Windows, where the window the mouse is over is always the active window. Or, you might want to make the active window system modal (meaning nothing else can happen until the user gets rid of it), like several Mac-based programs do. You might want the ability to move windows by clicking anywhere in them, instead of just in their title bar, like WinAmp. The implementation of calcall() will vary wildly depending on which behaviors you decide to incorporate into your GUI.

I’ll give you a hint, though - the calcall() function is notstateless, in fact, your calcall() function will probably end up being a rather complex state machine. The perfect example of this is dragging and dropping things. In order to properly calculate the difference between a normal “mouse button released” event, and a similar but completely different “whatever the user was dragging has just been dropped” event, calcall() must maintain a state. If you’re rusty on finite state machines, save yourself a lot of headaches and brush up on them before you tackle calcall()’s implementation.

The wm_xxx() functions included in the window header file were the ones I felt represented the minimum set of messages a GUI would need to calculate and dispatch. Your needs may differ, and there’s no reason why you have to stick to the Microsoft Windows set of messages; if a custom message would be perfect for you, now’s the time to implement it.

Wrapping It Up

In the first part of this article I PDL’d out a function called CApplication::RenderGUI(), the master function behind calculating and drawing our GUI:

void CApplication::RenderGUI(void) {

// get position and button status of mouse cursor

// calculate mouse cursor’s effects on windows / send messages

// render all windows

// render mouse

// flip to screen

}

Now, finally, we’re at a position where we can begin filling in some of that PDL. Check it out:

void CApplication::RenderGUI(void) {

// get position and button status of mouse cursor

m_mouse.Refresh();

// calculate mouse cursor’s effects on windows / send messages

GetDesktop()-›PumpMessages();

// render all windows

GetDesktop()-›RenderAll();

// render mouse

m_mouse.Render();

// flip to screen

GetBackBuffer()-›Flip();

}

Hopefully, seeing this code now will show you how things are starting to come together.

Part III: Implementing Controls

This section doesn’t have as much code as the others - this is mainly because we programmers are fairly picky when it comes to the appearance of our GUI. We like to code things up so that our buttons, our textboxes, and our GUI appear unique, and fit our own aesthetic tastes. Consequently, everyone’s control code will be slightly (or maybe drastically different), and it wouldn’t make sense to include my particular drawing code. Besides, writing code to draw all the GUI elements is fun, in fact, in my opinion, it’s the mostfun you can have implementing a GUI. Go wild.

That being said, let’s start by determining which GUI controls we need.

GUI Controls We’ll Need

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Developing a GUI in C++ and DirectX»

Представляем Вашему вниманию похожие книги на «Developing a GUI in C++ and DirectX» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Отзывы о книге «Developing a GUI in C++ and DirectX»

Обсуждение, отзывы о книге «Developing a GUI in C++ and DirectX» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x