Sign in to follow this  

quick paramter help

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

I am using the directx sdk samples and am a little confused by the 7th paramter. D3DXCreateEffectFromFile( g_engine->GetDevice(), str, NULL, NULL, g_dwShaderFlags, g_pEffectPool, &m_pMaterials[i].m_pEffect, NULL ); I don't quite understand this part. &m_pMaterials[i].m_pEffect Anyone have any ideas?

Share this post


Link to post
Share on other sites
Each material in the material array pointed to by m_pMaterials has a pointer member to an ID3DXEffect. The call is passing the address of this member pointer to the Create function, which will modify the value of the pointer to point at the newly created effect.

What is effectively happening is that the CreateEffect call is "filling" one of the members of the elements of the array.

If you're having trouble with the actual syntax, I'd recommend reviewing some of the C++ syntax as it is quite basic.

Share this post


Link to post
Share on other sites
Thanks for the info. My application stores the material array in this.

In my header file
Material **materials;

Would you know how I could replace the parameter so it would work here. I have tried unsuccessfully multiple times.

Share this post


Link to post
Share on other sites
It looks like you are using an array of Material pointers. Why not use an array of Materials? (or an std::vector of them, for that matter.)

Anyway, as you have it now, it should be:

&materials[i]->m_pEffect

If it was an array of Materials (and not pointers to them), it would be:

&materials[i].m_pEffect

Share this post


Link to post
Share on other sites
Doesn't work errors say

error C2065: 'materials' : undeclared identifier
error C2227: left of '->m_pEffect' must point to class/struct/union/generic type

Share this post


Link to post
Share on other sites
This is what I am using to load materials into an array

