Visual Basic - мастерская разработчика
Библиотеки

DirectX

Обзоры
DirectDraw
Direct3D
DirectX Audio
DirectPlay
DirectInput
Fido Topics
SourceCode
Tools&Libs

OpenGL

Статьи и учебники
Fido Topics
SourceCode
Tools&Libs

Архив по Glide

Движки

Обзоры
Учебники
SourceCode
Downloads

Создание игр

Ваши игры

Обзорные статьи
Учебники
Fido Topics
SourceCode
Download

Stuff

Программер-Чат

Псевдо-FTP
Disclaimer
Оффтопик

 

Загружаем .x и текстуры в окне

<Переход к содержанию>

В этой части мы наконец подошли к тому, что многие из вас наверное ждали с нетерпением. Мы начнем работать с объектами, заранее подготовленными в других программах (моделями) и текстурами. Работа с моделями и текстурами занимает наверное большую часть трехмерного программирования, поэтому Direct3D:RM имеет мощные средства обработки текстур и моделей. Соответственно, много тут и заморочек с координатами текстур. У меня долгое время не получалось нормально сделать "комнату" с текстурированным потолком, стенами, полом и т.п. Вся бяка заключалась в координатах текстур. Ну да ладно, в такие дебри мы залезать пока не будем. Наша задача на эту главу - загрузить шарик из файла .x, растянуть по его поверхности текстуру и заставить все это чудо крутиться. Как я и обещал, пример будет иллюстрироваться в оконном режиме, но это ни на что не будет влиять. В дальнейшем, я намереваюсь давать все примеры в полноэкранном режиме по той причине, что в нем Direct3D работает быстрее, а главное - моя вудуха не работает в окне :)

Для этого туториала вам понадобится во первых .x-файл с шариком, а во вторых .bmp-файл с текстурой. Все это я включил в готовый пример, который можно скачать прямо сейчас. В архиве кроме шарика есть еще парочка объектов .x, чтобя вы потренировались. В следующей части я научу вас как сомому легко и просто создавать объекты .x

Прежде чем мы начнем, вот несколько теоретических определений:
X - это родной формат DirectX для трехмерных моделей. Он используется только Direct3D:RM, но после продолжительного мозголомания можно заставить и Direct3D:IM работать с ним.
Direct3D:RM поддержиывает файлы текстур форматов BMP и PPM (в большинстве случае вы конечно же будете работать с BMP, так как эти форматы даже по размеру не отличаются, а BMP известен всем). Впрочем, вы можете хранить текстуры в любых других форматах, главное чтобы вы смогли загрузить текстуру в буфер DirectDraw, а уже оттуда D3D:RM сможет перетянуть ее себе. Туториал как загружать форматы gif и jpg в буфер DirectDraw в скором времени должен появиться у меня на сайте в разделе DirectDraw.

Кстати о буферах. Вы можете загружать текстуры как напрямую в объект текстуры, который сразу же назначать объединению, так вы можете загружать текстуры в буфера DirectDraw и хранить их там. Преимущество второго способа, как я уже сказал - вы можете использовать текстуры разных форматов. Для простоты, здесь мы будем ипользовать первый способ, а туториал для второго способы выйдет чуть попозже.

Начнем же.

Тут я как и впрошлой части предполагаю, что вы запаслись "универсальной формой выбора драйвера..." и модулем mdlDirect3DRM, причем модуль должен быть "версии" не раньше прошлой части.

Начнем опять с модуля. Мы немножко подправим Declarations, и допишем новую функцию InitWindowed, которая будет инициализировать нам оконный режим. Остальное останется прежним. Старт у нас будет происходить опять в процедуре Sub Main. Обратите внимание, что при вызове форма frmDriver находит все видеокарты в системе, даже если они не работают в окне (3dfx Voodoo), поэтому бкдьте осторожны при выборе драйвера. Если хотите делать программу для распространения, лучше исключите из frmDriver распознавание вторичных видеокарт.

