ПрограммированиеФорумОбщее

Сбой при загрузке меша

#0
23:05, 14 янв 2012

Доброго времени суток! Возможно мой вопрос покажется несколько глупым, однако я новичок в этом деле. у меня есть рабочая ф-ция отрисовки меша. Мне необходимо засунуть ее в класс. Вот как я сделал:

//Mesh.cpp
HRESULT Mesh::LoadMesh(LPCSTR fileName)
{
  LPD3DXBUFFER pMaterialBuffer;

  if(FAILED(D3DXLoadMeshFromX(fileName, D3DXMESH_SYSTEMMEM, pDirect3DDevice, NULL, &pMaterialBuffer, NULL, &numOfMaterials, &pMesh)))
  {
    MessageBox(NULL, "Could not find model", "Fatal error", MB_OK|MB_ICONEXCLAMATION);
    return E_FAIL;
  }

  D3DXMATERIAL* d3dxMaterial = (D3DXMATERIAL*)pMaterialBuffer->GetBufferPointer();
  meshMaterials = new D3DMATERIAL9[numOfMaterials];
  if(meshMaterials == NULL)
    return E_OUTOFMEMORY;
  meshTextures = new LPDIRECT3DTEXTURE9[numOfMaterials];
  if(meshTextures == NULL)
    return E_OUTOFMEMORY;

  for(DWORD i = 0; i < numOfMaterials; i++)
  {
    meshMaterials[i] = d3dxMaterial[i].MatD3D;
    meshMaterials[i].Ambient = meshMaterials[i].Diffuse;

    meshTextures[i] = NULL;
    if(d3dxMaterial->pTextureFilename != NULL && lstrlenA(d3dxMaterial[i].pTextureFilename) > 0)
      if(FAILED(D3DXCreateTextureFromFileA(pDirect3DDevice, d3dxMaterial[i].pTextureFilename, &meshTextures[i])))
      {
        MessageBox(NULL, "Could not find texture map", "Fatal error", MB_OK|MB_ICONEXCLAMATION);
        return E_FAIL;
      }
  }
  
  pMaterialBuffer->Release();

  if(!(pMesh->GetFVF() & D3DFVF_NORMAL)) //вычисляем нормали для меша
  {
    ID3DXMesh* pTempMesh = 0;
    pMesh->CloneMeshFVF(D3DXMESH_MANAGED, pMesh->GetFVF() | D3DFVF_NORMAL, pDirect3DDevice, &pTempMesh);
    D3DXComputeNormals(pTempMesh, 0);

    pMesh->Release();
    pMesh = pTempMesh;
  }

  return S_OK;
}
//Mesh.h
Mesh(LPDIRECT3DDEVICE9 device);
  ~Mesh();
  HRESULT LoadMesh(LPCSTR fileName);
  LPD3DXMESH GetMesh();
  void DrawMesh();
private:
  D3DMATERIAL9* meshMaterials;
  LPDIRECT3DTEXTURE9* meshTextures;
  LPD3DXMESH pMesh;
  DWORD numOfMaterials;
  LPDIRECT3DDEVICE9 pDirect3DDevice;
