Главная » 2011 » Январь » 6 » Постая программа на GLScene
22:46
Постая программа на GLScene

Введение


Наверно вы удивлены зачем использовать GLScene, а не чистое API ну или хотя бы другой движок. Скажу только одно, это статья для тех кто хотел попробовать написать что то своё с использованием 3д графики, но из за недостатка знаний не решался на сей шаг. Как показывает практика в странах бывшего Советского Союза очень популярен Pascal (и его разновидности), по этому в качестве языка программирования выбран Object Pascal. О преимуществе GLScene, я писал в другой своей статье, так что останавливаться на этом не будем. Сражу скажу, код тут не весь, я описал только самое сложное и то что может вызвать вопросы остальные вещи просты и не должны быть проблемой, по этой причине я вынес их из статьи. Ну что вперёд?
image

Первая программа


GLScene - это объектная надстройка над OpenGL для Borlan Delphi, хотя некоторые считают GLScene игровым движком. Оно и так и не так. GLScene упрощает жизнь многим программистам и открывает широкие возможности по работе с графикой.
Последние версии библиотеки GLScene и множество примеров доступны на сайте http://www.glscene.org/.
Установка

Официально поддерживаются Delphi 5-7, Delphi 2005-2010 (и более новые) и Lazarus.
1) Распаковываем архив GLScene в нужную папку, например, С:\Borland\Delphi7\Source\GLScene.
2) Затем необходимо прописать пути к файлам GLScene. Для этого заходим в меню Tools -> Environment Options, переходим на вкладку Library и в Library path добавляем С:\Borland\Delphi7\Source\GLScene и все ее подпапки.
Сейчас нужно скопировать 4 dll из папок …GLScene\Source\PhysicsAPIs и …GLScene\Source\SoundAPIs в папку …:\Windows\system32.
Теперь ищем папку с пакетами для нужной версии Delphi и запускаем файлы GLScene.dpk (собственно Сцена) и GLSS_BASS.dpk, GLSS_FMOD.dpk, GLSS_OpenAL (поддержка звуковых библиотек BASS, FMOD и OpenAL), а в открывшихся окнах нажимаем кнопку "Compile" а потом "Install". Все, Сцена установлена.
Ее компоненты можно найти на вкладках GLScene (основные компоненты), GLScene PFX (эффекты), GLScene Utils (вспомогательные компоненты), GLScene Terrain (компоненты для создания земной поверхности) и GLScene Shaders (компоненты для шейдеров).
Создание
Нашей первой программой не будет "Hello World!", мы напишем небольшую сценой с самым простым ландшафтом и ходящем по нему персонажем.
Параметры объектов можете установить по вкусы, для примеры я поставил такие:
GLSceneViewer1-> Camera GLCamera2 (Главное окно просмотра, в нем мы и увидим наш мир)
Align alClient
GLNavigator1-> MovingObject DummyCube2 (Используем его для управлением нашем Актером)
UseVirtualUp True
VirtualUp X=0, Y=0, Z=1
GLUserInterface1-> GLNavigator GLNavigator1 (Для подключения мыши к упавлению)
MouseSpeed 20
GLCadencer1-> Scene GLScene1 (Главный таймер Сцены, будет обновлять сцену)
GLWaterPlane1-> Position X=-25, Y=-100, Z=-40 (Вода)
Scale X=2000, Y=2000, Z=2000
Elastic 5
RainForce 80
RainTimeInterval 1
Up X=0, Y=0, Z=1
GLLightSource1-> Position X=50, Y=50, Z=50 (Источник света)
DummyCube2-> Up X=0, Y=0, Z=1 (Пустой куб)
GLCamera1-> DepthOfView 1000 (Камера)
Up X=0, Y=1, Z=0

GLTerrainRenderer1 HeightDataSource GLBitmapHDS1 (Рендер земли, на вход нужно подать 2х цветную карту высот)
Material Texture-убрать галочку с Disable
Scale X=10, Y=10, Z=0,5
Up X=0, Y=1, Z=0
Ещё добавим DCE физику.


uses jpeg, tga, GLkeyboard, VectorGeometry,GLFile3DS, GLFilemd2;

// загружаем карту высот для нашей земли
GLBitmapHDS1.Picture.LoadFromFile('media\terrain.bmp');
// загружаем текстуру на землю
GLTerrainRenderer1.Material.Texture.Image.LoadFromFile('media\clover.jpg');

//Здесь мы загружаем части тела
Legs.LoadFromFile('.\model\lower.md3');
Torso.LoadFromFile('.\model\upper.md3');
Head.LoadFromFile('.\model\head.md3');

