Программа – трехмерный игровой движок на базе библиотек DirectX и PhysX
Разработка игрового "движка" с использованием языка C++ для написания кода, графического пакета DirectX9 для вывода графики. Использование физического "движка" PhysX для взаимодействия объектов. Технико-математическое описание задачи, листинг программы.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | дипломная работа |
Язык | русский |
Дата добавления | 02.09.2013 |
Размер файла | 4,5 M |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
3.3.4 Технико-математическое описание задачи
Для реализации основных действий программы необходимы следующие расчеты:
Матрица положения объекта и направление источника света должна задаваться программистом в ручную. Для демонстрации работы «движка» необходимо расчитать положение двух объектов, которые будут загружаться в программу. Это человек и комната. Человек должен находиться в центре комнаты, Будет проще использовать для расчета положение человека и комнаты единичную матрицу, тогда получится, что центр человека и комнаты находится в точке x=0, y=0, z=0. Но по скольку сетки получились не пропорциональными по отношению друг к другу, немного подредактируем матрицу, чтобы изменить масштаб.
Матрица положения человека:Матрица положения комнаты:
0.10000.1000
00.10000.100
000.10000.10
000100010
Источники освещения расположены случайным образом.
Расчет положения камеры. При нажатии определенных клавиш камера должна перемещаться по миру в разные стороны. Расчет движения производится в отдельной функции. Функции передается два значения - смещение, на которое нужно переместиться, и вектор, определяющий движение. Расчет движения происходит следующим образом - рассчитывается новое положение вектора, смещая его на указанное число, затем задается матрица перемещения на основе рассчитанного вектора, которая перемножается с матрицей движения. В программе это выглядит следующим образом:
D3DXVec3Subtract(vect, vecModifier, pos );
//рассчитываем положение вектора (по оси y перемещение происходить не будет)
vect.x:=vect.x*fOffset; vect.y:=0; vect.z:=vect.z*fOffset;
// расчитываем матрицу положения
D3DXMatrixTranslation(tView, vect.x, vect.y, vect.z);
D3DXMatrixMultiply(mvMat, mvMat, tView);
Если произошло движение мышью, то необходимо повернуть камеру. Для этого тоже создана отдельная функция. В качестве параметров функция получает угол, на который нужно повернуться, ось, вдоль которой нужно вертеться. Если ось равна 0, то поворачивается вдоль оси Y (по горизонтали), если 1, то вдоль оси Х.
Затем необходимо задать вектора и определить положение матрицы.
Сначала задаем вектор позиции pos, равный (0,0,0)
Для движения вперед/назад определяем вектор vecFB, равный (0, 0, -10). Из его значения видно, что движение происходит вдоль оси Z, которая направлена в глубь экрана.
Для движения влево/вправо определяем вектор vecLR, равный (10,0,0). Этот вектор направлен вдоль оси Х. Ось Х всегда направлена вправо, поэтому тут необходимо просто указать в этой составляющей положительное число. В данном случае выбрано число10.
Для расчетов используется еще один вектор - up, который равен (0,10,0). Этот вектор определяет, куда смотрит макушка персонажа. Поскольку персонаж не наклоняется, вектор направлен вдоль оси Y, ровно вверх.
После того как векторы определены перемножаем матрицы с помощью специальной функции DirectX
//Перемножаем полученные, в результате движения, матрицы
View:=worldMat;
D3DXMatrixMultiply(View, xrMat, yrMat);
D3DXMatrixMultiply(View, View, mvMat);
Теперь необходимо трансформировать координаты с учетом векторов, с помощью функции DirectX - D3DXVec3TransformCoord, которой передаем 3 параметра - вектор, вектор и матрица положения камеры.
D3DXVec3TransformCoord(pos, pos, View);
D3DXVec3TransformCoord(vecFB, vecFB, View);
D3DXVec3TransformCoord(vecLR, vecLR, View);
D3DXVec3TransformNormal(up, up, View);
И последнее действие - устанавливаем положение камеры -
D3DXMatrixLookAtLH(View, pos, vecFB, up);
pDevice.SetTransform(D3DTS_VIEW, View);
3.4 Инструкция пользователя
В этом разделе даны подробные указания по работе с движком. Поскольку он может быть использован по-разному, необходимо выделить несколько пунктов, по которым пользователь сможет найти указания к использованию именно той области работы движка, которая ему нужна.
Поскольку данный программный продукт не является конечным, он предназначен для пользователей, которые знакомы с синтаксисом языка Delphi и (хотябы в общих чертах) с DirectX9. Пользователю, не знакомому с программированием эта программа будет безполезна.
3.4.1 Как работать с «движком»
Для начала необходимо посмотреть на программный код всех модулей, который можно увидеть в разделе «Приложения». Основные изменения при программировании собственных проектов, нужны в функциях «движка» InitObject, InitGraphObject и KeyControl.
Загрузка пользовательского объекта
Для того, чтобы добавить загрузку еще одного объекта, достаточно скорректировать значение константы CURRENT_OBJECTS_NUM (она должна быть равна количеству объектов, загружаемых в программе) и написать ряд команд, аналогичных уже имеющимся (которые загружают тестовые объекты). В функции InitObject:
if typ='Название пользовательского объекта' then
objects[index].LoadMeshFromFile('путь к Х-файлу пользовательского объекта', 'путь к текстуре пользовательского объекта');
Далее, в разделе «Var» функции InitGraphObject необходимо добавить еще одну переменную типа D3DMATRIX. Эта переменная устанавливает положение объекта. Далее необходимо задать ее значения и вызвать метод SetWorldPos, в параметре которого указать заполненную матрицу. Объект установлен.
Если пользователю нужен новый источник освещения, то в разделе «Var» функции InitGraphObject нужно указать еще одну переменную типа TD3DXVECTOR3 и заполнить ее значением направления нового источника света. Чтобы установить новую лампочку нужно вызвать метод «движка» объекта SetLightPos. Пример:
lp:=D3DXVECTOR3(20, 20, 0);
objects[n].SetLightPos(lp, l);
Где lp - вектор направления новой лампочки, n - номер объекта, а l - индекс лампочки.
Устройства ввода
Чтобы назначить действие какой-либо клавиши клавиатуры или мыши, нужно добавить одну строчку (в функцию «движка» игры KeyControl), в которой сначала идет проверка на нажатие нужной клавиши, а далее, если клавиша нажата, действие. Пример:
if bKeyBuffer[DIK_Клавиша] = $080 then Действие;
Константы, которые определяют клавиши можно найти в заголовочном файле DirectInput. Содержимое этого файла можно посмотреть на прилагаемом диске в папке DirectX\Borland_D6-7. Для добавления действий по нажатию клавиш мыши не нужно писать проверку, она уже есть в функции, осталось только добавить код действия в блок begin end; Пример:
if ms.rgbButtons[0] = $080 then begin действие end;
Эта программная строчка определяет действие при нажатии 0-й клавиши мыши.
3.4.2 Как использовать «движок» в собственном проекте
Первое действие, которое необходимо совершить, для использования модуля движка в собственной программе - это подключение его к программе, в файле проекта. Как это сделать, можно разобраться по примеру файла проекта данной программы (Game.dpr).
1. В разделе uses нужно подключить модули DirectX и «движка»;
2. В разделе «var» главной программы объявить переменную, для хранения класса движка (в данной программе это переменная «ge»);
3. В программе вызвать конструктор движка, на этапе инициализации;
4. Вызвать функцию формирования сцены (ge.RenderScene).
Рекомендации по возможностям расширения движка
Для реализации алгоритма проверки столкновений в игре удобнее всего модернизировать функцию MoveCamera, так как именно в этой функции происходит перемещение камеры по виртуальному миру. Для проверки столкновений нужно сначала получить точки, по которым будет определяться, произошло ли столкновение. Для этого лучше всего подойдет функция LoadMeshFromFile, которая находится в модуле DXGObject. В нее можно добавить получение данных из Х-файла и точек окружности или куба, в которые будут вписаны объекты (это зависит от того, какой алгоритм проверки столкновений решит реализовать пользователь).
Так же в функцию модуля «движка» объекта LoadMeshFromFile можно добавить и поддержку анимации, то есть загрузку данных о скелете (если он есть) или загрузку анимации из Х-файла.
Функции действий пользователь легко может добавить в класс «движка» игры или «движка» объекта.
3.4.3 Запуск exe-файла
Для успешного запуска откомпилированного файла необходимо, чтобы на компьютере был установлен DirectX 9, все файлы сеток и текстур были на месте и, поскольку в программе используются функции модуля D3DX9, необходимо, чтобы в одной папке с проектом находились две библиотеки dll - D3DX9_27.dll и D3DX9sab.dll. Если планируется дальнейшее использование модуля D3DX9 в своих проектах, пользователю рекомендуется скопировать эти две библиотеки в папку system32, тогда не возникнет необходимости копировать их в каждую папку с проектом.
При запуске проекта сначала будет произведен запрос на отображение в полноэкранном режиме, и если нажата кнопка «Yes», то произойдет запуск программы в полноэкранном режиме, иначе (если «No») соответственно в оконном.
Далее происходит прорисовка окна и формирование сцены.
Если программа не запустилась и выдала ошибку на этапе инициализации, значит аппаратное и/или программное обеспечение компьютера не соответствует требованиям программы. В таком случае можно попробовать установить более свежую версию DirectX 9. Если и это не помогло, то программа не запустится.
После отображения окна, можно начинать работу в приложении. Перемещение по миру происходит с помощью клавиш: `w'- вверх, `s'- вниз, `a' - влево, `d' - вправо. Поворот камеры происходит при нажатии клавиш «стрелок» на клавиатуре и при движении мышью. По нажатию клавиши `Esc' происходит завершение работы приложения.
3.5 Оценка результатов решения задачи
Проект успешно выполняет все действия, которые ставились целью на этапе постановки задачи:
1. Инициализация графики;
2. Загрузка объектов;
3. Обработка данных, полученных с устройств ввода.
Поставленная задача выполнена.
ЭКОНОМИЧЕСКАЯ ЧАСТЬ
Расчет предполагаемой прибыли от реализации созданного программного продукта
Проект предназначен для компании «Маклай».
Данный программный продукт может принести предприятию определенные плюсы:
· Упрощение разработки приложений
· Уменьшение временных затрат на производство
· Качественный результат
4. Описание и расчет затрат на выполнение проекта
Разработка данной программы, так же как и разработка любого другого программного продукта, требует определенных материальных, временных и трудовых затрат, а следовательно должна соответственно окупаться. С экономической точки зрения затраты связанные с выполнением проекта, должны быть покрыты доходами от реализации конечного продукта.
5. Определение трудоёмкости
Трудоемкость выполнения программного продукта -- характеризуется перечнем основных этапов и видов работ, которые должны быть выполнены. Упорядочен данный перечень в соответствии со смысловым содержанием каждого вида работ и взаимосвязями между всеми видами работ.
Форма расположения работ по этапам:
1.Разработка технического задания (ТЗ):
- получение ТЗ;
2. Подготовительный этап:
-сбор информации;
-разработка общей методики создания продукта;
3. Основной этап:
- Разработка основного алгоритма;
-Отладка;
4. Завершающий этап:
-Подготовка технической документации;
-сдача продукта.
Трудоемкость выполнения работы оценивается экспертным путем в человеко-днях и носит вероятностный характер. Определим трудоёмкость по видам работ.
Таблица №1: Расчет трудоёмкости по проекту
Виды работ |
Трудоёмкость, чел/час |
|
получение ТЗ |
2 |
|
сбор информации и ознакомление с предметной областью |
50 |
|
выбор объектного построения программы |
10 |
|
разработка общей методики создания продукта |
12 |
|
разработка основного алгоритма |
100 |
|
Отладка |
20 |
|
подготовка технической документации |
10 |
|
сдача продукта |
1 |
|
Итого |
205 |
Суммарная трудоемкость составила 205 чел.\час.
Расчет расходов на заработную плату.
На основе данных о трудоемкости и средней заработной плате по отрасли рассчитываем основную заработную плату. Предположим, что заработная плата программиста без опыта работы составляет 25000 тыс. руб. в месяц. (21 рабочий день, 8 часовой рабочий день) или 148,8 руб./час.
Таким образом, расходы на заработную плату по нашему проекту составляют:
ЗП = 148,8 *125 = 18600 руб.
Отчисления на ЗП (Пенсионный Фонд, Фонд соц. страхования, Фонд обязательного мед. страхования, территории. фонды мед. страхования) составляют 26% (20,0+2,9+1,1+2,0 соответственно). В денежном выражении составляют: = 18600 *0,26= 4836 руб.
Рассчитаем затраты на материалы:
Материалы, затраченные на создание проекта, приведены в таблице 2.
Таблица №2: Расчет затрат на материалы
Расходные материалы: |
Количество: |
Цена за единицу, руб: |
Сумма, руб: |
|
бумага а4 |
1 упаковка |
150 |
150 |
|
картридж для принтера |
2 штуки |
500 |
1000 |
|
диск |
1 штука |
20 |
15 |
|
папка |
1 штука |
100 |
100 |
|
файлы |
100 штук |
1 |
100 |
|
Итого |
1365 |
Рассчитаем амортизацию.
Стоимость компьютера 24 тыс. руб. Используем его в течении 5 лет (60 мес.). Годовая амортизация составит в месяц 400 руб. В час: 2,38 руб. Умножив на трудоёмкость, определим:
АО = 2,38*125= 297,5 руб.
Рассчитаем расходы на электроэнергию.
ПК в среднем потребляет 0,6 Квт/час. 0,6*135=81КВт. Примерная стоимость 1 Квт/ч около 1,97 руб.
Итого: 81*1,97=159,57руб.
Все результаты расчета затрат приведены в таблице 3.
Таблица №3: Смета всех затрат
Наименование статей затрат |
Сумма, руб. |
|
Расходные материалы |
1365 |
|
Основная заработная плата |
18600 |
|
Расходы на электроэнергию |
159,57 |
|
Амортизационные отчисления |
297,5 |
|
Отчисления на ЗП |
4836 |
|
Итого |
25258,07 |
Таким образом, суммарная стоимость затрат на создание данного программного продукта составляет 25258,07 рублей, следовательно эту программу ниже этой цены продать нельзя, так как в этом случае программа не будет являться экономически эффективной.
Рыночная стоимость аналогичного программного продукта составляет 35000 рублей.
Таким образом, реализовав наш программный продукт, мы можем получить прибыль в размере 9742 рубля.
6. Заключение
Существует множество графических «движков» для 3D игр, написанных на различных языках, использующих различные технологии. Среди них не так много написаны на языке программирования Delphi под DirectX. На пути к осуществлению конечной цели, которой являлась разработка графического движка, возникло множество проблем, связанных с нехваткой учебной информации и практических примеров. Было переведено множество кодов с языка С++, разобраны различные алгоритмы организации программы. Теперь эта работа поможет молодым программистам, желающим работать в этом направлении. С ее помощью они смогут освоить программирование 3D игр под DirectX на Delphi и использовать эти знания и опыт в своих проектах.
Написание «движка» игры еще не завершено. В этой работе еще нет просчета столкновений и искусственного интеллекта, который просчитывал бы действия противника. Эти два пункта обязательно должны присутствовать в игровой программе, но их написание слишком сложный процесс, требующий больших затрат времени (обычно этим занимается не один программист).
Можно отметить, что процесс написания любой программы никогда нельзя назвать завершенным. Всегда существуют множество направлений для расширения функций программы. Графический движок - это только начальная стадия написания полноценной 3D игры. Этот движок обладает массой возможностей для расширения и модернизации. И даже написанная с его помощью, полноценная трехмерная игра всегда будет иметь возможности для расширения и оптимизации.
Хотя процесс написания графического «движка» для трехмерной игры еще не завершен, этот проект может быть реализован, так как он может быть задействован в разных проектах. Он вполне годится для обучения, так как его программный код достаточно понятно написан. К тому же этот проект может использоваться в качестве базы для последующих разработок какой-нибудь организации.
Приложение №1
Результат выполнения программы
Запрос на полноэкранный режим
Окно программы
Приложение №2
Исходный код файла проекта Game.dpr
program Game;
uses
windows,
messages,
Direct3D9, //модуль основных функций Direct3D
dxfunc, //модуль инициализации Direct3D и загрузки Х-файлов
GraphEngine; //модуль "движка" игры
{$R *.RES}
var
wc : TWndClassEx; //класс окна
pWnd : HWND; //окно
pMsg : TMsg; //сообщения Windows
//Переменные для работы с Direct3D
pD3D: IDirect3D9=nil;
pD3DDevice: IDirect3DDevice9=nil;
//Переменная движка игры
ge:CGraphEngine;
Procedure GraphEngine(); //процедура реализации движка
begin
if (SUCCEEDED(pD3DDevice.BeginScene())) then //Если процедура
//BeginScene была выполнена, то вызываем движок
begin
//очистка экрана
pD3DDevice.Clear(0, nil, D3DCLEAR_TARGET or D3DCLEAR_ZBUFFER , D3DCOLOR_XRGB(255,255,255), 1.0, 0);
ge.RenderScene(); //формирование сцены
pD3DDevice.EndScene(); //конец отображения сцены
end;
pD3DDevice.Present(nil, nil, 0, nil); //Функция для отображения сцены, без
//нее сцена не сформируется
end;
procedure Init; //Функция инициализации графики
var b:boolean; //вспомогательная переменная
begin
b:=false;
//инициализация графики
if (DX3DInit(pD3D, pD3DDevice, pWnd, 800, 600, b)<>true) then
begin //если процедура инициализации вернула false, значит произашла
//ошибка
MessageBox(pWnd, 'Ошибка инициализации DirectX?', 'Error', MB_OK); //выводим сообщение об ошибке
exit; //выходим из программы
end;
ge:=CGraphEngine.CGraphEngine(pD3DDevice, pWnd); //вызываем
//конструктор движка
end;
function WindowProc(wnd: HWND; Msg: Integer; wParam: wParam; lParam: lParam): Lresult; stdcall;
begin
Result:=0;
case msg of
WM_CREATE:
begin
end;
WM_DESTROY: //Событие завершения програмы. Освобождаем
//захваченые ресурсы
begin
pD3DDevice := nil;
pD3D := nil;
PostQuitMessage(0);
ReleaseDirectInput();
exit;
end;
else
Result:=DefWindowProc(wnd,msg,wparam,lparam);
end;
end;
begin
//заполняем структуру TWndClassEx для определения параметров окна
wc.cbSize := sizeof(wc); //размер структуры
wc.style:=cs_classdc;
wc.lpfnWndProc := @WindowProc;
wc.cbClsExtra := 0;
wc.cbWndExtra := 0;
wc.hInstance := HInstance;
wc.hCursor := LoadCursor(0, IDC_ARROW);
wc.hbrBackground:= COLOR_BTNFACE+1;
wc.lpszMenuName := nil;
wc.lpszClassName:= 'Room Example';
RegisterClassEx(wc);
//создание окна
pWnd := CreateWindowEx(WS_EX_APPWINDOW, 'Room Example', 'Delphi DirectX Game',
WS_CAPTION or WS_SYSMENU or WS_MINIMIZEBOX, 0, 0, 250, 130, 0, 0,
Hinstance, nil);
Init; //инициализация графики
ShowWindow(pWnd, SW_normal); //Показать окно
UpdateWindow(pWnd); //Обновить окно
//Цикл обработки сообщений (бесконечен)
while (true) do
begin
if (PeekMessage(pmsg, 0, 0, 0, PM_REMOVE)) then //если есть
//сообщение, то обрабатываем его
begin
TranslateMessage(pmsg);
DispatchMessage(pmsg);
if (pmsg.message = WM_QUIT) then exit; //если нажата
//клавиша выхода, то завершаем работу программы
end
else
GraphEngine(); //вызываем функцию движка
end;
end.
Приложение №3
Исходный код модуля «движка» игры GraphEngine.pas
unit GraphEngine;
interface
uses
windows,
Direct3D9, //модуль основных функций Direct3D
D3DX9, //модуль разширенных функций Direct3D
DirectInput, //модуль для работы с устройствами ввода
Classes,
DXTypes, //Модуль, содержащий некоторые дополнительные типы
DXGObject, //Модуль "движка" объекта
dxfunc; //Модуль инициализации графики
const NUM_OBJECTS = 20; //максимальное колличество объектов
CURRENT_OBJECTS_NUM = 2; //реальное колличество объектов
type
CGraphEngine = class //создаем класс "движка" игры
private
// Input variable
pDevice:IDirect3DDevice9; //устройтво Direct3D
objects:array [0..NUM_OBJECTS] of CDXGObject; //массив игровых
//объектов
function InitObject(typ:string;index:integer):boolean; //функция
//инициализации объектов
procedure InitGraphObjects(); //функция установки параметров вывода
//объектов
function KeyControl():boolean; //Функция для обработки данных,
//полученных с устройств ввода
procedure MoveCamera(fOffset:real; vecModifier:TD3DXVECTOR3); //Функция перемещения камеры
procedure RotateCamera(fOffset:real; Axis:integer); //Функция поворота
//камеры
public
constructor CGraphEngine(pD3DDevice:IDirect3DDevice9; hWnd: HWND); overload;
destructor CGraphEngine(); overload;
procedure RenderScene(); //Функция отображения сцены
end;
var
lpDI8: IDirectInput8 = nil; //главное устройтво DirectInput
lpDIKeyboard: IDirectInputDevice8 = nil; //клавиатура
lpDIMouse: IDirectInputDevice8 = nil; //мышь
worldMat, xrMat, yrMat, mvMat:D3DMATRIX; //матрици для преобразования
pos, vecLR, vecFB, up: TD3DXVECTOR3; //вектора направления осмотра
procedure InitDirectInput( hWnd: HWND ); //функция инициализации
//устройств ввода
procedure ReleaseDirectInput(); //Функция освобождения захваченых DirectInput ресурсов
implementation
constructor CGraphEngine.CGraphEngine(pD3DDevice:IDirect3DDevice9; hWnd: HWND);
var w:D3DMATRIX;
begin
//назначаем переменной pDevice устройство, созданное в главной программе
pDevice:=pD3DDevice;
// инициализация векторов и матриц
pos := D3DXVECTOR3(0.0, 0.0, 0.0);
vecLR := D3DXVECTOR3(10.0, 0.0, 0.0);
vecFB := D3DXVECTOR3(0.0, 0.0, -10.0);
up := D3DXVECTOR3(0.0, 10.0, 0.0);
D3DXMatrixIdentity(xrMat);
D3DXMatrixIdentity(yrMat);
D3DXMatrixIdentity(mvMat);
// Init view matrix
w._41:=20;
w._42:=-10;
w._43:=90;
worldMat:=w;
//Инициализируем объекты
InitGraphObjects();
//Инициализируем устройства ввода
InitDirectInput(hWnd);
end;
destructor CGraphEngine.CGraphEngine();
var i:integer;
begin
for i:=0 to CURRENT_OBJECTS_NUM do
objects[i]:=nil; //удаляем все игровые объекты
end;
procedure CGraphEngine.InitGraphObjects();
var
pos,pos1,rot:D3DMATRIX;
lp,lp1,lp2:TD3DXVECTOR3;
begin
// инициализация объектов
InitObject('SO_DEFAULT_ROOM', 0);
InitObject('SO_DX_MAN', 1);
// позиция комнаты
Pos._11:=0.1; Pos._12:=0; Pos._13:=0; Pos._14:=0;
Pos._21:=0; Pos._22:=0.1; Pos._23:=0; Pos._24:=0;
Pos._31:=0; Pos._32:=0; Pos._33:=0.1; Pos._34:=0;
Pos._41:=0; Pos._42:=0; Pos._43:=0; Pos._44:=10;
//устанавливаем объект (комнату) в позицию
objects[0].SetWorldPos(Pos);
//позиция человека
Pos1._11:=0.1; Pos1._12:=0; Pos1._13:=0; Pos1._14:=0;
Pos1._21:=0; Pos1._22:=0.1; Pos1._23:=0; Pos1._24:=0;
Pos1._31:=0; Pos1._32:=0; Pos1._33:=0.1; Pos1._34:=0;
Pos1._41:=0; Pos1._42:=0; Pos1._43:=0; Pos1._44:=1;
//поворачиваем объект (человека)
D3DXMatrixRotationX(Rot, -1.5);
D3DXMatrixMultiply(Pos1, Pos1, Rot);
//устанавливаем объект (человека) в позицию
objects[1].SetWorldPos(Pos1);
//Назначаем векторы направления освещения
lp:=D3DXVECTOR3(20, 20, 0);
lp1:=D3DXVECTOR3(8, 30, 15);
lp2:=D3DXVECTOR3(-8, -30, -15);
//Устанавливаем источники освещения
objects[0].SetLightPos(lp, 0);
objects[1].SetLightPos(lp1, 1);
//objects[0].SetLightPos(lp2, 2);
end;
function CGraphEngine.InitObject(typ:string;index:integer):boolean;
begin
objects[index]:=CDXGObject.CDXGObject(pDevice);
if typ='SO_DEFAULT_ROOM' then
objects[index].LoadMeshFromFile('media\room.x', 'media\doski.bmp');
if typ='SO_DX_MAN'then
objects[index].LoadMeshFromFile('media\tiny.x', '');
result:=true;
end;
procedure CGraphEngine.RenderScene();
var i:integer;
begin
//если функция KeyControl вернула false, значит дальнейшее выполнение программы
//не имеет смысла (программа не реагирует на устройства ввода)
if KeyControl=false then exit; //выходим из программы если функция KeyControl вернула false
//Отображаем сцену
pDevice.SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
pDevice.SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
pDevice.SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
//Очищаем переменную устройства Direct3D
pDevice.Clear(0, nil, D3DCLEAR_STENCIL, D3DCOLOR_XRGB(255,255,255), 1.0, 0);
//Отображаем объекты на экране
for i:=0 to CURRENT_OBJECTS_NUM-1 do
objects[i].Render(0);
end;
//////////////////////////
//directInput////////
//////////////////////////
procedure InitDirectInput( hWnd: HWND );
var
dipropdw: TDIPROPDWORD; // Структура для задания характеристик мыши
begin
// Создаём главный объект DirectInput
if FAILED(DirectInput8Create(GetModuleHandle(nil), DIRECTINPUT_VERSION, IID_IDirectInput8, lpDI8, nil ) ) then
Exit;
lpDI8._AddRef();
// Создаём объект для работы с клавиатурой
if FAILED( lpDI8.CreateDevice( GUID_SysKeyboard, lpDIKeyboard, nil ) ) then
Exit;
lpDIKeyboard._AddRef();
// Устанавливаем предопределённый формат для "простогй клавиатуры".
// В большинстве случаев можно удовлетвориться и установками,
//заданными в структуре
// c_dfDIKeyboard по умолчанию, но в особых случаях нужно заполнить её
//самому
if FAILED( lpDIKeyboard.SetDataFormat( c_dfDIKeyboard ) ) then
Exit;
// Устанавливаем уровень кооперации. Подробности о флагах смотри в
//DirectX SDK
if FAILED(lpDIKeyboard.SetCooperativeLevel(hWnd, DISCL_BACKGROUND or DISCL_NONEXCLUSIVE ) ) then
Exit;
// Захвытываем клавиатуру
lpDIKeyboard.Acquire();
// Создаём объект для работы с мышью
if FAILED( lpDI8.CreateDevice(GUID_SysMouse, lpDIMouse, nil)) then
Exit;
lpDIMouse._AddRef();
// Устанавлаваем предопределённый формат данных
if FAILED( lpDIMouse.SetDataFormat(c_dfDIMouse)) then
Exit;
// Устанавливаем уровень кооперации для мыши
if FAILED(lpDIMouse.SetCooperativeLevel(hWnd, DISCL_FOREGROUND or
DISCL_EXCLUSIVE)) then
Exit;
// Захвытываем мышь
lpDIMouse.Acquire();
end;
procedure ReleaseDirectInput();
begin
// Удаляем объект для работы с клавиатурой
if lpDIKeyboard <> nil then
begin
lpDIKeyboard.Unacquire(); // Освобождаем устройство
lpDIKeyboard._Release();
lpDIKeyboard := nil;
end;
// Удаляем объект для работы с мышью
if lpDIMouse <> nil then
begin
lpDIMouse.Unacquire();
lpDIMouse._Release();
lpDIMouse := nil;
end;
// Последним удаляем главный объект DirectInput
if lpDI8 <> nil then
begin
lpDI8._Release();
lpDI8 := nil;
end;
end;
function CGraphEngine.KeyControl():boolean;
var View:D3DMATRIX; //матрица положения камеры
bKeyBuffer: array [0..255] of Byte; //буфер-массив клавиш клавиатуры
ms: TDIMOUSESTATE; //переменная для данных, полученных от мыши
begin
//присваеваем результату работы функции значение false
Result := FALSE;
// Производим опрос состояния клавиш, данные записываются в буфер
//массив
lpDIKeyboard.GetDeviceState( SizeOf( bKeyBuffer ), @bKeyBuffer );
//Если нажата клавиша Esc выход из программы
if bKeyBuffer[DIK_ESCAPE] = $080 then PostQuitMessage(0);
// Изменяем положение камеры в зависимости от нажатой клавиши
if bKeyBuffer[DIK_W] = $080 then MoveCamera(0.05, vecFB);
if bKeyBuffer[DIK_S] = $080 then MoveCamera(-0.05, vecFB);
if bKeyBuffer[DIK_A] = $080 then MoveCamera(0.05, vecLR);
if bKeyBuffer[DIK_D] = $080 then MoveCamera(-0.05, vecLR);
if bKeyBuffer[DIK_left] = $080 then RotateCamera(-0.05, 0);
if bKeyBuffer[DIK_RIGHT] = $080 then RotateCamera(0.05, 0);
if bKeyBuffer[DIK_UP] = $080 then RotateCamera(0.05, 1);
if bKeyBuffer[DIK_DOWN] = $080 then RotateCamera(-0.05, 1);
//производим опрос состояния мыши
lpDImouse.GetDeviceState(SizeOf(TDIMOUSESTATE), @ms);
//поворачиваем камеру в зависимости от движений мыши
if ms.lX<0 then RotateCamera(-0.05, 0) else
if ms.lX>0 then RotateCamera(0.05, 0);
if ms.lY<0 then RotateCamera(0.05, 1) else
if ms.lY>0 then RotateCamera(-0.05, 1);
if ms.rgbButtons[0] = $080 then begin end;
if ms.rgbButtons[1] = $080 then begin end;
if ms.rgbButtons[2] = $080 then begin end;
if ms.rgbButtons[3] = $080 then begin end;
// устанавливаем векторы положения
pos := D3DXVECTOR3(0.0, 0.0, 0.0);
vecLR := D3DXVECTOR3(10.0, 0.0, 0.0);
vecFB := D3DXVECTOR3(0.0, 0.0, -10.0);
up := D3DXVECTOR3(0.0, 10.0, 0.0);
//перемножаем матрици
View:=worldMat;
D3DXMatrixMultiply(View, xrMat, yrMat);
D3DXMatrixMultiply(View, View, mvMat);
//Трансформируем координаты
D3DXVec3TransformCoord(pos, pos, View);
D3DXVec3TransformCoord(vecFB, vecFB, View);
D3DXVec3TransformCoord(vecLR, vecLR, View);
D3DXVec3TransformNormal(up, up, View);
//Устанавливаем положение камеры
D3DXMatrixLookAtLH(View, pos, vecFB, up);
pDevice.SetTransform(D3DTS_VIEW, View);
//Включаем освещение
pDevice.SetRenderState(D3DRS_LIGHTING, DWord(true));
//функция выполнира работу успешно и присваеваем результату значение true
result:=true;
end;
procedure CGraphEngine.MoveCamera(fOffset:real;
vecModifier:TD3DXVECTOR3);
var tView:TD3DXMATRIX; //матрица преобразования
vect:TD3DXVECTOR3; //вектор положения камеры
begin
D3DXVec3Subtract(vect, vecModifier, pos);
//корректируем значение вектора положения камеры
vect.x:=vect.x*fOffset; vect.y:=0; vect.z:=vect.z*fOffset;
D3DXMatrixTranslation(tView, vect.x, vect.y, vect.z); //устанавливаем положение камеры с учетом новой позиции
D3DXMatrixMultiply(mvMat, mvMat, tView); //устанавливаем камеру в новую позицию
end;
procedure CGraphEngine.RotateCamera(fOffset:real; Axis:integer);
var tView:TD3DXMATRIX;
begin
case (Axis) of
0:begin
D3DXMatrixRotationY(tView, fOffset); //поворачиваем камеру на
//коэффициент fOffset
D3DXMatrixMultiply(yrMat, yrMat, tView); //устанавливаем камеру в
//новую позицию по оси у
exit;
end;
1:begin
D3DXMatrixRotationX(tView, fOffset);
D3DXMatrixMultiply(xrMat, xrMat, tView); //устанавливаем камеру в
//новую позицию по оси х
exit;
end;
end;
end;
end.
Приложение №4
Исходный код модуля «движка» Объекта DXGObject.pas
unit DXGObject;
interface
uses
windows,
messages,
Direct3D9, //модуль основных функций Direct3D
D3DX9, //модуль разширенных функций Direct3D
Classes,
DXTypes, //Модуль, содержащий некоторые дополнительные типы
dxfunc; //Модуль инициализации графики
const MAX_OBJECT_EFFECTS = 10; //максимальное колличество эффектов
//(используется при установки освещения)
type
asingle= array [0..2] of single;
CDXGObject = class //создаем класс движка объекта
// 3D Устройство
pDevice:IDirect3DDevice9;
// Сетка Mesh
dwNumMaterials:DWord; //номер материала
pMesh:ID3DXMesh; //сетка
pMeshTextures:PAIDirect3DTexture9; //Текстура
pMeshMaterials:PAD3DMATERIAL9; //материал
pTexture:array [0..MAX_OBJECT_EFFECTS] of IDirect3DTexture9; //массив
//текстур
Light:array [0..MAX_OBJECT_EFFECTS] of D3DLIGHT9; //массив
//источников света
// Мировая матрица
matWorld:D3DMATRIX;
constructor CDXGObject(pD3DDevice:IDirect3DDevice9);
procedure LoadMeshFromFile(filename:string; texturename:string); //Процедура Загрузки Х-файла
procedure LoadTexture(filename:PAnsiChar; index:integer); //Процедура
//Загрузки текстуры
function GetWorldPos():D3DMATRIX ; //Функция получения позиции
//мира (мировой матрици)
procedure SetWorldPos(matrix:D3DMATRIX); //Процедура определения
//положения объекта
procedure SetLightPos(Pos:TD3DXVECTOR3; index:integer); //Процедура установки источника освещения
procedure Positioning(); //Процедура установки позиции объекта
function Render(ef_index:DWORD=1):boolean; //Функция отображения
// объекта
end;
implementation
constructor CDXGObject.CDXGObject(pD3DDevice:IDirect3DDevice9);
begin
pDevice:=pD3DDevice; //получаем образец устройства Direct3D
D3DXMatrixIdentity(matWorld); //инициализируем мировую матрицу
end;
procedure CDXGObject.LoadTexture(filename:PAnsiChar; index:integer);
begin
//Загрузка текстуры из файла
D3DXCreateTextureFromFileEx(pDevice, filename, D3DX_DEFAULT,
D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED,
D3DX_FILTER_TRIANGLE or D3DX_FILTER_MIRROR,
D3DX_FILTER_TRIANGLE or D3DX_FILTER_MIRROR,
0, nil, nil, pTexture[index]);
end;
procedure CDXGObject.SetLightPos(Pos:TD3DXVECTOR3; index:integer);
begin
//выделяем память под сткуктуру источника света
ZeroMemory(@light[index], sizeof(D3DLIGHT9));
//Заполняем структуру источника света (задаем параметры параметры)
light[index]._Type := D3DLIGHT_DIRECTIONAL; //тип освещения (рассеяный свет)
light[index].Direction := pos; //Направление
light[index].Diffuse.r :=1; //Цвет (белый)
light[index].Diffuse.g :=1;
light[index].Diffuse.b :=1;
light[index].Diffuse.a :=1;
//Устанавливаем источник освещения
pDevice.SetLight(index, light[index]);
pDevice.LightEnable(index, true);
end;
function CDXGObject.GetWorldPos():D3DMATRIX;
begin
result:=matWorld; //получаем мировую матрицу
end;
procedure CDXGObject.SetWorldPos(matrix:D3DMATRIX);
begin
matWorld:=matrix; //определяем мировую матрицу
end;
procedure CDXGObject.Positioning();
begin
pDevice.SetTransform(D3DTS_WORLD, GetWorldPos()); //Устанавливаем
//матрицу позиции объекта
end;
function CDXGObject.Render(ef_index:DWORD):boolean;
var i: integer;
begin
//присваеваем результату работы функции значение false
Result:= false;
Positioning();
// отображение объекта
for i:=0 to dwNumMaterials-1 do
begin
pDevice.SetMaterial(pMeshMaterials[i]); //устанавливаем материал
if pMeshTextures[i]<>nil then //устанавливаем текстуру, если она есть
pDevice.SetTexture(0, pMeshTextures[i]);
pMesh.DrawSubset(i); //Рисуем сетку
end;
//функция выполнира работу успешно и присваеваем результату значение true
result:=true;
end;
procedure CDXGObject.LoadMeshFromFile(filename:string; texturename:string);
begin
dwNumMaterials := LoadMesh(filename, pDevice, pMesh, pMeshTextures,
texturename, pMeshMaterials); //загрузка Х-файла
end;
end.
Приложение №5
Исходный код модуля инициализации графики и загрузки Х-файлов dxfunc.pas.
unit dxfunc;
interface
uses Direct3D9, D3DX9, windows, SySUtils;
type
//массив указателей на тип, для работы с тексурой, с неопределенным количеством элементов
PAIDirect3DTexture9=^AIDirect3DTexture9;
AIDirect3DTexture9=array[0..0] of IDirect3DTexture9;
//массив указателей на тип, для работы с материалом, с неопределенным количеством элементов
AD3DMATERIAL9 = array [0..0] of TD3DMATERIAL9;
PAD3DMATERIAL9 = ^AD3DMATERIAL9;
//массив указателей на тип, для работы с материалом, с неопределенным количеством элементов
AD3DXMATERIAL = array [0..0] of TD3DXMATERIAL;
PAD3DXMATERIAL = ^AD3DXMATERIAL;
//функция инициализации Direct3D
function DX3DInit(var ppiD3D9: IDirect3D9; //переменные для работы с DirectX
var ppiD3DDevice9: IDirect3DDevice9;
hWnd: THandle; //Переменная, для хранения параметров окна
iWidth, iHeight: Integer; //Разрешение (размер создаваемого окна)
var bFullScreen: Boolean):Boolean; //параметр, указывающий на то, нужно ли выводить программу в полноэкранном режиме
//Функция загрузки Х-файла
function LoadMesh(filename:String; //Имя Х-файла
ppiD3DDevice9:IDirect3DDevice9; //Переменная для работы с DirectX
var ppMesh:ID3DXMesh; //Сетка
var pMeshTextures: PAIDirect3DTexture9; //Текстура
texturefilename: String; //Имя файла bmp текстуры
var pMeshMaterials: PAD3DMATERIAL9):DWORD; //Материал
//Функция загрузки текстуры
function LoadTexture(
text_buf:PByteArray;
iWidth, iHeight:Integer;
filename:String):Boolean;
implementation
function DX3DInit(var ppiD3D9: IDirect3D9;
var ppiD3DDevice9: IDirect3DDevice9;
hWnd: THandle;
iWidth, iHeight: Integer;
var bFullScreen: Boolean):Boolean;
var
d3dpp:TD3DPresentParameters;
iRes: Integer; //Используется для хранения ответа пользователя на
//запрос отображения
wndRect, clientRect: TRect;
d3ddm : TD3DDISPLAYMODE;
Flags: DWORD; //дополнительный флаг
hRes : HRESULT;
Aspect : real; //Номер адаптера
matProjection : TD3DMATRIX; //Матрица проекции
begin
//присваеваем результату работы функции значение false
Result:= false;
ppiD3D9:=Direct3DCreate9(D3D_SDK_VERSION); //создаем устройство Direct3D
if ppiD3D9=nil then //есди устройство не созданно, то завершаем работу
//функции
exit;
// Заполняем основные параметры представления
ZeroMemory(@d3dpp, sizeof(d3dpp));
d3dpp.BackBufferWidth := iWidth; //ширина заднего буфера
d3dpp.BackBufferHeight := iHeight; //Высота заднего буфера
d3dpp.AutoDepthStencilFormat := D3DFMT_D16;
d3dpp.EnableAutoDepthStencil := TRUE;
// Запрос на отображение в полноэкранном режиме
if (bFullScreen=false) then
iRes:=MessageBox(hWnd, 'Use fullscreen mode?', 'Screen', MB_YESNO or MB_ICONQUESTION)
else
iRes := IDYES;
if(iRes = IDYES) then
begin
//////////////////////////////////////////////////////////
// Полноэкранный режим
//////////////////////////////////////////////////////////
// Установка параметров полноэкранного режима
d3dpp.BackBufferFormat := D3DFMT_R5G6B5;
d3dpp.SwapEffect := D3DSWAPEFFECT_FLIP;
d3dpp.Windowed := FALSE;
d3dpp.FullScreen_RefreshRateInHz := D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval := D3DPRESENT_INTERVAL_DEFAULT;
end
else
begin
//////////////////////////////////////////////////////////
// Оконный режим
//////////////////////////////////////////////////////////
GetWindowRect(hWnd, wndRect);
GetClientRect(hWnd, clientRect);
//Задаем разрешение (размеры) окна
iWidth := iWidth + (wndRect.right-wndRect.left) - (clientRect.right-clientRect.left);
iHeight := iHeight + (wndRect.bottom-wndRect.top) - (clientRect.bottom-clientRect.top);
//создать окно
MoveWindow(hWnd, wndRect.left, wndRect.top, iWidth, iHeight, TRUE);
// Получить формат пикселя
ppiD3D9.GetAdapterDisplayMode(D3DADAPTER_DEFAULT, d3ddm);
// Установка параметров
d3dpp.BackBufferFormat := d3ddm.Format;
d3dpp.SwapEffect := D3DSWAPEFFECT_DISCARD;
d3dpp.Windowed := TRUE;
end;
Flags := D3DCREATE_MIXED_VERTEXPROCESSING;
// Создать 3D устройство
hRes := ppiD3D9.CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, hWnd, Flags,
@d3dpp, ppiD3DDevice9);
if (FAILED(hRes)) then
exit;
// Установить перспективу
Aspect := d3dpp.BackBufferWidth / d3dpp.BackBufferHeight;
D3DXMatrixPerspectiveFovLH(matProjection, D3DX_PI/4.0, Aspect, 0.1, 2000.0);
ppiD3DDevice9.SetTransform(D3DTS_PROJECTION, matProjection);
//Отключить освещение
ppiD3DDevice9.SetRenderState(D3DRS_LIGHTING, DWORD(FALSE));
//функция выполнира работу успешно и присваеваем результату значение true
Result:=true;
end;
function LoadMesh(filename:String;
ppiD3DDevice9:IDirect3DDevice9;
var ppMesh:ID3DXMesh;
var pMeshTextures: PAIDirect3DTexture9;
texturefilename: String;
var pMeshMaterials: PAD3DMATERIAL9):DWORD;
var
pD3DXMtrlBuffer: ID3DXBUFFER;
dwNumMaterials: DWORD;
d3dxMaterials: PAD3DXMATERIAL;
i:Integer;
begin
//Чтение данных из Х-файла
D3DXLoadMeshFromX(PAnsiChar(filename), D3DXMESH_SYSTEMMEM, ppiD3DDevice9,
nil, @pD3DXMtrlBuffer, nil, @dwNumMaterials, ppMesh);
d3dxMaterials := pD3DXMtrlBuffer.GetBufferPointer();
// Инициализируем материалы и текстуры
GetMem(pMeshMaterials, SizeOf(TD3DMATERIAL9)*dwNumMaterials);
GetMem(pMeshTextures, SizeOf(IDIRECT3DTEXTURE9)*dwNumMaterials);
for i:=0 to dwNumMaterials-1 do
begin
// Копируем материал
pMeshMaterials[i] := d3dxMaterials[i].MatD3D;
// Создаем текстуру, если она есть
if (FAILED(D3DXCreateTextureFromFile(ppiD3DDevice9,
d3dxMaterials[i].pTextureFilename, pMeshTextures[i]))=true) then
if (FAILED(D3DXCreateTextureFromFile(ppiD3DDevice9,
PAnsiChar(texturefilename), pMeshTextures[i]))) then
pMeshTextures[i] := nil;
end;
Result:=dwNumMaterials;
end;
function LoadTexture(text_buf:PByteArray;iWidth, iHeight:Integer; filename:String):Boolean;
var
hFile:THandle;
bmpfilehdr:BITMAPFILEHEADER;
dwRead:DWORD;
ptr:String;
bmpinfohdr:BITMAPINFOHEADER;
iImageSize, bytesgiven, i, p:Integer;
buf:array of byte;
btSurf:PByte;
imagebits:PByteArray;
wdSurf: PWord;
tlImage:PRGBTRIPLE;
begin
Result:=false;
hFile := CreateFile(PAnsiChar(filename), GENERIC_READ, 0, nil,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile = INVALID_HANDLE_VALUE) then
exit;
if (ReadFile(hFile, bmpfilehdr, sizeof(bmpfilehdr), dwRead, nil)=false) then
exit;
ptr:=Chr(bmpfilehdr.bfType);
if (ptr[1]<>'B') then
exit;
// Проверяем заголовок изображения
if(ReadFile(hFile, bmpinfohdr, sizeof(bmpinfohdr), dwRead, nil)=false) then
exit;
if (bmpinfohdr.biCompression<>BI_RGB) then
exit;
iImageSize:=bmpinfohdr.biSizeImage;
if (iImageSize=0) then
iImageSize:=iWidth*bmpinfohdr.biBitCount*iHeight;
// Читаем данные изображения в буфер
SetLength(buf,iImageSize);
if (ReadFile(hFile, buf[0], iImageSize, dwRead, nil)=false) then
exit;
if (bmpinfohdr.biBitCount<>24)then
exit;
bytesgiven:=(iWidth*3+3) and (not 3);
btSurf := PByte(text_buf);
imagebits := @buf[(iHeight-1)*bytesgiven];
for i:=0 to iHeight-1 do
begin
wdSurf:=PWord(btSurf);
tlImage:=PRGBTRIPLE(imagebits);
for p:=0 to iWidth-1 do
begin
PDWord(wdSurf)^ := (tlImage.rgbtBlue) +
(tlImage.rgbtGreen SHL 8) +
(tlImage.rgbtRed SHL 16)+
$FF000000;
tlImage:=Pointer(Integer(tlImage)+3);
wdSurf:=Pointer(Integer(wdSurf)+4);
end;
btSurf := Pointer(Integer(btSurf)+iWidth*4);
imagebits := Pointer(Integer(imagebits)-bytesgiven);
end;
Result:=true;
end;
end.
Размещено на Allbest.ru
Подобные документы
Игровой движок Unity, его использование для создания приложений, связанных с архитектурой, обучением, визуализацией данных и электронными книгами. Разработка системы освещения для работы с двухмерными объектами в виде расширения редактора Unity.
дипломная работа [2,5 M], добавлен 11.02.2017Использование DirectX для решения задач по выводу и обработке графики в Microsoft Windows. Описание используемых DirectX-функций. Исходный текст отлаженной программы. Техника работы с окнами. Результаты работы программы, составление алгоритма, листинг.
контрольная работа [226,0 K], добавлен 18.05.2014Разработка компьютерной игры "Эволюция" с помощью игрового движка Unit. Сравнение критериев игры-аналога и разрабатываемой игры. Разработка графического интерфейса пользователя. Настройки камеры в редакторе Unity. Структура файла сохранения игры.
дипломная работа [3,6 M], добавлен 11.02.2017Ознакомление с интерфейсом, основными возможностями и преимуществами использования программы OpenGL - популярной библиотекой для работы с 2D и 3D графикой. Рассмотрение назначения, базовых компонент и правил инициализации программного движка DirectX.
презентация [19,4 K], добавлен 14.08.2013Подбор игрового движка и описание его основных характеристик. Разработка структуры, алгоритма и интерфейса программы. Проектирование иерархии классов. Выделение типового приема визуализации. Тестирование правильности работы программного обеспечения.
курсовая работа [3,1 M], добавлен 19.01.2017Структура Android-приложений. Особенности игрового движка. Алгоритмизация и программирование. Список игровых состояний. Настройка, отладка и тестирование программы. Разработка руководства пользователя. Тестирование инсталляции и отображения элементов.
дипломная работа [4,5 M], добавлен 19.01.2017Изучение аэродинамики как одной из разделов физики в современном мире. Компьютерное моделирование взаимодействия самолета с окружающей средой. Создание физического движка. Освоение языка программирования C++, графического программного интерфейса OpenGL.
практическая работа [1,1 M], добавлен 03.05.2015Описание алгоритма решения задачи по вычислению суммы элементов строк матрицы с использованием графического способа. Детализация укрупненной схемы алгоритма и разработка программы для решения задачи в среде Turbo Pascal. Листинг и тестирование программы.
курсовая работа [446,0 K], добавлен 19.06.2014Разработка программного продукта, предназначенного для имитации физического взаимодействия между объектами на основе игрового симулятора. Проектирование программы "LonelySpaceRanger", код которой представлен на языке VisualС++. Разработка интерфейса.
дипломная работа [3,2 M], добавлен 30.11.2011High Level Shader Language как высокоуровневый Си-подобный язык для написания шейдеров. Программа для работы с шейдерами, вид и краткое описание интерфейса. Характеристика особенностей создания трехмерных изображений. Структурные элементы программы.
курсовая работа [485,2 K], добавлен 16.01.2014