Example #1
0
void SolarSysDemo::genSphericalTexCoords()
{
	// D3DXCreate* functions generate vertices with position 
	// and normal data.  But for texturing, we also need
	// tex-coords.  So clone the mesh to change the vertex
	// format to a format with tex-coords.

	D3DVERTEXELEMENT9 elements[64];
	UINT numElements = 0;
	VertexPNT::Decl->GetDeclaration(elements, &numElements);

	ID3DXMesh* temp = 0;
	HR(mSphere->CloneMesh(D3DXMESH_SYSTEMMEM, 
		elements, gd3dDevice, &temp));

	ReleaseCOM(mSphere);

	// Now generate texture coordinates for each vertex.
	VertexPNT* vertices = 0;
	HR(temp->LockVertexBuffer(0, (void**)&vertices));

	for(UINT i = 0; i < temp->GetNumVertices(); ++i)
	{
		// Convert to spherical coordinates.
		D3DXVECTOR3 p = vertices[i].pos;
	
 
		float theta = atan2f(p.z, p.x);
		float phi   = acosf(p.y / sqrtf(p.x*p.x+p.y*p.y+p.z*p.z));

		// Phi and theta give the texture coordinates, but are not in 
		// the range [0, 1], so scale them into that range.

		float u = theta / (2.0f*D3DX_PI);
		float v = phi   / D3DX_PI;
		
		// Save texture coordinates.
		
		vertices[i].tex0.x = u;
		vertices[i].tex0.y = v;
	}
	HR(temp->UnlockVertexBuffer());

	// Clone back to a hardware mesh.
	HR(temp->CloneMesh(D3DXMESH_MANAGED | D3DXMESH_WRITEONLY,
		elements, gd3dDevice, &mSphere));

	ReleaseCOM(temp);
}
Example #2
0
void Cone3D::buildTexCoords(IDirect3DDevice9* gd3dDevice)
{
	D3DVERTEXELEMENT9 elements[64];
	UINT numElements = 0;
	VertexPos::Decl->GetDeclaration(elements, &numElements);

	ID3DXMesh* temp = 0;
	HR(mpMesh->CloneMesh(D3DXMESH_SYSTEMMEM,
		elements, gd3dDevice, &temp));

	ReleaseCOM(mpMesh);

	// Now generate texture coordinates for each vertex.
	VertexPos* vertices = 0;
	HR(temp->LockVertexBuffer(0, (void**)&vertices));

	D3DXVECTOR3 maxPoint(-FLT_MAX, -FLT_MAX, -FLT_MAX);
	D3DXVECTOR3 minPoint(FLT_MAX, FLT_MAX, FLT_MAX);

	for (UINT i = 0; i < temp->GetNumVertices(); ++i)
	{
		D3DXVec3Maximize(&maxPoint, &maxPoint, &vertices[i].mPos);
		D3DXVec3Minimize(&minPoint, &minPoint, &vertices[i].mPos);
	}

	float a = minPoint.z;
	float b = maxPoint.z;
	float h = b - a;

	for (int i = 0; i < (int)temp->GetNumVertices(); i++)
	{
		float x = vertices[i].mPos.x;
		float y = vertices[i].mPos.z;
		float z = vertices[i].mPos.y;

		float theta = atan2f(z, x);
		float y2 = y - b;

		float u = theta / (2.0f * D3DX_PI);
		float v = y2 / -h;

		vertices[i].mTexCoord.x = u;
		vertices[i].mTexCoord.y = v;
	}

	HR(temp->UnlockVertexBuffer());

	HR(temp->CloneMesh(D3DXMESH_MANAGED | D3DXMESH_WRITEONLY,
		elements, gd3dDevice, &mpMesh));

	ReleaseCOM(temp);
}
Example #3
0
void MeshX::BuildSkinnedMesh()
{
	ID3DXMesh* oldMesh = allocMeshHierarchy.GetMeshList().front()->MeshData.pMesh;

	//compute normal
	D3DVERTEXELEMENT9 elements[MAX_FVF_DECL_SIZE];
	oldMesh->GetDeclaration(elements);

	ID3DXMesh* tempMesh = 0;
	ID3DXMesh* tempOpMesh = 0;
	oldMesh->CloneMesh(D3DXMESH_SYSTEMMEM, elements, pDevice, &tempMesh);
	 
	if( !HasNormals(tempMesh) )
		D3DXComputeNormals(tempMesh, 0);

	//optimize the mesh
	DWORD* adj = new DWORD[tempMesh->GetNumFaces()*3];
	ID3DXBuffer* remap = 0;
	tempMesh->GenerateAdjacency(0.00001f, adj);
	tempMesh->Optimize(D3DXMESH_SYSTEMMEM | D3DXMESHOPT_VERTEXCACHE | 
		D3DXMESHOPT_ATTRSORT, adj, 0, 0, &remap, &tempOpMesh);

	SafeRelease(tempMesh);

	// In the .X file (specifically the array DWORD vertexIndices[nWeights]
	// data member of the SkinWeights template) each bone has an array of
	// indices which identify the vertices of the mesh that the bone influences.
	// Because we have just rearranged the vertices (from optimizing), the vertex 
	// indices of a bone are obviously incorrect (i.e., they index to vertices the bone
	// does not influence since we moved vertices around).  In order to update a bone's 
	// vertex indices to the vertices the bone _does_ influence, we simply need to specify
	// where we remapped the vertices to, so that the vertex indices can be updated to 
	// match.  This is done with the ID3DXSkinInfo::Remap method.
	skinInfo->Remap(tempOpMesh->GetNumVertices(), 
		(DWORD*)remap->GetBufferPointer());
	SafeRelease(remap); // Done with remap info.

	DWORD        numBoneComboEntries = 0;
	ID3DXBuffer* boneComboTable      = 0;
	DWORD maxVertInfluences;
	skinInfo->ConvertToIndexedBlendedMesh(tempOpMesh, 0,  
		128, 0, 0, 0, 0, &maxVertInfluences,
		&numBoneComboEntries, &boneComboTable, &this->mesh);

	SafeRelease(tempOpMesh);
	SafeRelease(boneComboTable);
	delete[] adj;
}
Example #4
0
void LoadXFile(const std::string & filename, ID3DXMesh** meshOut, std::vector<Mtrl> & mtrls, std::vector<IDirect3DTexture9*> & texs)
{
	ID3DXMesh* meshSys				= 0;
	ID3DXBuffer * adjBuffer			= 0;
	ID3DXBuffer * mtrlBuffer		= 0;
	DWORD numMtrls					= 0;

    //step 1. Load the x file into system memory
    HR(D3DXLoadMeshFromX(filename.c_str(), D3DXMESH_SYSTEMMEM, gd3dDevice, &adjBuffer, &mtrlBuffer, 0, &numMtrls, &meshSys));

    //step 2. look into MAX_FVF_DECL_SIZE
    D3DVERTEXELEMENT9 elems[MAX_FVF_DECL_SIZE];
    HR(meshSys->GetDeclaration(elems));

    bool hasNormals = false;
	D3DVERTEXELEMENT9 term = D3DDECL_END();
    for(int i = 0; i < MAX_FVF_DECL_SIZE; ++i)
    {
        //did we reach end?
        if(elems[i].Stream == 0xff)
            break;

        if(elems[i].Type == D3DDECLTYPE_FLOAT3 && elems[i].Usage == D3DDECLUSAGE_NORMAL && elems[i].UsageIndex == 0)
        {
            hasNormals = true;
            break;
        }
    }

    //step 3.
    D3DVERTEXELEMENT9 elements[64];
    UINT numElements = 0;
    VertexPNT::Decl->GetDeclaration(elements, &numElements);
   
    ID3DXMesh * temp = 0;
    //HR(meshSys->CloneMesh(D3DXMESH_SYSTEMMEM, elements, gd3dDevice, &temp));
	 HR(meshSys->CloneMesh(D3DXMESH_32BIT, elements, gd3dDevice, &temp));
	ReleaseCOM(meshSys);
	meshSys = temp;

    //step 4
    if( hasNormals == false )
        HR(D3DXComputeNormals(meshSys, 0));

    //step 5
    HR(meshSys->Optimize(D3DXMESH_MANAGED | D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT
        | D3DXMESHOPT_VERTEXCACHE, (DWORD*)adjBuffer->GetBufferPointer(), 0, 0, 0, meshOut));

    ReleaseCOM(meshSys); //Done w/ system mesh
    ReleaseCOM(adjBuffer); //done with buffer

    //step 6: get the materials and load the textures
    if(mtrlBuffer != 0 && numMtrls != 0)
    {
		D3DXMATERIAL *d3dxMtrls = (D3DXMATERIAL*)mtrlBuffer->GetBufferPointer();
		
		for(DWORD i = 0; i < numMtrls; ++i)
		{
			//save the ith material.  MatD3D ambient
			//doesnt have a default value, so I'm setting
			//it to be the same as the diffuse
			Mtrl m;
			m.ambient = d3dxMtrls[i].MatD3D.Diffuse;
			m.diffuse = d3dxMtrls[i].MatD3D.Diffuse;
			m.spec = d3dxMtrls[i].MatD3D.Specular;
			m.specPower = d3dxMtrls[i].MatD3D.Power;
			mtrls.push_back(m);

			//check if the ith material has an associative texture
			if(d3dxMtrls[i].pTextureFilename != 0)
			{
				//yes, load the texture for the ith subset
				IDirect3DTexture9* tex = 0;
				char *texFN = d3dxMtrls[i].pTextureFilename;
				HR(D3DXCreateTextureFromFile(gd3dDevice, texFN, &tex));

				//save the loaded texure
				texs.push_back(tex);
			}
			else
			{
				//no texture
				texs.push_back( 0 );
			}
		}
	}

	ReleaseCOM(mtrlBuffer); // done with the buffer
}
Example #5
0
void LoadXFile(
			   const std::string& filename, 
			   ID3DXMesh** meshOut,
			   std::vector<Mtrl>& mtrls, 
			   std::vector<IDirect3DTexture9*>& texs)
{
	// Step 1: Load the .x file from file into a system memory mesh.

	ID3DXMesh* meshSys      = 0;
	ID3DXBuffer* adjBuffer  = 0;
	ID3DXBuffer* mtrlBuffer = 0;
	DWORD numMtrls          = 0;

	HR(D3DXLoadMeshFromX(filename.c_str(), D3DXMESH_SYSTEMMEM, gd3dDevice,
		&adjBuffer,	&mtrlBuffer, 0, &numMtrls, &meshSys));


	// Step 2: Find out if the mesh already has normal info?

	D3DVERTEXELEMENT9 elems[MAX_FVF_DECL_SIZE];
	HR(meshSys->GetDeclaration(elems));

	bool hasNormals = false;
	D3DVERTEXELEMENT9 term = D3DDECL_END();
	for(int i = 0; i < MAX_FVF_DECL_SIZE; ++i)
	{
		// Did we reach D3DDECL_END() {0xFF,0,D3DDECLTYPE_UNUSED, 0,0,0}?
		if(elems[i].Stream == 0xff )
			break;

		if( elems[i].Type == D3DDECLTYPE_FLOAT3 &&
			elems[i].Usage == D3DDECLUSAGE_NORMAL &&
			elems[i].UsageIndex == 0 )
		{
			hasNormals = true;
			break;
		}
	}


	// Step 3: Change vertex format to VertexPNT.

	D3DVERTEXELEMENT9 elements[64];
	UINT numElements = 0;
	VertexPNT::Decl->GetDeclaration(elements, &numElements);

	ID3DXMesh* temp = 0;
	HR(meshSys->CloneMesh(D3DXMESH_SYSTEMMEM, 
		elements, gd3dDevice, &temp));
	ReleaseCOM(meshSys);
	meshSys = temp;


	// Step 4: If the mesh did not have normals, generate them.

	if( hasNormals == false)
		HR(D3DXComputeNormals(meshSys, 0));


	// Step 5: Optimize the mesh.

	HR(meshSys->Optimize(D3DXMESH_MANAGED | 
		D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE, 
		(DWORD*)adjBuffer->GetBufferPointer(), 0, 0, 0, meshOut));
	ReleaseCOM(meshSys); // Done w/ system mesh.
	ReleaseCOM(adjBuffer); // Done with buffer.

	// Step 6: Extract the materials and load the textures.

	if( mtrlBuffer != 0 && numMtrls != 0 )
	{
		D3DXMATERIAL* d3dxmtrls = (D3DXMATERIAL*)mtrlBuffer->GetBufferPointer();

		for(DWORD i = 0; i < numMtrls; ++i)
		{
			// Save the ith material.  Note that the MatD3D property does not have an ambient
			// value set when its loaded, so just set it to the diffuse value.
			Mtrl m;
			m.ambient   = d3dxmtrls[i].MatD3D.Diffuse;
			m.diffuse   = d3dxmtrls[i].MatD3D.Diffuse;
			m.spec      = d3dxmtrls[i].MatD3D.Specular;
			m.specPower = d3dxmtrls[i].MatD3D.Power;
			mtrls.push_back( m );

			// Check if the ith material has an associative texture
			if( d3dxmtrls[i].pTextureFilename != 0 )
			{
				// Yes, load the texture for the ith subset
				IDirect3DTexture9* tex = 0;
				char* texFN = d3dxmtrls[i].pTextureFilename;
				HR(D3DXCreateTextureFromFile(gd3dDevice, texFN, &tex));

				// Save the loaded texture
				texs.push_back( tex );
			}
			else
			{
				// No texture for the ith subset
				texs.push_back( 0 );
			}
		}
	}
	ReleaseCOM(mtrlBuffer); // done w/ buffer
}
Example #6
0
WaterDemo::WaterDemo(HINSTANCE hInstance, std::string winCaption, D3DDEVTYPE devType, DWORD requestedVP)
    : D3DApp(hInstance, winCaption, devType, requestedVP)
{
    if(!checkDeviceCaps())
    {
        MessageBox(0, "checkDeviceCaps() Failed", 0, 0);
        PostQuitMessage(0);
    }

    InitAllVertexDeclarations();

    mLight.dirW = D3DXVECTOR3(0.0f, -2.0f, -1.0f);
    D3DXVec3Normalize(&mLight.dirW, &mLight.dirW);
    mLight.ambient = D3DXCOLOR(0.3f, 0.3f, 0.3f, 1.0f);
    mLight.diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
    mLight.spec    = D3DXCOLOR(0.7f, 0.7f, 0.7f, 1.0f);

    mGfxStats = new GfxStats();
    mSky = new Sky("grassenvmap1024.dds", 10000.0f);

    D3DXMATRIX waterWorld;
    D3DXMatrixTranslation(&waterWorld, 0.0f, 2.0f, 0.0f);

    Mtrl waterMtrl;
    waterMtrl.ambient   = D3DXCOLOR(0.26f, 0.23f, 0.3f, 0.90f);
    waterMtrl.diffuse   = D3DXCOLOR(0.26f, 0.23f, 0.3f, 0.90f);
    waterMtrl.spec      = 1.0f*WHITE;
    waterMtrl.specPower = 64.0f;

    Water::InitInfo waterInitInfo;
    waterInitInfo.dirLight = mLight;
    waterInitInfo.mtrl     = waterMtrl;
    waterInitInfo.vertRows         = 128;
    waterInitInfo.vertCols         = 128;
    waterInitInfo.dx               = 1.0f;
    waterInitInfo.dz               = 1.0f;
    waterInitInfo.waveMapFilename0 = "wave0.dds";
    waterInitInfo.waveMapFilename1 = "wave1.dds";
    waterInitInfo.waveMapVelocity0 = D3DXVECTOR2(0.05f, 0.08f);
    waterInitInfo.waveMapVelocity1 = D3DXVECTOR2(-0.02f, 0.1f);
    waterInitInfo.texScale = 16.0f;
    waterInitInfo.toWorld = waterWorld;

    mWater = new Water(waterInitInfo);
    mWater->setEnvMap(mSky->getEnvMap());

    ID3DXMesh* tempMesh = 0;
    LoadXFile("BasicColumnScene.x", &tempMesh, mSceneMtrls, mSceneTextures);

    // Get the vertex declaration for the NMapVertex.
    D3DVERTEXELEMENT9 elems[MAX_FVF_DECL_SIZE];
    UINT numElems = 0;
    HR(NMapVertex::Decl->GetDeclaration(elems, &numElems));

    // Clone the mesh to the NMapVertex format.
    ID3DXMesh* clonedTempMesh = 0;
    HR(tempMesh->CloneMesh(D3DXMESH_MANAGED, elems, gd3dDevice, &clonedTempMesh));

    // Now use D3DXComputeTangentFrameEx to build the TNB-basis for each vertex
    // in the mesh.

    HR(D3DXComputeTangentFrameEx(
           clonedTempMesh, // Input mesh
           D3DDECLUSAGE_TEXCOORD, 0, // Vertex element of input tex-coords.
           D3DDECLUSAGE_BINORMAL, 0, // Vertex element to output binormal.
           D3DDECLUSAGE_TANGENT, 0,  // Vertex element to output tangent.
           D3DDECLUSAGE_NORMAL, 0,   // Vertex element to output normal.
           0, // Options
           0, // Adjacency
           0.01f, 0.25f, 0.01f, // Thresholds for handling errors
           &mSceneMesh, // Output mesh
           0));         // Vertex Remapping

    // Done with temps.
    ReleaseCOM(tempMesh);
    ReleaseCOM(clonedTempMesh);

    D3DXMatrixIdentity(&mSceneWorld);
    D3DXMatrixIdentity(&mSceneWorldInv);

    HR(D3DXCreateTextureFromFile(gd3dDevice, "floor_nmap.bmp", &mSceneNormalMaps[0]));
    HR(D3DXCreateTextureFromFile(gd3dDevice, "bricks_nmap.bmp", &mSceneNormalMaps[1]));

    HR(D3DXCreateTextureFromFile(gd3dDevice, "whitetex.dds", &mWhiteTex));

    // Initialize camera.
    gCamera->pos().y = 7.0f;
    gCamera->pos().z = -30.0f;
    gCamera->setSpeed(10.0f);

    mGfxStats->addVertices(mSceneMesh->GetNumVertices());
    mGfxStats->addTriangles(mSceneMesh->GetNumFaces());

    mGfxStats->addVertices(mWater->getNumVertices());
    mGfxStats->addTriangles(mWater->getNumTriangles());

    mGfxStats->addVertices(mSky->getNumVertices());
    mGfxStats->addTriangles(mSky->getNumTriangles());


    buildFX();

    onResetDevice();
}
Example #7
0
void XManager::loadXFile(IDirect3DDevice9* dev, const std::string& filename, ID3DXMesh** meshOut, std::vector<Material>* mtrls, std::vector<IDirect3DTexture9*>* texs) {
	// Step 1: Load the .x file from file into a system memory mesh.

	ID3DXMesh* meshSys      = 0;
	ID3DXBuffer* adjBuffer  = 0;
	ID3DXBuffer* mtrlBuffer = 0;
	DWORD numMtrls          = 0;

	HR(D3DXLoadMeshFromX(filename.c_str(), D3DXMESH_SYSTEMMEM, dev,
		&adjBuffer,	&mtrlBuffer, 0, &numMtrls, &meshSys));


	// Step 2: Find out if the mesh already has normal info?

	D3DVERTEXELEMENT9 elems[MAX_FVF_DECL_SIZE];
	HR(meshSys->GetDeclaration(elems));
	
	bool hasNormals = false;
	D3DVERTEXELEMENT9 term = D3DDECL_END();
	for(int i = 0; i < MAX_FVF_DECL_SIZE; ++i)
	{
		// Did we reach D3DDECL_END() {0xFF,0,D3DDECLTYPE_UNUSED, 0,0,0}?
		if(elems[i].Stream == 0xff )
			break;

		if( elems[i].Type == D3DDECLTYPE_FLOAT3 &&
			elems[i].Usage == D3DDECLUSAGE_NORMAL &&
			elems[i].UsageIndex == 0 )
		{
			hasNormals = true;
			break;
		}
	}


	// Step 3: Change vertex format to CustomVertex3NormalUV

	D3DVERTEXELEMENT9 elements[64];
	UINT numElements = 0;
	CustomVertex3NormalUV::decl->GetDeclaration(elements, &numElements);

	ID3DXMesh* temp = 0;
	HR(meshSys->CloneMesh(D3DXMESH_SYSTEMMEM, 
		elements, dev, &temp));
	SAFERELEASECOM(meshSys);
	meshSys = temp;


	// Step 4: If the mesh did not have normals, generate them.

	if( hasNormals == false)
		HR(D3DXComputeNormals(meshSys, 0));


	// Step 5: Optimize the mesh.

	HR(meshSys->Optimize(D3DXMESH_MANAGED | 
		D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE, 
		(DWORD*)adjBuffer->GetBufferPointer(), 0, 0, 0, meshOut));
	SAFERELEASECOM(meshSys); // Done w/ system mesh.
	SAFERELEASECOM(adjBuffer); // Done with buffer.

	// Step 6: Extract the materials and load the textures.

	if( mtrlBuffer != 0 && numMtrls != 0 )
	{
		D3DXMATERIAL* d3dxmtrls = (D3DXMATERIAL*)mtrlBuffer->GetBufferPointer();

		for(DWORD i = 0; i < numMtrls; ++i)
		{
			// Save the ith material.  Note that the MatD3D property does not have an ambient
			// value set when its loaded, so just set it to the diffuse value.
			Material m;
			m.ambient   = d3dxmtrls[i].MatD3D.Diffuse;
			m.diffuse   = d3dxmtrls[i].MatD3D.Diffuse;
			m.spec      = d3dxmtrls[i].MatD3D.Specular;
			m.specPower = d3dxmtrls[i].MatD3D.Power;
			mtrls->push_back( m );

			// Check if the ith material has an associative texture
			if( d3dxmtrls[i].pTextureFilename != 0 )
			{
				IDirect3DTexture9* tex = 0;
				std::string s(d3dxmtrls[i].pTextureFilename);
				const char folder[] = "./texture/";
				unsigned int pos = s.find_last_of('\/');
				std::string newFileName(folder);

				// std::string::npos gets returned if no / was found
				if(pos != std::string::npos) {
					//std::string sub = s.substr(pos,s.size());

					if(strcmp(s.substr(pos+1,s.size()).c_str(),"Watcher.tga") == 0) {
						newFileName.append("Watcher_Black.tga");
					}
					else {
						newFileName.append(s.substr(pos+1,s.size()));
					}
				}
				else {
					
					newFileName.append(s);
					
				}
				// Save the loaded texture
				HR(D3DXCreateTextureFromFile(dev, newFileName.c_str(), &tex));
				texs->push_back( tex );
			}
			else
			{
//--------------------------------------------------------------------------------------
HRESULT CLoaderXFile::Load( WCHAR* szFileName, FRAME_TRANSFORM_TYPE requestedBHT )
{
    HRESULT hr = E_FAIL;
    ID3DXBuffer *pMat = NULL;
    ID3DXMesh *pRawMesh = NULL;
    ID3DXMesh *pMesh = NULL;
    DWORD cMat;
    IDirect3DDevice9* pDev9 = NULL;
    DWORD* pAdjBuffer = NULL;

    // Create a d3d9 object
    IDirect3D9* pD3D9 = Direct3DCreate9( D3D_SDK_VERSION );

    if( pD3D9 == NULL )
        return E_FAIL;

    D3DPRESENT_PARAMETERS pp;
    pp.BackBufferWidth = 320;
    pp.BackBufferHeight = 240;
    pp.BackBufferFormat = D3DFMT_X8R8G8B8;
    pp.BackBufferCount = 1;
    pp.MultiSampleType = D3DMULTISAMPLE_NONE;
    pp.MultiSampleQuality = 0;
    pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    pp.hDeviceWindow = GetShellWindow();
    pp.Windowed = true;
    pp.Flags = 0;
    pp.FullScreen_RefreshRateInHz = 0;
    pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
    pp.EnableAutoDepthStencil = false;

    hr = pD3D9->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, NULL, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &pp, &pDev9 );
    if(FAILED(hr))
        goto Error;

    if( szFileName )
    {
        hr = D3DXLoadMeshFromX( szFileName, 0, pDev9, NULL, &pMat, NULL, &cMat, &pRawMesh );
        if(FAILED(hr))
            goto Error;
    }

    D3DVERTEXELEMENT9 declTanBi[] = 
    {
        { 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 },
        { 0, 32, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,  0 },
        { 0, 44, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,  0 },
        D3DDECL_END()
    };
    D3DVERTEXELEMENT9* pdecl = declTanBi;

    // Make a clone with the desired vertex format.
    if( SUCCEEDED( pRawMesh->CloneMesh( D3DXMESH_32BIT | D3DXMESH_DYNAMIC, pdecl, pDev9, &m_pMesh ) ) )
    {
        // Optimize
        pAdjBuffer = new DWORD[ 3*m_pMesh->GetNumFaces() ];
        if( !pAdjBuffer )
        {
            hr = E_OUTOFMEMORY;
            goto Error;
        }
        m_pMesh->GenerateAdjacency( 0.001f, pAdjBuffer );
        m_pMesh->OptimizeInplace( D3DXMESHOPT_ATTRSORT,
                                    pAdjBuffer,
                                    NULL,
                                    NULL,
                                    NULL );

        // Attributes
        m_pMesh->GetAttributeTable( NULL, &m_dwNumAttr );
        if( m_dwNumAttr > 0 )
        {
            m_pAttr = new D3DXATTRIBUTERANGE[m_dwNumAttr];
            m_pMesh->GetAttributeTable( m_pAttr, &m_dwNumAttr );
        }

        // Materials
        m_dwNumMaterials = cMat;
        if( m_dwNumMaterials > 0 )
        {
            D3DXMATERIAL* pMaterialBuffer = (D3DXMATERIAL*)pMat->GetBufferPointer();
            m_pMats = new D3DXMATERIAL[ m_dwNumMaterials ];
            if( !m_pMats )
            {
                hr = E_OUTOFMEMORY;
                goto Error;
            }

            for( DWORD m=0; m<m_dwNumMaterials; m++ )
            {
                CopyMemory( &m_pMats[m], &pMaterialBuffer[m], sizeof(D3DXMATERIAL) );
            }
        }

        // Create the intermediate mesh
        hr = CreateIntermediateMesh( declTanBi, 6 );
        if(FAILED(hr))
            goto Error;
    }

    hr = S_OK;
Error:
    SAFE_RELEASE( pMat );
    SAFE_RELEASE( pRawMesh );
    SAFE_RELEASE( pMesh );
    SAFE_RELEASE( pDev9 );
    SAFE_RELEASE( pD3D9 );
    SAFE_DELETE_ARRAY( pAdjBuffer );

    return hr;
}
Example #9
0
void SphereCylDemo::genCylTexCoords(AXIS axis)
{
	// D3DXCreate* functions generate vertices with position 
	// and normal data.  But for texturing, we also need
	// tex-coords.  So clone the mesh to change the vertex
	// format to a format with tex-coords.

	D3DVERTEXELEMENT9 elements[64];
	UINT numElements = 0;
	VertexPNT::Decl->GetDeclaration(elements, &numElements);

	ID3DXMesh* temp = 0;
	HR(mCylinder->CloneMesh(D3DXMESH_SYSTEMMEM, 
		elements, gd3dDevice, &temp));

	ReleaseCOM(mCylinder);

	// Now generate texture coordinates for each vertex.
	VertexPNT* vertices = 0;
	HR(temp->LockVertexBuffer(0, (void**)&vertices));

	// We need to get the height of the cylinder we are projecting the
	// vertices onto.  That height depends on which axis the client has
	// specified that the cylinder lies on.  The height is determined by 
	// finding the height of the bounding cylinder on the specified axis.

	D3DXVECTOR3 maxPoint(-FLT_MAX, -FLT_MAX, -FLT_MAX);
	D3DXVECTOR3 minPoint(FLT_MAX, FLT_MAX, FLT_MAX);

	for(UINT i = 0; i < temp->GetNumVertices(); ++i)
	{
		D3DXVec3Maximize(&maxPoint, &maxPoint, &vertices[i].pos);
		D3DXVec3Minimize(&minPoint, &minPoint, &vertices[i].pos);
	}

	float a = 0.0f;
	float b = 0.0f;
	float h = 0.0f;
	switch( axis )
	{
	case X_AXIS:
		a = minPoint.x;
		b = maxPoint.x;
		h = b-a;
		break;
	case Y_AXIS:
		a = minPoint.y;
		b = maxPoint.y;
		h = b-a;
		break;
	case Z_AXIS:
		a = minPoint.z;
		b = maxPoint.z;
		h = b-a;
		break;
	}


	// Iterate over each vertex and compute its texture coordinate.

	for(UINT i = 0; i < temp->GetNumVertices(); ++i)
	{
		// Get the coordinates along the axes orthogonal to the
		// axis the cylinder is aligned with.

		float x = 0.0f;
		float y = 0.0f;
		float z = 0.0f;
		switch( axis )
		{
		case X_AXIS:
			x = vertices[i].pos.y;
			z = vertices[i].pos.z;
			y = vertices[i].pos.x;
			break;
		case Y_AXIS:
			x = vertices[i].pos.x;
			z = vertices[i].pos.z;
			y = vertices[i].pos.y;
			break;
		case Z_AXIS:
			x = vertices[i].pos.x;
			z = vertices[i].pos.y;
			y = vertices[i].pos.z;
			break;
		}

		// Convert to cylindrical coordinates.

		float theta = atan2f(z, x);
		float y2    = y - b; // Transform [a, b]-->[-h, 0]

		// Transform theta from [0, 2*pi] to [0, 1] range and
		// transform y2 from [-h, 0] to [0, 1].

		float u = theta / (2.0f*D3DX_PI);
		float v = y2 / -h; 

		// Save texture coordinates.

		vertices[i].tex0.x = u;
		vertices[i].tex0.y = v;
	}

	HR(temp->UnlockVertexBuffer());

	// Clone back to a hardware mesh.
	HR(temp->CloneMesh(D3DXMESH_MANAGED | D3DXMESH_WRITEONLY,
		elements, gd3dDevice, &mCylinder));

	ReleaseCOM(temp);
}