-
Изучая 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файл отображается, включаю комп виснет.Кто знает в чем проблема подскажите плиз. -
Может кто кинет исходник с загрузкой текстуры из X файла?
-
Sapersky (09.09.08 14:43) [2]Вообще-то в самом X-файле никаких текстур нет (во всяком случае, на моей памяти не было), они должны присутствовать в виде отдельных файлов, обычно в той же папке.
-
Ну даа, в 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 -
> Elec3C ©
Нееее, фигурные скобки я поставил потому что без них виснет, а в процедуре прорисовки я убираю строку установки текстуры:
for i:= 0 to NumMat-1 do
begin
// ppiD3DDevice9.SetTexture(0,pMeshTextures[i]);
D3DMesh.DrawSubset(i);
end;
Спасибо за исходник,ща гляну как правильно делать)) -
> 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 -
>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 путь не указывается, просто имя файла. -
> Sapersky
Ну наконец-то!!!Всего то надо было к имени файла тексуры прибавить путь к папке,где она находится вместе с X файлом. Я то думал что DirectX автоматически добавляет этот путь , т.е загружает текстуру именно оттуда где находится X-файл. Спасибо за помощь! А то еще бы несколько дней...
и пришлось бы бится головой о стену)))