Sign in to follow this  

DrawSubset Problem

This topic is 2308 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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

This topic is 2308 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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