Detail props/Aspect ratio fix: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
(Created page with ''''This bug in Valve's stock code affects detail sprite materials stored at a location other than <code>detail\detailsprites</code>'''. The aspect ratio used whe…')
 
m (A little editing of the last operation with the code)
Line 1: Line 1:
{{otherlang2
|ru=Detail_props/Aspect_ratio_fix:ru
}}
'''This bug in Valve's stock code affects [[Detail props|detail sprite]] materials stored at a location other than <code>detail\detailsprites</code>'''. The aspect ratio used when selecting subregions of the custom texture is mistakenly read from <code>detail\detailsprites</code> at all times, meaning that the custom texture's aspect ratio must match that of the stock file.
'''This bug in Valve's stock code affects [[Detail props|detail sprite]] materials stored at a location other than <code>detail\detailsprites</code>'''. The aspect ratio used when selecting subregions of the custom texture is mistakenly read from <code>detail\detailsprites</code> at all times, meaning that the custom texture's aspect ratio must match that of the stock file.


Line 27: Line 31:
</source>
</source>


Then '''insert this''' as the start of <code>CDetailObjectSystem::LevelInitPostEntity()</code>, the next function in the file, '''replacing the <code>pWorld</code> conditional block''':
Then in function void CDetailObjectSystem::LevelInitPostEntity() replace this code:
<source lang=cpp>
const char *pDetailSpriteMaterial = DETAIL_SPRITE_MATERIAL;
C_World *pWorld = GetClientWorldEntity();
if ( pWorld && pWorld->GetDetailSpriteMaterial() && *(pWorld->GetDetailSpriteMaterial()) )
{
pDetailSpriteMaterial = pWorld->GetDetailSpriteMaterial();
}
m_DetailSpriteMaterial.Init( pDetailSpriteMaterial, TEXTURE_GROUP_OTHER );
</source>


on this code:
<source lang=cpp>
<source lang=cpp>
void CDetailObjectSystem::LevelInitPostEntity()
if ( m_DetailObjects.Count() || m_DetailSpriteDict.Count() )
{
if ( m_DetailObjects.Count() || m_DetailSpriteDict.Count() )
{
{
const char *pDetailSpriteMaterial = DETAIL_SPRITE_MATERIAL;
const char *pDetailSpriteMaterial = DETAIL_SPRITE_MATERIAL;
Line 38: Line 50:
if ( pWorld && pWorld->GetDetailSpriteMaterial() && *(pWorld->GetDetailSpriteMaterial()) )
if ( pWorld && pWorld->GetDetailSpriteMaterial() && *(pWorld->GetDetailSpriteMaterial()) )
pDetailSpriteMaterial = pWorld->GetDetailSpriteMaterial();  
pDetailSpriteMaterial = pWorld->GetDetailSpriteMaterial();  
 
m_DetailSpriteMaterial.Init( pDetailSpriteMaterial, TEXTURE_GROUP_OTHER );
m_DetailSpriteMaterial.Init( pDetailSpriteMaterial, TEXTURE_GROUP_OTHER );
PrecacheMaterial( pDetailSpriteMaterial );
PrecacheMaterial( pDetailSpriteMaterial );
IMaterial *pMat = m_DetailSpriteMaterial;
IMaterial *pMat = m_DetailSpriteMaterial;
 
// adjust for non-square textures (cropped)
// adjust for non-square textures (cropped)
float flRatio = pMat->GetMappingWidth() / pMat->GetMappingHeight();
float flRatio = pMat->GetMappingWidth() / pMat->GetMappingHeight();
Line 57: Line 69:
}
}
</source>
</source>
The first line after this new code should be <code>if ( GetDetailController() )</code>.


[[Category:Bug fixes]]
[[Category:Bug fixes]]
[[Category:Snippets]]
[[Category:Snippets]]

Revision as of 23:30, 12 May 2013

Template:Otherlang2

This bug in Valve's stock code affects detail sprite materials stored at a location other than detail\detailsprites. The aspect ratio used when selecting subregions of the custom texture is mistakenly read from detail\detailsprites at all times, meaning that the custom texture's aspect ratio must match that of the stock file.

This happens because Valve's aspect ratio code runs before the world has spawned and the detail sprite material becomes known. The fix is moving it to a function called post-spawn.

The fix

Go to CDetailObjectSystem::LevelInitPreEntity() in client\detailobjectsystem.cpp and remove this code block from about half-way down:

if ( m_DetailObjects.Count() || m_DetailSpriteDict.Count() )
{
	// There are detail objects in the level, so precache the material
	PrecacheMaterial( DETAIL_SPRITE_MATERIAL );
	IMaterial *pMat = m_DetailSpriteMaterial;
	// adjust for non-square textures (cropped)
	float flRatio = pMat->GetMappingWidth() / pMat->GetMappingHeight();
	if ( flRatio > 1.0 )
	{
		for( int i = 0; i<m_DetailSpriteDict.Count(); i++ )
		{
			m_DetailSpriteDict[i].m_TexUL.y *= flRatio;
			m_DetailSpriteDict[i].m_TexLR.y *= flRatio;
			m_DetailSpriteDictFlipped[i].m_TexUL.y *= flRatio;
			m_DetailSpriteDictFlipped[i].m_TexLR.y *= flRatio;
		}
	}
}

Then in function void CDetailObjectSystem::LevelInitPostEntity() replace this code:

	const char *pDetailSpriteMaterial = DETAIL_SPRITE_MATERIAL;
	C_World *pWorld = GetClientWorldEntity();
	if ( pWorld && pWorld->GetDetailSpriteMaterial() && *(pWorld->GetDetailSpriteMaterial()) )
	{
		pDetailSpriteMaterial = pWorld->GetDetailSpriteMaterial(); 
	}
	m_DetailSpriteMaterial.Init( pDetailSpriteMaterial, TEXTURE_GROUP_OTHER );

on this code:

if ( m_DetailObjects.Count() || m_DetailSpriteDict.Count() )
	{
		const char *pDetailSpriteMaterial = DETAIL_SPRITE_MATERIAL;
		C_World *pWorld = GetClientWorldEntity();
		if ( pWorld && pWorld->GetDetailSpriteMaterial() && *(pWorld->GetDetailSpriteMaterial()) )
			pDetailSpriteMaterial = pWorld->GetDetailSpriteMaterial(); 
 
		m_DetailSpriteMaterial.Init( pDetailSpriteMaterial, TEXTURE_GROUP_OTHER );
		PrecacheMaterial( pDetailSpriteMaterial );
		IMaterial *pMat = m_DetailSpriteMaterial;
 
		// adjust for non-square textures (cropped)
		float flRatio = pMat->GetMappingWidth() / pMat->GetMappingHeight();
		if ( flRatio > 1.0 )
		{
			for( int i = 0; i<m_DetailSpriteDict.Count(); i++ )
			{
				m_DetailSpriteDict[i].m_TexUL.y *= flRatio;
				m_DetailSpriteDict[i].m_TexLR.y *= flRatio;
				m_DetailSpriteDictFlipped[i].m_TexUL.y *= flRatio;
				m_DetailSpriteDictFlipped[i].m_TexLR.y *= flRatio;
			}
		}
	}