Все мы играем или играли в игры. Некоторые нам нравятся, в некоторых чего-то нам не хватает. Иногда даже говорим: «Если б эту игру делал я, то я бы добавил\изменил…», или что-нибудь в этом роде. А вам никогда не приходило в голову написать свою собственную игру? Вот этим мы как раз и займемся.
Речь, конечно, не идет о продолжении Quak’а или чего-нибудь в этом роде. Достаточно просто получить представление о том, как вообще пишутся игры. Писать мы с вами будем что-то типа тенниса для двоих (Рис. 1).
Итак, что нам нужно для написания игры? Кроме мозгов, нам еще пригодится знание какого-нибудь языка программирования и библиотека OpenGL. В данной статье мы будем пользоваться языком С++ и компилятором Microsoft Visual C++ 6.0. Объяснять, почему, не буду это отдельный разговор (отдельная статья).
Что ж, давайте настроим наш компилятор. Но вначале нам придется скачать один файл (библиотеку GLUT), он небольшой (всего 93 Кб): http://www.opengl.fud.ru/glut.zip. Теперь разархивируйте файлы mui32.lib и glut32.lib в папку Lib, где у вас установлен Visual C++ (скорее всего, это: C:\Program Files\Microsoft Visual Studio\VC98\Lib). Файл glut.h поместите в папку Include\GL (C:\Program Files\Microsoft Visual Studio\VC98\Include\GL\), a glut32.dll в папку C:\Windows\System. На этом с установкой библиотеки закончили.
Откройте Visual C++ и создайте приложение Win32 Console Application.
Теперь нажмите Build > Set Active Configuration и выберите Win32 Release. Затем выберите Project > Setting и перейдите на вкладку Link. В строке Object > library modules допишите следующие библиотеки: opengl32.lib, glu32.lib, glaux.lib и glut32.lib. (Рис. 2).
Перед тем, как начать писать свою игру, давайте немного определимся с терминологией, используемой в программировании 3D-графики.
Рендеринг это процесс подготовки, выдачи (прорисовки) изображения на экран. В общем, это все действия, которые связаны с выдачей картинки на экран.
Буфер это область для временного хранения данных.
Двойная буферизация это один из способов рендеринга, при котором используется два буфера. Содержимое первого (переднего) буфера (front buffer) выводится на экран, и вы видите какое то изображение. В это время задний буфер (back buffer) подготавливает следующий кадр. Когда кадр готов, тогда передний и задний буфер меняются местами. Затем все повторяется сначала. Таким образом можно избежать мерцания экрана.
Пока что нам этого хватит. Переходим к написанию кода.
Давайте сейчас рассмотрим, из чего состоит приложение, написанное на OpenGL (графическая библиотека, которую мы будем использовать при программировании игр и 3D-графики. Есть, конечно, и альтернатива DirectX, но ее мы трогать не будем :-)). Для работы с окнами мы будем использовать, как уже говорилось, библиотеку GLUT.
Первым делом нам нужно инициализировать (подготовить к работе) библиотеку OpenGL. Функция main() (которая всегда присутствует в приложениях, написанных на C++) будет включать вызовы функций GLUT, которые нам позволят устанавливать параметры окна. Также в функцию main() мы должны включить функцию Display, с помощью которой мы и будем рисовать. Вот пример функции main():
Теперь разберем каждую строчку нашего кода. Начнем с первой:
glutInit(&argc,argv) инициализация. Эта функция производит необходимые начальные действия по созданию окна.
glutInitDisplayMode(int Mode) с помощью этой функции устанавливаются необходимые режимы отображения информации, которые можно использовать совместно с помощью операции побитового ИЛИ в языке С++ это значок |.
Для начала рассмотрим самые необходимые на первых порах режимы:
GLUT_RGB режим RGB (отображение цвета с помощью трех основных цветов красного, зеленого и синего). Используется по умолчанию.
GLUT_SINGLE окно с одиночным буфером. Этот режим используется также по умолчанию.
GLUT_DOUBLE окно с двойным буфером (см. выше).
GLUT_DEPTH окно с буфером глубины (Z-buffer’ом), о котором тоже уже сказано.
Листаем далее:
glutWindowSize(400,500) с помощью этой функции мы определяем размер нашего окна (в данном случае 400 ширина, 500 высота). Размер задается в пикселях.
Место, где будет расположено окно (левый верхний угол окна) мы задаем функцией glutWindowPosition(int x, int y).
А теперь мы должны создать само окно. Это делается с помощью glutCreateWindow(string), где в скобках мы пишем заголовок окна.
Функция glutDisplayFunc(имя функции) здесь мы будем «рисовать» и рассчитывать различные трансформации изображения. В качестве параметра вы должны указать имя вашей функции. Например, вы написали функцию:
Тогда наша функция будет иметь вид:
То есть, мы указали, что функцией, ответственной за рисование всех объектов (в нашем примере круга), назначается MyDisplay (аплодисменты :-)).
Контроль всех событий происходит внутри бесконечного цикла glutMainLoop(void).
Вот, собственно и все! Теперь давайте посмотрим полный листинг нашей программы:
Теперь скомпилируйте весь этот код (для этого в Microsoft Visual C++ нажмите клавишу F7) и посмотрите, что у нас получилось. А получилось у нас… «прозрачное» некрасивое окошко. Лиха беда начало все самое интересное у нас впереди.