void CRenderPrimitive::SetGraphicSphere(float radius)
{
	ID3DXMesh *pMesh;

	D3DXCreateSphere( g_pD3dDevice, radius,
		8, 8, &pMesh, NULL);

	mMesh.Create(g_pD3dDevice, pMesh, &mMaterial, 1);

	pMesh->Release();
}
void CRenderPrimitive::SetGraphicCylinder(float radius, float length)
{
	ID3DXMesh *pMesh;

	D3DXCreateCylinder( g_pD3dDevice, radius, radius, length,
		8, 1, &pMesh, NULL);

	mMesh.Create(g_pD3dDevice, pMesh, &mMaterial, 1);

	pMesh->Release();

	mIsCylinder = 1;
}
void CRenderPrimitive::SetGraphicBox(float Width, float Height, float Depth)
{
	//create the render mesh
	ID3DXMesh *pMesh;

	D3DXCreateBox( g_pD3dDevice,  
		Width, Height, Depth,
		&pMesh, NULL);

	mMesh.Create(g_pD3dDevice, pMesh, &mMaterial, 1);

	pMesh->Release();
}
Example #4
0
// Creates a sphere.  Returns true on success, false otherwise
bool CreateSphere(float radius, int color, ID3DXMesh **mesh)
{
	assert(g3D->mDevice != NULL);
	assert(mesh != NULL);
	
	const unsigned int kSlices = 16;
	const unsigned int kStacks = 16;

	ID3DXMesh *tempMesh; // Temp D3D mesh object

	// Create the sphere
	if(D3DXCreateSphere(g3D->mDevice, radius, kSlices, kStacks, &tempMesh, NULL) != D3D_OK)
		return false;
		
	// Flag for how to create the D3D mesh.  We want the vertex buffer and index
	// buffer memory to be managed by DirectX	
	DWORD flag = D3DXMESH_VB_MANAGED | D3DXMESH_IB_MANAGED;

	// Copy the sphere, converting to our FVF 
	if(tempMesh->CloneMeshFVF(flag, SVertexType, g3D->mDevice, mesh) != D3D_OK)
		return false;

	SVertex *v;

	// Lock the vertex data of our sphere
	if((*mesh)->LockVertexBuffer(0, (void**)&v) != D3D_OK)
	{	
		(*mesh)->Release();
			return false;
	}

	// Set the sphere's color
	for(unsigned int i = 0; i < (*mesh)->GetNumVertices(); ++i)
		v[i].color = color;

	// Unlock the vertex data
	(*mesh)->UnlockVertexBuffer();

	tempMesh->Release(); // Free up the temporary mesh
		return true;	
}
Example #5
0
void MeshManager::CreateSphereMesh(){
	// Create MeshComponents for Sphere mesh
	MeshComponents* meshComp = new MeshComponents();
	meshComp->numMaterials		= 1;
	meshComp->bufMeshMaterial	= NULL;
	meshComp->material			= NULL;
	meshComp->texture			= NULL;

	//Create main sphere to be used to draw spheres place by user
	//Create a temporary sphere first
	ID3DXMesh* tempSphere;
	D3DXCreateSphere(m_Device, 1.0f, 10, 16, &tempSphere, 0);
	//Clone temp sphere to the main sphere and give its vertices a color value
	tempSphere->CloneMeshFVF( D3DXMESH_MANAGED, D3DFVF_XYZ | D3DFVF_DIFFUSE, m_Device, &meshComp->mesh );
	//Release the temp sphere
	tempSphere->Release();

	// Add sphere to meshCollection/List
	m_mMeshCollection.insert( make_pair("sphere", meshComp) );
	m_vMeshList.push_back( meshComp );
}
Example #6
0
/**
 * Exports all geometry into a D3D .x file into the current working folder.
 * @param Filename	Desired filename (may include path)
 * @param bShow		Whether the D3D .x file viewer should be invoked. If shown, we'll block until it has been closed.
 */
void F3DVisualizer::Export( const TCHAR* Filename, bool bShow/*=false*/ )
{
	ID3DXMesh* Mesh;
	Mesh = NULL;
	int32 NumPrimitives = NumTriangles() + NumLines()*2;
	int32 NumVertices = NumTriangles()*3 + NumLines()*4;
	HRESULT Result = D3DXCreateMeshFVF( NumPrimitives, NumVertices, D3DXMESH_32BIT, D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE|D3DFVF_SPECULAR, D3D->D3DDevice, &Mesh );
	void* VertexBuffer = NULL;
	void* IndexBuffer = NULL;
	Result = Mesh->LockVertexBuffer(D3DLOCK_DISCARD, &VertexBuffer);
	Result = Mesh->LockIndexBuffer(D3DLOCK_DISCARD, &IndexBuffer);

	D3DXVertex* Vertices = (D3DXVertex*)VertexBuffer;
	uint32* Indices = (uint32*) IndexBuffer;
	int32 NumVerticesStored = 0;
	int32 NumIndicesStored = 0;

	// Add the triangles to the vertexbuffer and indexbuffer.
	for ( int32 TriangleIndex=0; TriangleIndex < NumTriangles(); ++TriangleIndex )
	{
		const FVector4& P1 = Triangles[TriangleIndex].Vertices[0];
		const FVector4& P2 = Triangles[TriangleIndex].Vertices[1];
		const FVector4& P3 = Triangles[TriangleIndex].Vertices[2];
		const FColor& Color = Triangles[TriangleIndex].Color;
		Vertices[NumVerticesStored+0].Pos[0] = P1[0];
		Vertices[NumVerticesStored+0].Pos[1] = P1[1];
		Vertices[NumVerticesStored+0].Pos[2] = P1[2];
		Vertices[NumVerticesStored+0].Color1 = Color.DWColor();
		Vertices[NumVerticesStored+0].Color2 = 0;
		Vertices[NumVerticesStored+1].Pos[0] = P2[0];
		Vertices[NumVerticesStored+1].Pos[1] = P2[1];
		Vertices[NumVerticesStored+1].Pos[2] = P2[2];
		Vertices[NumVerticesStored+1].Color1 = Color.DWColor();
		Vertices[NumVerticesStored+1].Color2 = 0;
		Vertices[NumVerticesStored+2].Pos[0] = P3[0];
		Vertices[NumVerticesStored+2].Pos[1] = P3[1];
		Vertices[NumVerticesStored+2].Pos[2] = P3[2];
		Vertices[NumVerticesStored+2].Color1 = Color.DWColor();
		Vertices[NumVerticesStored+2].Color2 = 0;

		// Reverse triangle winding order for the .x file.
		Indices[NumIndicesStored+0] = NumVerticesStored + 0;
		Indices[NumIndicesStored+1] = NumVerticesStored + 2;
		Indices[NumIndicesStored+2] = NumVerticesStored + 1;

		NumVerticesStored += 3;
		NumIndicesStored += 3;
	}

	// Add the lines to the vertexbuffer and indexbuffer.
	for ( int32 LineIndex=0; LineIndex < NumLines(); ++LineIndex )
	{
		const FVector4& P1 = Lines[LineIndex].Vertices[0];
		const FVector4& P2 = Lines[LineIndex].Vertices[1];
		const FColor& Color = Lines[LineIndex].Color;
		Vertices[NumVerticesStored+0].Pos[0] = P1[0];
		Vertices[NumVerticesStored+0].Pos[1] = P1[1] - 5.0f;
		Vertices[NumVerticesStored+0].Pos[2] = P1[2];
		Vertices[NumVerticesStored+0].Color1 = 0;
		Vertices[NumVerticesStored+0].Color2 = Color.DWColor();
		Vertices[NumVerticesStored+1].Pos[0] = P1[0];
		Vertices[NumVerticesStored+1].Pos[1] = P1[1] + 5.0f;
		Vertices[NumVerticesStored+1].Pos[2] = P1[2];
		Vertices[NumVerticesStored+1].Color1 = 0;
		Vertices[NumVerticesStored+1].Color2 = Color.DWColor();
		Vertices[NumVerticesStored+2].Pos[0] = P2[0];
		Vertices[NumVerticesStored+2].Pos[1] = P2[1] - 5.0f;
		Vertices[NumVerticesStored+2].Pos[2] = P2[2];
		Vertices[NumVerticesStored+2].Color1 = 0;
		Vertices[NumVerticesStored+2].Color2 = Color.DWColor();
		Vertices[NumVerticesStored+3].Pos[0] = P2[0];
		Vertices[NumVerticesStored+3].Pos[1] = P2[1] + 5.0f;
		Vertices[NumVerticesStored+3].Pos[2] = P2[2];
		Vertices[NumVerticesStored+3].Color1 = 0;
		Vertices[NumVerticesStored+3].Color2 = Color.DWColor();

		Indices[NumIndicesStored+0] = NumVerticesStored+0;
		Indices[NumIndicesStored+1] = NumVerticesStored+2;
		Indices[NumIndicesStored+2] = NumVerticesStored+1;
		Indices[NumIndicesStored+3] = NumVerticesStored+2;
		Indices[NumIndicesStored+4] = NumVerticesStored+3;
		Indices[NumIndicesStored+5] = NumVerticesStored+1;

		NumVerticesStored += 4;
		NumIndicesStored += 6;
	}

	Mesh->UnlockVertexBuffer();
	Mesh->UnlockIndexBuffer();
	Result = D3DXComputeNormals( Mesh, NULL );
	D3DXMATERIAL MeshMaterial;
	MeshMaterial.MatD3D.Ambient.r = 0.1f;
	MeshMaterial.MatD3D.Ambient.g = 0.1f;
	MeshMaterial.MatD3D.Ambient.b = 0.1f;
	MeshMaterial.MatD3D.Ambient.a = 0.0f;
	MeshMaterial.MatD3D.Diffuse.r = 1.0f;
	MeshMaterial.MatD3D.Diffuse.g = 1.0f;
	MeshMaterial.MatD3D.Diffuse.b = 1.0f;
	MeshMaterial.MatD3D.Diffuse.a = 1.0f;
	MeshMaterial.MatD3D.Emissive.r = 1.0f;
	MeshMaterial.MatD3D.Emissive.g = 1.0f;
	MeshMaterial.MatD3D.Emissive.b = 1.0f;
	MeshMaterial.MatD3D.Emissive.a = 1.0f;
	MeshMaterial.MatD3D.Specular.r = 1.0f;
	MeshMaterial.MatD3D.Specular.g = 1.0f;
	MeshMaterial.MatD3D.Specular.b = 1.0f;
	MeshMaterial.MatD3D.Specular.a = 1.0f;
	MeshMaterial.MatD3D.Power = 16.0f;
	MeshMaterial.pTextureFilename = NULL;

	D3DXEFFECTINSTANCE EffectInstance;
	EffectInstance.pEffectFilename = "D3DExport.fx";
	EffectInstance.NumDefaults = 0;
	EffectInstance.pDefaults = NULL;

	// Write out the .x file.
	D3DXSaveMeshToX( Filename, Mesh, NULL, &MeshMaterial, &EffectInstance, 1, D3DXF_FILEFORMAT_BINARY );
	Mesh->Release();

	// Write out the .fx file, if it doesn't always exist.
	HANDLE ShaderFile = CreateFile( TEXT("D3DExport.fx"), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
	if (ShaderFile != INVALID_HANDLE_VALUE)
	{
		::DWORD BytesWritten;
		WriteFile(ShaderFile, ShaderFxFile, (uint32)FCStringAnsi::Strlen(ShaderFxFile), &BytesWritten, NULL);
		CloseHandle( ShaderFile );
	}

	// If specified, run the default viewer for .x files and block until it's closed.
	if ( bShow )
	{
		system( TCHAR_TO_ANSI(Filename) );
	}
}
Example #7
0
// Create a torus with the parameters specified
// Returns true for success, false otherwise
bool CreateTorus(float innerRad, float outerRad, int color, ID3DXMesh **mesh)
{
	assert(g3D->mDevice != NULL);
	assert(mesh != NULL);

	const unsigned int kSides = 16; // Number of divisions looking at the torus form the side
	const unsigned int kRings = 16; // Number of divisions looking at the torus from the top
									// so you can see the hole in the middle

	ID3DXMesh *temp = NULL; // Temp D3D mesh object

	// Create the torus
	// By paramter:
	// g3D->mDevice -- Pointer to the Direct3D device to be associated with the torus
	// innerRad -- Inner radius of the torus
	// outerRad -- Outside radius of the torus
	// kSides -- Number of sides in a cross-section of the torus 
	// kRings -- Number of rings in a cross-section of the torus
	// &temp -- A pointer to a ID3DXMesh*, it will get filled with the 
	//			the created mesh
	// NULL --  Optional pointer to a ID3DXBuffer, if a valid pointer was passed
	//			it would be filled with the adjacency information for each face in 
	//			the mesh.  By passing NULL, we say we don't want this information
	if(D3DXCreateTorus(g3D->mDevice, innerRad, outerRad, kSides, kRings, &temp, NULL) != D3D_OK)
		return false;

	// Next we clone the mesh.  This does two things.  First, it allows us to
	// specify the vertex format we want on the cloned mesh.  Second, it copies the 
	// current mesh data into the ID3DXMesh we passed to this function.
	// By parameter:
	// D3DXMESH_VB_MANAGED | D3DXMESH_IB_MANAGED -- Flags specifying how we want the mesh to be
	//												cloned.  This particular flag combo says
	//												"Have the vertex buffer and index buffer
	//												associated with this mesh be in pooled memory
	//												that DirectX manages for us."
	// SVertexType -- Flexible vertex format that we want the cloned mesh to be converted to
	// g3D->mDevice -- IDirect3DDevice9 to associate this mesh with
	// mesh -- A pointer to a ID3DXMesh* that will get filled with the cloned mesh   
	if(temp->CloneMeshFVF(D3DXMESH_VB_MANAGED | D3DXMESH_IB_MANAGED, SVertexType, 
						  g3D->mDevice, mesh) != D3D_OK)
	{
		return false;
	}

	// Okay so up to this point we've created a stock D3D torus, then converted 
	// it a torus with the FVF that we want.  Now were going to loop through each
	// vertex and set it to the color that we want it to be.

	SVertex *v;

	// Lock the vertex buffer
	if((*mesh)->LockVertexBuffer(0, (void**)&v) != D3D_OK)
	{	
		(*mesh)->Release();
		return false;
	}

	// Loop through all the verts in the mesh, setting each one's 
	// color to the color passed into the function
	for(unsigned int i = 0; i < (*mesh)->GetNumVertices(); ++i)
		v[i].color = color;

	// We're done with the vertex buffer, so unlock it so it may be used
	// by others
	(*mesh)->UnlockVertexBuffer();

	temp->Release(); // Last but not least, free up the temporary mesh
		return true;
}
Example #8
0
// This functions creates a sphere of "radius" and vertex color "color"
bool CreateSphere(float radius, int color, ID3DXMesh **mesh)
{
	assert(g3D->mDevice != NULL);
	assert(mesh != NULL);
	
	// This is the number of divisions the sphere will have vertically and
	// horizontally
	const unsigned int kSlices = 16; // Vertical divisions
	const unsigned int kStacks = 16; // Horizontal divisions

	ID3DXMesh *temp = NULL; // Temp D3D mesh object

	// Create the sphere
	// By parameter:
	// g3D->mDevice -- Pointer to the Direct3D device to be associated with the sphere
	// radius -- Radius of the sphere
	// kSlices -- Number of vertical divisions in the sphere
	// kStacks -- Number of horizontal divisions in the sphere
	// &temp -- A pointer to a ID3DXMesh*, it will get filled with the 
	//			the created mesh
	// NULL --  Optional pointer to a ID3DXBuffer, if a valid pointer was passed
	//			it would be filled with the adjacency information for each face in 
	//			the mesh.  By passing NULL, we say we don't want this information
	if(D3DXCreateSphere(g3D->mDevice, radius, kSlices, kStacks, &temp, NULL) != D3D_OK)
		return false;

	// Next we clone the mesh.  This does two things.  First, it allows us to
	// specify the vertex format we want on the cloned mesh.  Second, it copies the 
	// current mesh data into the ID3DXMesh we passed to this function.
	// By parameter:
	// D3DXMESH_VB_MANAGED | D3DXMESH_IB_MANAGED -- Flags specifying how we want the mesh to be
	//												cloned.  This particular flag combo says
	//												"Have the vertex buffer and index buffer
	//												associated with this mesh be in pooled memory
	//												that DirectX manages for us."
	// SVertexType -- Flexible vertex format that we want the cloned mesh to be converted to
	// g3D->mDevice -- IDirect3DDevice9 to associate this mesh with
	// mesh -- A pointer to a ID3DXMesh* that will get filled with the cloned mesh   
	if(temp->CloneMeshFVF(D3DXMESH_VB_MANAGED | D3DXMESH_IB_MANAGED, SVertexType, 
						  g3D->mDevice, mesh) != D3D_OK)
	{
		return false;
	}

	// Okay so up to this point we've created a stock D3D sphere, then converted 
	// it a sphere with the FVF that we want.  Now were going to 
	// loop through each vertex and set it to the color that we want it to be

	SVertex *v;

	// Lock the vertex buffer
	if((*mesh)->LockVertexBuffer(0, (void**)&v) != D3D_OK)
	{	
		(*mesh)->Release();
			return false;
	}

	// Loop through all the verts in the mesh, setting each one's 
	// color to the color passed into the function
	for(unsigned int i = 0; i < (*mesh)->GetNumVertices(); ++i)
		v[i].color = color;

	// Don't be stingy, unlock the vertex buffer so others can use it
	(*mesh)->UnlockVertexBuffer();

	temp->Release(); // Last but not least, free up the temporary mesh
		return true;	
}
Example #9
0
HRESULT HelloShadowVolume::RestoreDeviceObjects()
{
    HRESULT hr;
    IDirect3DDevice8* device;
    hr = m_spD3D->CreateDevice(
             D3DADAPTER_DEFAULT,
             D3DDEVTYPE_HAL,
             m_hWnd,
             D3DCREATE_HARDWARE_VERTEXPROCESSING,
             &m_dpps,
             &device);
    if (FAILED(hr))
    {
        MessageBox(0, L"CreateDevice failed", 0, 0);
        return E_FAIL;
    }
    m_spDevice.reset(device, [](IDirect3DDevice8* device) {
        device->Release();
    });

    m_spDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
    m_spDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
    m_spDevice->SetRenderState(D3DRS_DITHERENABLE, TRUE);
    D3DVIEWPORT8 viewport = { 0, 0, m_iWidth, m_iHeight };
    m_spDevice->SetViewport(&viewport);

    D3DXVECTOR3 eye(0.0f, 0.0f, 30.0f);
    D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
    D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
    D3DXMatrixLookAtLH(&m_mtView, &eye, &target, &up);

    D3DXMatrixPerspectiveFovLH(&m_mtProj, 0.2*D3DX_PI, (float)m_iWidth / (float)m_iHeight, 1.0f, 100.f);

    m_cPlaneTint = { 0.7f, 0.6f, 0.4f, 1.0f };


    ID3DXMesh* plane;
    //D3DXCreatePolygon(m_spDevice.get(), 2.0f, 4, &plane, NULL);
    CreatePlane(m_spDevice.get(), 15.0f, 10, &plane);
    //D3DXCreateSphere(m_spDevice.get(), 1.0f,20,20, &plane, NULL);

    IDirect3DVertexBuffer8* vb;
    IDirect3DIndexBuffer8* ib;
    plane->GetVertexBuffer(&vb);
    plane->GetIndexBuffer(&ib);
    m_spPlaneVB.reset(vb, [](IDirect3DVertexBuffer8* vb) {
        vb->Release();
    });
    m_spPlaneIB.reset(ib, [](IDirect3DIndexBuffer8* ib) {
        ib->Release();
    });
    m_dwPlaneNumVertices = plane->GetNumVertices();
    m_dwPlaneNumFaces = plane->GetNumFaces();

    plane->Release();

    DWORD decl[] = {
        D3DVSD_STREAM(0),
        D3DVSD_REG(0, D3DVSDT_FLOAT3),
        D3DVSD_REG(3, D3DVSDT_FLOAT3),
        D3DVSD_END()
    };
    hr = CreateVSFromBinFile(m_spDevice.get(), decl, L"plane.vso", &m_dwPlaneVSH);
    if (FAILED(hr))
    {
        MessageBox(0, 0, L"CreateVSFromBinFile failed", 0);
        return E_FAIL;
    }
    hr = CreatePSFromBinFile(m_spDevice.get(), L"plane.pso", &m_dwPlanePSH);
    if (FAILED(hr))
    {
        MessageBox(0, 0, L"CreatePSFromBinFile failed", 0);
        return E_FAIL;
    }

    D3DXMATRIX Rx, Tz;
    D3DXMatrixRotationX(&Rx, D3DX_PI*0.5f);
    D3DXMatrixTranslation(&Tz, 0.0f, -3.0f, 0.0f);
    m_mtPlaneWorld = Rx * Tz;

    ID3DXMesh* occluder;
    CreateOccluder(m_spDevice.get(), &occluder);
    IDirect3DVertexBuffer8* vbOccluder;
    IDirect3DIndexBuffer8* ibOccluder;
    occluder->GetVertexBuffer(&vbOccluder);
    occluder->GetIndexBuffer(&ibOccluder);
    m_spOccluderVB.reset(vbOccluder, [](IDirect3DVertexBuffer8* vb) {
        vb->Release();
    });
    m_spOccluderIB.reset(ibOccluder, [](IDirect3DIndexBuffer8* ib) {
        ib->Release();
    });
    m_dwOccluderNumVertices = occluder->GetNumVertices();
    m_dwOccluderNumFaces = occluder->GetNumFaces();
    occluder->Release();

    hr = CreateVSFromBinFile(m_spDevice.get(), decl, L"occluder.vso", &m_dwOccluderVSH);
    if (FAILED(hr))
    {
        MessageBox(0, 0, L"CreateVSFromBinFile failed", 0);
        return E_FAIL;
    }
    hr = CreatePSFromBinFile(m_spDevice.get(), L"occluder.pso", &m_dwOccluderPSH);
    if (FAILED(hr))
    {
        MessageBox(0, 0, L"CreatePSFromBinFile failed", 0);
        return E_FAIL;
    }
    m_cOccluderTint = { 0.3f, 0.0f, 0.8f, 1.0f };
    D3DXMATRIX Rz, T;
    D3DXMatrixTranslation(&T, 5.1f * cosf(0.5), 0.0f, 5.1f * sinf(0.5));
    D3DXMatrixIdentity(&m_mtVolumeWorld);
    D3DXMatrixRotationZ(&Rz, 0.5f);
    m_mtOccluderWorld = T * Rz;

    ID3DXMesh* volume;
    CreateVolume(m_spDevice.get(), &volume);
    IDirect3DVertexBuffer8* vbVolume;
    IDirect3DIndexBuffer8* ibVolume;
    volume->GetVertexBuffer(&vbVolume);
    volume->GetIndexBuffer(&ibVolume);
    m_spVolumeVB.reset(vbVolume, [](IDirect3DVertexBuffer8* vb) {
        vb->Release();
    });
    m_spVolumeIB.reset(ibVolume, [](IDirect3DIndexBuffer8* ib) {
        ib->Release();
    });
    m_dwVolumeNumVertices = volume->GetNumVertices();
    m_dwVolumeNumFaces = volume->GetNumFaces();
    volume->Release();

    hr = CreateVSFromBinFile(m_spDevice.get(), decl, L"volume.vso", &m_dwVolumeVSH);
    if (FAILED(hr))
    {
        MessageBox(0, 0, L"CreateVSFromBinFile failed", 0);
        return E_FAIL;
    }
    hr = CreatePSFromBinFile(m_spDevice.get(), L"volume.pso", &m_dwVolumePSH);
    if (FAILED(hr))
    {
        MessageBox(0, 0, L"CreatePSFromBinFile failed", 0);
        return E_FAIL;
    }
    m_cVolumeTint = { 0.7f, 0.0f, 0.0f, 1.0f };

    D3DXMATRIX Sx;
    D3DXMatrixIdentity(&m_mtVolumeWorld);
    D3DXMatrixScaling(&Sx, 6.0f, 1.0f, 1.0f);
    D3DXMatrixRotationZ(&Rz, 0.5f);
    m_mtVolumeWorld = Sx * Rz;

    return S_OK;
}
void CMeshConverter::OptimiseGraphicsObject(void)
{
	int						i;
	int						j;
	ID3DXMesh*				pXMesh;
	CGraphicsPrimitive*		pcPrimitive;
	CVertexBufferExtended*	psVertexBuffer;
	void*					pvDestIndexBuffer;
	void*					pvDestVertexBuffer;
	void*					pvSrcIndexBuffer;
	void*					pvSrcVertexBuffer;
	int						iVertSize;
	DWORD*					pvAdjacency;
	int						iPrimitiveStart;
	int						iOldVertSize;
	int						iNumIndices;
	int						iOldVertexBufferIndex;
	int						iNumTriangles;
	void*					pvDestBaseIndexBuffer;
	SIndexBuffer*			psIndexBuffer;
	DWORD					iMeshOptions;

	mpcGraphicsObject->SortPrimitives();
	mpcGraphicsObject->Lock();
	psIndexBuffer = mpcGraphicsObject->GetIndexBuffer();
	iVertSize = 0;
	iNumIndices = 0;
	iOldVertexBufferIndex = 0;
	iNumTriangles = 0;
	iOldVertSize = 0;
	iMeshOptions = D3DXMESH_SYSTEMMEM;
	SetFlag((int*)&iMeshOptions, D3DXMESH_32BIT, psIndexBuffer->iIndexSize == 4);
	for (i = 0; i < mpcGraphicsObject->GetNumPrimitives(); i++)
	{
		pcPrimitive = mpcGraphicsObject->GetPrimitive(i);
		psVertexBuffer = mpcGraphicsObject->GetVertexBufferForIndex(pcPrimitive->miVertexBufferIndex);

		if (iOldVertSize != psVertexBuffer->iVertexSize)
		{
			if (iNumIndices != 0)
			{
				gcD3D.CreateMesh(iNumTriangles, iNumIndices, iMeshOptions, psVertexBuffer->iVertexFormat, &pXMesh);
				iVertSize = pXMesh->GetNumBytesPerVertex();
				pXMesh->LockIndexBuffer(D3DLOCK_NO_DIRTY_UPDATE, &pvDestBaseIndexBuffer);
				pXMesh->LockVertexBuffer(D3DLOCK_NO_DIRTY_UPDATE, &pvDestVertexBuffer);

				psVertexBuffer = mpcGraphicsObject->GetVertexBufferForIndex(iOldVertexBufferIndex);
				pvSrcVertexBuffer = psVertexBuffer->pvLockedBuffer;

				if (iVertSize != psVertexBuffer->iVertexSize)
				{
					gcLogger.Error("D3DX vertex size differs from expected size");
					break;
				}

				memcpy(pvDestVertexBuffer, pvSrcVertexBuffer, psVertexBuffer->iVertexSize * psVertexBuffer->iNumVerticies);

				pvDestIndexBuffer = pvDestBaseIndexBuffer;
				for (j = iPrimitiveStart; j < i; j++)
				{
					pcPrimitive = mpcGraphicsObject->GetPrimitive(j);
					pvSrcIndexBuffer = RemapSinglePointer(psIndexBuffer->pvLockedBuffer, 2 * pcPrimitive->miStartIndex);
					memcpy(pvDestIndexBuffer, pvSrcIndexBuffer, psIndexBuffer->iIndexSize * pcPrimitive->miNumVertices);
					pvDestIndexBuffer = RemapSinglePointer(pvDestIndexBuffer, pcPrimitive->miNumVertices);
				}

				pvAdjacency = (DWORD*)malloc(pcPrimitive->miNumPrimitives * 3 * sizeof(DWORD));
				pXMesh->GenerateAdjacency(0.0f, pvAdjacency);
				pXMesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE | D3DXMESHOPT_DONOTSPLIT, pvAdjacency, NULL, NULL, NULL);
				free(pvAdjacency);

				pvDestIndexBuffer = pvDestBaseIndexBuffer;
				for (j = iPrimitiveStart; j < i; j++)
				{
					pcPrimitive = mpcGraphicsObject->GetPrimitive(j);
					pvSrcIndexBuffer = RemapSinglePointer(psIndexBuffer->pvLockedBuffer, 2 * pcPrimitive->miStartIndex);
					memcpy(pvSrcIndexBuffer, pvDestIndexBuffer, psIndexBuffer->iIndexSize * pcPrimitive->miNumVertices);
					pvDestIndexBuffer = RemapSinglePointer(pvDestIndexBuffer, pcPrimitive->miNumVertices);
				}

				memcpy(pvSrcVertexBuffer, pvDestVertexBuffer, psVertexBuffer->iVertexSize * psVertexBuffer->iNumVerticies);

				pXMesh->UnlockIndexBuffer();
				pXMesh->UnlockVertexBuffer();
				pXMesh->Release();
			}
			iPrimitiveStart = i;
			iNumIndices = 0;
			iOldVertexBufferIndex = pcPrimitive->miVertexBufferIndex;
		}
		else
		{
			iNumIndices += pcPrimitive->miNumVertices;
			iNumTriangles += pcPrimitive->miNumPrimitives;
			if (iOldVertexBufferIndex != pcPrimitive->miVertexBufferIndex)
			{
				gcUserError.Set("Primitive vertex buffer index is F****D!");
				break;
			}
		}
	}
	mpcGraphicsObject->Unlock();
}
Example #11
0
ID3DXMesh* CMesh::createD3DXMesh() const
{
    HRESULT hr;
    ID3DXMesh* dxMesh = 0;

    DWORD meshOpts = D3DXMESH_MANAGED;
    if( getIndexStride() == 4 )
        meshOpts |= D3DXMESH_32BIT;


    // get declaration
    D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE];
    UINT numElements;
    getVertexDecl().getObject()->GetDeclaration( decl, &numElements );
    // create mesh
    hr = D3DXCreateMesh( getIndexCount()/3, getVertexCount(), meshOpts, decl, &CD3DDevice::getInstance().getDevice(), &dxMesh );
    if( FAILED(hr) )
        return NULL;

    // copy VB
    {
        const void* srcVB = lockVBRead();
        void* dxVB = 0;
        hr = dxMesh->LockVertexBuffer( 0, &dxVB );
        if( FAILED(hr) ) {
            dxMesh->Release();
            return NULL;
        }
        memcpy( dxVB, srcVB, getVertexCount() * getVertexStride() );
        hr = dxMesh->UnlockVertexBuffer();
        unlockVBRead();
    }
    // copy IB
    {
        const void* srcIB = lockIBRead();
        void* dxIB = 0;
        hr = dxMesh->LockIndexBuffer( 0, &dxIB );
        if( FAILED(hr) ) {
            dxMesh->Release();
            return NULL;
        }
        memcpy( dxIB, srcIB, getIndexCount() * getIndexStride() );
        hr = dxMesh->UnlockIndexBuffer();
        unlockIBRead();
    }
    // copy groups
    {
        int ngroups = getGroupCount();
        D3DXATTRIBUTERANGE* attrs = new D3DXATTRIBUTERANGE[ngroups];
        DWORD* attrBuf = 0;
        hr = dxMesh->LockAttributeBuffer( 0, &attrBuf );
        if( FAILED(hr) ) {
            dxMesh->Release();
            return NULL;
        }
        for( int g = 0; g < ngroups; ++g ) {
            attrs[g].AttribId = g;
            const CMesh::CGroup& group = getGroup(g);
            attrs[g].VertexStart = group.getFirstVertex();
            attrs[g].VertexCount = group.getVertexCount();
            attrs[g].FaceStart = group.getFirstPrim();
            attrs[g].FaceCount = group.getPrimCount();
            for( int f = 0; f < group.getPrimCount(); ++f )
                *attrBuf++ = g;
        }
        dxMesh->UnlockAttributeBuffer();
        hr = dxMesh->SetAttributeTable( attrs, ngroups );
        delete[] attrs;
    }

    return dxMesh;
}
bool CMeshBundle::loadMesh( const CResourceId& id, const CResourceId& fullName, CMesh& mesh ) const
{
	// try to load with D3DX
	// obsolete case: .X files
	if( CStringHelper::endsWith( fullName.getUniqueName(), ".x" ) || CStringHelper::endsWith( fullName.getUniqueName(), ".X" ) ) {
		ID3DXBuffer* adjancency = NULL;
		ID3DXBuffer* material = NULL;
		ID3DXBuffer* effects = NULL;
		DWORD matCount;
		ID3DXMesh* dxmesh = NULL;

		HRESULT hres = D3DXLoadMeshFromX(
			fullName.getUniqueName().c_str(),
			D3DXMESH_SYSTEMMEM,
			&CD3DDevice::getInstance().getDevice(),
			&adjancency,
			&material,
			&effects,
			&matCount,
			&dxmesh );
		if( !SUCCEEDED( hres ) )
			return false;
		assert( dxmesh );

		if( adjancency )
			adjancency->Release();
		if( material )
			material->Release();
		if( effects )
			effects->Release();

		//
		// init our mesh

		assert( !mesh.isCreated() );
		// HACK - very limited
		int formatFlags = 0;
		DWORD dxFormat = dxmesh->GetFVF();
		if( dxFormat & D3DFVF_XYZ )
			formatFlags |= CVertexFormat::V_POSITION;
		if( dxFormat & D3DFVF_NORMAL )
			formatFlags |= CVertexFormat::V_NORMAL;
		if( dxFormat & D3DFVF_TEX1 )
			formatFlags |= CVertexFormat::V_UV0_2D;
		CVertexFormat vertFormat( formatFlags );
		// HACK
		int indexStride = 2;

		CD3DVertexDecl* vertDecl = RGET_VDECL( CVertexDesc( vertFormat ) );
		mesh.createResource( dxmesh->GetNumVertices(), dxmesh->GetNumFaces()*3, vertFormat, indexStride, *vertDecl, CMesh::BUF_STATIC );

		//
		// now, copy data into our mesh

		void *dxvb, *dxib;
		dxmesh->LockVertexBuffer( 0, &dxvb );
		dxmesh->LockIndexBuffer( 0, &dxib );
		void* myvb = mesh.lockVBWrite();
		void* myib = mesh.lockIBWrite();

		memcpy( myvb, dxvb, mesh.getVertexCount() * mesh.getVertexStride() );
		memcpy( myib, dxib, mesh.getIndexCount() * mesh.getIndexStride() );
		
		dxmesh->UnlockVertexBuffer();
		dxmesh->UnlockIndexBuffer();
		mesh.unlockVBWrite();
		mesh.unlockIBWrite();

		//
		// create groups

		int ngroups;
		dxmesh->GetAttributeTable( 0, (DWORD*)&ngroups );
		D3DXATTRIBUTERANGE *attrs = new D3DXATTRIBUTERANGE[ngroups];
		dxmesh->GetAttributeTable( attrs, (DWORD*)&ngroups );
		for( int i = 0; i < ngroups; ++i ) {
			const D3DXATTRIBUTERANGE& a = attrs[i];
			mesh.addGroup( CMesh::CGroup( a.VertexStart, a.VertexCount, a.FaceStart, a.FaceCount ) );
		}
		delete[] attrs;

		// release d3dx mesh
		dxmesh->Release();

	} else {

		// our own format
		assert( !mesh.isCreated() );
		bool ok = CMeshSerializer::loadMeshFromFile( fullName.getUniqueName().c_str(), mesh );
		if( !ok )
			return false;
	}
	mesh.computeAABBs();
	CONSOLE.write( "mesh loaded '" + id.getUniqueName() + "'" );
	return true;
}