skeletal animation problem

Started by
8 comments, last by kslam 15 years, 10 months ago
Hi, I got a problem, when I load a charecter model by using directx 9, the charecter model not load in the world origin, I have to zoom out the camera to : D3DXMatrixLookAtLH(&view, &D3DXVECTOR3(0.0f, 0.0f, -5000.0f), &D3DXVECTOR3(0.0f, 0.0f, 0.0f), &D3DXVECTOR3(0.0f, 1.0f, 0.0f)); D3DXMatrixPerspectiveFovLH(&proj, 0.2f, 1.33333f, 0.01f, 100000.0f); then I can see the model but I can't see the texture, but I draw this model in local origin at 3d animation software. I also try to load the Blender's sample model, but I totally can not see the model. I can see the model if I opened the .x file in Directx viewer. The original source code which I using is from the book, The author draw the model by using 3Ds Max, and can be loaded properly. Is it the problem from the Model's .x(3d software) file or from the source code ? Some of the source code are as below :

-----------------------------------------------------------------------
//Set camera
	D3DXMATRIX view, proj, world, r, s;

	D3DXMatrixLookAtLH(&view, &D3DXVECTOR3(0.0f, 0.0f, -5000.0f), 	&D3DXVECTOR3(0.0f, 0.0f, 0.0f), &D3DXVECTOR3(0.0f, 1.0f, 0.0f));
	D3DXMatrixPerspectiveFovLH(&proj, 0.2f, 1.33333f, 0.01f, 	100000.0f);
	D3DXMatrixRotationYawPitchRoll(&r, m_angle, 0.0f, 0.0f);
	D3DXMatrixScaling(&s, 1.0f, 1.0f, 1.0f);
	world = s * r;
	

	m_pDevice->SetTransform(D3DTS_VIEW, &view);
	m_pDevice->SetTransform(D3DTS_PROJECTION, &proj);
	m_pDevice->SetTransform(D3DTS_WORLD, &world);

m_skinnedMesh.SetPose(world, NULL, m_unitTime);

-----------------------------------------------------------------------
void SKINNEDMESH::SetPose(D3DXMATRIX world, ID3DXAnimationController* animControl, float time)
{
	if(animControl != NULL)
		animControl->AdvanceTime(time, NULL);
	else m_pAnimControl->AdvanceTime(time, NULL);

	UpdateMatrices((BONE*)m_pRootBone, &world);

-----------------------------------------------------------------------void SKINNEDMESH::Render(BONE *bone)
{
	if(bone == NULL)bone = (BONE*)m_pRootBone;

	//If there is a mesh to render...
	if(bone->pMeshContainer != NULL)
	{
		BONEMESH *boneMesh = (BONEMESH*)bone->pMeshContainer;

		if (boneMesh->pSkinInfo != NULL)
		{		
			// set up bone transforms
			int numBones = boneMesh->pSkinInfo->GetNumBones();
			for(int i=0;i < numBones;i++)
				D3DXMatrixMultiply(&boneMesh->currentBoneMatrices,
								   &boneMesh->boneOffsetMatrices, 
								   boneMesh->boneMatrixPtrs);

			//Update the skinned mesh
			BYTE *src = NULL, *dest = NULL;
			boneMesh->OriginalMesh->LockVertexBuffer(D3DLOCK_READONLY, (VOID**)&src);
			boneMesh->MeshData.pMesh->LockVertexBuffer(0, (VOID**)&dest);

			boneMesh->pSkinInfo->UpdateSkinnedMesh(boneMesh->currentBoneMatrices, NULL, src, dest);

			boneMesh->MeshData.pMesh->UnlockVertexBuffer();
			boneMesh->OriginalMesh->UnlockVertexBuffer();

			//Render the mesh
			for(int i=0;i < boneMesh->NumAttributeGroups;i++)
			{
				int mtrlIndex = boneMesh->attributeTable.AttribId;
				m_pDevice->SetMaterial(&(boneMesh->materials[mtrlIndex]));
				//m_pDevice->SetTexture(0, boneMesh->textures[mtrlIndex]);
				boneMesh->MeshData.pMesh->DrawSubset(mtrlIndex);
			}
		}
	}

	if(bone->pFrameSibling != NULL)Render((BONE*)bone->pFrameSibling);
	if(bone->pFrameFirstChild != NULL)Render((BONE*)bone->pFrameFirstChild);

-----------------------------------------------------------------------


Thank you Kslam
Advertisement
If the mesh can be seen properly in the mesh viewer, then it is extremely likely that the problem is in your code.

Does your code load and display other .x files properly, like tiny.x, etc?

With regard to the texture, the code you posted has the SetTexture() line commented out.

Also, do you successfully load the texture when the .x file is loaded? If so, how do you know?

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

The model create using 3ds max can load successfully( position and texture).
The tiny.x can be loaded but not in origin coordinate, I have to zoom out in order to see the model and can not see the texture. Do u know how to set the model to origin position in Directx 9.

The texture code as below :

HRESULT BONE_HIERARCHY::CreateMeshContainer(LPCSTR Name,											CONST D3DXMESHDATA *pMeshData,											CONST D3DXMATERIAL *pMaterials,											CONST D3DXEFFECTINSTANCE *pEffectInstances,											DWORD NumMaterials,											CONST DWORD *pAdjacency,											LPD3DXSKININFO pSkinInfo,											LPD3DXMESHCONTAINER *ppNewMeshContainer){	//Create new Bone Mesh	BONEMESH *boneMesh = new BONEMESH;	memset(boneMesh, 0, sizeof(BONEMESH));	//Get mesh data	boneMesh->OriginalMesh = pMeshData->pMesh;	boneMesh->MeshData.pMesh = pMeshData->pMesh;	boneMesh->MeshData.Type = pMeshData->Type;	pMeshData->pMesh->AddRef();		//Add Reference so that the mesh isnt deallocated	IDirect3DDevice9 *m_pDevice = NULL;		pMeshData->pMesh->GetDevice(&m_pDevice);	//Get Device ptr from mesh	//Copy materials and load textures (just like with a static mesh)	for(int i=0;i<NumMaterials;i++)	{		D3DXMATERIAL mtrl;		memcpy(&mtrl, &pMaterials, sizeof(D3DXMATERIAL));		boneMesh->materials.push_back(mtrl.MatD3D);		if(mtrl.pTextureFilename)		{			char textureFname[200];			strcpy(textureFname, "units/");			strcat(textureFname, mtrl.pTextureFilename);			//Load texture			IDirect3DTexture9* newTexture = NULL;			D3DXCreateTextureFromFile(m_pDevice, textureFname, &newTexture);			boneMesh->textures.push_back(newTexture);		}	}	if(pSkinInfo != NULL)	{		//Get Skin Info		boneMesh->pSkinInfo = pSkinInfo;		pSkinInfo->AddRef();	//Add reference so that the SkinInfo isnt deallocated		//Clone mesh and store in boneMesh->MeshData.pMesh		pMeshData->pMesh->CloneMeshFVF(D3DXMESH_MANAGED, pMeshData->pMesh->GetFVF(), 									   m_pDevice, &boneMesh->MeshData.pMesh);				//Get Attribute Table		boneMesh->MeshData.pMesh->GetAttributeTable(NULL, &boneMesh->NumAttributeGroups);		boneMesh->attributeTable = new D3DXATTRIBUTERANGE[boneMesh->NumAttributeGroups];		boneMesh->MeshData.pMesh->GetAttributeTable(boneMesh->attributeTable, NULL);		//Create bone offset and current matrices		int NumBones = pSkinInfo->GetNumBones();		boneMesh->boneOffsetMatrices = new D3DXMATRIX[NumBones];				boneMesh->currentBoneMatrices = new D3DXMATRIX[NumBones];		//Get bone offset matrices		for(int i=0;i < NumBones;i++)			boneMesh->boneOffsetMatrices = *(boneMesh->pSkinInfo->GetBoneOffsetMatrix(i));	}	//Set ppNewMeshContainer to the newly created boneMesh container	*ppNewMeshContainer = boneMesh;	return S_OK;}


Something I notice, you have a very small fov in your perspective matrix. Your view is in an extreme "zoom" mode. You're not zooming out, you're zooming in, which makes the model appear much larger than a more normal perspective. Try setting the fov in your perspective matrix call to something a little more "normal," such as D3DX_PI/4.0f.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

I can see the model, but I can't see the texture.

The settexture code as below :

void SKINNEDMESH::Render(BONE *bone){	if(bone == NULL)bone = (BONE*)m_pRootBone;	//If there is a mesh to render...	if(bone->pMeshContainer != NULL)	{		BONEMESH *boneMesh = (BONEMESH*)bone->pMeshContainer;		if (boneMesh->pSkinInfo != NULL)		{					// set up bone transforms			int numBones = boneMesh->pSkinInfo->GetNumBones();			for(int i=0;i < numBones;i++)				D3DXMatrixMultiply(&boneMesh->currentBoneMatrices,								   &boneMesh->boneOffsetMatrices, 								   boneMesh->boneMatrixPtrs);			//Update the skinned mesh			BYTE *src = NULL, *dest = NULL;			boneMesh->OriginalMesh->LockVertexBuffer(D3DLOCK_READONLY, (VOID**)&src);			boneMesh->MeshData.pMesh->LockVertexBuffer(0, (VOID**)&dest);			boneMesh->pSkinInfo->UpdateSkinnedMesh(boneMesh->currentBoneMatrices, NULL, src, dest);			boneMesh->MeshData.pMesh->UnlockVertexBuffer();			boneMesh->OriginalMesh->UnlockVertexBuffer();			//Render the mesh			for(int i=0;i < boneMesh->NumAttributeGroups;i++)			{				int mtrlIndex = boneMesh->attributeTable.AttribId;				m_pDevice->SetMaterial(&(boneMesh->materials[mtrlIndex]));				m_pDevice->SetTexture(0, boneMesh->textures[mtrlIndex]);				boneMesh->MeshData.pMesh->DrawSubset(mtrlIndex);			}		}	}	if(bone->pFrameSibling != NULL)Render((BONE*)bone->pFrameSibling);	if(bone->pFrameFirstChild != NULL)Render((BONE*)bone->pFrameFirstChild);}
this is main cpp file.

#include <windows.h>#include <d3dx9.h>#include "debug.h"#include "skinnedmesh.h"#include "shader.h"class APPLICATION{	public:				APPLICATION();		HRESULT Init(HINSTANCE hInstance, int width, int height, bool windowed);		HRESULT Update(float deltaTime);		HRESULT Render();		HRESULT Cleanup();		HRESULT Quit();		DWORD FtoDword(float f){return *((DWORD*)&f);}	private:		IDirect3DDevice9* m_pDevice; 		SKINNEDMESH m_skinnedMesh;		DWORD m_time, m_pressTime;		int m_fps, m_lastFps, m_col;		float m_angle, m_unitTime, m_colFade;		D3DXVECTOR4 m_activeCol, m_lastCol, m_currentCol;		HWND m_mainWindow;		ID3DXFont *m_pFont;		//Shaders		SHADER m_unitVS, m_unitPS;		D3DXHANDLE m_worldHandle, m_viewProjHandle, m_sunHandle, m_teamColHandle;};int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd){    APPLICATION app;	if(FAILED(app.Init(hInstance, 800, 600, true)))return 0;	MSG msg;	memset(&msg, 0, sizeof(MSG));	int startTime = timeGetTime(); 	while(msg.message != WM_QUIT)	{		if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))		{			::TranslateMessage(&msg);			::DispatchMessage(&msg);		}		else        {				int t = timeGetTime();			float deltaTime = (t - startTime)*0.001f;			app.Update(deltaTime);			app.Render();			startTime = t;        }    }	app.Cleanup();    return msg.wParam;}APPLICATION::APPLICATION(){	m_pDevice = NULL; 	m_mainWindow = 0;	srand(GetTickCount());	m_fps = m_lastFps = m_col = 0;	m_angle = m_unitTime = m_colFade = 0.0f;	m_time = m_pressTime = GetTickCount();	m_currentCol = m_lastCol = m_activeCol = D3DXVECTOR4(1.0f, 0.0f, 0.0f, 1.0f);}HRESULT APPLICATION::Init(HINSTANCE hInstance, int width, int height, bool windowed){	debug.Print("Application initiated");	//Create Window Class	WNDCLASS wc;	memset(&wc, 0, sizeof(WNDCLASS));	wc.style         = CS_HREDRAW | CS_VREDRAW;	wc.lpfnWndProc   = (WNDPROC)::DefWindowProc; 	wc.hInstance     = hInstance;	wc.lpszClassName = "D3DWND";	//Register Class and Create new Window	RegisterClass(&wc);	m_mainWindow = CreateWindow("D3DWND", "Example 8.1: Team Color", WS_EX_TOPMOST, 0, 0, width, height, 0, 0, hInstance, 0); 	SetCursor(NULL);	ShowWindow(m_mainWindow, SW_SHOW);	UpdateWindow(m_mainWindow);	//Create IDirect3D9 Interface	IDirect3D9* d3d9 = Direct3DCreate9(D3D_SDK_VERSION);    if(d3d9 == NULL)	{		debug.Print("Direct3DCreate9() - FAILED");		return E_FAIL;	}	//Check that the Device supports what we need from it	D3DCAPS9 caps;	d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);	//Hardware Vertex Processing or not?	int vp = 0;	if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)		vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;	else vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;	//Check vertex & pixelshader versions	if(caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))	{		debug.Print("Warning - Your graphic card does not support vertex and pixelshaders version 2.0");	}	//Set D3DPRESENT_PARAMETERS	D3DPRESENT_PARAMETERS d3dpp;	d3dpp.BackBufferWidth            = width;	d3dpp.BackBufferHeight           = height;	d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;	d3dpp.BackBufferCount            = 1;	d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;	d3dpp.MultiSampleQuality         = 0;	d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 	d3dpp.hDeviceWindow              = m_mainWindow;	d3dpp.Windowed                   = windowed;	d3dpp.EnableAutoDepthStencil     = true; 	d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;	d3dpp.Flags                      = 0;	d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;	d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;	//Create the IDirect3DDevice9	if(FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_mainWindow,								 vp, &d3dpp, &m_pDevice)))	{		debug.Print("Failed to create IDirect3DDevice9");		return E_FAIL;	}	//Release IDirect3D9 interface	d3d9->Release();	D3DXCreateFont(m_pDevice, 18, 0, 0, 1, false,  				   DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,				   DEFAULT_PITCH | FF_DONTCARE, "Arial", &m_pFont);	//m_skinnedMesh.Load("units/magician.x", m_pDevice);	m_skinnedMesh.Load("units/tiny1.x", m_pDevice);	m_skinnedMesh.SetAnimation("Run");	//Set sampler state	for(int i=0;i<4;i++)	{		m_pDevice->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);		m_pDevice->SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);		m_pDevice->SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_POINT);	}	//Setup shaders	m_unitVS.Init(m_pDevice, "shaders/lighting.vs", VERTEX_SHADER);	m_worldHandle = m_unitVS.GetConstant("matW");	m_viewProjHandle = m_unitVS.GetConstant("matVP");	m_sunHandle = m_unitVS.GetConstant("DirToSun");	m_unitPS.Init(m_pDevice, "shaders/teamCol.ps", PIXEL_SHADER);	m_teamColHandle = m_unitPS.GetConstant("tmCol");	return S_OK;}HRESULT APPLICATION::Update(float deltaTime){			//Rotate unit	m_angle += deltaTime * 0.2f;	m_unitTime = deltaTime * 0.5f;	if(m_angle > D3DX_PI * 2.0f)m_angle -= D3DX_PI * 2.0f;	//change color	m_colFade += deltaTime * 0.4f;	if(m_colFade > 1.0f)m_colFade = 1.0f;	m_currentCol = m_lastCol * (1.0f - m_colFade) + m_activeCol * m_colFade;	if(KEYDOWN(VK_SPACE) && GetTickCount() - m_pressTime > 300)	{		m_pressTime = GetTickCount();		m_col++;		if(m_col > 11)m_col = 0;		D3DXVECTOR4 tmColors[] = {D3DXVECTOR4(1.0f, 0.0f, 0.0f, 1.0f),								  D3DXVECTOR4(0.0f, 1.0f, 0.0f, 1.0f),								  D3DXVECTOR4(0.0f, 0.0f, 1.0f, 1.0f),								  D3DXVECTOR4(1.0f, 1.0f, 0.0f, 1.0f),								  D3DXVECTOR4(1.0f, 0.0f, 1.0f, 1.0f),								  D3DXVECTOR4(0.0f, 1.0f, 1.0f, 1.0f),								  D3DXVECTOR4(0.5f, 0.25f, 0.0f, 1.0f),								  D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f),								  D3DXVECTOR4(1.0f, 0.5f, 0.0f, 1.0f),								  D3DXVECTOR4(0.0f, 0.25f, 0.0f, 1.0f),								  D3DXVECTOR4(0.25f, 0.0f, 0.0f, 1.0f),								  D3DXVECTOR4(0.0f, 0.0f, 0.25f, 1.0f)};		m_lastCol = m_currentCol;		m_activeCol = tmColors[m_col];		m_colFade = 0.0f;	}	else if(KEYDOWN(VK_ESCAPE))	{		Quit();	}	return S_OK;}	HRESULT APPLICATION::Render(){    // Clear the viewport    m_pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);	D3DVIEWPORT9 v,v2;	m_pDevice->GetViewport(&v);	v2 = v;	v.Y = 200;	v.Height = 200;	m_pDevice->SetViewport(&v);	m_pDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DXCOLOR(m_currentCol.x, m_currentCol.y, m_currentCol.z, 1.0f), 1.0f, 0);	m_pDevice->SetViewport(&v2);	//FPS Calculation	m_fps++;	if(GetTickCount() - m_time > 1000)	{		m_lastFps = m_fps;		m_fps = 0;		m_time = GetTickCount();	}	//Set camera	D3DXMATRIX view, proj, world, r, s;	D3DXMatrixLookAtLH(&view, &D3DXVECTOR3(0.0f, 1000.0f, -5000.0f), &D3DXVECTOR3(0.0f, 4.0f, 0.0f), &D3DXVECTOR3(0.0f, 1.0f, 0.0f));	D3DXMatrixPerspectiveFovLH(&proj, 0.2f, 1.33333f, 0.01f, 10000.0f);	D3DXMatrixRotationYawPitchRoll(&r, m_angle, 0.0f, 0.0f);	D3DXMatrixScaling(&s, 1.2f, 1.2f, 1.2f);	world = s * r;	m_pDevice->SetTransform(D3DTS_VIEW, &view);	m_pDevice->SetTransform(D3DTS_PROJECTION, &proj);	m_pDevice->SetTransform(D3DTS_WORLD, &world);    // Begin the scene     if(SUCCEEDED(m_pDevice->BeginScene()))    {		m_unitVS.SetMatrix(m_worldHandle, world);		m_unitVS.SetMatrix(m_viewProjHandle, view * proj);		D3DXVECTOR3 sun;		D3DXVec3Normalize(&sun, &D3DXVECTOR3(0.5f, 1.0f, -0.5));		m_unitVS.SetVector3(m_sunHandle, sun);		m_unitPS.SetVector4(m_teamColHandle, m_currentCol);		m_unitVS.Begin();		m_unitPS.Begin();		m_skinnedMesh.SetPose(world, NULL, m_unitTime);		m_skinnedMesh.Render(NULL);		m_unitPS.End();		m_unitVS.End();		RECT r[] = {{10, 10, 0, 0}, {720, 10, 0, 0}};		m_pFont->DrawText(NULL, "Space: Change Team Color", -1, &r[0], DT_LEFT| DT_TOP | DT_NOCLIP, 0xff000000);		//FPS		char number[50];		std::string text = "FPS: ";		text += _itoa(m_lastFps, number, 10);		m_pFont->DrawText(NULL, text.c_str(), -1, &r[1], DT_LEFT| DT_TOP | DT_NOCLIP, 0xff000000);        // End the scene.		m_pDevice->EndScene();		m_pDevice->Present(0, 0, 0, 0);    }	return S_OK;}HRESULT APPLICATION::Cleanup(){	try	{		m_pFont->Release();		m_pDevice->Release();		debug.Print("Application terminated");	}	catch(...){}	return S_OK;}HRESULT APPLICATION::Quit(){	::DestroyWindow(m_mainWindow);	::PostQuitMessage(0);	return S_OK;}



This is skinmesh cpp file.


#include "skinnedMesh.h"class BONE_HIERARCHY: public ID3DXAllocateHierarchy{	public:		STDMETHOD(CreateFrame)(THIS_ LPCSTR Name, LPD3DXFRAME *ppNewFrame);		STDMETHOD(CreateMeshContainer)(THIS_ LPCTSTR 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);};HRESULT BONE_HIERARCHY::CreateFrame(LPCSTR Name, LPD3DXFRAME *ppNewFrame){	BONE *newBone = new BONE;	memset(newBone, 0, sizeof(BONE));	//Copy name	if(Name != NULL)	{		newBone->Name = new char[strlen(Name)+1];		strcpy(newBone->Name, Name);	}	//Set the transformation matrices	D3DXMatrixIdentity(&newBone->TransformationMatrix);	D3DXMatrixIdentity(&newBone->CombinedTransformationMatrix);	//Return the new bone...	*ppNewFrame = (D3DXFRAME*)newBone;	return S_OK;}HRESULT BONE_HIERARCHY::CreateMeshContainer(LPCSTR Name,											CONST D3DXMESHDATA *pMeshData,											CONST D3DXMATERIAL *pMaterials,											CONST D3DXEFFECTINSTANCE *pEffectInstances,											DWORD NumMaterials,											CONST DWORD *pAdjacency,											LPD3DXSKININFO pSkinInfo,											LPD3DXMESHCONTAINER *ppNewMeshContainer){	//Create new Bone Mesh	BONEMESH *boneMesh = new BONEMESH;	memset(boneMesh, 0, sizeof(BONEMESH));	//Get mesh data	boneMesh->OriginalMesh = pMeshData->pMesh;	boneMesh->MeshData.pMesh = pMeshData->pMesh;	boneMesh->MeshData.Type = pMeshData->Type;	pMeshData->pMesh->AddRef();		//Add Reference so that the mesh isnt deallocated	IDirect3DDevice9 *m_pDevice = NULL;		pMeshData->pMesh->GetDevice(&m_pDevice);	//Get Device ptr from mesh	//Copy materials and load textures (just like with a static mesh)	for(int i=0;i<NumMaterials;i++)	{		D3DXMATERIAL mtrl;		memcpy(&mtrl, &pMaterials, sizeof(D3DXMATERIAL));		boneMesh->materials.push_back(mtrl.MatD3D);		if(mtrl.pTextureFilename)		{			char textureFname[200];			strcpy(textureFname, "units/");			strcat(textureFname, mtrl.pTextureFilename);			//Load texture			IDirect3DTexture9* newTexture = NULL;			D3DXCreateTextureFromFile(m_pDevice, textureFname, &newTexture);			boneMesh->textures.push_back(newTexture);		}	}	if(pSkinInfo != NULL)	{		//Get Skin Info		boneMesh->pSkinInfo = pSkinInfo;		pSkinInfo->AddRef();	//Add reference so that the SkinInfo isnt deallocated		//Clone mesh and store in boneMesh->MeshData.pMesh		pMeshData->pMesh->CloneMeshFVF(D3DXMESH_MANAGED, pMeshData->pMesh->GetFVF(), 									   m_pDevice, &boneMesh->MeshData.pMesh);				//Get Attribute Table		boneMesh->MeshData.pMesh->GetAttributeTable(NULL, &boneMesh->NumAttributeGroups);		boneMesh->attributeTable = new D3DXATTRIBUTERANGE[boneMesh->NumAttributeGroups];		boneMesh->MeshData.pMesh->GetAttributeTable(boneMesh->attributeTable, NULL);		//Create bone offset and current matrices		int NumBones = pSkinInfo->GetNumBones();		boneMesh->boneOffsetMatrices = new D3DXMATRIX[NumBones];				boneMesh->currentBoneMatrices = new D3DXMATRIX[NumBones];		//Get bone offset matrices		for(int i=0;i < NumBones;i++)			boneMesh->boneOffsetMatrices = *(boneMesh->pSkinInfo->GetBoneOffsetMatrix(i));	}	//Set ppNewMeshContainer to the newly created boneMesh container	*ppNewMeshContainer = boneMesh;	return S_OK;}HRESULT BONE_HIERARCHY::DestroyFrame(LPD3DXFRAME pFrameToFree) {	if(pFrameToFree)	{		//Free name		if(pFrameToFree->Name != NULL)			delete [] pFrameToFree->Name;		//Free bone		delete pFrameToFree;	}	pFrameToFree = NULL;    return S_OK; }HRESULT BONE_HIERARCHY::DestroyMeshContainer(LPD3DXMESHCONTAINER pMeshContainerBase){	BONEMESH *boneMesh = (BONEMESH*)pMeshContainerBase;	//Release textures	for(int i=0;i < boneMesh->textures.size();i++)		if(boneMesh->textures != NULL)			boneMesh->textures->Release();	//Release mesh data	if(boneMesh->MeshData.pMesh)boneMesh->MeshData.pMesh->Release();	if(boneMesh->pSkinInfo)boneMesh->pSkinInfo->Release();	if(boneMesh->OriginalMesh)boneMesh->OriginalMesh->Release();	delete boneMesh;    return S_OK;}////////////////////////////////////////////////////////////////////////////////////////////////////									SKINNED MESH												////////////////////////////////////////////////////////////////////////////////////////////////////struct VERTEX{	VERTEX();	VERTEX(D3DXVECTOR3 pos, D3DCOLOR col){position = pos; color = col;}	D3DXVECTOR3 position;	D3DCOLOR color;	static const DWORD FVF;};const DWORD VERTEX::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;SKINNEDMESH::SKINNEDMESH(){	m_pRootBone = NULL;	m_pAnimControl = NULL;}SKINNEDMESH::~SKINNEDMESH(){	BONE_HIERARCHY boneHierarchy;	boneHierarchy.DestroyFrame(m_pRootBone);	if(m_pAnimControl)m_pAnimControl->Release();}void SKINNEDMESH::Load(char fileName[], IDirect3DDevice9 *Dev){	m_pDevice = Dev;	BONE_HIERARCHY boneHierarchy;	D3DXLoadMeshHierarchyFromX(fileName, D3DXMESH_MANAGED, 							   m_pDevice, &boneHierarchy,							   NULL, &m_pRootBone, &m_pAnimControl);	SetupBoneMatrixPointers((BONE*)m_pRootBone);}void SKINNEDMESH::UpdateMatrices(BONE* bone, D3DXMATRIX *parentMatrix){	if(bone == NULL)return;	D3DXMatrixMultiply(&bone->CombinedTransformationMatrix,					   &bone->TransformationMatrix,					   parentMatrix);	if(bone->pFrameSibling)UpdateMatrices((BONE*)bone->pFrameSibling, parentMatrix);	if(bone->pFrameFirstChild)UpdateMatrices((BONE*)bone->pFrameFirstChild, &bone->CombinedTransformationMatrix);}void SKINNEDMESH::Render(BONE *bone){	if(bone == NULL)bone = (BONE*)m_pRootBone;	//If there is a mesh to render...	if(bone->pMeshContainer != NULL)	{		BONEMESH *boneMesh = (BONEMESH*)bone->pMeshContainer;		if (boneMesh->pSkinInfo != NULL)		{					// set up bone transforms			int numBones = boneMesh->pSkinInfo->GetNumBones();			for(int i=0;i < numBones;i++)				D3DXMatrixMultiply(&boneMesh->currentBoneMatrices,								   &boneMesh->boneOffsetMatrices, 								   boneMesh->boneMatrixPtrs);			//Update the skinned mesh			BYTE *src = NULL, *dest = NULL;			boneMesh->OriginalMesh->LockVertexBuffer(D3DLOCK_READONLY, (VOID**)&src);			boneMesh->MeshData.pMesh->LockVertexBuffer(0, (VOID**)&dest);			boneMesh->pSkinInfo->UpdateSkinnedMesh(boneMesh->currentBoneMatrices, NULL, src, dest);			boneMesh->MeshData.pMesh->UnlockVertexBuffer();			boneMesh->OriginalMesh->UnlockVertexBuffer();			//Render the mesh			for(int i=0;i < boneMesh->NumAttributeGroups;i++)			{				int mtrlIndex = boneMesh->attributeTable.AttribId;				m_pDevice->SetMaterial(&(boneMesh->materials[mtrlIndex]));				m_pDevice->SetTexture(0, boneMesh->textures[mtrlIndex]);				boneMesh->MeshData.pMesh->DrawSubset(mtrlIndex);			}		}	}	if(bone->pFrameSibling != NULL)Render((BONE*)bone->pFrameSibling);	if(bone->pFrameFirstChild != NULL)Render((BONE*)bone->pFrameFirstChild);}ID3DXMesh* SKINNEDMESH::GetCurrentMesh(BONE *bone){	if(bone == NULL)		bone = (BONE*)m_pRootBone;	if(bone->pMeshContainer != NULL)		return bone->pMeshContainer->MeshData.pMesh;	ID3DXMesh* mesh = NULL;	if(bone->pFrameSibling != NULL)mesh = GetCurrentMesh((BONE*)bone->pFrameSibling);	if(mesh == NULL && bone->pFrameFirstChild != NULL)mesh = GetCurrentMesh((BONE*)bone->pFrameFirstChild);	return mesh;}void SKINNEDMESH::SetupBoneMatrixPointers(BONE *bone){	if(bone->pMeshContainer != NULL)	{		BONEMESH *boneMesh = (BONEMESH*)bone->pMeshContainer;		if(boneMesh->pSkinInfo != NULL)		{			int NumBones = boneMesh->pSkinInfo->GetNumBones();			boneMesh->boneMatrixPtrs = new D3DXMATRIX*[NumBones];			for(int i=0;i < NumBones;i++)			{				BONE *b = (BONE*)D3DXFrameFind(m_pRootBone, boneMesh->pSkinInfo->GetBoneName(i));				if(b != NULL)boneMesh->boneMatrixPtrs = &b->CombinedTransformationMatrix;				else boneMesh->boneMatrixPtrs = NULL;			}		}	}	if(bone->pFrameSibling != NULL)SetupBoneMatrixPointers((BONE*)bone->pFrameSibling);	if(bone->pFrameFirstChild != NULL)SetupBoneMatrixPointers((BONE*)bone->pFrameFirstChild);}BONE* SKINNEDMESH::FindBone(char name[]){	return (BONE*) D3DXFrameFind(m_pRootBone, name);}void SKINNEDMESH::SetPose(D3DXMATRIX world, ID3DXAnimationController* animControl, float time){	if(animControl != NULL)		animControl->AdvanceTime(time, NULL);	else m_pAnimControl->AdvanceTime(time, NULL);	UpdateMatrices((BONE*)m_pRootBone, &world);}int SKINNEDMESH::SetAnimation(char name[]){	ID3DXAnimationSet *anim = NULL;	for(int i=0;i<m_pAnimControl->GetMaxNumAnimationSets();i++)	{		anim = NULL;		m_pAnimControl->GetAnimationSet(i, &anim);		if(anim != NULL)		{			if(strcmp(name, anim->GetName()) == 0)			{				m_pAnimControl->SetTrackAnimationSet(0, anim);				anim->Release();				return i;			}			anim->Release();		}	}	return -1;}void SKINNEDMESH::SetAnimation(int index){	ID3DXAnimationSet *anim = NULL;	m_pAnimControl->GetAnimationSet(index, &anim);	if(anim != NULL)m_pAnimControl->SetTrackAnimationSet(0, anim);	anim->Release();}float SKINNEDMESH::GetAnimationDuration(int index){	float duration = 0.0f;	ID3DXAnimationSet *anim = NULL;	m_pAnimControl->GetAnimationSet(index, &anim);	if(anim != NULL)duration = anim->GetPeriod();	anim->Release();	return duration;}std::vector<std::string> SKINNEDMESH::GetAnimations(){	ID3DXAnimationSet *anim = NULL;	std::vector<std::string> animations;	for(int i=0;i<m_pAnimControl->GetMaxNumAnimationSets();i++)	{		anim = NULL;		m_pAnimControl->GetAnimationSet(i, &anim);		if(anim != NULL)		{			animations.push_back(anim->GetName());			anim->Release();		}	}	return animations;}




this is vs file.


uniform extern float4x4 matW;uniform extern float4x4 matVP;uniform extern float3 DirToSun;struct VS_INPUT{   float4 position : POSITION0;   float3 normal : NORMAL0;   float2 uv : TEXCOORD0;};struct VS_OUTPUT{   float4 position : POSITION0;   float2 uv : TEXCOORD0;   float  shade : TEXCOORD1;};VS_OUTPUT Main(VS_INPUT input){   VS_OUTPUT output = (VS_OUTPUT)0;   // Project position homogeneous clip space.   float4 temp = mul(input.position, matW);   output.position = mul(temp, matVP);   // Do basic diffuse lighting calculating to compute vertex shade.   output.shade = max(0.0f, dot(normalize(input.normal), DirToSun));   output.shade = 0.2f + output.shade * 0.8f;   output.uv = input.uv;   return output;}




this is ps file.

sampler unitTexture;uniform extern float4 tmCol;float4 Main(float2 UV : TEXCOORD0, float shade : TEXCOORD1) : COLOR{    float4 c0 = tex2D(unitTexture, UV);    float Inv = 1.0f - c0.a;    //Weigh pixel and team color using the alpha channel    float4 c1 = float4(c0.rgb * Inv + tmCol.rgb * c0.a, 1.0f);    //return Shaded pixel    return c1 * shade;}
A previous question:
Quote:do you successfully load the texture when the .x file is loaded? If so, how do you know?


kslam: you do not test any return codes from any of your calls.
D3DXCreateTextureFromFile(m_pDevice, textureFname, &newTexture);

How do you know if the texture was loaded correctly?

If you don't test any return codes, then you may have many errors.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

I validate the code below, the program run without error but can't see texture. (The model is red color without texture)
If I disable the VS and PS code, the model become black color.
I think this code is custom made for the 3ds Max model.

HRESULT hResult = D3DXCreateTextureFromFile(m_pDevice, textureFname, &newTexture);
if (FAILED(hResult))
{
strcpy(emsg, "Error creating texture.");
PostQuitMessage(WM_QUIT);
break;
}

-------------------------------------------------------------

HRESULT hResult = m_pDevice->SetTexture(0, boneMesh- textures[mtrlIndex]);
if (FAILED(hResult))
{
strcpy(emsg, "Error settexture.");
PostQuitMessage(WM_QUIT);
break;
}
In this loop:
for(int i=0;i < boneMesh->NumAttributeGroups;i++){	int mtrlIndex = boneMesh->attributeTable.AttribId;	m_pDevice->SetMaterial(&(boneMesh->materials[mtrlIndex]));	m_pDevice->SetTexture(0, boneMesh->textures[mtrlIndex]);	boneMesh->MeshData.pMesh->DrawSubset(mtrlIndex);}

you're drawing the subset with the mtrlIndex instead of the attribute group number.

That may not be the problem but you should be using:
boneMesh->MeshData.pMesh->DrawSubset(i);

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

It didn't works.

This topic is closed to new replies.

Advertisement