Продолжаем рассматривать пример, который я начал в прошлом номере. Мы уже успели рассмотреть достаточно много новых функций, и сегодня наш запас немного увеличится. Главное - рассмотреть функции загрузки сцены и текстуры.
Рис 1. Пример формы
Сразу же переходим к делу. Начнём с загрузки сцены:
function TForm1.LoadScene: Boolean;
begin
if(OpenDialog1.Execute()) then
begin
FDirect3D.CreateMeshBuilder(FD3DMeshBuilder);
FD3DMeshBuilder.Load(PChar(OpenDialog1.FileName), nil,
D3DRMLOAD_FROMFILE, nil, nil);
FD3DMeshBuilder.SetPerspective(true);
ScaleScene(FD3DMeshBuilder, 10);
FDirect3D.CreateFrame(FD3DScene, FD3DMeshBuilderFrame);
FD3DMeshBuilderFrame.SetRotation(FD3DScene, 1, 0, 0, 0.1);
FD3DMeshBuilderFrame.AddVisual(FD3DMeshBuilder);
Result:=true;
Exit;
end;
Result:=false;
end;
На эту функцию, я уже ссылался в прошлом месяце, но не расписал её внутренности. Сегодня я сделаю это. Первая функция - CreateMeshBuilder создаёт новый объект сцены. В качестве параметра выступает ссылка на этот объект типа IDirect3DRMMeshBuilder, который будет создан. IDirect3DRMMeshBuilder умеет загружать сцены DirectX из файла, это как раз то, что нам сегодня нужно.
После создания объекта FD3DMeshBuilder, мы вызываем уго функцию Load. Она загружает сцену из файла. Первый параметр - имя файла DirectX сцены. Второй - позиция объекта, который нужно загрузить. Если этот параметр - 0, то загружаются все объекты, если не 0, то только указанный. Третий параметр - позиция загрузки. Если указан D3DRMLOAD_BYPOSITION, то используется второй параметр, для определения позиции загрузки. Флаг D3DRMLOAD_FROMFILE - означает, что загрузка происходит из файла. Четвёртый параметр - адрес функции, которая будет вызываться каждый раз, когда надо загрузить текстуру. Эта функция может отсутствовать, то есть можно указывать nil. Последний параметр - адрес данных передаваемых функции, указанной в предыдущем параметре. Если здесь 0, то функции ничего передаваться не будет.
SetPerspective - устанавливает перспективу сцены.
ScaleScene - моя процедура, которая масштабирует сцену. В ней ничего особенного нет, ты и сам сможешь с ней разобраться.
Далее, создаётся новая сцена (CreateFrame), которая разворачивается (SetRotation) и добавляется к общей сцене (AddVisual), на которой у нас уже есть камера и освещение.
Теперь рассмотрим процедуру загрузки текстуры:
function TForm1.LoadWrapTexture: Boolean;
var
D3DTexture: IDirect3DRMTexture;
begin
if (OpenDialog2.Execute()) then
begin
FDirect3D.LoadTexture(PChar(OpenDialog2.FileName), D3DTexture);
FD3DMeshBuilder.SetTexture(D3DTexture);
FD3DMeshBuilder.SetPerspective(true);
D3DTexture:=nil;
Result:=true;
Exit;
end;
Result := false;
end;
Функция LoadTexture - загружает текстуру из файла. Первый параметр - путь к файлу, из которого будет происходить загрузка. Второй параметр - имя объекта, куда будет загружена текстура.
FD3DMeshBuilder.SetTexture - устанавливает загруженную текстуру нашей сцене. Далее устанавливаю перспективу. После того, как текстура назначена сцене, её можно удалять (D3DTexture:=nil).
Прежде чем закончить, я хочу обратить твоё внимание на то, что при инициализации DirectDraw мы не меняли разрешение экрана. В оконных приложениях средствами DirectX этого делать нельзя. Ты можешь сначала изменить эти параметры с помощью WinAPI, а потом инициализировать оконный DirectX, который сможет прочитать эти значения и использовать в своём распоряжении.
Ещё одно замечание - мы не устанавливали уровень доступа с помощью SetCooperativeLevel. Этого также делать нельзя. Будь внимателен при работе с DirectX в окне. Далеко не все функции можно здесь использовать. Здесь не работают функции переключения страниц. Это связано с тем, что в окне DirectX использует ту же область памяти, что и GDI, а у GDI только одна поверхность и её изменять нельзя. Поэтому мы и подключали объект отсечения (IdirectDrawClipper), который следить за нашим приложением и учитывает окна GDI, которые находятся под нашим окном.
И последнее - нельзя использовать функцию FastBlt, которая быстрее всех копирует содержимое поверхности из одной области видеопамяти в другую.
Вот и всё. В остальном, идёт простое повторение уже рассмотренных функций, поэтому попробуй разобраться с ними сам. Хотя некоторые тонкости я опустил, чтобы не забивать голову лишними вещами. Но к ним мы ещё вернёмся. До новых встреч!!!