Skinned mesh loading problems (manual xfile parsing) D3DX is broke!

Started by
5 comments, last by transformation 19 years, 7 months ago
After reading this thread, I made some xfile parsing routines using the shown pseudocode. Anyway, I keep on getting an unhandled exception error from a null pointer - "Access violation reading location 0x00000000." But It's coming from inside the D3DXLoadSkinMeshFromXof function, not from my code. I have the debug output to full but nothing is being said. I have a feeling that maybe my xfile parsing functions are a bit out, any help would be appreciated.

// Stars the enumerating process
bool top_level( char* name ) {

    ID3DXFile* xfile = NULL;
    ID3DXFileEnumObject* enumer = NULL;

    D3DXFileCreate( &xfile );
    xfile->RegisterTemplates( D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES );

    if( FAILED( xfile->CreateEnumObject( name, D3DXF_FILELOAD_FROMFILE, &enumer ) ) )
        return false;

    DWORD objects = 0;
    enumer->GetChildren( &objects );

    for( DWORD i = 0; i < objects; i++ ) {

        HRESULT hr = S_OK;
        ID3DXFileData* data = 0;
        
        hr = enumer->GetChild( i, &data );

        if( SUCCEEDED( hr ) ) {

            if( !deal_with_data( data ) ) {
                data->Release();
                continue;
            }

            if( !parse_children( data ) ) {
                data->Release();
                continue;
            }

            data->Release();
        }
    }

    enumer->Release();
    xfile->Release();

    return true;
}

// enumerates children
bool parse_children( ID3DXFileData* data ) {

    HRESULT hr = S_OK;

    DWORD children = 0;
    data->GetChildren( &children );

    for( DWORD i = 0; i < children; ++i ) {

        ID3DXFileData* child = 0;
        hr = data->GetChild( i, &child );

        if( SUCCEEDED( hr ) ) {

            if( !deal_with_data( child ) ) {
                child->Release();
                return false;
            }

            if( !parse_children( child ) ) {
                child->Release();
                return false;
            }

            child->Release();
        }
    }

    return true;
}

// just checks if its a mesh and loads it.
bool deal_with_data( ID3DXFileData* data ) {

    GUID guid;
    HRESULT hr;

    data->GetType( &guid );

    if( guid == TID_D3DRMMesh )
    {
        DWORD num_materials = 0;

        ID3DXMesh* mesh = 0;
        ID3DXBuffer* mats = 0;
        ID3DXSkinInfo* skin = 0;

        hr = D3DXLoadSkinMeshFromXof( data, D3DXMESH_WRITEONLY, g_device, NULL, &mats, NULL,
                                      &num_materials, &skin, &mesh ); // <-- Breaks over here!!!

        if( FAILED( hr ) )
            return false;

        // Ignore this, im just testing if loading succeeds then releasing.
        if( skin ) skin->Release();
        if( mats ) mats->Release();
        if( mesh ) mesh->Release();

        return true;
    }

    return true;
}

Thanks. Oh and by the way, Im using the Tiny.x that comes with the DX SDK.
Advertisement
Somebody has to know...
Everything looks fine to me. The only thing D3DXLoadSkinMeshFromXof really needs is a pointer to the ID3DXFileData data. I can't imagine how the method would screw up unless the ID3DXFileData pointer was currupted somewhere, or the X-File itself is messed up.

Are you using the regular Tiny.x mesh?

EDIT: err, I missed that last line of your first post; hehe.

Have you tried using Debug mode of Direct3D, turning up the slider to full blast, and see what it tells ya before it bytes the dust?

One other thing. I've had a simular problem as this when I tried loading all needed objects from an X-File, freeing everything off except what I wanted, then using the D3DXLoadSkinMeshFromXof function. In that order.

I think the D3DXLoadSkinMeshFromXof relies on other parts of the file to get it's data. So it might be possible to Release() something that it will need in the function. I can't be too sure, so don't totally change your code to try it.
Debug output is full and no output at all before my app bites the dust. Is there some kind of email where i can contact the dx team, maybe sent them the source code and have them check it out. If no one here can actually see the problem then maybe it's a bug in d3dx? I know that the problem being with d3dx is not very probable, but I cant figure this one out...

Does anyone else have anything?
Are you sure you can specify NULL as the input for ppAdjacency and ppEffectInstances?

The docs state (at least):
"For mesh files that do not contain effect instance information, default effect instances will be generated from the material information in the .x file"

This would seem to indicate that your NULL pointer reference happens when D3DXLoadSkinMeshFromXof tries to write to your Adjacency or EffectInstances pointers.

Try passing in values, even if you don't use them. If the docs don't explicitly say that a NULL pointer is acceptable, you probably don't want to rely on Microsoft to test and avoid the crash for you.
Well, I think Cauthon has the right idea. Just to show what I used for my function call:

D3DXLoadSkinMeshFromXof(pDataObj, 0, m_Graphics->GetDeviceCOM(), &Adjacency, &MaterialBuffer, NULL, &Mesh->m_NumMaterials, &Mesh->m_SkinInfo, &Mesh->m_Mesh)


Anyway, as you can see I passed a pointer to ppAdjacency, but not to ppEffectInstances. After reading the MSDN library section on the function, I'm led to believe that while ppEffectInstances can be NULL, ppAdjacency must be inclueded.

Cheers!
Thanks a lot Cauthon and silverRohan. It was the ppAdjacensy pointer after all...

You know since Im using the debug version of d3dx, the least they can do is have a check in the function on the parameter and return D3DERR_INVALIDCALL or something if a NULL value is passed in to something that shouldn't be NULL. After all it is the *debug* version so this kind of checking should be there right?

On a similar note, this dosen't really seem like the usual behaviour for a d3dx function call. Usually, all the parameters with [out] specified can be null if you dont want them right? I mean except for the main object you are going for, but the extra objects that come out with the main object can usually be null.

DOes anyone have any info on why ppAdjacensy *has* to come out?

Thanks again.

This topic is closed to new replies.

Advertisement