Declarations модуля теперь выглядят так:

Public dx As New DirectX7 'Объект DirectX
Public dd7 As DirectDraw7 'Объект DD для оконного режима
Public dd4 As DirectDraw4 'Объект DD для полноэкранного режима
Public d3d As Direct3D7 'Объект D3D:IM
Public d3dRm As Direct3DRM3 'Объект D3D:RM
Public ddsd As DDSURFACEDESC2 'Описание поверхности
Public Caps As DDSCAPS2 'Описание аппаратных возможностей
Public Device As Direct3DRMDevice3 'Устройство рендеринга
Public Scene As Direct3DRMFrame3 'Фрейм сцены
Public Camera As Direct3DRMFrame3 'Фрейм камеры
Public World As Direct3DRMFrame3 'Фрейм объектов
Public MeshBuilder As Direct3DRMMeshBuilder3 'Конструктор объединений
Public dds4Primary As DirectDrawSurface4 'Главная поверхность для DD4
Public dds4Back As DirectDrawSurface4 'Задний буфер для DD4
Public Viewport As Direct3DRMViewport2 'Вьюпорт
Public Clipper As DirectDrawClipper 'Клиппер DirectDraw

Public driverGuid As String 'Используемая видеокарта
Public renderGuid As String 'Используемое устройство рендеринга видеокарты

Public Running As Boolean 'Программа работает?

Вот новая функция, инициализирующая D3D:RM в окне. Мы проводим инициализацию на основе базовой формы. Устройство рендеринга создается из предварительно созданного клиппера. Клиппер нужен для того, чтобы обрезать (и не рендерить) части изображения, которые перекрыты другими формами, находятся за краями экрана и т.п. ScaleMode формы должен быть установлен в 3-Pixel !!!

Public Sub InitWindowed(Window As Form) 'Direct3D:RM в окне
'Создать DirectDraw и клиппер
Set dd7 = dx.DirectDrawCreate(driverGuid)
Set Clipper = dd7.CreateClipper(0)
Clipper.SetHWnd Window.hWnd
'Создать объекты Direct3D:RM из клиппера
Set d3dRm = dx.Direct3DRMCreate
Set Device = d3dRm.CreateDeviceFromClipper(Clipper, renderGuid, Window.ScaleWidth, Window.ScaleHeight)
Set Scene = d3dRm.CreateFrame(Nothing)
Set Camera = d3dRm.CreateFrame(Scene)
Set Viewport = d3dRm.CreateViewport(Device, Camera, 0, 0, Device.GetWidth, Device.GetHeight)
Scene.AddLight d3dRm.CreateLight(D3DRMLIGHT_AMBIENT, dx.CreateColorRGB(1, 1, 1))
Set MeshBuilder = d3dRm.CreateMeshBuilder
End Sub

Переходим к форме. Нам нужны процедуры старта, организации выхода и цикла рендеринга. Все очень просто:

Private Sub Form_Load()
Me.Show
mdlDirect3DRM.InitWindowed Me
'Подготавливаем сцену и запускаем
SetMyDefaults
Running = True
Run
End Sub

Private Sub Form_KeyPress(KeyAscii As Integer)
Running = False
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
mdlDirect3DRM.DestroyEverything 'При выходе все надо уничтожить
End Sub

Private Sub Run()
Do While Running = True
DoEvents
d3dRm.Tick 1 'Рендеринг кадра
Loop
End
End Sub

Начальные установки геометрии сцены происходят в процедуре SetMyDefaults

Private Sub SetMyDefaults()
CreateMyObject 'Создать объект
'Здесь вы можете установить качество текстур. Для программной эмуляции ставьте
'D3DRMTEXTURE_NEAREST, для аппаратного ускорения применяйте один из фильтров

