Sign in to follow this  
Tiege

DrawSubset Problem

Recommended Posts

So my code is crap. I just want an animated x file to load and render. I tried avoided skinning, materials, textures, bones, because I'm hoping I can just get a dark figure to load on the screen and walk without them.

When my program reaches:

pDrawMesh->DrawSubset(iMaterial);

I get a memory error (Access violation)

The values of my MeshContainer at this point:
[img]http://img508.imageshack.us/img508/9163/errorsl.jpg[/img]


Maybe you can find whats obviously wrong with my code.
(Note: I really have little idea what good Rendering functions to draw the meshes should look like)

my CAllocateHierarchy:
[code]

#include "Utilities.h"

/********************************ANIMATION***************************************/
LPD3DXFRAME pFrameRoot = NULL;
LPD3DXANIMATIONCONTROLLER pAnimController = NULL;

class CAllocateHierarchy : public ID3DXAllocateHierarchy
{
public:
STDMETHOD( CreateFrame )( THIS_ LPCSTR Name, LPD3DXFRAME *ppNewFrame );
STDMETHOD( CreateMeshContainer )( THIS_
LPCSTR Name,
CONST D3DXMESHDATA *pMeshData,
CONST D3DXMATERIAL *pMaterials,
CONST D3DXEFFECTINSTANCE *pEffectInstances,
DWORD NumMaterials,
CONST DWORD *pAdjacency,
LPD3DXSKININFO pSkinInfo,
LPD3DXMESHCONTAINER *ppNewMeshContainer );
STDMETHOD( DestroyFrame )( THIS_ LPD3DXFRAME pFrameToFree );
STDMETHOD( DestroyMeshContainer )( THIS_ LPD3DXMESHCONTAINER pMeshContainerBase );

CAllocateHierarchy()
{
}
};

HRESULT CAllocateHierarchy::CreateFrame( LPCSTR Name, LPD3DXFRAME* ppNewFrame )
{
D3DXFRAME* pFrame;

*ppNewFrame = NULL;

pFrame = new D3DXFRAME;

// copy name
if (Name != NULL)
{
pFrame->Name = new char[strlen(Name) + 1];
strcpy(pFrame->Name, Name);
}

D3DXMatrixIdentity( &pFrame->TransformationMatrix );

pFrame->pMeshContainer = NULL;
pFrame->pFrameSibling = NULL;
pFrame->pFrameFirstChild = NULL;

*ppNewFrame = (D3DXFRAME*)pFrame;
pFrame = NULL;

return S_OK;
}

HRESULT CAllocateHierarchy::CreateMeshContainer(
LPCSTR Name,
CONST D3DXMESHDATA *pMeshData,
CONST D3DXMATERIAL *pMaterials,
CONST D3DXEFFECTINSTANCE *pEffectInstances,
DWORD NumMaterials,
CONST DWORD *pAdjacency,
LPD3DXSKININFO pSkinInfo,
LPD3DXMESHCONTAINER *ppNewMeshContainer )
{

D3DXMESHCONTAINER *pMeshContainer = NULL;
LPDIRECT3DDEVICE9 pd3dDevice = NULL;
LPD3DXMESH pMesh = NULL;

int NumFaces;

*ppNewMeshContainer = NULL;

pMesh = pMeshData->pMesh;

pMesh->GetDevice( &pd3dDevice );

NumFaces = pMesh->GetNumFaces();

pMeshContainer = new D3DXMESHCONTAINER;

pMeshContainer->MeshData.pMesh = pMesh;
pMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH;

pMeshContainer->NumMaterials = max( 1, NumMaterials );
pMeshContainer->pMaterials = new D3DXMATERIAL[pMeshContainer->NumMaterials];
//pMeshContainer->ppTextures = new LPDIRECT3DTEXTURE9[pMeshContainer->NumMaterials];
pMeshContainer->pAdjacency = new DWORD[NumFaces*3];


memset( &pMeshContainer->pMaterials[0].MatD3D, 0, sizeof( D3DMATERIAL9 ) );
pMeshContainer->pMaterials[0].MatD3D.Diffuse.r = 0.0f;
pMeshContainer->pMaterials[0].MatD3D.Diffuse.g = 0.5f;
pMeshContainer->pMaterials[0].MatD3D.Diffuse.b = 0.3f;
pMeshContainer->pMaterials[0].MatD3D.Specular = pMeshContainer->pMaterials[0].MatD3D.Diffuse;

pd3dDevice->Release();

*ppNewMeshContainer = pMeshContainer;
pMeshContainer = NULL;

if( pMeshContainer != NULL )
DestroyMeshContainer( pMeshContainer );

return S_OK;
}
/*
HRESULT CAllocateHierarchy::DestroyFrame( LPD3DXFRAME pFrameToFree )
{
//delete[] pFrameToFree->Name;
//delete pFrameToFree;
return S_OK;
}

HRESULT CAllocateHierarchy::DestroyMeshContainer( LPD3DXMESHCONTAINER pMeshContainerBase )
{
D3DXMESHCONTAINER* pMeshContainer = ( D3DXMESHCONTAINER* )pMeshContainerBase;

//delete[] pMeshContainer->Name;
// delete[] pMeshContainer->pAdjacency;
// delete[] pMeshContainer->pMaterials;

// (pMeshContainer->MeshData.pMesh)->Release();
// (pMeshContainer->pSkinInfo)->Release();
// delete pMeshContainer;

return S_OK;
}
*/
/******************************END ANIMATION*************************************/



