Как сделать игру на directx
Разработка простой игры в Code::blocks с использованием Direct3D 9
Введение
Итак, в свободное от работы время решил я изучить популярный графический API. Прочитав несколько книг и разобрав кучу примеров и туториалов (в том числе из DirectX SDK), я осознал, что настал тот самый момент, когда стоит попробовать свои силы самостоятельно. Основная проблема была в том, что большинство существующих примеров просто демонстрируют ту или иную возможность API и реализованы процедурно чуть ли не в одном cpp-файле, да еще и с использованием обертки DXUT, и не дают представления о том, какую структуру должно иметь конечное приложение, какие классы нужно спроектировать и как это все должно друг с другом взаимодействовать, чтобы все было красиво, читабельно и эффективно работало. Данный недостаток касается и книг по Direct3D: например, для многих новичков не является очевидным тот факт, что состояния рендера (render states) не всегда нужно обновлять при отрисовке каждого кадра, а также, что большинство тяжеловесных операций (типа заполнения вершинного буфера) следует выполнить всего один раз при инициализации приложения (либо при загрузке игрового уровня).
Первым делом мне необходимо было определиться с самой идеей игры. На ум сразу пришла старая игра из 1992 года под MS-DOS, которая, я думаю, многим знакома. Это логическая игра Lines компании Gamos.
Начало разработки
До сих пор я не упоминал, какие инструменты использовались. Во-первых, необходим DirectX software development kit (SDK), всегда доступный для свободного скачивания на сайте Microsoft: DirectX SDK. Если вы собираетесь использовать версию Direct3D 9, как я, то после установки необходимо через главное меню открыть DirectX Control Panel и на вкладке Direct3D 9 выбрать, какая версия библиотек будет использоваться при сборке — retail либо debug (это влияет на то, будет ли Direct3D сообщать отладчику о результатах своей деятельности):
Почему Direct3D 9-й версии? Потому что это последняя версия, где все еще есть fixed function pipeline, то есть фиксированный графический конвейер, включающий в себя, например, функции расчета освещения, обработки вершин, смешивания и так далее. Начиная с 10-й версии, разработчикам предлагается самостоятельно реализовывать эти функции в шейдерах, что является неоспоримым преимуществом, но, на мой взгляд, сложновато для восприятия при первых опытах с Direct3D.
Почему Code::blocks? Наверное, глупо было использовать кросс-платформенную IDE для разработки приложения, использующего некросс-платформенный API. Просто Code::blocks занимает в несколько раз меньше места, чем Visual Studio, что оказалось очень актуальным для моего дачного ПК.
Старт разработки с Direct3D оказался очень прост. В Code::blocks я создал пустой проект (empty project), затем в build options нужно было сделать две вещи:
1) На вкладке search directories и подвкладке compiler добавить путь к директории include DirectX SDK — например, так:
После этого в исходном коде приложения нужно будет включить заголовочные файлы Direct3D:
Структура приложения
Здесь я допустил первую ошибку: начал размышлять над тем, какой шаблон проектирования выбрать. Пришел к выводу, что лучше всего подходит MVC (model-view-controller): моделью будет класс игры (game), включающий всю логику — вычисление путей перемещения, появление шаров, разбор взрывных комбинаций; представлением будет класс движка (engine), отвечающий за отрисовку и взаимодействие с Direct3D; контроллером будет собственно обертка (app) — сюда входит цикл обработки сообщений, обработка пользовательского ввода, а также, что самое главное, менеджер состояний и обеспечение взаимодействия объектов game и engine. Вроде бы все просто, и можно начинать писать заголовочные файлы, но не тут-то было! На этом этапе оказалось очень сложно сориентироваться и понять, какие методы должны быть у этих классов. Понятно, что сказалось полное отсутствие опыта, и я решил прибегнуть к совету одной из книг: «Не пытайтесь с самого начала написать идеальный код, пусть он будет неоптимальным и сумбурным. Понимание приходит со временем, и рефакторингом можно заняться потом.» В итоге после нескольких итераций рефакторинга уже работающего макета определение трех основных классов приняло вид:
Рассмотрим подробнее классы движка и контроллера.
TEngine
В самом начале вычисляется, сколько миллисекунд прошло с предыдущего вызова Render(), затем обновляются прогрессы анимаций, если они активны. Очищаются буферы методом Clear и последовательно рисуются платформа, шары и система частиц, если она активна. Напоследок выводится строка с текущим значением заработанных очков.
TApplication
Внимания заслуживает только то, что находится внутри блока else — это так называемая IdleFunction, которая выполняется при отсутствии сообщений.
А вот и функция менеджера состояний:
Что ж, пожалуй, на этом все!
Заключение
Здесь самое место, чтобы перечислить недостатки. Разумеется, в коде куча мест для оптимизаций. Кроме того, я не упомянул о таких вещах, как смена параметров видеорежима (разрешение экрана, multisampling) и обработка потери устройства (LostDevice). На счет последнего имеется подробное обсуждение на сайте gamedev.ru.
Надеюсь, мои изыскания принесут кому-то пользу. Кстати, исходники на github.
games maker Все о создании игр и не только
Виртуальная камера. Перспективная проекция.
Сегодня мы более подробно рассмотрим устройство виртуальной камеры. Направление («взгляд») камеры всегда совпадает с положительным направлением оси z, а сама камера расположена в начале координат.
Виртуальная камера. Реализация. Часть вторая.
В первой части урока мы обсудили вспомогательные классы и функции, а во второй рассмотрим непосредственно код, который реализует функциональность камеры.
Виртуальная камера. Часть первая.
В этом уроке мы рассмотрим реализацию камеры. К данному моменту вы уже должны хорошо усвоить все уроки по преобразованиям из раздела Математика.
DirectX API: Инициализация Direct3D
Сегодня мы напишем программу, которую будем использовать в качестве шаблона в нескольких ближайших уроках. В заготовку стандартного приложения Windows мы добавим код, в котором будет инициализироваться Direct3d.
Установка DirectX SDK и directx end-user runtimes
Для того чтобы писать программы, в которых используется DirectX, нужно установить Directx sdk. Для запуска программ написанных с использованием DirectX, необходимо установить directx end-user runtimes. В данном уроке мы рассмотрим установку обоих компонентов.
Индексные буферы (Index buffers) в Direct3D
В прошлом уроке было упражнение, в котором вы должны были построить куб. Особо наблюдательные могли заметить, что для этого нужно было запихать в вершинный буфер координаты 36 вершин.
Преобразования матриц в DirectX
Сегодня будет совсем маленький урок. Мы не будем изучать что-то новое, вместо этого закрепим материал по преобразованиям. Зато, вам придётся довольно много поработать самостоятельно.
Поверхности (surfaces) Direct3D
При создании устройства IDirect3DDevice9, автоматически создаются две поверхности: основной буфер и фоновый буфер (front/back buffer; встречаются и другие переводы: передний буфер и задний буфер). Для указания свойств этих поверхностей нужно заполнить структуру D3DPRESENT_PARAMETERS
Cоздание простой геометрии в DirectX
Инициализация DirectInput
Для начала нужно добавить к проекту следующие библиотечные файлы: dinput8.lib, dxguid.lib. Заголовочный файл для DirectInput следующий: dinput.h.
Direct3D Урок 06: Использование DirectInput
Сегодня мы поговорим о том, как использовать в наших программах возможности DirectInput. Это более продвинутый интерфейс для ввода, разработанный Microsoft специально для использования в играх!
Direct3D Урок 05: Туман
Direct3D Урок 04: Прозрачность
Сегодня мы поговорим о том, как использовать эффекты прозрачности в ваших проектах. Данным методом пользуются во многих случаях. Когда вам нужно изобразить огонь, воду, дым, стекло, различные зеркала, обычные прозрачные объекты и т.д.
Direct3D Урок 03: Использование текстур
Direct3D Урок 02: Отображение объектов
Direct3D Урок 01: Инициализация приложения
Если вы читаете эту статью, вам очень хочется попробовать себя в роли не простого игрока, а полноценного разработчика игр. Прочитав данную статью вы научитесь Инициализировать Direct3D девятой версии.
Ввод с клавиатуры в DirectInput
Сегодня мы рассмотрим программу использующую как Direct3D, так и DirectInput. При запуске программы на экран выводится чёрный квадрат. Используя стрелочки клавиатуры квадрат можно перемещать.
Наш чайник выглядит не очень естественно, блеск слишком сильный, больше похоже не на фарфор, а на полированный алюминий. Для того, чтобы отражение немного приглушить, можно затемнить текстуру.
Поставим себе новую задачу – покроем чайник, кроме текстуры отражений, обычной текстурой. Но что делать, если наша модель не содержит в вертексах текстурных координат?
До сих пор мы использовали для наложения текстур координаты, непосредственно заданные в вертексах. Существуют и другие способы, при которых текстурные координаты рассчитываются непосредственно при растеризации.
До сих пор для того, чтобы создать какой-либо геометрический объект, мы выполняли некоторые стандартные действия, занимающие достаточно объемный код.
Чтобы приступить к изучению четвертой компоненты цвета A (альфа-компоненты), приготовим, как водится, опытный проект. Предыдущий проект преобразован для использования одной пары текстурных координат и цвета в вертексе.
До сих пор мы накладывали на наши модели не более одной текстуры, в то время как Direct3D позволяет использовать одновременно до восьми текстур.
До сих пор мы применяли в основном стандартные функции Direct3D, совместимые практически с любыми современными видеоадаптерами. И только в предыдущем проекте мы столкнулись с возможной несовместимостью.
При текстурировании существует проблема. Текстура состоит из конечного числа точек, которые называются текселями.
А теперь еще немного теории. Мы уже достаточно близко познакомились с Direct3D, теперь будет легче понять принципы его работы.
До сих пор все наши проекты состояли из одной единственной формы. Весь код проекта не был распределен по модулям.
Представим, что все пространство пронизывает направленный свет. Каким образом можно определить, насколько ярко будет освещен произвольный участок поверхности?
DirectInput мышь
В сегодняшнем уроке мы рассмотрим получение данных ввода с устройства мышь, используя DirectInput.
Представьте, что у нас есть карта некоторой поверхности, представляющая из себя список высот точек на прямоугольном участке.
Представьте, что нам нужно изобразить кирпичную стену. До сих пор мы рисовали цветные треугольники, очевидно, что при таком подходе для изображения стены понадобится огромное количество треугольников.
От проекта к проекту мы постепенно осваиваем приемы программирования DirectX. Как правило, каждый новый проект основывается на предыдущих, поэтому дальше я не буду комментировать все изменения и дополнения, если эти изменения и дополнения уже изучены.
Очевидно, что способ, которым мы в предыдущей главе рисовали треугольники, неудобен и неполноценен для 3D игр.
Переделаем предыдущий проект для отображения двух треугольников. Для этого в InitGeometry добавим еще три вершины
Пора, наконец, нарисовать что-то существенное. В Direct3D, за редким исключением, вывод графики основан на выводе примитивов – серий треугольников. Треугольники выбраны потому, что на них можно разбить любой многоугольник или, как его еще называют, полигон.
Обратили внимание на то, что поле Color в формате вертекса стало явно избыточным? Если во все вертексы все равно пишется одно и то же значение цвета, то может можно его туда не писать вообще, а задать цвет как-то по другому? DirectX предоставляет такую возможность – это использование материала
Зачем каждая новая игра повторно устанавливает свою версию DirectX
DirectX входит в состав Microsoft Windows. Это группа интерфейсов API (интерфейсов прикладного программирования), которые разработчики могут использовать для 3D-графики, видео, мультимедиа, звука и функций геймпада в Windows. Многие игры в Windows используют Direct3 DirectX для графики. Если они этого не делают, они используют межплатформенные OpenGL или API Vulkan. Другие неигровые приложения могут использовать DirectX для таких функций, как 3D-графика.
Windows 7 включает DirectX 11, а Windows 10 – DirectX 12. Когда разработчики разрабатывают игры, они выбирают версии DirectX, которые хотят использовать. Например, игра, написанная только для DirectX 11, не будет работать в Windows XP, где последней версией является DirectX 9.
Если он включен в Windows, почему игры устанавливают его
Если DirectX является частью Windows, почему игры устанавливают свою версию? Короткий ответ заключается в том, что в версиях DirectX царит беспорядок.
Не существует единой библиотеки DirectX Direct3D, от которой зависели бы все игры, или даже нескольких библиотек. Разработчики игр должны ориентироваться на точную версию вспомогательной библиотеки Direct3D. Более поздняя версия библиотеки не может быть использована. Например, если разработчик игры нацелил свою игру на d3ddx10_40.dll, игра не может использовать d3ddx10_41.dll. Требуется версия 40, и подойдёт только этот файл.
Эти файлы находятся в папке C:\Windows\System32 в 64-разрядной системе, а 32-разрядные библиотеки расположены в C: \ Windows \ SysWOW64.
Даже если вы запустили последний установщик DirectX, нет никакой гарантии, что он установит все старые небольшие версии библиотек DirectX в вашей системе. Microsoft также решила не связывать эти файлы библиотеки Direct3D с самой Windows. Даже библиотеки Direct3D, созданные до выпуска Windows 10, например, не все включены в Windows 10. Они должны быть установлены приложением, которое в них нуждается. Как отмечает Microsoft в документации, предназначенной для разработчиков игр, «Windows Update и Service Packs не предоставляют никаких дополнительных компонентов DirectX».
Это также усложняется тем, что 32-разрядные игры нуждаются в 32-битных версиях файлах библиотеки, а для 64-разрядных игр требуется 64-разрядная библиотека.
Это похоже на ситуацию с библиотеками Microsoft Visual C++ Redistributable. Различные приложения зависят от разных версий библиотек, и вам нужно установить много разных версий.
Почему каждая игра должна переустанавливать DirectX
Следовательно, каждая игра должна установить точную младшую версию библиотек DirectX, в которой она нуждается. Но если вы уже установили определенную версию библиотеки DirectX один раз, то, конечно, игре не нужно запускать установщик DirectX – правильно?
Неправильно! Для игр нет возможности легко проверить, установлены ли нужные библиотеки DirectX. Как отмечает сайт поддержки Steam, установщик Microsoft DirectX является единственным официально поддерживаемым способом проверки правильности установленных файлов DirectX. Игры запускают установщик DirectX часто в фоновом режиме, который устанавливает все необходимые библиотеки и устраняет любые проблемы в системе.
Конечно, не все игры должны запускать установщик DirectX при первом запуске. Для игр, которые используют OpenGL или Vulkan, а не Direct3D DirectX, его не нужно запускать. Некоторые игры также зависят только от основных версий DirectX, таких как DirectX 11, 10 или 9, и не нужно вызывать установщик DirectX, потому что они не используют ни одну из вспомогательных библиотек.
Можно ли удалить библиотеки DirectX
Вы не должны удалять любую из библиотек DirectX в папке System32 или SysWOW64. Если они присутствуют в вашей системе, это связано с тем, что игра или другое приложение, которое вы установили, нуждались в них. Если вы начнете удалять файлы библиотеки, приложения перестанут работать. Невозможно реально определить, какие файлы библиотеки DirectX необходимы для игр в вашей системе, поэтому нет способа узнать, какие из них безопасны для удаления.
Оставьте их! Существует причина, по которой не существует официального способа удаления этих файлов библиотеки. Они не будут вызывать никаких проблем в вашей системе и будут использоваться только теми приложениями, которые их требуют.
Если вы действительно отчаянно пытаетесь очистить эти старые библиотеки, вам лучше переустановить Windows, чтобы получить новую систему вместо случайного удаления файлов библиотек. Но они снова начнут появляться после установки игр. Не беспокойтесь об этом!
Что делать, если у меня проблемы с DirectX
Если при попытке запуска или установки игры появляется сообщение об ошибке, связанное с DirectX, возможно, установщик игры не запускает входящий в комплект дистрибутив DirectX. Однако, бесполезно загружать установщик DirectX с веб-сайта Microsoft, так как вам нужно запустить установщик, который требует сама игра.
Как сделать игру на directx
Итак, вы запустили игру, зашли на сервер, появились, и видите на своем мониторе черный экран с интерфейсом, на котором *бегают* название точек захвата.
Вот пару примеров как это выглядит:
Это свидетельствует о том, что ваша видеокарта не поддерживает API DirectX 11, который использует игра для рендера изображения.
Решением этой проблемы, это эмуляция DirectX 11
Способ который я предлагаю в этом гайде, очень требователен к процессору и видеокарте, так что игра будет сильно глючить, и многого от неё не ожидайте.
Так же хочу заметить то, что эмуляция на видеокартах с версией DirectX 9, будет происходить очень медленно, по этому, я не думаю что вы будете довольны таким геймплеем.
Далее установка Windows SDK, он является основным компонентом эмуляции. Если у вас установлен Windows 10 с последней ревизией, то Windows SDK вам устанавливать НЕ нужно.
Иным версиям Windows установите следующий пакет программ по ссылке ниже: https://go.microsoft.com/fwlink/p/?linkid=2120843
Так же, сама утилита которая будет эмулировать DirectX 11, что бы её установить пройдите по ссылке ниже:
https://drive.google.com/file/d/1Hi1v3moN7mZWvoVdSpvmZn4HqElbhFxA/view
После установки всех программ, можем переходить к настройке утилиты.
После запуска Dxcpl.exe, вы увидите это:
После нажатия у вас выскочит такое окно, оно отвечает в какой из программ, в нашем случае это BattleBit, мы будем эмулировать DirectX 11.
Нажимаем на троеточие (. ), и указываем путь к исполняемой программе (.exe), она находится в папке с игрой, путь должен примерно выглядеть так: D:\Steam\steamapps\common\BattleBit\BattleBit.exe
далее нажимаем на кнопку Add, что бы добавить её в список программ.
В данном окне это все, нажимаете ОК, что бы сохранить список программ.
Далее, что нужно изменить это, выбрать версию которую мы хотим эмулировать, и включить функцию растеризации (FORCE WARP), все что нужно сделать, вы можете увидеть на иллюстрации ниже.
После изменения параметров, нажимаем на Применить, и далее вы можете закрывать утилиту.
На этом все, но рекомендую заранее установить настройки графики на самые низкие, и разрешение экрана снизить на минимальное с возможных, и в дополнение сделать Screen Scale на 50, или даже ниже что бы получить свой FPS не ниже 30.