Directx 9 как отобразить ребра объекта
Ребра и четырехугольники в DirectX 9
Directx 9 как отобразить ребра объекта
m_pShape = new C3dShape;
m_pShape-»Create (vlist, nv, flist) ;


int nv = sizeof(vlist) / sizeof(D3DVECTOR);
D3DVECTOR nlist [] = 0, 0>, < 0, 1, 0), < 0, 0, 1), (-1, 0, 0),
int nn = sizeof(nlist) / sizeof(D3DVECTOR);
int flist [] = (4, 0, 4, 3, 4, 2, 4, 1, 4,
4, 3, 0, 7, 0, 6, 0, 2, 0, 4, 4, 1, 5, 1, 6, 1, 7, 1, 4, 0, 3, 1, 3, 5, 3, 4, 3, . 4, 0, 5, 4, 5, 7, 5, 3, 5, 4, 2, 2, 6, 2, 5, 2, 1, 2, 0
Directx 9 как отобразить ребра объекта
m_pShape = new C3dShape;
m_pShape-»Create (vlist, nv, flist) ;
Список вершин теперь состоит из восьми элементов, по одному для каждого из углов куба, а список граней содержит шесть элементов по числу граней куба. На рис. 4-15 изображен куб с пронумерованными вершинами, он поможет вам понять значения элементов списка данных граней в приведенном выше фрагменте. Следует помнить о том, что вершины каждой грани должны перечисляться по часовой стрелке относительно того направления, с которого будет видна данная грань.
Рис. 4-15. Нумерация вершин куба
Прежде, чем читать дальше, следует самостоятельно убедиться в том, что вы поняли смысл описания граней. Может, на это придется потратить немного времени, зато в дальнейшем вы не будете создавать невидимые поверхности, ориентированные в неверном направлении. Функция OnEditDefcube строит фигуру, изображенную на рис. 4-16. Чтобы увидеть куб на экране, выполните команду Edit] Default Cube.
Как вы думаете, почему закраска граней выглядит такой однородной? Выполните команду View ¦ Normals, и вы увидите, что нормали к вершинам куба обращены от углов, по направлению от центра куба. Поскольку мы не стали задавать свои нормали, механизм визуализации создал их по умолчанию, усредняя нормали всех граней, прилегающих к вершине. Подобное решение может показаться до-
Глава 4. Создание фигур
Рис. 4-16. Вращающийся куб с принятым по умолчанию расположением нормалей
вольно странным, особенно при создании куба. Тем не менее оно выглядит вполне разумно при создании сферы или другой криволинейной фигуры, поскольку усредненные нормали помогают создать более реалистичный объект — закраска сглаживает края прилегающих граней.
Разумеется, мы все же рассчитывали увидеть другой куб, с плоскими гранями и четко различимыми ребрами. Для того чтобы решить эту проблему, достаточно определить свои собственные нормали. Для вершин каждой грани мы задаем нормали, направление которых совпадает с нормалью грани. Приведенная ниже функция создает куб с плоскими гранями:
int nv = sizeof(vlist) / sizeof(D3DVECTOR);
D3DVECTOR nlist [] = < < i,0, 0>, < 0, 1, 0), < 0, 0, 1), (-1, 0, 0),
Создание твердых тел
int nn = sizeof(nlist) / sizeof(D3DVECTOR);
int flist [] = (4, 0, 4, 3, 4, 2, 4, 1, 4,
4, 3, 0, 7, 0, 6, 0, 2, 0, 4, 4, 1, 5, 1, 6, 1, 7, 1, 4, 0, 3, 1, 3, 5, 3, 4, 3, . 4, 0, 5, 4, 5, 7, 5, 3, 5, 4, 2, 2, 6, 2, 5, 2, 1, 2, 0
m_pShape = new C3dShape;
m_pShape-»Create (vlist, nv, nlist, nn, flist);
Если запустить приложение и отобразить куб с плоскими гранями вместе с нормалями (сначала выполните команду Edit ¦ Flat-Faced Cube, затем — команду View ¦ Normals), вы увидите нечто похожее на рис. 4-17.
Рис. 4-17. Куб с плоскими гранями и векторами нормалей
Итак, теперь мы умеем создавать фигуры с плавными переходами граней (при которых нормали генерируются механизмом визуализации) или с более резкими переходами (при которых нормали задаются программистом). Иногда бывает нужно создать криволинейный объект, на котором присутствуют острые ребра. На рис. 4-18 изображен конус с закругленными сторонами и плоским основанием (команда Edit ¦ Cone).
Глава 4. Создание фигур
Рис. 4-18. Конус
Если внимательно рассмотреть конус, можно заметить, что его боковая поверхность составлена из 16 треугольников, а основание имеет форму диска. Закраска боковых треугольников создает иллюзию криволинейной поверхности, а закраска основания придает ему плоский вид; между боковой поверхностью и основанием существует резко очерченная граница. Как добиться подобного эффекта?
Стороны конуса строятся точно так же, как и наш первый куб на стр. 101 — мы передаем механизму визуализации координаты вершин треугольников, образующих боковую поверхность, и он самостоятельно генерирует нормали, усредняя векторы нормалей для прилегающих граней. Это создает иллюзию кривизны боковой поверхности. Если бы мы просто включили основание конуса в список граней, использованных для создания боковой поверхности, то нормали для основания также были бы определены посредством усреднения нормалей основания и боковых граней. В результате нижняя грань казалась бы выпуклой, а граница между боковой поверхностью и основанием выглядела бы размытой.
Существуют два основных способа для получения плоского основания и резкой границы между основанием и боковой поверхностью. Самое простое, что можно сделать, — это внести основание в список граней с отдельным набором вершин. Разумеется, координаты этих вершин должны совпадать с координатами нижних сторон боковых граней, иначе в фигуре появятся «дырки». Задавая отдельные вершины для нижней грани, мы тем самым указываем, что нижняя грань не имеет прилегающих граней; когда механизм визуализации будет генерировать нормали для вершин основания, он просто использует для этой цели нормаль основания. Такой подход приводит к желаемому результату (плоскому основанию с резким переходом), однако он немного расточителен, поскольку нам приходится задавать лишний набор вершин (в данном случае — 16).
Более разумное решение состоит в том, чтобы использовать для основания конуса те же самые вершины, что и для боковых граней, но при этом задать для них нормали. Именно так работает функция, построившая конус на рис. 4-18. Ее преимущество заключается в том, что нам не придется задавать лишние вершины.
Создание твердых тел
Конечно, хранение нормалей тоже потребует определенных расходов, однако все равно такой подход оказывается более экономичным, поскольку одна и та же нормаль используется для всех вершин основания. Пример программы приведен в следующем разделе, где мы рассматриваем тела вращения (такие, как конус).
Тела вращения
Тела вращения я впервые увидел в раннем детстве. Мой отец работал токарем, стоял целый день у токарного станка и точил фланцы, стержни, винты с нарезкой, трубы и т. д. (рис. 4-19). Токарный станок вращает металлическую заготовку, зажатую в патроне. К заготовке подносится резец, который срезает ненужный материал при вращении заготовки; положение резца определяет радиус детали. Продольное перемещение резца с одновременным вращением заготовки позволяет выточить стержень (гладкий или нарезной). Основная идея моего рассказа заключается в том, что твердый объект можно описать с помощью простой функции, определяющей радиус объекта в любой точке его длины.
Рис. 4-19. Токарный станок
Процесс построения тел вращения мало чем отличается от создания других трехмерных объектов. Необходимо задать набор вершин, определить, к каким граням они относятся, и затем при желании указать нормали. Поскольку тело вращения можно описать функцией зависимости радиуса от продольной координаты, нетрудно создать фрагмент программы, в котором такая функция используется для генерации вершин и данных граней. На рис. 4-20 изображено тело вращения, построенное именно этим способом. Чтобы увидеть тело вращения на экране, выполните команду Edit ¦ Solid of Revolution.
Ниже приводится фрагмент приложения Shapes, в котором создается изображенный на рисунке объект:
DirectX 9 Graphics. Поверхности и растры (Surfaces & Bitmaps)
Т.к. наш сайт посвящён созданию компьютерных игр, ряд функций будут созданы "с прицелом" на дальнейшую разработку игрового движка.
Содержание
Intro
Обрати внимание
Монитор показывает то, что на него отправляет видеоадаптер. Видеоадаптер отображает содержимое фреймбуфера, которое отправляется на монитор по одному пикселю за раз (чаще всего это группа пикселей, но передаются они невероятно быстро).
Фреймбуфер хранится в памяти видеокарты (=видеопамяти), которую обычно ставят на базе максимально быстрых модулей RAM. В стародавние времена видеопамяти в видеокартах было очень мало и стоила она заметно дороже обычной оперативы. Сегодня ситуация не особо изменилась. Так вот. Фреймбуфер (frame buffer) "сидит" в видеопамяти и представляет собой конечную "картинку", которую пользователь видит на мониторе. Отсюда следует, что самый быстрый способ создавать графику — это просто напрямую редактировать фреймбуфер. В этом случае изменения будут отображаться на экране с минимальной задержкой. Но на деле напрямую во фреймбуфер не "рисуют", т.к. при смене кадров в этом случае заметно перелистывание ("моргание", flick). Вместо этого изображение формируют в специальном бэкбуфере, который затем целиком отправляют во фреймбуфер. DirectX поддерживает двойную (2 бэкбуфера, постоянно сменяющих друг друга) и тройную (3 бэкбуфера) буферизации. Также существует пара других методов смены кадров без моргания. Но в данной статье они не рассматриваются.
Первичная поверхность (Primary Surface)
- Та, которая отправляется во фреймбуфер и оттуда — на монитор.
- Обычно хранится в памяти видеоадаптера (=видеопамяти).
Вторичная внеэкранная поверхность (Secondary Offscreen Surface)
- Представляет собой обычный массив в памяти, по своей структуре напоминающий растровое изображение (bitmap).
Создаём поверхность (Creating a Surface)
Отрисовка поверхности (Блиттинг)
Пример приложения, блиттирующего поверхности
- MS Visual C++ 2010;
- DirectX SDK 9
- Windows SDK (для программирования под Win7/8/10).
- + инструкции по их установке ты найдёшь в разделе "Софт" нашего сайта;
- Бесплатны;
- Без труда гуглятся.
Создаём Проект приложения D3D9Surface01
- Создай пустой Проект с именем D3D9Surface01.
Добавляем в Проект WinMain.cpp
- В "Обозревателе решений" главного окна MSVC++2010 щёлкни правой кнопкой мыши по папке (в терминологии Майкрософт это не папки, а фильтры!) "Файлы исходного кода" Проекта D3D9Surface01.
- Во всплывающем меню Добавить->Создать элемент.
- В появившемся окне выбери "Файл С++ (.cpp)" и в поле "Имя" введи WinMain.cpp. Жмём "Добавить".
- В только что созданном и открытом файле WinMain.cpp набираем исходный код простейшего оконного приложения, взятого из статьи Создание приложений Сpp Win32:
- Сохрани Решение (Файл->Сохранить все).
Добавляем в Проект заголовочный файл dxfunc.h
- Убедись, что MSVC++2010 запущена и вней открыт Проект D3D9Surface01, созданный выше.
- В "Обозревателе решений" главного окна MSVC++2010 щёлкни правой кнопкой мыши по папке (в терминологии Майкрософт это не папки, а фильтры!) "Заголовочные файлы" Проекта D3D9Surface01.
- Во всплывающем меню Добавить->Создать элемент.
- В появившемся окне выбери "Заголовочный файл (.h)" и в поле "Имя" введи "dxfunc.h".
- Жмём "Добавить".
- В только что созданном и открытом файле dxfunc.h набираем следующий код:
- Сохрани Решение (Файл->Сохранить все).
Добавляем в Проект файл исходного кода dxfunc.cpp
- Убедись, что MSVC++2010 запущена и вней открыт Проект D3D9Surface01, созданный выше.
- В "Обозревателе решений" главного окна MSVC++2010 щёлкни правой кнопкой мыши по папке (в терминологии Майкрософт это не папки, а фильтры!) "Файлы исходного кода" Проекта D3D9Surface01.
- Во всплывающем меню Добавить->Создать элемент.
- В появившемся окне выбери "Файл C++ (.cpp)" и в поле "Имя" введи "dxfunc.cpp".
- Жмём "Добавить".
- В только что созданном и открытом файле dxfunc.cpp набираем следующий код:
- Сохрани Решение (Файл->Сохранить все).
Готовим Проект D3D9Surface01 к компиляции
Прежде чем начать модифицировать код, скомпилируем Проект D3D9Surface01. Для успешной компиляции изменим его настройки (=свойства).
Выбираем многобайтовую кодировку
Примечание
- Убедись, что MSVC++2010 запущена и в ней открыт наш текущий Проект D3D9Surface01.
- В Обозревателе решений щёлкаем правой кнопкой мыши по названию Проекта D3D9Surface01.
- Во всплывающем контекстном меню выбираем "Свойства".
- В появившемся окне установки свойств Проекта жмём Свойства конфигурации->Общие, в правой части в строке "Набор символов" выставляем значение "Использовать многобайтовую кодировку".
- Жмём ОК.
- Сохрани Решение (Файл->Сохранить все)
Отключаем инкрементную компоновку (incremental linking)
Ошибка LINK : fatal error LNK1123: failure during conversion to COFF: file invalid or corrupt
В MS Visual C++ 2010 даже компиляция консольных приложений нередко завершается неудачей, а вместо исполняемого файла программист видит сообщение:
LINK : fatal error LNK1123: failure during conversion to COFF: file invalid or corrupt.
ПРИЧИНА: MS Visual С++ 2010 «не нравится» версия .NET Framework, установленная в операционной системе. В общих чертах, MS Visual С++ 2010 спрограммирована для работы под управлением .NET Framework 4.0 и сильно к нему привязана. Если точнее, к нему сильно привязана система инкрементной компоновки приложений (incremental linking), которая по умолчанию включена для всех создаваемых проектов.
Во время установки MS Visual C++ 2010 пытается установить свой «родной» .NET Framework 4.0, проверяя версию этой программной платформы, установленную в ОС на данный момент. Если версия .NET Framework ниже 4.0, то она обновляется до 4.0 и всё прекрасно компилируется. Если версия .NET Framework выше 4.0, то всё оставляется как есть: IDE успешно завершает установку, но при компиляции ВСЕХ приложений выскакивает данная ошибка. Более того, ошибка была замечена даже при наличии в системе .NET Framework версии 4.0, но отличающейся от «родной» припиской вроде «Beta» или «Release Candidate».
ВАРИАНТЫ РЕШЕНИЙ:
1. Отключить инкрементную линковку в опциях Проекта.
В главном меню MSVC++2010 выбираем: Проект->Свойства->Свойства конфигурации->Компоновщик(Linker)->Включить инкрементное построение (Incremental Linking). Данный пункт по умолчанию включен для всех новых проектов. Выставляем его в Нет (No). И жмём OK. Инкрементное построение заметно сокращает время компилирования больших проектов. Но в нашем случае его отсутствие некритично.
2. Удалить (переместить в другое место) утилиту cvtres.exe из каталога bin установленной MS Visual C++ 2010.
В нашем случае (Win7 x64) полный путь до данного файла такой: C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\cvtres.exe . Официальное название данного приложения — Microsoft® Resource File To COFF Object Conversion Utility (утилита конвертации файлов двоичных ресурсов в Component Object File Format). Опытным путём установлено, что при линковке IDE «спотыкается» именно об него.
3. Удалить из системы все версии .NET Framework (включая языковые пакеты и всякие профайлеры, если есть) и саму MS Visual C++ 2010.
Всё вышеперечисленное можно без труда найти в меню «Программы и компоненты» (MS Windows Vista/7/8). Затем заново установить MS Visual C++ 2010. При этом автоматом установится .NET Framework 4.0, идущий с ней в наборе.
Третий пункт — самый долгий. На деле почти всегда хватает выполнения первых двух. Данным вопросом озадачивались ребята здесь: https://www.cyberforum.ru/cpp-beginners/thread637174.html?ysclid=l3akpmanrq. После этого линковка (=компоновка) проходит идеально. Подобные «костыли» в IDE от Майков — не редкость. Можно предположить, что команда с головой ударилась в тестирование .NET-возможностей MSVC++2010, совсем забыв о Win32-направлении (либо признав его бесперспективным).
- Убедись, что MSVC++2010 запущена и в ней открыт Проект, с которым работаешь.
- В Обозревателе решений щёлкаем правой кнопкой мыши по названию Проекта.
- Во всплывающем контекстном меню выбираем «Свойства».
- В появившемся окне установки свойств Проекта жмём Свойства конфигурации -> Компоновщик -> Общие (Configuration Properties -> Linker -> General), в правой части в строке «Включить инкрементную компоновку» ставим значение Нет (/INCREMENTAL:NO).
- Жмём ОК.
Удаляем файл cvtres.exe
В нашем случае (Win7 x64) полный путь до данного файла такой: C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\cvtres.exe
В Win32-кодинге он особо ни на что не влияет. Зато без него линковка идёт как по маслу.
Отключаем использование компоновщиком библиотеки libci.dll
- Убедись, что MSVC++2010 запущена и в ней открыт Проект, с которым работаешь в данный момент.
- В Главном меню MS Visual C++ 2010 выбираем Проект -> Свойства (Project -> Properties).
- В появившемся окне установки свойств Проекта последовательно щёлкаем по раскрывающимся ветвям иерархического дерева: Свойства конфигурации -> Компоновщик -> Командная строка (Configuration Properties -> Linker -> Command Promt).
- Пишем в него строку: /NODEFAULTLIB:libci
- Жмём ОК.
- Сохрани Решение (Файл->Сохранить все).
Указываем пути к DirectX SDK 9
- Убедись, что MSVC++2010 запущена и в ней открыт наш текущий Проект D3D9Surface01.
- Убедись, что DirectX SDK 9 установлен на компьютере и ты уверенно можешь назвать полный путь к его каталогу.
- Жмём правой кнопкой мыши по названию Проекта D3D9Surface01. Во всплывающем меню выбираем пункт "Свойства".
- В меню свойств Проекта щёлкаем левой кнопкой мыши по пункту Каталоги включения. В правой части этой строки видим кнопку с чёрным треугольником, указывающим на наличие выпадающего меню. Нажимаем на неё -> выбираем "Изменить. "
- Жмём "ОК".
- В меню свойств Проекта щёлкаем левой кнопкой мыши по пункту Каталоги библиотек. В правой части этой строки видим кнопку с чёрным треугольником, указывающим на наличие выпадающего меню. Нажимаем на неё -> выбираем "Изменить. "
- В появившемся меню "Каталоги библиотек" жмём кнопку "Создать строку" (с жёлтой папкой) и указываем полный путь к 32-разрядным версиям файлов библиотек DirectX SDK 9 (lib). В нашем случае это C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x86. Можно просто выбрать каталог из дерева каталогов, нажав кнопку с троеточием, расположенную справа от строки ввода.
- Жмём "ОК".
- На Странице свойств тоже жмём "ОК".
- Сохрани Решение (File -> Save All).
Указываем пути к Windows SDK
Важно!
- Убедись, что MSVC++2010 запущена и в ней открыт Проект, с которым работаешь в данный момент.
- Убедись, что Windows SDK (в нашем случае версия 7) установлен на компьютере и ты уверенно можешь назвать полный путь к его каталогу.
- Жмём правой кнопкой мыши по названию Проекта. Во всплывающем меню выбираем пункт «Свойства».
- В меню свойств Проекта щёлкаем левой кнопкой мыши по пункту Каталоги включения. В правой части этой строки видим кнопку с чёрным треугольником, указывающим на наличие выпадающего меню. Нажимаем на неё -> выбираем «Изменить. «
- Меняй порядок считывания каталогов включений с помощью кнопок с чёрными стрелками в верхней части окна «Каталоги вложений».
- Жмём «ОК».
- В меню свойств Проекта щёлкаем левой кнопкой мыши по пункту Каталоги библиотек. В правой части этой строки видим кнопку с чёрным треугольником, указывающим на наличие выпадающего меню. Нажимаем на неё -> выбираем «Изменить. «
- В появившемся меню «Каталоги библиотек» жмём кнопку «Создать строку» (с жёлтой папкой) и указываем полный путь к папке с файлами библиотек (lib) Windows SDK. В нашем случае (Win7 x64) это C:\Program Files (x86)\MicrosoftSDKs\Windows\v7.0A\Lib. Можно просто выбрать каталог из дерева каталогов, нажав кнопку с троеточием, расположенную справа от строки ввода.
- Меняй порядок считывания каталогов вложений с помощью кнопок с чёрными стрелками в верхней части окна.
- Жмём «ОК».
- На Странице свойств тоже жмём «ОК».
- Сохрани Решение (File -> Save All). Готово.
Прописываем библиотеки d3d9.lib и WinMM.LIB в окне "Дополнительные зависимости" (Additional dependencies) компоновщика (Linker)
- Убедись, что MSVC++2010 запущена и в ней открыт наш текущий Проект.
- В Главном меню MS Visual C++ 2010 выбираем Проект -> Свойства (Project -> Properties).
- В появившемся окне установки свойств Проекта последовательно щёлкаем по раскрывающимся ветвям иерархического дерева: Свойства конфигурации -> Компоновщик -> Ввод (Configuration Properties -> Linker -> Input).
- В правой части, напротив строки "Дополнительные зависимости" жмём кнопку с чёрным треугольником.
- В всплывающем списке жмём "Изменить".
- В появившемся окне "Дополнительные зависимости" в верхнем поле ввода прописываем в столбик (один под другим) имена файлов трёх библиотек:
- Жмём ОК, ОК.
- Сохрани Решение (Файл->Сохранить все).
Компилируем Проект D3D9Surface01
- Жми кнопку с зелёным треугольником на панели инструментов главного окна MSVC++2010 или F5 на клавиатуре.
Обрати внимание
- Нажми Esc на клавиатуре для выхода из программы.
Изменения в WinMain.cpp
На данном этапе исходный код приложения D3D9Surface01 одинаков с оным Проекта D3D9Init01. Но это ненадолго. Пробил час применить написанную выше теорию на практике. Ты увидишь, в каких именно участках кода создаются и вызываются поверхности. БОльшая часть кода будет добавлена в авторские функции GameInit и GameRun.
Displaying mesh using DirectX 9
This is my program to load a mesh tiger.x and display it. But it is not getting displayed. The value of the variable numMaterials remains 1 all the time. I guess there is some issue with my program. Someone please help me to figure it out. Thanks.
The tiger.x mesh file below
2 Answers 2
The problem is that you are rendering to the window and then calling UpdateWindow which forces a re-paint, thus erasing the drawing.
I suggest you download the DirectX SDK and look at the samples to see how to build a ‘correct’ rendering loop.
You have to handle the WM_PAINT event.
-
The Overflow Blog
Related
Hot Network Questions
Subscribe to RSS
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.3.11.43304
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.