HRESULT CAllocateHierarchy::DestroyFrame(LPD3DXFRAME pFrameToFree)
{
// free siblings and children first
if (pFrameToFree->pFrameSibling)
DestroyFrame(pFrameToFree->pFrameSibling);

if (pFrameToFree->pFrameFirstChild)
DestroyFrame(pFrameToFree->pFrameFirstChild);


// now free the current frame
if (pFrameToFree)
{
// free Name string
if (pFrameToFree->Name != NULL)
delete [] pFrameToFree->Name;

// free mesh container
DestroyMeshContainer(pFrameToFree->pMeshContainer);

// free frame
delete pFrameToFree;
}

pFrameToFree = NULL;

return S_OK;
}

HRESULT CAllocateHierarchy::DestroyMeshContainer(LPD3DXMESHCONTAINER pMeshContainerBase)
{
if(pMeshContainerBase != NULL)
delete pMeshContainerBase;

return S_OK;
}
[/code]

Everything else:
[code]

#include "Utilities.h"
#include "allocatehierarchy.h"

//globals
LPDIRECT3D9 d3dObject=NULL;
LPDIRECT3DDEVICE9 d3dDevice=NULL;

//declare functions
void initDInput(HINSTANCE hInstance, HWND hWnd); // sets up and initializes DirectInput
void Render();
void DrawFrame(LPD3DXFRAME frame);



HRESULT InitD3D( HWND hWnd )
{
//create D3D Object
if( NULL == ( d3dObject=Direct3DCreate9(D3D_SDK_VERSION) ) )
return E_FAIL;

//setup structure for parameters for D3D Device
D3DPRESENT_PARAMETERS presParams;
ZeroMemory(&presParams,sizeof(presParams));
presParams.Windowed=TRUE;
presParams.SwapEffect=D3DSWAPEFFECT_DISCARD;
presParams.BackBufferFormat=D3DFMT_UNKNOWN;
presParams.PresentationInterval=D3DPRESENT_INTERVAL_ONE;


//create D3D Device
if( FAILED (d3dObject->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING, &presParams, &d3dDevice) ) )
{
return E_FAIL;
}
// Turn on ambient lighting
d3dDevice->SetRenderState( D3DRS_AMBIENT, 0xffffffff );


return S_OK;
}

HRESULT InitMesh()
{
CAllocateHierarchy Alloc;

D3DXLoadMeshHierarchyFromX( "tiny.x", // File load
D3DXMESH_MANAGED, // Load Options
d3dDevice, // D3D Device
&Alloc, // Hierarchy allocation class
NULL, // NO Effects
&pFrameRoot, // Frame hierarchy
&pAnimController);
// Animation Controller

//check value of pFrameRoot via Debug
if (&pFrameRoot)
;

return S_OK;
}