// Check if the mesh has any materials.
if( m_staticMesh->NumMaterials > 0 )
{
// Create the array of materials.
m_staticMesh->materials = new Material*[m_staticMesh->NumMaterials];

// Get the list of materials from the material buffer.
D3DXMATERIAL *materials = (D3DXMATERIAL*)materialBuffer->GetBufferPointer();

// Load each material into the array via the material manager.
for( unsigned long m = 0; m < m_staticMesh->NumMaterials; m++ )

Share this post


Link to post
Share on other sites
Quote:
Doesn't work errors say

error C2065: 'materials' : undeclared identifier
error C2227: left of '->m_pEffect' must point to class/struct/union/generic type


I assume that you are trying to do this inside the loop of the code snippet you posted, so we'll need to see that as well.

Also, earlier you said that you have a variable called 'materials' in a header file (is it a global variable?), and now you're creating a local variable with the same name...

In short, we need to see more code.

Share this post


Link to post
Share on other sites
Ok this should be enough code hopefully. Its set up with an oop design, unlike the directx sample. This code is obviously unfinished as I am trying to merge the sdk sample with my application. Currently working on the materials. As you can see my application uses materials differently from the sdk. Blue coding equals code from the dx SDK. Black coding is from my application.

Header File (snippet)



//-----------------------------------------------------------------------------
// Mesh Container Structure
//-----------------------------------------------------------------------------
struct MeshContainer : public D3DXMESHCONTAINER
{
char **materialNames; // Temporary array of material (texture) names.
Material **materials; // Array of materials used by the mesh container.
ID3DXMesh *originalMesh; // Original mesh.
ID3DXEffect *m_pEffect;
D3DXATTRIBUTERANGE *attributeTable; // Mesh's attribute table.
unsigned long totalAttributeGroups; // Total number of attribute groups.
D3DXMATRIX **boneMatrixPointers; // Array of pointers to the bone transformation matrices.
};

//-----------------------------------------------------------------------------
// Mesh Class
//-----------------------------------------------------------------------------
class Mesh : public BoundingVolume, public Resource< Mesh >
{
public:
Mesh( char *name, char *path = "./" );
virtual ~Mesh();

void Update();
void Render();

void CloneAnimationController( ID3DXAnimationController **animationController );

MeshContainer *GetStaticMesh();
Vertex *GetVertices();
unsigned short *GetIndices();

LinkedList< Frame > *GetFrameList();
Frame *GetFrame( char *name );
Frame *GetReferencePoint( char *name );

private:
void PrepareFrame( Frame *frame );
void UpdateFrame( Frame *frame, D3DXMATRIX *parentTransformationMatrix = NULL );
void RenderFrame( Frame *frame );

private:
Frame *m_firstFrame; // First frame in the mesh's frame hierarchy.
ID3DXAnimationController *m_animationController; // Animation controller.

D3DXMATRIX *m_boneMatrices; // Array of bone transformation matrices.
unsigned long m_totalBoneMatrices; // Number of bones in the array.

MeshContainer *m_staticMesh; // A static (non-animated) version of the mesh.
Vertex *m_vertices; // Array of vertices from the static mesh.
unsigned short *m_indices; // Array of indices into the vertex array.

LinkedList< Frame > *m_frames; // Linked list of pointers to all the frames in the mesh.
LinkedList< Frame > *m_refPoints; // Linked list of pointers to all the reference points in the mesh.
};




CPP File(Snippet)



/ Check if the mesh has any materials.
if( m_staticMesh->NumMaterials > 0 )
{
// Create the array of materials.
m_staticMesh->materials = new Material*[m_staticMesh->NumMaterials];

// Get the list of materials from the material buffer.
D3DXMATERIAL *materials = (D3DXMATERIAL*)materialBuffer->GetBufferPointer();

// Load each material into the array via the material manager.
for( unsigned long m = 0; m < m_staticMesh->NumMaterials; m++ )
{
// Ensure the material has a texture.
if( materials[m].pTextureFilename )
{
// Get the name of the material's script and load it.
char *name = new char[strlen( materials[m].pTextureFilename ) + 5];
sprintf( name, "%s.txt", materials[m].pTextureFilename );
m_staticMesh->materials[m] = g_engine->GetMaterialManager()->Add( name, GetPath() );
SAFE_DELETE_ARRAY( name );
}
else
m_staticMesh->materials[m] = NULL;
}
}
//create effect
D3DXEFFECTINSTANCE *pEI = (D3DXEFFECTINSTANCE *)pEffectInstance->GetBufferPointer();
for( UINT i = 0; i < m_staticMesh->NumMaterials; ++i )
{
// Obtain the effect

hr = S_OK;
// Try the mesh's directory
StringCchCopyW( str, MAX_PATH, wszMeshPath );
MultiByteToWideChar( CP_ACP, 0, pEI[i].pEffectFilename, -1, str + lstrlenW( str ), MAX_PATH );

if( pEI[i].pEffectFilename == NULL )


hr = E_FAIL;

WCHAR wszFxName[MAX_PATH];
MultiByteToWideChar( CP_ACP, 0, pEI[i].pEffectFilename, -1, wszFxName, MAX_PATH );

if( SUCCEEDED( hr ) )
D3DXCreateEffectFromFile( g_engine->GetDevice(), str, NULL, NULL, g_dwShaderFlags, g_pEffectPool,
&materials[i]->m_pEffect, NULL ); <-------------This is where I originally posted.
if( !m_pMaterials[i].m_pEffect )
{
// No valid effect for this material. Use the default.
m_pMaterials[i].m_pEffect = g_pEffect;
m_pMaterials[i].m_pEffect->AddRef();
}

// Set the technique this material should use
D3DXHANDLE hTech;
m_pMaterials[i].m_pEffect->FindNextValidTechnique( NULL, &hTech );
m_pMaterials[i].m_pEffect->SetTechnique( hTech );

// Create a parameter block to include all parameters for the effect.
m_pMaterials[i].m_pEffect->BeginParameterBlock();
for( UINT param = 0; param < pEI[i].NumDefaults; ++param )
{
D3DXHANDLE hHandle = m_pMaterials[i].m_pEffect->GetParameterByName( NULL, pEI[i].pDefaults[param].pParamName );
D3DXPARAMETER_DESC desc;
if( hHandle != NULL )
{
m_pMaterials[i].m_pEffect->GetParameterDesc( hHandle, &desc );
if( desc.Type == D3DXPT_BOOL ||
desc.Type == D3DXPT_INT ||
desc.Type == D3DXPT_FLOAT ||
desc.Type == D3DXPT_STRING )
{
m_pMaterials[i].m_pEffect->SetValue( pEI[i].pDefaults[param].pParamName,
pEI[i].pDefaults[param].pValue,
pEI[i].pDefaults[param].NumBytes );
}
}
}




[Edited by - Njguy on November 18, 2008 8:14:11 PM]

Share this post


Link to post
Share on other sites
I'm confused.

First you said that 'materials' is of type Material**. In the second code snippet, you are creating a local variable with the same name, that is of type D3DXMATERIAL*. In the third code snippet, in the blue section, you use 'materials' as if it was an array of pointers. Actually in that code snippet, it looks like you wanted to use m_pMaterials instead.

So I'm not sure what's going on, perhaps you could clarify.

Share this post


Link to post
Share on other sites
Basically if you look under the CPP section, in the black coding, I make an array of materials that I get out of the directx file(didn't show that part its above). I am trying to get the blue coding to use that array. Basically they are two different coding styles that im trying to merge and its throwing me off completely. The blue coding is trying to get the materials array, but my application's array is set up slightly differently. Thanks for the help you have given me so far by the way.

Share this post


Link to post
Share on other sites
In that part of the code, 'materials' is an array of D3DXMATERIAL objects (structs). So, if you write:

materials[i]

the result is an object (as opposed to a pointer). Therefore to access it's members, you need to use a dot, not an arrow.

I guess you used an arrow because I told you to, but I only said so because you showed me this definition of 'materials':

Material** materials;

and here it is an array of pointers, not objects. I still don't understand where this definition came from...

Now given that in this code snippet (the blue one) 'materials' is an array of D3DXMATERIALs (objects, not pointers), you should write &materials[i].m_pEffect instead of &materials[i]->m_pEffect. However, this won't work either because a D3DXMATERIAL structure doesn't have a member called m_pEffect. So, I think you got some of your variables mixed up.

If you're still having trouble making this work, post the exact error messages that the compiler gives you, and if you make any changes to the code, post the new code as well.

Share this post


Link to post
Share on other sites
I tried typing &materials[i].m_pEffect before, but it still give the same error messages. Its strange because if I right click it and hit go to definition, it will take me to

Material **materials;

in the .h file, so I don't know what the problem is.


Here is the error, it is the same with dot as it is with the pointer. Note there are a lot more errors, most of them have to do with this same thing, other material errors.

1>c:\documents and settings\hp_administrator\desktop\source\chapter 10\engine\mesh.cpp(261) : error C2065: 'materials' : undeclared identifier
1>c:\documents and settings\hp_administrator\desktop\source\chapter 10\engine\mesh.cpp(261) : error C2228: left of '.m_pEffect' must have class/struct/union

Share this post


Link to post
Share on other sites
This is really weird, if I add this in the .h file

MeshContainer *m_pMaterials;

under the Mesh class, all of the errors associated with materials go away. This seems to point m_pMaterials to the Mesh container structure. it makes the rrors go away, but I don't get how this would solve the problem.

Share this post


Link to post
Share on other sites
Not sure what's going on. Post the entire contents of the .h and .cpp file. Place each one between [ source] and [ /source] tags (without a space after the [).

Share this post


Link to post
Share on other sites
Ok, there is a lot more to the engine, this is just mesh.h and mesh.cpp. This will obviously not compile, as I am still in the process of merging.


.h file
Mesh.h


#ifndef MESH_H
#define MESH_H

//-----------------------------------------------------------------------------
// Frame Structure
//-----------------------------------------------------------------------------
struct Frame : public D3DXFRAME
{
D3DXMATRIX finalTransformationMatrix; // Frame's final transformation after being combined with its parent.

//-------------------------------------------------------------------------
// Returns the frame's translation.
//-------------------------------------------------------------------------
D3DXVECTOR3 GetTranslation()
{
return D3DXVECTOR3( finalTransformationMatrix._41, finalTransformationMatrix._42, finalTransformationMatrix._43 );
}
};

//-----------------------------------------------------------------------------
// Mesh Container Structure
//-----------------------------------------------------------------------------
struct MeshContainer : public D3DXMESHCONTAINER
{
char **materialNames; // Temporary array of material (texture) names.
Material **materials; // Array of materials used by the mesh container.
ID3DXMesh *originalMesh; // Original mesh.
ID3DXEffect *m_pEffect;
D3DXATTRIBUTERANGE *attributeTable; // Mesh's attribute table.
unsigned long totalAttributeGroups; // Total number of attribute groups.
D3DXMATRIX **boneMatrixPointers; // Array of pointers to the bone transformation matrices.
};

//-----------------------------------------------------------------------------
// Allocate Hierarchy Class
//-----------------------------------------------------------------------------
class AllocateHierarchy : public ID3DXAllocateHierarchy
{
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 pMeshContainerToFree );
};

//-----------------------------------------------------------------------------
// Mesh Class
//-----------------------------------------------------------------------------
class Mesh : public BoundingVolume, public Resource< Mesh >
{
public:
Mesh( char *name, char *path = "./" );
virtual ~Mesh();
void Update();
void Render();

void CloneAnimationController( ID3DXAnimationController **animationController );

MeshContainer *m_pMaterials;
MeshContainer *GetStaticMesh();
Vertex *GetVertices();
unsigned short *GetIndices();

LinkedList< Frame > *GetFrameList();
Frame *GetFrame( char *name );
Frame *GetReferencePoint( char *name );

private:
void PrepareFrame( Frame *frame );
void UpdateFrame( Frame *frame, D3DXMATRIX *parentTransformationMatrix = NULL );
void RenderFrame( Frame *frame );

private:
Frame *m_firstFrame; // First frame in the mesh's frame hierarchy.
ID3DXAnimationController *m_animationController; // Animation controller.

D3DXMATRIX *m_boneMatrices; // Array of bone transformation matrices.
unsigned long m_totalBoneMatrices; // Number of bones in the array.

MeshContainer *m_staticMesh; // A static (non-animated) version of the mesh.
Vertex *m_vertices; // Array of vertices from the static mesh.
unsigned short *m_indices; // Array of indices into the vertex array.

LinkedList< Frame > *m_frames; // Linked list of pointers to all the frames in the mesh.
LinkedList< Frame > *m_refPoints; // Linked list of pointers to all the reference points in the mesh.
};

#endif



.cpp file
Mesh.cpp

#include "Engine.h"
// Variables
DWORD g_dwShaderFlags = D3DXFX_NOT_CLONEABLE; // Shader creation flag for all effects
ID3DXEffectPool* g_pEffectPool = NULL; // Effect pool for sharing parameters
extern ID3DXEffect* g_pEffect;




//--------------------------------------------------------------------------------------
struct MESHVERTEX
{
D3DXVECTOR3 Position;
D3DXVECTOR3 Normal;
D3DXVECTOR2 Tex;

const static D3DVERTEXELEMENT9 Decl[4];
};


//--------------------------------------------------------------------------------------
const D3DVERTEXELEMENT9 MESHVERTEX::Decl[] =
{
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
{ 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
D3DDECL_END()
};




//-----------------------------------------------------------------------------
// Creates a new frame.
//-----------------------------------------------------------------------------
HRESULT AllocateHierarchy::CreateFrame( THIS_ LPCSTR Name, LPD3DXFRAME *ppNewFrame )
{
// Create the new frame and zero its memory.
Frame *frame = new Frame;
ZeroMemory( frame, sizeof( Frame ) );

// Copy the frame's name.
if( Name == NULL )
{
// There is no name, so create a unique name.
static unsigned long nameCount = 0;
char newName[32];
sprintf( newName, "unknown_frame_%d", nameCount );
nameCount++;

frame->Name = new char[strlen( newName ) + 1];
strcpy( frame->Name, newName );
}
else
{
frame->Name = new char[strlen( Name ) + 1];
strcpy( frame->Name, Name );
}

*ppNewFrame = frame;

return S_OK;
}

//-----------------------------------------------------------------------------
// Creates a new mesh container.
//-----------------------------------------------------------------------------
HRESULT AllocateHierarchy::CreateMeshContainer( THIS_ LPCSTR Name, CONST D3DXMESHDATA *pMeshData, CONST D3DXMATERIAL *pMaterials, CONST D3DXEFFECTINSTANCE *pEffectInstances, DWORD NumMaterials, CONST DWORD *pAdjacency, LPD3DXSKININFO pSkinInfo, LPD3DXMESHCONTAINER *ppNewMeshContainer )
{
// Create the new mesh container and zero its memory.
MeshContainer *meshContainer = new MeshContainer;
ZeroMemory( meshContainer, sizeof( MeshContainer ) );

// Copy the mesh's name.
if( Name == NULL )
{
// There is no name, so create a unique name.
static unsigned long nameCount = 0;
char newName[32];
sprintf( newName, "unknown_mesh_%d", nameCount );
nameCount++;

meshContainer->Name = new char[strlen( newName ) + 1];
strcpy( meshContainer->Name, newName );
}
else
{
meshContainer->Name = new char[strlen( Name ) + 1];
strcpy( meshContainer->Name, Name );
}

// Check if the mesh has any materials.
if( ( meshContainer->NumMaterials = NumMaterials ) > 0 )
{
// Allocate some memory for the mesh's materials, and their names (i.e. texture names).
meshContainer->materials = new Material*[meshContainer->NumMaterials];
meshContainer->materialNames = new char*[meshContainer->NumMaterials];

// Store all the material (texture) names.
for( unsigned long m = 0; m < NumMaterials; m++ )
{
if( pMaterials[m].pTextureFilename )
{
meshContainer->materialNames[m] = new char[strlen( pMaterials[m].pTextureFilename ) + 1];
memcpy( meshContainer->materialNames[m], pMaterials[m].pTextureFilename, ( strlen( pMaterials[m].pTextureFilename ) + 1 ) * sizeof( char ) );
}
else
meshContainer->materialNames[m] = NULL;

meshContainer->materials[m] = NULL;
}
}

// Store the mesh's adjacency information.
meshContainer->pAdjacency = new DWORD[pMeshData->pMesh->GetNumFaces() * 3];
memcpy( meshContainer->pAdjacency, pAdjacency, sizeof( DWORD ) * pMeshData->pMesh->GetNumFaces() * 3 );

// Store the mesh data.
meshContainer->MeshData.pMesh = meshContainer->originalMesh = pMeshData->pMesh;
meshContainer->MeshData.Type = D3DXMESHTYPE_MESH;
pMeshData->pMesh->AddRef();
pMeshData->pMesh->AddRef();

// Check if this mesh is a skinned mesh.
if( pSkinInfo != NULL )
{
// Store the skin information and the mesh data.
meshContainer->pSkinInfo = pSkinInfo;
pSkinInfo->AddRef();

// Clone the original mesh to create the skinned mesh.
meshContainer->originalMesh->CloneMeshFVF( D3DXMESH_MANAGED, meshContainer->originalMesh->GetFVF(), g_engine->GetDevice(), &meshContainer->MeshData.pMesh );

// Store the attribute table.
meshContainer->MeshData.pMesh->GetAttributeTable( NULL, &meshContainer->totalAttributeGroups );
meshContainer->attributeTable = new D3DXATTRIBUTERANGE[meshContainer->totalAttributeGroups];
meshContainer->MeshData.pMesh->GetAttributeTable( meshContainer->attributeTable, NULL );
}

*ppNewMeshContainer = meshContainer;

return S_OK;
}

//-----------------------------------------------------------------------------
// Destroys the given frame.
//-----------------------------------------------------------------------------
HRESULT AllocateHierarchy::DestroyFrame( THIS_ LPD3DXFRAME pFrameToFree )
{
SAFE_DELETE_ARRAY( pFrameToFree->Name );
SAFE_DELETE( pFrameToFree );

return S_OK;
}

//-----------------------------------------------------------------------------
// Destroys the given mesh conatiner.
//-----------------------------------------------------------------------------
HRESULT AllocateHierarchy::DestroyMeshContainer( THIS_ LPD3DXMESHCONTAINER pMeshContainerToFree )
{
MeshContainer *meshContainer = (MeshContainer*)pMeshContainerToFree;

// Go through all of the materials.
for( unsigned long m = 0; m < meshContainer->NumMaterials; m++ )
{
// Remove this material from the material manager.
if( meshContainer->materials )
g_engine->GetMaterialManager()->Remove( &meshContainer->materials[m] );

// Destroy the material's name.
SAFE_DELETE_ARRAY( meshContainer->materialNames[m] );
}

// Destroy the mesh container.
SAFE_DELETE_ARRAY( meshContainer->Name );
SAFE_DELETE_ARRAY( meshContainer->pAdjacency );
SAFE_DELETE_ARRAY( meshContainer->pMaterials );
SAFE_DELETE_ARRAY( meshContainer->materialNames );
SAFE_DELETE_ARRAY( meshContainer->materials );
SAFE_DELETE_ARRAY( meshContainer->boneMatrixPointers );
SAFE_DELETE_ARRAY( meshContainer->attributeTable );
SAFE_RELEASE( meshContainer->MeshData.pMesh );
SAFE_RELEASE( meshContainer->pSkinInfo );
SAFE_RELEASE( meshContainer->originalMesh );
SAFE_DELETE( meshContainer );

return S_OK;
}

//-----------------------------------------------------------------------------
// The mesh class constructor.
//-----------------------------------------------------------------------------
Mesh::Mesh( char *name, char *path ) : Resource< Mesh >( name, path )
{
HRESULT hr;
WCHAR str[MAX_PATH];
WCHAR wszMeshPath[MAX_PATH];

// Create the list of reference points.
m_frames = new LinkedList< Frame >;
m_refPoints = new LinkedList< Frame >;

// Load the mesh's frame hierarchy.
AllocateHierarchy ah;
D3DXLoadMeshHierarchyFromX( GetFilename(), D3DXMESH_MANAGED, g_engine->GetDevice(), &ah, NULL, (D3DXFRAME**)&m_firstFrame, &m_animationController );

// Disable all the animation tracks initially.
if( m_animationController != NULL )
for( unsigned long t = 0; t < m_animationController->GetMaxNumTracks(); ++t )
m_animationController->SetTrackEnable( t, false );

// Invalidate the bone transformation matrices array.
m_boneMatrices = NULL;
m_totalBoneMatrices = 0;

// Prepare the frame hierarchy.
PrepareFrame( m_firstFrame );

// Allocate memory for the bone matrices.
m_boneMatrices = new D3DXMATRIX[m_totalBoneMatrices];

// Create a static (non-animated) version of the mesh.
m_staticMesh = new MeshContainer;
ZeroMemory( m_staticMesh, sizeof( MeshContainer ) );

// Load the mesh.
ID3DXBuffer *materialBuffer, *adjacencyBuffer, *pEffectInstance;
D3DXLoadMeshFromX( GetFilename(), D3DXMESH_MANAGED, g_engine->GetDevice(), &adjacencyBuffer, &materialBuffer, &pEffectInstance, &m_staticMesh->NumMaterials, &m_staticMesh->originalMesh );

// Optimise the mesh for better rendering performance.
m_staticMesh->originalMesh->OptimizeInplace( D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE, (DWORD*)adjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL );

// Finished with the adjacency buffer, so destroy it.
SAFE_RELEASE( adjacencyBuffer );

// Check if the mesh has any materials.
if( m_staticMesh->NumMaterials > 0 )
{
// Create the array of materials.
m_staticMesh->materials = new Material*[m_staticMesh->NumMaterials];

// Get the list of materials from the material buffer.
D3DXMATERIAL *materials = (D3DXMATERIAL*)materialBuffer->GetBufferPointer();

// Load each material into the array via the material manager.
for( unsigned long m = 0; m < m_staticMesh->NumMaterials; m++ )
{
// Ensure the material has a texture.
if( materials[m].pTextureFilename )
{
// Get the name of the material's script and load it.
char *name = new char[strlen( materials[m].pTextureFilename ) + 5];
sprintf( name, "%s.txt", materials[m].pTextureFilename );
m_staticMesh->materials[m] = g_engine->GetMaterialManager()->Add( name, GetPath() );
SAFE_DELETE_ARRAY( name );
}
else
m_staticMesh->materials[m] = NULL;
}
}
//create effect
D3DXEFFECTINSTANCE *pEI = (D3DXEFFECTINSTANCE *)pEffectInstance->GetBufferPointer();
for( UINT i = 0; i < m_staticMesh->NumMaterials; ++i )
{
// Obtain the effect

hr = S_OK;
// Try the mesh's directory
StringCchCopyW( str, MAX_PATH, wszMeshPath );
MultiByteToWideChar( CP_ACP, 0, pEI[i].pEffectFilename, -1, str + lstrlenW( str ), MAX_PATH );

if( pEI[i].pEffectFilename == NULL )
hr = E_FAIL;

WCHAR wszFxName[MAX_PATH];
MultiByteToWideChar( CP_ACP, 0, pEI[i].pEffectFilename, -1, wszFxName, MAX_PATH );

if( SUCCEEDED( hr ) )
D3DXCreateEffectFromFile( g_engine->GetDevice(), str, NULL, NULL, g_dwShaderFlags, g_pEffectPool,
&m_pMaterials[i].m_pEffect, NULL );
if( !m_pMaterials[i].m_pEffect )
{
// No valid effect for this material. Use the default.
m_pMaterials[i].m_pEffect = g_pEffect;
m_pMaterials[i].m_pEffect->AddRef();
}

// Set the technique this material should use
D3DXHANDLE hTech;
m_pMaterials[i].m_pEffect->FindNextValidTechnique( NULL, &hTech );
m_pMaterials[i].m_pEffect->SetTechnique( hTech );

// Create a parameter block to include all parameters for the effect.
m_pMaterials[i].m_pEffect->BeginParameterBlock();
for( UINT param = 0; param < pEI[i].NumDefaults; ++param )
{
D3DXHANDLE hHandle = m_pMaterials[i].m_pEffect->GetParameterByName( NULL, pEI[i].pDefaults[param].pParamName );
D3DXPARAMETER_DESC desc;
if( hHandle != NULL )
{
m_pMaterials[i].m_pEffect->GetParameterDesc( hHandle, &desc );
if( desc.Type == D3DXPT_BOOL ||
desc.Type == D3DXPT_INT ||
desc.Type == D3DXPT_FLOAT ||
desc.Type == D3DXPT_STRING )
{
m_pMaterials[i].m_pEffect->SetValue( pEI[i].pDefaults[param].pParamName,
pEI[i].pDefaults[param].pValue,
pEI[i].pDefaults[param].NumBytes );
}
}
}



// Create the bounding volume around the mesh.
BoundingVolumeFromMesh( m_staticMesh->originalMesh );

// Destroy the material buffer.
SAFE_RELEASE( materialBuffer );

// Create a vertex array and an array of indices into the vertex array.
m_vertices = new Vertex[m_staticMesh->originalMesh->GetNumVertices()];
m_indices = new unsigned short[m_staticMesh->originalMesh->GetNumFaces() * 3];

// Use the arrays to store a local copy of the static mesh's vertices and
// indices so that they can be used by the scene manager on the fly.
Vertex* verticesPtr;
m_staticMesh->originalMesh->LockVertexBuffer( 0, (void**)&verticesPtr );
unsigned short *indicesPtr;
m_staticMesh->originalMesh->LockIndexBuffer( 0, (void**)&indicesPtr );

memcpy( m_vertices, verticesPtr, VERTEX_FVF_SIZE * m_staticMesh->originalMesh->GetNumVertices() );
memcpy( m_indices, indicesPtr, sizeof( unsigned short ) * m_staticMesh->originalMesh->GetNumFaces() * 3 );

m_staticMesh->originalMesh->UnlockVertexBuffer();
m_staticMesh->originalMesh->UnlockIndexBuffer();
}

//-----------------------------------------------------------------------------
// The mesh class destructor.
//-----------------------------------------------------------------------------
Mesh::~Mesh()
{
// Destroy the frame hierarchy.
AllocateHierarchy ah;
D3DXFrameDestroy( m_firstFrame, &ah );

// Destroy the frames list and reference points list.
m_frames->ClearPointers();
SAFE_DELETE( m_frames );
m_refPoints->ClearPointers();
SAFE_DELETE( m_refPoints );

// Release the animation controller.
SAFE_RELEASE( m_animationController );

// Destroy the bone matrices.
SAFE_DELETE_ARRAY( m_boneMatrices );

// Destroy the static mesh.
if( m_staticMesh )
{
// Remove all the static mesh's textures.
for( unsigned long m = 0; m < m_staticMesh->NumMaterials; m++ )
if( m_staticMesh->materials )
g_engine->GetMaterialManager()->Remove( &m_staticMesh->materials[m] );

// Clean up the rest of it.
SAFE_DELETE_ARRAY( m_staticMesh->materials );
SAFE_RELEASE( m_staticMesh->originalMesh );
SAFE_DELETE( m_staticMesh );
}

// Destroy the vertex and index arrays.
SAFE_DELETE_ARRAY( m_vertices );
SAFE_DELETE_ARRAY( m_indices );
}

//-----------------------------------------------------------------------------
// Updates the mesh.
//-----------------------------------------------------------------------------
void Mesh::Update()
{
UpdateFrame( m_firstFrame );
}

//-----------------------------------------------------------------------------
// Renders the mesh.
//-----------------------------------------------------------------------------
void Mesh::Render()
{
RenderFrame( m_firstFrame );
}

//-----------------------------------------------------------------------------
// Create a clone of the mesh's animation controller.
//-----------------------------------------------------------------------------
void Mesh::CloneAnimationController( ID3DXAnimationController **animationController )
{
if( m_animationController )
m_animationController->CloneAnimationController( m_animationController->GetMaxNumAnimationOutputs(), m_animationController->GetMaxNumAnimationSets(), m_animationController->GetMaxNumTracks(), m_animationController->GetMaxNumEvents(), &*animationController );
else
*animationController = NULL;
}

//-----------------------------------------------------------------------------
// Returns the static (non-animated) version of the mesh.
//-----------------------------------------------------------------------------
MeshContainer *Mesh::GetStaticMesh()
{
return m_staticMesh;
}

//-----------------------------------------------------------------------------
// Returns the mesh's static (non-animated) vertices.
//-----------------------------------------------------------------------------
Vertex *Mesh::GetVertices()
{
return m_vertices;
}

//-----------------------------------------------------------------------------
// Returns the mesh's face indices for the vertices.
//-----------------------------------------------------------------------------
unsigned short *Mesh::GetIndices()
{
return m_indices;
}

//-----------------------------------------------------------------------------
// Returns the list of frames in the mesh.
//-----------------------------------------------------------------------------
LinkedList< Frame > *Mesh::GetFrameList()
{
return m_frames;
}

//-----------------------------------------------------------------------------
// Returns the frame with the given name.
//-----------------------------------------------------------------------------
Frame *Mesh::GetFrame( char *name )
{
m_frames->Iterate( true );
while( m_frames->Iterate() )
if( strcmp( m_frames->GetCurrent()->Name, name ) == 0 )
return m_frames->GetCurrent();

return NULL;
}

//-----------------------------------------------------------------------------
// Returns the reference point wth the given name.
//-----------------------------------------------------------------------------
Frame *Mesh::GetReferencePoint( char *name )
{
m_refPoints->Iterate( true );
while( m_refPoints->Iterate() )
if( strcmp( m_refPoints->GetCurrent()->Name, name ) == 0 )
return m_refPoints->GetCurrent();

return NULL;
}

//-----------------------------------------------------------------------------
// Prepares the given frame.
//-----------------------------------------------------------------------------
void Mesh::PrepareFrame( Frame *frame )
{
m_frames->Add( frame );

// Check if this frame is actually a reference point.
if( strncmp( "rp_", frame->Name, 3 ) == 0 )
m_refPoints->Add( frame );

// Set the initial final transformation.
frame->finalTransformationMatrix = frame->TransformationMatrix;

// Prepare the frame's mesh container, if it has one.
if( frame->pMeshContainer != NULL )
{
MeshContainer *meshContainer = (MeshContainer*)frame->pMeshContainer;

// Check if this mesh is a skinned mesh.
if( meshContainer->pSkinInfo != NULL )
{
// Create the array of bone matrix pointers.
meshContainer->boneMatrixPointers = new D3DXMATRIX*[meshContainer->pSkinInfo->GetNumBones()];

// Set up the pointers to the mesh's bone transformation matrices.
for( unsigned long b = 0; b < meshContainer->pSkinInfo->GetNumBones(); b++ )
{
Frame *bone = (Frame*)D3DXFrameFind( m_firstFrame, meshContainer->pSkinInfo->GetBoneName( b ) );
if( bone == NULL )
continue;

meshContainer->boneMatrixPointers[b] = &bone->finalTransformationMatrix;
}

// Keep track of the maximum bones out of all the mesh containers.
if( m_totalBoneMatrices < meshContainer->pSkinInfo->GetNumBones() )
m_totalBoneMatrices = meshContainer->pSkinInfo->GetNumBones();
}

// Check if the mesh has any materials.
if( meshContainer->NumMaterials > 0 )
{
// Load all the materials in via the material manager.
for( unsigned long m = 0; m < meshContainer->NumMaterials; m++ )
{
// Ensure the material has a texture.
if( meshContainer->materialNames[m] != NULL )
{
// Get the name of the material's script and load it.
char *name = new char[strlen( meshContainer->materialNames[m] ) + 5];
sprintf( name, "%s.txt", meshContainer->materialNames[m] );
meshContainer->materials[m] = g_engine->GetMaterialManager()->Add( name, GetPath() );
SAFE_DELETE_ARRAY( name );
}
}
}
}

// Prepare the frame's siblings.
if( frame->pFrameSibling != NULL )
PrepareFrame( (Frame*)frame->pFrameSibling );

// Prepare the frame's children.
if( frame->pFrameFirstChild != NULL )
PrepareFrame( (Frame*)frame->pFrameFirstChild );
}

//-----------------------------------------------------------------------------
// Updates the given frame's transformation matrices.
//-----------------------------------------------------------------------------
void Mesh::UpdateFrame( Frame *frame, D3DXMATRIX *parentTransformationMatrix )
{
if( parentTransformationMatrix != NULL )
D3DXMatrixMultiply( &frame->finalTransformationMatrix, &frame->TransformationMatrix, parentTransformationMatrix );
else
frame->finalTransformationMatrix = frame->TransformationMatrix;

// Update the frame's siblings.
if( frame->pFrameSibling != NULL )
UpdateFrame( (Frame*)frame->pFrameSibling, parentTransformationMatrix );

// Update the frame's children.
if( frame->pFrameFirstChild != NULL )
UpdateFrame( (Frame*)frame->pFrameFirstChild, &frame->finalTransformationMatrix );
}

//-----------------------------------------------------------------------------
// Renders the given frame's mesh containers, if it has any.
//-----------------------------------------------------------------------------
void Mesh::RenderFrame( Frame *frame )
{
MeshContainer *meshContainer = (MeshContainer*)frame->pMeshContainer;

// Render this frame's mesh, if it has one.
if( frame->pMeshContainer != NULL )
{
// Check if this mesh is a skinned mesh.
if( meshContainer->pSkinInfo != NULL )
{
// Create the bone transformations using the mesh's transformation matrices.
for( unsigned long b = 0; b < meshContainer->pSkinInfo->GetNumBones(); ++b )
D3DXMatrixMultiply( &m_boneMatrices[b], meshContainer->pSkinInfo->GetBoneOffsetMatrix( b ), meshContainer->boneMatrixPointers[b] );

// Update the meshes vertices with the new bone transformation matrices.
PBYTE sourceVertices, destinationVertices;
meshContainer->originalMesh->LockVertexBuffer( D3DLOCK_READONLY, (void**)&sourceVertices );
meshContainer->MeshData.pMesh->LockVertexBuffer( 0, (void**)&destinationVertices );
meshContainer->pSkinInfo->UpdateSkinnedMesh( m_boneMatrices, NULL, sourceVertices, destinationVertices );
meshContainer->originalMesh->UnlockVertexBuffer();
meshContainer->MeshData.pMesh->UnlockVertexBuffer();

// Render the mesh by atrtribute group.
for( unsigned long a = 0; a < meshContainer->totalAttributeGroups; a++ )
{
g_engine->GetDevice()->SetMaterial( meshContainer->materials[meshContainer->attributeTable[a].AttribId]->GetLighting() );
g_engine->GetDevice()->SetTexture( 0, meshContainer->materials[meshContainer->attributeTable[a].AttribId]->GetTexture() );
meshContainer->MeshData.pMesh->DrawSubset( meshContainer->attributeTable[a].AttribId );
}
}
else
{
// This is not a skinned mesh, so render it like a static mesh.
for( unsigned long m = 0; m < meshContainer->NumMaterials; m++)
{
if( meshContainer->materials[m] )
{
g_engine->GetDevice()->SetMaterial( meshContainer->materials[m]->GetLighting() );
g_engine->GetDevice()->SetTexture( 0, meshContainer->materials[m]->GetTexture() );
}
else
g_engine->GetDevice()->SetTexture( 0, NULL );

meshContainer->MeshData.pMesh->DrawSubset( m );
}
}
}

// Render the frame's siblings.
if( frame->pFrameSibling != NULL )
RenderFrame( (Frame*)frame->pFrameSibling );

// Render the frame's children.
if( frame->pFrameFirstChild != NULL )
RenderFrame( (Frame*)frame->pFrameFirstChild );
}

Share this post


Link to post
Share on other sites

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