//Загружаем тэг лист, для корректного отображения частей модели
LegsTags:=TMD3TagList.Create;
LegsTags.LoadFromFile('.\model\lower.md3');
TorsoTags:=TMD3TagList.Create;
TorsoTags.LoadFromFile('.\model\upper.md3');
//Подгружаем тектсуру
LoadSkin('.\model\','default',Head,Torso,Legs,'.tga');
//Загрузка анимации

LoadQ3Anims(Legs.Animations,'.\model\animation.cfg','BOTH');
LoadQ3Anims(Legs.Animations,'.\model\animation.cfg','LEGS');
LoadQ3Anims(Torso.Animations,'.\model\animation.cfg','BOTH');
LoadQ3Anims(Torso.Animations,'.\model\animation.cfg','TORSO');

//Включаем циклическое повторение и активируем нужную анимацию
Legs.AnimationMode:=aamLoop;
Torso.AnimationMode:=aamLoop;
Legs.SwitchToAnimation('LEGS_IDLE');
Torso.SwitchToAnimation('TORSO_STAND');

GLUserInterface1.MouseLookActivate;

//Пишем в Cadencer Progress
//Суть движения такова, мы прикладываем силу к нашему Дамми кубу с моделью игрока и подключаем анимацию

if iskeydown(vk_escape)then close;

// обработка перемещения
setvector(v, 0, 0, 0);
if iskeydown(vk_shift)then spd:=180 else spd:=40;
if iskeydown('s') then addvector(v, affinevectormake(-1, 0, 0));
if iskeydown('w') then addvector(v, affinevectormake(1, 0, 0));
if iskeydown('a') then addvector(v, affinevectormake(0, 0, -1));
if iskeydown('d') then addvector(v, affinevectormake(0, 0, 1));

if iskeydown(vk_down) then GLGameMenu1.SelectNext;
if iskeydown(vk_up) then GLGameMenu1.SelectPrev;
if iskeydown(vk_return) then begin
case GLGameMenu1.Selected of
0: begin
GLGameMenu1.Visible:=false;
GLCadencer1.Enabled:=true;
end;
1: begin
GLFullScreenViewer1.Active:=true;
GLGameMenu1.Visible:=false;
end;
2:Close;
end;
end;

with GetOrCreateDCEDynamic(dc_player) do begin
if iskeydown(vk_space)then Jump(2, 10); // корявый прыжок
if(v[0]<>0)or(v[2]<>0)then
ApplyAccel(vectorscale(vectornormalize(v), spd));
end;

if m_turn then begin
adt:=0.2/(1+deltatime);
dw:=width div 2;
dh:=height div 2;
dc_player.Turn(adt*(mouse.CursorPos.X-dw));
GLCamera1.MoveAroundTarget(adt*(dh-mouse.CursorPos.Y), 0);
mouse.CursorPos:=point(dw, dh);
end;

// анимация
if(v[0]<>0)or(v[2]<>0)then begin
if legs.CurrentAnimation='LEGS_IDLE' then
legs.SwitchToAnimation('LEGS_WALK');
end
else
if legs.CurrentAnimation='LEGS_WALK' then
legs.SwitchToAnimation('LEGS_IDLE');

m1:=LegsTags.GetTransform('tag_torso',Legs.CurrentFrame);
m2:=LegsTags.GetTransform('tag_torso',Legs.NextFrameIndex);
Torso.Matrix:=InterpolateMatrix(m1,m2,Legs.CurrentFrameDelta);

m1:=TorsoTags.GetTransform('tag_head',Torso.CurrentFrame);
m2:=TorsoTags.GetTransform('tag_head',Torso.NextFrameIndex);
Head.Matrix:=InterpolateMatrix(m1,m2,Torso.CurrentFrameDelta);

m1:=TorsoTags.GetTransform('tag_weapon',Torso.CurrentFrame);
m2:=TorsoTags.GetTransform('tag_weapon',Torso.NextFrameIndex);
Weapon.Matrix:=InterpolateMatrix(m1,m2,Torso.CurrentFrameDelta);

GLSceneViewer1.Invalidate;

function TForm1.InterpolateMatrix(m1, m2: TMatrix; delta: single): TMatrix;
var
i,j : integer;
begin
// Используем для стыковки модели в каждом кадре
for j:=0 to 3 do
for i:=0 to 3 do
Result[i][j]:=m1[i][j]+(m2[i][j]-m1[i][j])*delta;
end;

procedure TForm1.FormMouseWheel(Sender: TObject; Shift: TShiftState;
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
begin
// Приблежение и отдаление колёсиком мыши
if wheeldelta > 0 then
glcamera1.AdjustDistanceToTarget(0.98)
else glcamera1.AdjustDistanceToTarget(1.02)
end;

procedure TForm1.GLFullScreenViewer1MouseWheel(Sender: TObject;
Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint;
var Handled: Boolean);
begin
if wheeldelta > 0 then
glcamera1.AdjustDistanceToTarget(0.98)
else glcamera1.AdjustDistanceToTarget(1.02)
end;


Заключение
В этом примере я некоторые вещи опустил, это те вещи каторые можно легко доделать в процессе написания. Статьи по теме можно поискать на glscene.ru и mir-games.ru
p.s. пока я готовил материал и писал эту статьи я начал делать мальнькую игрушку.
image

Категория: Статьи | Просмотров: 2172 | Добавил: De:Light | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Вы вошли как: Гость
09:17
Вы вошли как: Гость
Календарь
«  Январь 2011  »
ПнВтСрЧтПтСбВс
     12
3456789
10111213141516
17181920212223
24252627282930
31
Категории
Новости [11]
Статьи [23]
GLscene,Web Design,IT,etc...
Счетчик

Онлайн всего: 1
Гостей: 1
Пользователей: 0