Sign in to follow this  

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

This topic is 4843 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

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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

This topic is 4843 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