//главный файл - где я вызываю ф-цию
HRESULT InitBall()
{
  if(FAILED(m_meshBall.LoadMesh("models/ball.x")))
    return E_FAIL;

  ball = new Ball(0.01f, meshBall);
  ball->SetGravity();
  
  return S_OK;
}
//кусок опущен
if (SUCCEEDED(InitialDX(hWnd))) 
    {
    if(SUCCEEDED(InitBall()))
    {
      ShowWindow(hWnd, nShowCmd);    // Вывод окна 
      UpdateWindow(hWnd);   // Обновление окна 
//далее код опущен

Ф-ция вылетает с ошибкой "Could not find model". Я не понимаю почему - ведь если она не в отдельном классе, то все работает.
ЗЫ: все бы ничего, да только я пытался многие ф-ции из главного файла перенести в классы, но та же проблема. Ни инициализацию директа, ни WinMain - ничего не выходит. Искал в интернете как реализовать, читал книгу, но все-равно что-то не доходит в чем проблема. Помогите разобраться пожалуйста!
Заранее спасибо.

#1
1:07, 15 янв 2012

maked0n
> if(FAILED(D3DXLoadMeshFromX(fileName, D3DXMESH_SYSTEMMEM, pDirect3DDevice,
> NULL, &pMaterialBuffer, NULL, &numOfMaterials, &pMesh)))

посмотри что возвращает функция D3DXLoadMeshFromX вот так:

HRESULT hr;
hr = D3DXLoadMeshFromX(fileName, D3DXMESH_SYSTEMMEM, pDirect3DDevice,
NULL, &pMaterialBuffer, NULL, &numOfMaterials, &pMesh);


>Return Values
>If the function succeeds, the return value is D3D_OK. If the function fails, the return value can be one of the following values: D3DERR_INVALIDCALL, E_OUTOFMEMORY.

и в ключи Debug версию DirectX в DirectX Control Panel, может быть что покажет в Output.

#2
12:37, 15 янв 2012

Ф-ция возвращает D3DERR_INVALIDCALL.  Debug включил, вывело MessageBox: "Исключение unknown software exception (0x80000003) в приложении по адресу 0x7c90120e".

#3
15:01, 15 янв 2012

а D3D инициализируется до того как грузится мешь?

#4
19:42, 15 янв 2012
HRESULT InitBall()
{
  if(FAILED(m_meshBall.LoadMesh("models/ball.x")))
    return E_FAIL;

  ball = new Ball(0.01f, meshBall);
  ball->SetGravity();
  
  return S_OK;
}
//кусок опущен
if (SUCCEEDED(InitialDX(hWnd))) 
    {
    if(SUCCEEDED(InitBall()))
    {
//код далее опущен

Да.

#5
10:12, 16 янв 2012

эм...  помоему нужно писать полный путь до модели.
сказать точно немогу я щас не с пк.

#6
18:35, 16 янв 2012

Dzhekson6000
нет, не нужно - эта ф-ция работает, если не находиться в отдельном классе.

#7
6:42, 17 янв 2012

maked0n
Сейчас я посмотрел. У меня используется полный путь до файла.

    char lpBuffer[250] = {0};
    strcat(lpBuffer,"E:\\Documents and Settings\\User\\Мои документы\\Visual Studio 2010\\Projects\\1\\Debug");
    strcat(lpBuffer,"\\");
    strcat(lpBuffer,models);

    if( FAILED( D3DXLoadMeshFromX(lpBuffer, D3DXMESH_SYSTEMMEM,
               dev, NULL,
               &pMeshBuffer, NULL, &dwNumber,
               &meshob ) ) )
       {MessageBox( NULL, "Could not load .x file", "Error", MB_OK );}

попробуй.
Потом можешь использовать функцию GetCurrentDirectory, но при отладки она криво работает

#8
20:38, 17 янв 2012

Dzhekson6000
переписал вот так:

if(FAILED(m_meshBall.LoadMesh("C:\\Documents and Settings\\maked0n\\Мои документы\\Visual Studio 2010\\Projects\\ballance2\\Release\\models\\ball.x")))
    return E_FAIL;

все-равно не работает. та же ошибка

#9
21:30, 17 янв 2012

Если будут 2 полных текста программы (1 - как работало, 2 - как не работает), то тут люди разберутся почти сразу.

#10
21:41, 17 янв 2012

как НЕ работает - самый первый пост, а вот как работало(та же самая ф-ция, только не в классе):

HRESULT LoadMesh()
{
        LPD3DXBUFFER pMaterialBuffer;

  HRESULT hr = D3DXLoadMeshFromX("models/ball.x", D3DXMESH_SYSTEMMEM, pDirect3DDevice, NULL, &pMaterialBuffer, NULL, &numOfMaterials, &pMesh);
  if(hr == E_OUTOFMEMORY)
  {
    MessageBox(NULL, "Could not find model", "E_OUTOFMEMORY", MB_OK|MB_ICONEXCLAMATION);
    return E_FAIL;
  }
  else if(hr == D3DERR_INVALIDCALL)
  {
    MessageBox(NULL, "Could not find model", "D3DERR_INVALIDCALL", MB_OK|MB_ICONEXCLAMATION);
    return E_FAIL;
  }

  D3DXMATERIAL* d3dxMaterial = (D3DXMATERIAL*)pMaterialBuffer->GetBufferPointer();
  meshMaterials = new D3DMATERIAL9[numOfMaterials];
  if(meshMaterials == NULL)
    return E_OUTOFMEMORY;
  meshTextures = new LPDIRECT3DTEXTURE9[numOfMaterials];
  if(meshTextures == NULL)
    return E_OUTOFMEMORY;

  for(DWORD i = 0; i < numOfMaterials; i++)
  {
    meshMaterials[i] = d3dxMaterial[i].MatD3D;
    meshMaterials[i].Ambient = meshMaterials[i].Diffuse;

    meshTextures[i] = NULL;
    if(d3dxMaterial->pTextureFilename != NULL && lstrlenA(d3dxMaterial[i].pTextureFilename) > 0)
      if(FAILED(D3DXCreateTextureFromFileA(pDirect3DDevice, d3dxMaterial[i].pTextureFilename, &meshTextures[i])))
      {
        MessageBox(NULL, "Could not find texture map", "Fatal error", MB_OK|MB_ICONEXCLAMATION);
        return E_FAIL;
      }
  }
  
  pMaterialBuffer->Release();

  if(!(pMesh->GetFVF() & D3DFVF_NORMAL)) //вычисляем нормали для меша
  {
    ID3DXMesh* pTempMesh = 0;
    pMesh->CloneMeshFVF(D3DXMESH_MANAGED, pMesh->GetFVF() | D3DFVF_NORMAL, pDirect3DDevice, &pTempMesh);
    D3DXComputeNormals(pTempMesh, 0);

    pMesh->Release();
    pMesh = pTempMesh;
  }

  return S_OK;
}

в классе все использующиеся переменные(кроме локальных) объявлены как private-члены, а во втором варианте просто в начале как обычные глобальные переменные.

#11
22:37, 17 янв 2012

как pDirect3DDevice в класс передаётся?

#12
0:10, 18 янв 2012

Dzhekson6000
в конструкторе

Mesh::Mesh(LPDIRECT3DDEVICE9 device)
{
  meshMaterials = 0;
  meshTextures = 0;
  numOfMaterials = 0L;
  pMesh = 0;
  pDirect3DDevice = device;
}
ПрограммированиеФорумОбщее

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