VOID SetupMatrices()
{
// Set up world matrix
D3DXMATRIXA16 matWorld;
D3DXMATRIX mtranslate;

//rotate model
D3DXMatrixRotationY( &matWorld, 0 );

//translate model
D3DXMatrixTranslation(&mtranslate, 0.0f, 0.0f, 0.0f);

d3dDevice->SetTransform( D3DTS_WORLD, &(matWorld * mtranslate) );

// Set up our view matrix. A view matrix can be defined given an eye point,
// a point to lookat, and a direction for which way is up. Here, we set the
// eye five units back along the z-axis and up three units, look at the
// origin, and define "up" to be in the y-direction.
D3DXVECTOR3 vEyePt( -4.0f, 8.0f,0.0f );
D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUpVec( 0.0f, 0.0f, 1.0f );
D3DXMATRIXA16 matView;
D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
d3dDevice->SetTransform( D3DTS_VIEW, &matView );


// For the projection matrix, we set up a perspective transform (which
// transforms geometry from 3D view space to 2D viewport space, with
// a perspective divide making objects smaller in the distance). To build
// a perpsective transform, we need the field of view (1/4 pi is common),
// the aspect ratio, and the near and far clipping planes (which define at
// what distances geometry should be no longer be rendered).
D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f );
d3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}


void Render()
{
//clear buffer
d3dDevice->Clear(0,NULL,D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,50,100),1.0f,0);

//begin scene
d3dDevice->BeginScene();

SetupMatrices();

if (pFrameRoot)
DrawFrame(pFrameRoot);
else
MessageBox( NULL, "Could not find tiger.x", "Meshes.exe", MB_OK );

//end scene
d3dDevice->EndScene();

//present screen
d3dDevice->Present( NULL, NULL, NULL, NULL );
}


void DrawMeshContainer(LPD3DXMESHCONTAINER meshContainerBase, LPD3DXFRAME frameBase)
{
D3DXFRAME *frame = frameBase;

D3DXMESHCONTAINER *meshContainer = meshContainerBase;

// Loop through all the materials in the mesh rendering each subset
for (unsigned int iMaterial = 0; iMaterial < meshContainer->NumMaterials; iMaterial++)
{
// use the material in our extended data rather than the one in meshContainer->pMaterials[iMaterial].MatD3D
//d3dDevice->SetMaterial( &meshContainer->exMaterials[iMaterial] );
//d3dDevice->SetTexture( 0, meshContainer->exTextures[iMaterial] );

// Select the mesh to draw, if there is skin then use the skinned mesh else the normal one
LPD3DXMESH pDrawMesh = meshContainer->MeshData.pMesh;

// Finally Call the mesh draw function
pDrawMesh->DrawSubset(iMaterial);
}
}

void DrawFrame(LPD3DXFRAME frame)
{
// Draw all mesh containers in this frame
LPD3DXMESHCONTAINER meshContainer = frame->pMeshContainer;
while (meshContainer)
{
DrawMeshContainer(meshContainer, frame);
meshContainer = meshContainer->pNextMeshContainer;
}

// Recurse for sibblings
if (frame->pFrameSibling != NULL)
DrawFrame(frame->pFrameSibling);

// Recurse for children
if (frame->pFrameFirstChild != NULL)
DrawFrame(frame->pFrameFirstChild);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
//case WM_COMMAND:
// handle menu selections etc.
//break;
//case WM_PAINT:
// draw our window - note: you must paint something here or not trap it!
//break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
// We do not want to handle this message so pass back to Windows
// to handle it in a default way
return DefWindowProc(hWnd, message, wParam, lParam);
}

return 0;
}

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style= CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc= (WNDPROC)WndProc;
wcex.cbClsExtra= 0;
wcex.cbWndExtra= 0;
wcex.hInstance= hInstance;
wcex.hIcon= 0;
wcex.hCursor= LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground= (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName= 0;
wcex.lpszClassName= "MyWindowClass";
wcex.hIconSm= 0;

// Now we can go ahead and register our new window class
RegisterClassEx(&wcex);

HWND hWnd = CreateWindow("MyWindowClass", "Poop", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

//call initD3D
InitD3D(hWnd);

InitMesh();

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

//enter main loop
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);

Render();
}

return (int)msg.wParam;
}
[/code]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this