'Device.SetTextureQuality D3DRMTEXTURE_LINEAR
Set World = d3dRm.CreateFrame(Scene)
World.AddVisual MeshBuilder 'Добавляем сконструированный объект
World.SetRotation Nothing, 0, 1, 0, 0.017 'Задаем миру вращение
Camera.SetPosition Nothing, 0, 0, -3.5 'Устанавливаем камеру
End Sub

Почти все это вы уже знаете. С помощью SetTextureQuality вы сможете устанавливать качество текстур. Если у вас стоит листание элементов (что я вам настоятельно рекомендую для всевозможных экспериментов), то посмотрите на список возможных фильтров. Не бойтесь ставить любые из них. Смотрите за качеством и скоростью рендеринга. Единственное замечание - без акселератора не имеет никакого смысла с этим возиться - вся что вам доступно - это D3DRMTEXTURE_NEAREST

Далее идет то, собственно для чего эта глава писалась - создание объекта из .x-файла и натягивание на него текстуры. Происходит это в процедуре CreateMyObject:

Private Sub CreateMyObject()
Dim Tex As Direct3DRMTexture3 'Текстура
Dim Wrap As Direct3DRMWrap, Box As D3DRMBOX 'Нужно для наложения текстуры
Dim maxy As Single, miny As Single, height As Single 'Нужно для "натягивания" текстуры
ChDir App.Path 'Все файлы лежат в текущей папке
'Загрузить объект из файла .x, масштабировать его так, чтобы он влез в экран
'И задать ему один цвет, чтобы не было проблем при наложении текстуры

MeshBuilder.LoadFromFile "sphere3.x", 0, D3DRMLOAD_FROMFILE, Nothing, Nothing
MeshBuilder.ScaleMesh 0.5, 0.5, 0.5
MeshBuilder.SetColorRGB 1, 1, 1
'Загрузить текстуру из файла, получить размеры объекта в MeshBuilder, вычислить
'как текстуру надо растягивать, чтобы она покрыла весь объект и создать
'объект Wrap, который отвечает за растяжение текстуры

Set Tex = d3dRm.LoadTexture("mytex.bmp")
MeshBuilder.GetBox Box
maxy = Box.Max.x
miny = Box.Min.y
height = maxy - miny
Set Wrap = d3dRm.CreateWrap(D3DRMWRAP_CYLINDER, Nothing, _
0, miny, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1 / height) 'Растяжение в циллиндрической форме
Wrap.Apply MeshBuilder 'Применить растяжение к объекту в MeshBuilder
MeshBuilder.SetTexture Tex 'Установить объекту текстуру
End Sub

После создания различных объектов и переменных, мы загружаем модель из файла, масштабируем ее и задаем белый цвет. Потом мы загружаем текстуру из файла и вот тут-то начинается самое сложное. Текстуру мало загрузить - надо еще указать как ее натягивать. Чтобы полностью растянуть текстуру по объекту, мы применяем такой метод: получим размеры модели в структуру D3DRMBOX, вычислим высоту модели, а затем создадим объект Wrap, которому укажем в параметрах циллиндрически растянуть текстуру на всю модель. В конце концов, мы устанавливаем текстуру объекту. Поиграйтесь с параметрами CreateWrap - посмотрите что получится.

Итак, вроде бы все. Запустите проект и если в папке проекта будут необходимые файлы, вы должны увидеть крутящийся шарик.

Вы можете скачать готовый проект (70k).

Задание для самых усердных:
1. Пусть программа работает в полном экране
2. Загрузите другой .x-файл (даны вместе с примером)

Следующая глава будет посвящена созданию собственных моделей.

Приятного программирования, Antiloop

Posted: 23.01.2k1
Autor: Antiloop
<anti_loop@mail.ru>

 


Проект
Создание Народного Учебника по OpenGL

Участвовать!
Поиск
Найдите статью или файл:


Рассылка
Новости сайта
La Vision в вашем почтовом ящике








Программирование на С++ Delphi и Паскаль
Центр демо-искусства в России