Конференция "Игры" » Загрузка техтуры из X -файла
 
  • Илья © (08.09.08 19:25) [0]
    Изучая DirectX столкнулся с проблемой загрузки текстуры из X-файла.
    Взял код загрузки из книги  М.Фленова :

    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;

    function LoadMesh(filename:String;
       ppiD3DDevice9:IDirect3DDevice9;
       var ppMesh:ID3DXMesh;
       var pMeshTextures: PAIDirect3DTexture9;
       texturefilename: String;
       var pMeshMaterials: PAD3DMATERIAL9):DWORD;

    implementation

    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;

    end.

    Далее в процедуре прорисовки отображаю сетку с материалами и текстурами:

    for i:= 0 to  NumMat-1 do
    begin
      ppiD3DDevice9.SetTexture(0,pMeshTextures[i]);
      D3DMesh.DrawSubset(i);
    end;

    NumMat - количество материалов
    Дело в том что в авторских исходниках все работает корректно,хотя код загрузки X-файла и загрузки текстуры ничем не различается(кроме того что он программирует без VCL).Дошло до того, что начал проверять
    по строкам - различий не нашел.С кодом разобрался, вроде все правильно и должно работать. Ну НЕ ЗНАЮ че ему надо, отключаю загрузку текстуры в функции LoadMesh Xфайл отображается, включаю комп виснет.Кто знает в чем проблема подскажите плиз.
  • Илья © (09.09.08 13:58) [1]
    Может кто кинет исходник с загрузкой текстуры из X файла?
  • Sapersky (09.09.08 14:43) [2]
    Вообще-то в самом X-файле никаких текстур нет (во всяком случае, на моей памяти не было), они должны присутствовать в виде отдельных файлов, обычно в той же папке.
  • Илья © (09.09.08 20:33) [3]
    Ну даа, в X Файле есть только ссылка на текстуру которая при экспорте в формат *.X сохраняется в папку с файлом сетки, да дело даж не в этом... Почему приложение виснет я не пойму(.Просматривал код загрузки на Си из книги "Франк Луна - Введение в программирование трехмерных игр с DX9" способ загрузки такой же...Может кто кинет ссылку на описание работоспособного кода загрузки?
  • Sapersky (10.09.08 15:35) [4]
    Рабочие исходники есть, очевидно, в составе примеров к DX9 SDK ( clootie.ru ).
    А так - пройди трассировкой, посмотри значения переменных; попробуй загрузить текстуры отдельно от меша; попробуй с другой моделью, в конце концов...
  • Elec3C © (11.09.08 04:09) [5]

    > Илья ©

    Ты код разбирал-то хоть или тупо скопипастил? Там, где комментарии поставил, там текстуры как раз и грузятся! У тебя же выходит так: массив текстур создал, но не загрузил в него текстуры и пытаемся рисовать пустой массив!
    P.S. Вот пример простой загрузки (сдк) : http://slil.ru/26133926
  • Илья © (11.09.08 07:15) [6]
    > Elec3C ©

    Нееее, фигурные скобки я поставил потому что без них виснет, а в процедуре прорисовки я убираю строку установки текстуры:
    for i:= 0 to  NumMat-1 do
    begin
     // ppiD3DDevice9.SetTexture(0,pMeshTextures[i]);
     D3DMesh.DrawSubset(i);
    end;

    Спасибо за исходник,ща гляну как правильно делать))
  • Илья © (11.09.08 10:46) [7]
    > Elec3C ©
    Попытки исправить загрузку текстуры X файла в функции LoadMesh не увенчались успехом.Решил написать код по новой ,опираясь на исходник SDK(http://slil.ru/26133926) .Вот что получилось:

    //используемые типы для загрузки
    type
    PAIDirect3DTexture9 = ^AIDirect3DTexture9;
    AIDirect3DTexture9 = array[0..0] of IDirect3DTexture9;

    PAD3DMaterial9 = ^AD3DMaterial9;
    AD3DMaterial9 = array [0..0] of TD3DMAterial9;

    PAD3DXMaterial = ^AD3DXMaterial;
    AD3DXMaterial = array [0..0]   of TD3DXMaterial;

    //функция загрузки
    procedure TMainForm.InitMesh;
    var
    matBuf : ID3DXBuffer;
    d3dxMaterials : PAD3DXMaterial;
    i : DWORD;
    begin
    if FAILED(D3DXLoadMeshFromX('X-file\1.x',D3DXMESH_SYSTEMMEM,Device,nil,@matBuf,nil,@NumMat,
                     D3DMesh)) then exit;

    d3dxMaterials:=matBuf.GetBufferPointer;

    GetMem(pMeshTextures,SizeOf(IDirect3DTexture9)*NumMat);
    GetMem(pMeshMaterials,sizeof(TD3DMaterial9)*NumMat);

    ZeroMemory(pMeshTextures,SizeOf(IDirect3DTexture9)*NumMat);

    i:=0;
    while i < NumMat do
    begin
     pMeshMaterials[i]:=d3dxMaterials[i].MatD3D;
     pMeshMaterials[i].Ambient:=pMeshMaterials[i].Diffuse;

     if FAILED(D3DXCreateTextureFromFile(Device,d3dxMaterials[i].pTextureFilename,
                                        pMeshTextures[i]))
     then
     if FAILED(D3DXCreateTextureFromFile(Device,'X-File\1.tga',
                                        pMeshTextures[i]))
     then
     pMeshTextures[i]:=nil;
     inc(i);
    end;
    end;

    //процедура прорисовки
    procedure TMainForm.Render;
    var
    i : DWORD;
    WorldMatrix,WorldMatrixY : TD3DMATRIX;
    begin
    Device.Clear(0,nil,D3DCLEAR_TARGET or D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,100,0),
                1.0,0);
    Angle:=Angle + 1;

    Device.BeginScene;

    D3DXMatrixRotationY(WorldMatrixY,Angle*pi/180);
    Device.SetTransform(D3DTS_WORLD,WorldMatrixY);

    i:=0;
    while  i < NumMat do
    begin
     Device.SetMaterial(pMeshMaterials[i]);
     Device.SetTexture(0,pMeshTextures[i]);
     D3DMesh.DrawSubset(i);
     inc(i)
    end;
    Device.EndScene;
    Device.Present(nil,nil,0,nil);
    end;

    X-файл (бокс с шахматной текстурой) я экспортировал из 3ds Max в папку
    X-file. Но следущая строка кода все равно не работает :

    D3DXCreateTextureFromFile(Device,d3dxMaterials[i].pTextureFilename,
                                        pMeshTextures[i]));

    Если явно указывать на текстуру (D3DXCreateTextureFromFile(Device,'X-File\1.tga',pMeshTextures[i])) ) то всё нормально;

    Эксперементировал с исходником - D3DXCreateTextureFromFile(Device,d3dxMaterials[i].pTextureFilename, pMeshTextures[i])) работает нормально. Ни че не пойму - код фактически одинаковый а результат разный.((
  • Sapersky (11.09.08 15:46) [8]
    Ну таки не совсем одинаковый. В примере перед загрузкой текстур есть ещё проверка на пустую строку:
    if (d3dxMaterials[i].pTextureFilename <> nil) and
      (StrLen(d3dxMaterials[i].pTextureFilename) > 0) then
  • Илья © (11.09.08 16:54) [9]
    >Sapersky
    Но ведь в исходнике это условие выполняется, значит должно все нормально загружаться(я поэтому и опустил эту проверку заранее зная что ее значение истинно,а значит и текстура есть).

    Я добавлял проверку этого условия в свой код -и  она ведь тоже завершается успешно,поскольку стоящие после условия операторы  тоже выполняются (в часности выполняется примитивная загрузка из графического файла 1.tga : D3DXCreateTextureFromFile(Device,'X-File\1.tga',
                                       pMeshTextures[i])  ), а она ,кстати ,может произойти только в том случае если условие
    FAILED(D3DXCreateTextureFromFile(Device,d3dxMaterials[i].pTextureFilename,
                                       pMeshTextures[i])) будет истинным.

    Получается что в исходнике строка D3DXCreateTextureFromFile(Device,d3dxMaterials[i].pTextureFilename,pMeshTextures [i]))  загружает текстуру Xфайла а у меня НЕТ; Понимаешь что я имею в виду? X файл то один а результаты разные.
  • Sapersky (11.09.08 18:04) [10]
    В общем случае проверять на пустую строку надо, текстура у материала вполне может отсутствовать.
    Судя по этому: 'X-file\1.x' X-файл и текстуры находятся в папке X-File, а в d3dxMaterials[i].pTextureFilename путь не указывается, просто имя файла.
  • Илья © (11.09.08 19:04) [11]
    > Sapersky

    Ну наконец-то!!!Всего то надо было к имени файла тексуры прибавить путь к папке,где она находится вместе с X файлом. Я то думал что DirectX автоматически добавляет этот путь , т.е загружает текстуру именно оттуда где находится X-файл. Спасибо за помощь! А то еще бы несколько дней...
    и пришлось бы бится головой о стену)))
 
Конференция "Игры" » Загрузка техтуры из X -файла
Есть новые Нет новых   [134430   +4][b:0][p:0.001]