ПрограммированиеФорумГрафика

Проблемы с CreateVertexBuffer

#0
20:17, 6 июля 2009

Такая проблема: при создании буфера вершин программа вылетает с 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;

Где я ошибся? Видимо где то с указателями.

#1
20:51, 6 июля 2009

Не должон.

pD3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Window,
        D3DCREATE_MIXED_VERTEXPROCESSING, @d3dpp, pDevice)

Если что-то не так, я программно выкидываю из приложения.

#2
22:36, 6 июля 2009

acces violation --- проверь указатели все..... пользуйся дебагером

#3
11:27, 7 июля 2009

В дельфи давно не писал, так что за орфографию не ручаюсь)

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)

#4
11:33, 7 июля 2009

Это из моего проекта - работает 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;

#5
11:34, 7 июля 2009

Ты похоже забыл про Lock и Unlock
("пацаны, засада -- они фигурные скобки вместо человеческих begin и end используют") :)

#6
14:22, 7 июля 2009

> color: SINGLE; // The vertex color
>D3DFVF_DIFFUSE
Ке-ке-ке.

#7
14:59, 7 июля 2009

Корован Историй
Это тестовый проект, догадайся, скока ему лет? - Хе-хе-хе.

#8
15:11, 7 июля 2009

DimaO
Я плохо знаком с синтаксисом паскаля, но в функцию CreateVertexBuffer вроде должен передаваться указатель на указатель, для сохранения указателя на созданый VB.

#9
15:59, 7 июля 2009

Black Angel
Для дельфи такой синтаксис нормален.

Автору поста я бы предложил-таки проверить, создался ли девайс вообще, или нет. Если не создался, то ясен пень пытаться вызывать CreateVertexBuffer на нем низя.

#10
17:29, 7 июля 2009

Спасибо за советы. Ваша правда. Видимо алгоритм не правильно проверял создание устройства.

pD3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Window,
        D3DCREATE_HARDWARE_VERTEXPROCESSING, @d3dpp, pDevice)

не создает устройство. Это может быть из-за кривого заполнения структуры PD3DPRESENT_PARAMETERS?

#11
17:38, 7 июля 2009

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;

#12
17:40, 7 июля 2009

JR-44
>Это из моего проекта - работает 100%
>Это из моего проекта - работает 100%
>Это из моего проекта - работает 100%
Худей, бро.

DimaO
>Это может быть из-за кривого заполнения структуры PD3DPRESENT_PARAMETERS?
Причина скорее всего в этом. И да, мой тебе совет, не слушай JR-44. Никогда :D

#13
17:44, 7 июля 2009

Корован Историй
Очень остроумно. У нас появился Билл Гейтс?

#14
18:15, 7 июля 2009

Извините за беспокойство. Кажется моя вина. d3dpp - это указатель, следовательно сначала нужно память под него освободить

GetMem(d3dpp,SizeOf(_D3DPRESENT_PARAMETERS_));
ПрограммированиеФорумГрафика

Тема в архиве.