Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как загрузить несколько .Х файлов?  (Прочитано 9032 раз)
0 Пользователей и 1 Гость смотрят эту тему.
simai
Гость
« : 12-04-2010 17:16 » 

Без проблем загружается один .х-файл (код Делфийный):

Код:
Result := D3DXLoadMeshFromX(PChar(FileName), D3DXMESH_SYSTEMMEM, FD3DDevice,
                            nil, @FpD3DXMaterialBuffer, nil,
                            @NumMaterials, FppMesh);

а так же несколько "меш"-й (при условии, что переменные FppMesh1, FppMesh2 ...FppMesh_n объявлены, например, в секции private:

Код:
private
    FppMesh1,
    FppMesh2,
...
    FppMesh_n: ID3DXMesh;
...

      case smth of
        1: Result := D3DXLoadMeshFromX(PChar(FileName), D3DXMESH_SYSTEMMEM, FD3DDevice,
                                       nil, @FpD3DXMaterialBuffer, nil,
                                       @NumMaterials, FppMesh1);

        2: Result := D3DXLoadMeshFromX(PChar(FileName), D3DXMESH_SYSTEMMEM, FD3DDevice,
                                       nil, @FpD3DXMaterialBuffer, nil,
                                       @NumMaterials, FppMesh2);
...

        n: Result := D3DXLoadMeshFromX(PChar(FileName), D3DXMESH_SYSTEMMEM, FD3DDevice,
                                       nil, @FpD3DXMaterialBuffer, nil,
                                       @NumMaterials, FppMesh_n);
      end;
...
  Result := FppMesh1.DrawSubset(0);
  Result := FppMesh2.DrawSubset(0);
...
  Result := FppMesh_n.DrawSubset(0);

Вопрос состоит в следующем: как сделать тоже самое (загрузить несколько "меш"-ей), только без объявления переменных FppMesh1 - FppMesh_n?

Я пробовал вот так:
Код:
  private
  ...
    FppMesh: ID3DXMesh;
    FppMeshList: TList;
    p: Pointer;
  ...
     
     for i := 1 to N do begin
Result := D3DXLoadMeshFromX(PChar(FileName), D3DXMESH_SYSTEMMEM, FD3DDevice,
                      nil, @FpD3DXMaterialBuffer, nil,
              @NumMaterials, FppMesh);
FppMeshList.Add(pointer(FppMesh));
     end;
...

     for i := 0 to FppMeshList.Count-1 do begin
        p := FppMeshList.Items[i];
Result := ID3DXMesh(p).DrawSubset(0);
     end;

В этом случае "показывается" только последний "меш", хотя при загрузке (см. цикл "for i := 1 to N do begin") в переменной FppMesh были различные значеня адреса (я проверял).

Хотя и в случае использования "n" переменных FppMesh1 - FppMesh_n не все так гладко - показываются только два первых "меш"-а, но я думаю, что в моей программе где-то ошибка (искать - нет времени)...

Меня больше интересует как "победить" коллекцию интерфейсов FppMeshList? Или (мой вопрос) в более общем виде - как "загрузить" несколько "меш"-й, что бы потом можно было манипулировать (перемещать, поворачивать, масштабировать, "зеркАлить") кажды "меш" отдельно?
Записан
zubr
Гость
« Ответ #1 : 12-04-2010 20:23 » 

Ну дык а FileName для всех FppMesh одинаков...
Записан
simai
Гость
« Ответ #2 : 12-04-2010 20:51 » 

For zubr:
Не придирайся, я написал в общем, не детализируя. Хотя мысль ты интересную подал. Я думаю, что должно работать и для одинаковых .х-файлов. В первоначальной картинке, должен быть виден один объект (поскольку он "совпадает" с остальными). С помощью поворота и переноса (а еще лучше и с материалами разных цветов) - одинаковые картинки можно развести в разные стороны. Но у меня (если быть точным), написано где-то так:
Код:
...
var FileName: array of String;
...
N := ...;
SetLength(FileName,N);
...
for i := 0 to N-1 do
  Result := D3DXLoadMeshFromX(PChar(FileName[i]), D3DXMESH_SYSTEMMEM, FD3DDevice,
                              nil, @FpD3DXMaterialBuffer, nil,
                              @NumMaterials, FppMesh);
Записан
zubr
Гость
« Ответ #3 : 12-04-2010 21:02 » 

Хмм...
Попробуй:
Код:
var
  FppMesh: ^ID3DXMesh;

  New(FppMesh);
  for i := 0 to N-1 do
  Result := D3DXLoadMeshFromX(PChar(FileName[i]), D3DXMESH_SYSTEMMEM, FD3DDevice,
                              nil, @FpD3DXMaterialBuffer, nil,
                              @NumMaterials, FppMesh^);
  FppMeshList.Add(FppMesh);
Записан
simai
Гость
« Ответ #4 : 12-04-2010 22:38 » new

Не, тут не так все просто (точнее не очень сложно, но и не тривиально). Все дело, оказывается в ссылках, которые ДОБАВЛЯБТСЯ, когда интерфейсом начинают пользоваться и УДАЛЯЮТСЯ (например, при завершении программы, иначе винда будет ругаться) - это мне тока что на другом форуме подсказали. Приведу рабочий код (уже проверил) для завершенности темы:

Добавляем пару внеклассовых функций:
Код:
function RefIUnknown(const Intf: IUnknown): Pointer;
begin
  Intf._AddRef;               // Increment the reference count.
  Result := Pointer(Intf);    // Save the interface pointer.
end;
 
// Release the interface whose value is stored in the pointer P.
procedure ReleaseIUnknown(P: Pointer);
var
  Intf: IUnknown;
begin
  Pointer(Intf) := P;
  // Delphi releases the interface when Intf goes out of scope.
end;

Соответственно
Загрузка "меш"-а:
Код:
    FppMesh: ID3DXMesh;
    FppMeshList: TList;
    p: Pointer;
    for i := 1 to N do begin
       ... D3DXLoadMeshFromX(..., FppMesh);

       FppMeshList.Add(RefIUnknown(FppMesh as IUnknown));
     end;

Работа с "меш"-ем:
Код:
 for i := 0 to FppMeshList.Count-1 do begin
        p := FppMeshList.Items[i];
        FppMesh := IUnknown(p) as ID3DXMesh;
        FppMesh.DrawSubset(0);

Удаление (например на закрытие формы - я у себя так сделал):
 
Код:
for i := 0 to FppMeshList.Count-1 do begin
        p := FppMeshList.Items[i];
        ReleaseIUnknown(p);
 end;

 Вот, собственно, и фсё...
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines