Такая проблема: при создании буфера вершин программа вылетает с acces violation. Код (на дельфи) такой:
procedure PrepareVBuffer; begin pDevice.CreateVertexBuffer(SizeOf(sVertexRHW)*4,0, D3DFVF_XYZRHW or D3DFVF_TEX1,D3DPOOL_DEFAULT,vBuffer,nil); end;
где
vBuffer: IDirect3DVertexBuffer9;
а sVertex задается так:
type sVertexRHW = record x,y,z,RHW: single; u,v: single; end;
Где я ошибся? Видимо где то с указателями.
Не должон.
pD3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Window,
D3DCREATE_MIXED_VERTEXPROCESSING, @d3dpp, pDevice)Если что-то не так, я программно выкидываю из приложения.
acces violation --- проверь указатели все..... пользуйся дебагером
В дельфи давно не писал, так что за орфографию не ручаюсь)
1) обязательно вначале инициализировать все D3D объекты в nil, чтобы потом можно было проверять. Т.е. pDevice := nil; vBuffer = nil; и т.д.
2) в D3DCREATE_MIXED_VERTEXPROCESSING есть реальная необходимость? если нет, используй HARDWARE
3) просто немного проверок:
var
hRet : HRESULT;
begin
pDevice := nil;
vBuffer := nil;
...
hRet = pD3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Window,
D3DCREATE_HARDWARE_VERTEXPROCESSING, @d3dpp, pDevice)
if (hRet<>D3D_OK) then
begin
ShowMessage("CreateDevice failed; hRet = " + intToStr(hRet) );
end;
if(pDevice <> nil) then
begin
hRet = pDevice.CreateVertexBuffer(SizeOf(sVertexRHW)*4,0, D3DFVF_XYZRHW or D3DFVF_TEX1,D3DPOOL_DEFAULT,vBuffer,nil);
if (hRet<>D3D_OK) then
begin
ShowMessage("CreateVertexBuffer failed; hRet = " + intToStr(hRet) );
end;
end;
end;
4) вывести описание кода ошибки (hRet) через DirectX Error Lookup (поставляется с SDK)
Это из моего проекта - работает 100%
type
TCustomVertex = packed record
x, y, z: Single; // The untransformed, 3D position for the vertex
// RHW:single;
nx, ny, nz: Single;
color: SINGLE; // The vertex color
tu,tv: Single; // The texture coordinates
end;
type
TMyIndex = packed record // индексы для рисования связанных треугольников
v1,v2,v3:word;
end;
const
D3DFVF_CUSTOMVERTEX = (D3DFVF_XYZ or D3DFVF_NORMAL or D3DFVF_DIFFUSE or D3DFVF_TEX1);// ); D3DFVF_XYZ or D3DFVF_NORMAL or D3DFVF_TEX1;
//---------------------
procedure TForm1.initvertex;
var
pvertices:pointer;
hRet : HRESULT;
begin
hRet:= (g_pd3dDevice.CreateVertexBuffer(SizeOf(TCustomVertex)*MaxTrModel,
0, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, g_pVB, nil));
if FAILED(hret) then ErrorOut(hRet,'Not CreateVertexBuffer');
if FAILED(g_pVB.Lock(0, 0, pvertices, D3DLOCK_DISCARD)) then ErrorOut(hRet,'Not Lock');
CopyMemory(pvertices, addr(MyModel_1[0]), SizeOf(TCustomVertex)*MaxTrModel);
g_pVB.Unlock;
hRet:= (g_pd3dDevice.CreateIndexBuffer(SizeOf(TMyIndex)*MaxMyIndex, 0,D3DFMT_INDEX16, D3DPOOL_MANAGED, g_pIB, nil));
if FAILED(hret) then ErrorOut(hRet,'Not CreateIndexBuffer');
if FAILED(g_pIB.Lock(0, 0, pvertices, D3DLOCK_DISCARD)) then ErrorOut(hRet,'Not Lock');
CopyMemory(pvertices, addr(MyIndex[0]), SizeOf(TMyIndex)*MaxMyIndex);
g_pIB.Unlock;
hRet:=(g_pd3dDevice.SetStreamSource(0,g_pVB,0,(SizeOf(TCustomVertex))));
if FAILED(hret) then ErrorOut(hRet,'Not SetStreamSource');
hRet:=(g_pd3dDevice.SetIndices(g_pIB));
if FAILED(hret) then ErrorOut(hRet,'Not SetIndices');
g_pd3dDevice.SetFVF(D3DFVF_CUSTOMVERTEX); // выход с ошибкой надо както освободить
end;
Ты похоже забыл про Lock и Unlock
("пацаны, засада -- они фигурные скобки вместо человеческих begin и end используют") :)
> color: SINGLE; // The vertex color
>D3DFVF_DIFFUSE
Ке-ке-ке.
Корован Историй
Это тестовый проект, догадайся, скока ему лет? - Хе-хе-хе.
DimaO
Я плохо знаком с синтаксисом паскаля, но в функцию CreateVertexBuffer вроде должен передаваться указатель на указатель, для сохранения указателя на созданый VB.
Black Angel
Для дельфи такой синтаксис нормален.
Автору поста я бы предложил-таки проверить, создался ли девайс вообще, или нет. Если не создался, то ясен пень пытаться вызывать CreateVertexBuffer на нем низя.
Спасибо за советы. Ваша правда. Видимо алгоритм не правильно проверял создание устройства.
pD3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Window,
D3DCREATE_HARDWARE_VERTEXPROCESSING, @d3dpp, pDevice)не создает устройство. Это может быть из-за кривого заполнения структуры PD3DPRESENT_PARAMETERS?
DimaO
Коннечно может. - вот мое:
if (g_pD3D=nil) then g_pD3D:=Direct3DCreate9(D3D_SDK_VERSION);
if (g_pD3D=nil) then begin
ErrorOut(hRet,'Error = Direct3DCreate9(D3D_SDK_VERSION)');
exit;
end;
if g_pd3dDevice=nil then begin
// if FAILED(g_pD3D.GetAdapterDisplayMode(D3DADAPTER_DEFAULT, d3ddm)) then ErrorOut(hRet,'Error = GetAdapterDisplayMode');
ZeroMemory(@d3ddm, SizeOf(d3ddm));
d3ddm.Width:=screenwidth;
d3ddm.Height:=screenheight;
d3ddm.Format:= D3DFMT_X8R8G8B8;
ZeroMemory(@d3dpp, SizeOf(d3dpp));
d3dpp.Windowed := false;
d3dpp.SwapEffect := D3DSWAPEFFECT_DISCARD;//discar copy
d3dpp.HDeviceWindow:=Handle;
d3dpp.BackBufferFormat := d3ddm.Format;
d3dpp.BackBufferWidth:=d3ddm.Width;
d3dpp.BackBufferHeight:=d3ddm.Height;
d3dpp.FullScreen_RefreshRateInHz:=d3ddm.RefreshRate;
D3DPP.BackBufferCount:=1;
d3dpp.EnableAutoDepthStencil := true;
d3dpp.AutoDepthStencilFormat :=D3DFMT_D16;
d3dpp.PresentationInterval :=D3DPRESENT_INTERVAL_IMMEDIATE;//immediate // D3DCREATE_MULTITHREADED
d3dpp.flags:=0;
d3dpp. MultiSampleType:=D3DMULTISAMPLE_4_SAMPLES;
d3dpp. MultiSampleQuality:=0;
// g_pd3dDevice.TestCooperativeLevel ;
if FAILED(g_pD3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
Handle ,
D3DCREATE_FPU_PRESERVE or D3DCREATE_MULTITHREADED or D3DCREATE_HARDWARE_VERTEXPROCESSING, //D3DCREATE_FPU_PRESERVE or D3DCREATE_MULTITHREADED
d3dpp,
g_pd3dDevice)) then ErrorOut(hRet,'Error = CreateDevice');
end;
JR-44
>Это из моего проекта - работает 100%
>Это из моего проекта - работает 100%
>Это из моего проекта - работает 100%
Худей, бро.
DimaO
>Это может быть из-за кривого заполнения структуры PD3DPRESENT_PARAMETERS?
Причина скорее всего в этом. И да, мой тебе совет, не слушай JR-44. Никогда :D
Корован Историй
Очень остроумно. У нас появился Билл Гейтс?
Извините за беспокойство. Кажется моя вина. d3dpp - это указатель, следовательно сначала нужно память под него освободить
GetMem(d3dpp,SizeOf(_D3DPRESENT_PARAMETERS_));
Тема в архиве.