Difference between revisions of "Talk:RpGeometry"

From GTAMods Wiki
Jump to navigation Jump to search
Line 11: Line 11:
  
 
:You are right, I somehow messed up the size of the data. Number of UV coordinates and unknown values are only bytes, not words! Thank you. --{{#if:Aschratt|[[User:Aschratt|Aschratt]]}} - [http://www.aschratt.com oO] 15:52, 8 January 2011 (UTC)
 
:You are right, I somehow messed up the size of the data. Number of UV coordinates and unknown values are only bytes, not words! Thank you. --{{#if:Aschratt|[[User:Aschratt|Aschratt]]}} - [http://www.aschratt.com oO] 15:52, 8 January 2011 (UTC)
 +
 +
 +
== About the attribute buffer ==
 +
 +
Attributes are typically used to define different optimized meshes (in DirectX). GTA uses them to group faces by their material index. The following C++ pseudocode shows how to use attributes with [http://msdn.microsoft.com/en-us/library/bb147196%28v=vs.85%29.aspx DirectX meshes]:
 +
 +
<source lang="c">// This method creates an IDirect3DMesh9 interface and buffers the RWGeometry data to it.
 +
HRESULT RWGeometry::Buffer(LPDIRECT3DDEVICE9* pDevice)
 +
{
 +
// Get the number of faces in general from the BinMeshPLG
 +
// The vertex count is defined inside the geometry section itself.
 +
// Mesh declaration: LPD3DXMESH m_pMesh;
 +
HRESULT hRes = D3DXCreateMeshFVF(m_pExtension->GetBinMeshPLG()->GetFaceCount(), m_dwVertexCount,
 +
D3DXMESH_MANAGED, CVertex::FVFFlags, pDevice,
 +
&m_pMesh);
 +
 +
// ... exception handling in here ...
 +
 +
// ... Setup vertices in here ...
 +
 +
m_pMesh->LockVertexBuffer(0, &pData);
 +
memcpy(pData, pVertices, (sizeof(CVertex) * dwVertices));
 +
m_pMesh->UnlockVertexBuffer();
 +
 +
// ... Setup indices in here ...
 +
 +
m_pMesh->LockIndexBuffer(0, &pData);
 +
memcpy(pData, pIndices, (sizeof(SHORT) * dwIndices));
 +
m_pMesh->UnlockIndexBuffer();
 +
 +
// Setup attributes
 +
DWORD* pAttributesBuffer;
 +
m_pMesh->LockAttributeBuffer(0, &pAttributes);
 +
memcpy(pAttributesBuffer, pAttributes, (sizeof(DWORD) * dwAttributes));
 +
m_pMesh->UnlockAttributeBuffer();
 +
 +
// That's it.
 +
return S_OK;
 +
}
 +
 +
// Each face is now connected to an attribute and each attribute represents one subset.
 +
// The number of subsets represents the number of material splits inside the BinMeshPLG section
 +
void RWGeometry::Render(LPDIRECT3DDEVICE9* pDevice)
 +
{
 +
for (DWORD dwSubset(0); dwSubset < m_pExtension->GetBinMeshPLG()->GetMaterialSplits(); ++dwSubset)
 +
{
 +
m_pMesh->DrawSubset(dwSubset);
 +
}
 +
}</source>
 +
--{{#if:Aschratt|[[User:Aschratt|Aschratt]]}} - [http://www.aschratt.com oO] 11:59, 21 April 2011 (UTC)

Revision as of 11:59, 21 April 2011

Possible incorrect structure

Under the "Structure" heading, you have an extra 2 byte value added which doesn't exist in the PC version of a DFF file, check for yourself. Should this be changed? Or maybe this is for another machine, such as the PS2? Here's the way I see the first structure.

2b - Flags 
2b - Unknown 
4b - Triangle count
4b - Vertex count
4b - Morph Target Count

This is confirmed for GTA:SA DFF files on the PC.

You are right, I somehow messed up the size of the data. Number of UV coordinates and unknown values are only bytes, not words! Thank you. --Aschratt - oO 15:52, 8 January 2011 (UTC)


About the attribute buffer

Attributes are typically used to define different optimized meshes (in DirectX). GTA uses them to group faces by their material index. The following C++ pseudocode shows how to use attributes with DirectX meshes:

// This method creates an IDirect3DMesh9 interface and buffers the RWGeometry data to it.
HRESULT RWGeometry::Buffer(LPDIRECT3DDEVICE9* pDevice)
{
	// Get the number of faces in general from the BinMeshPLG
	// The vertex count is defined inside the geometry section itself.
	// Mesh declaration: LPD3DXMESH m_pMesh;
	HRESULT hRes = D3DXCreateMeshFVF(m_pExtension->GetBinMeshPLG()->GetFaceCount(), m_dwVertexCount,
		D3DXMESH_MANAGED, CVertex::FVFFlags, pDevice,
		&m_pMesh);

	// ... exception handling in here ...

	// ... Setup vertices in here ...
	
	m_pMesh->LockVertexBuffer(0, &pData);
	memcpy(pData, pVertices, (sizeof(CVertex) * dwVertices));
	m_pMesh->UnlockVertexBuffer();

	// ... Setup indices in here ...

	m_pMesh->LockIndexBuffer(0, &pData);
	memcpy(pData, pIndices, (sizeof(SHORT) * dwIndices));
	m_pMesh->UnlockIndexBuffer();

	// Setup attributes
	DWORD* pAttributesBuffer;
	m_pMesh->LockAttributeBuffer(0, &pAttributes);
	memcpy(pAttributesBuffer, pAttributes, (sizeof(DWORD) * dwAttributes));
	m_pMesh->UnlockAttributeBuffer();

	// That's it.
	return S_OK;
}

// Each face is now connected to an attribute and each attribute represents one subset.
// The number of subsets represents the number of material splits inside the BinMeshPLG section
void RWGeometry::Render(LPDIRECT3DDEVICE9* pDevice)
{
	for (DWORD dwSubset(0); dwSubset < m_pExtension->GetBinMeshPLG()->GetMaterialSplits(); ++dwSubset)
	{
		m_pMesh->DrawSubset(dwSubset);
	}
}

--Aschratt - oO 11:59, 21 April 2011 (UTC)