hermitte
Hi,I met and solved your problems too.
It is the reason that this is must be some mistake in Texture rendering.
I think the problem is DirectX recyled the texture's memory .
When the 3d object rendering in multi-thread conidition, the memory has cleaned AUTOMATICLY,so this is a null pointer mistake.
My method is don't use MeshContainer to store your texture,just store your texture's name.
You must load the texture as your 3D object is need to initialised.JUST Look at my code.
private void DrawMeshContainer(MeshContainerDerived mesh, FrameDerived frame)
{
// Is there skin information
if (mesh.SkinInformation != null)
{
int attribIdPrev = -1;
// Draw
for (int iattrib = 0; iattrib < mesh.NumberAttributes; iattrib++)
{
int numBlend = 0;
BoneCombination[] bones = mesh.GetBones();
for (int i = 0; i < mesh.NumberInfluences; i++)
{
if (bones[iattrib].BoneId
!= -1)
{
numBlend = i;
}
}
if (device.DeviceCaps.MaxVertexBlendMatrices >= numBlend + 1)
{
// first calculate the world matrices for the current set of
// blend weights and get the accurate count of the number of
// blends
Matrix[] offsetMatrices = mesh.GetOffsetMatrices();
FrameDerived[] frameMatrices = mesh.GetFrames();
for (int i = 0; i < mesh.NumberInfluences; i++)
{
int matrixIndex = bones[iattrib].BoneId
;
if (matrixIndex != -1)
{
Matrix tempMatrix = offsetMatrices[matrixIndex] *
frameMatrices[matrixIndex].
CombinedTransformationMatrix;
device.Transform.SetWorldMatrixByIndex(i, tempMatrix);
}
}
device.RenderState.VertexBlend = (VertexBlend)numBlend;
// lookup the material used for this subset of faces
if ((attribIdPrev != bones[iattrib].AttributeId) ||
(attribIdPrev == -1))
{
//drawArgs.device.Material = meshMaterials[scriptedMachine.CurModel][j];
// drawArgs.device.SetTexture(0, meshTextures[scriptedMachine.CurModel][j]);
//device.Material = mesh.GetMaterials()[
// bones[iattrib].AttributeId].Material3D;
device.Material = mesh.GetMaterials()[
bones[iattrib].AttributeId].Material3D;
device.SetTexture(0, textures[bones[iattrib].AttributeId]);
//if you comment this line, It does works!so I find the way!
// device.SetTexture(0, mesh.GetTextures()[
// bones[iattrib].AttributeId]);
attribIdPrev = bones[iattrib].AttributeId;
}
try
{
mesh.MeshData.Mesh.DrawSubset(iattrib);
}
catch (Exception ex) {
;
}
}
}
}
else // standard mesh, just draw it after setting material properties
{
device.Transform.World = frame.CombinedTransformationMatrix;
ExtendedMaterial[] mtrl = mesh.GetMaterials();
for (int iMaterial = 0; iMaterial < mtrl.Length; iMaterial++)
{
device.Material = mtrl[iMaterial].Material3D;
device.SetTexture(0, textures[iMaterial]);
mesh.MeshData.Mesh.DrawSubset(iMaterial);
}
}
}
public override void Initialize(DrawArgs drawArgs)
{
scriptedMachine.Response(this.World);
device = drawArgs.device;
// Initialize the stats font
statsFont = ResourceCache.GetGlobalInstance().CreateFont(device, 15, 0, FontWeight.Bold, 1, false, CharacterSet.Default,
Precision.Default, FontQuality.Default, PitchAndFamily.FamilyDoNotCare | PitchAndFamily.DefaultPitch
, "Arial");
// Create our allocate hierarchy derived class
alloc = new AllocateHierarchyDerived(this);
textSprite = new Sprite(device);
// Load our file
string meshFile = (string)scriptedMachine.ModelList[0];
// Store the current folder, then switch to the folder where the media was found
MeshPath = meshFile;
rootFrame = Mesh.LoadHierarchyFromFile(meshFile, MeshFlags.Managed,
device, alloc, null);
// Calculate the center and radius of a bounding sphere
objectRadius = Frame.CalculateBoundingSphere(rootFrame.FrameHierarchy,
out objectCenter);
// Setup the matrices for animation
SetupBoneMatrices((FrameDerived)rootFrame.FrameHierarchy);
// Start the timer
timer.Start();
// Create any textures
textures = new Texture[textureNames.Length];
for (int i = 0; i < this.textureNames.Length; i++)
{
if (textureNames
!= null)
{
textures
= TextureLoader.FromFile(device,
textureNames
);
}
}
Initialized = true;
}
public override MeshContainer CreateMeshContainer(string name, MeshData meshData, ExtendedMaterial[] materials, EffectInstance[] effectInstances, GraphicsStream adjacency, SkinInformation skinInfo)
{
// We only handle meshes here
if (meshData.Mesh == null)
throw new ArgumentException();
// We must have a vertex format mesh
if (meshData.Mesh.VertexFormat == VertexFormats.None)
throw new ArgumentException();
MeshContainerDerived mesh = new MeshContainerDerived();
mesh.Name = name;
int numFaces = meshData.Mesh.NumberFaces;
Device dev = meshData.Mesh.Device;
// Make sure there are normals
if ((meshData.Mesh.VertexFormat & VertexFormats.Normal) == 0)
{
// Clone the mesh
Mesh tempMesh = meshData.Mesh.Clone(meshData.Mesh.Options.Value,
meshData.Mesh.VertexFormat | VertexFormats.Normal, dev);
meshData.Mesh = tempMesh;
meshData.Mesh.ComputeNormals();
}
// Store the materials
mesh.SetMaterials(materials);
mesh.SetAdjacency(adjacency);
Texture[] meshTextures = new Texture[materials.Length];
Material[] meshMaterials = new Material[materials.Length];
string[] textureNames = new string[materials.Length];
string xFilePath = Path.GetDirectoryName(app.MeshPath);
// Create any textures
for (int i = 0; i < materials.Length; i++)
{
meshMaterials
= materials
.Material3D;
// Set the ambient color for the material (D3DX does not do this)
meshMaterials
.Ambient = meshMaterials
.Diffuse;
if (materials
.TextureFilename != null)
{
string textureFilePath = Path.Combine(xFilePath, materials
.TextureFilename);
//meshTextures
= ResourceCache.GetGlobalInstance().CreateTextureFromFile(
// dev, textureFilePath);
// meshTextures
= TextureLoader.FromFile(dev,
// textureFilePath);
textureNames
= textureFilePath;
}
}
mesh.SetTextures(meshTextures);
// Animation.meshTextures = meshTextures;
// Animation.meshMaterials = meshMaterials;
mesh.MeshData = meshData;
app.TextureNames = textureNames;
// If there is skinning info, save any required data
if (skinInfo != null)
{
mesh.SkinInformation = skinInfo;
int numBones = skinInfo.NumberBones;
Matrix[] offsetMatrices = new Matrix[numBones];
for (int i = 0; i < numBones; i++)
offsetMatrices
= skinInfo.GetBoneOffsetMatrix(i);
mesh.SetOffsetMatrices(offsetMatrices);
app.GenerateSkinnedMesh(mesh);
}
return mesh;
}
}