⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 studio_render.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		meshBuilder.Color4fv( color );
		meshBuilder.AdvanceVertex();
	}
	meshBuilder.End();
	pMesh->Draw();

	// top and bottom
	meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, 2 );

	meshBuilder.Position3fv (v[6].Base());
	meshBuilder.Color4fv( color );
	meshBuilder.AdvanceVertex();

	meshBuilder.Position3fv (v[0].Base());
	meshBuilder.Color4fv( color );
	meshBuilder.AdvanceVertex();

	meshBuilder.Position3fv (v[4].Base());
	meshBuilder.Color4fv( color );
	meshBuilder.AdvanceVertex();

	meshBuilder.Position3fv (v[2].Base());
	meshBuilder.Color4fv( color );
	meshBuilder.AdvanceVertex();

	meshBuilder.End();
	pMesh->Draw();

	meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, 2 );

	meshBuilder.Position3fv (v[1].Base());
	meshBuilder.Color4fv( color );
	meshBuilder.AdvanceVertex();

	meshBuilder.Position3fv (v[7].Base());
	meshBuilder.Color4fv( color );
	meshBuilder.AdvanceVertex();

	meshBuilder.Position3fv (v[3].Base());
	meshBuilder.Color4fv( color );
	meshBuilder.AdvanceVertex();

	meshBuilder.Position3fv (v[5].Base());
	meshBuilder.Color4fv( color );
	meshBuilder.AdvanceVertex();

	meshBuilder.End();
	pMesh->Draw();
}

//-----------------------------------------------------------------------------
// Draws a wireframed box
//-----------------------------------------------------------------------------

void StudioModel::drawWireframeBox (Vector const *v, float const* color )
{
	IMesh* pMesh = g_pMaterialSystem->GetDynamicMesh( );

	CMeshBuilder meshBuilder;

	// The four sides
	meshBuilder.Begin( pMesh, MATERIAL_LINES, 4 );
	for (int i = 0; i < 10; i++)
	{
		meshBuilder.Position3fv (v[i & 7].Base());
		meshBuilder.Color4fv( color );
		meshBuilder.AdvanceVertex();
	}
	meshBuilder.End();
	pMesh->Draw();

	// top and bottom
	meshBuilder.Begin( pMesh, MATERIAL_LINE_STRIP, 4 );

	meshBuilder.Position3fv (v[6].Base());
	meshBuilder.Color4fv( color );
	meshBuilder.AdvanceVertex();

	meshBuilder.Position3fv (v[0].Base());
	meshBuilder.Color4fv( color );
	meshBuilder.AdvanceVertex();

	meshBuilder.Position3fv (v[2].Base());
	meshBuilder.Color4fv( color );
	meshBuilder.AdvanceVertex();

	meshBuilder.Position3fv (v[4].Base());
	meshBuilder.Color4fv( color );
	meshBuilder.AdvanceVertex();

	meshBuilder.Position3fv (v[6].Base());
	meshBuilder.Color4fv( color );
	meshBuilder.AdvanceVertex();

	meshBuilder.End();
	pMesh->Draw();

	meshBuilder.Begin( pMesh, MATERIAL_LINE_STRIP, 4 );

	meshBuilder.Position3fv (v[1].Base());
	meshBuilder.Color4fv( color );
	meshBuilder.AdvanceVertex();

	meshBuilder.Position3fv (v[7].Base());
	meshBuilder.Color4fv( color );
	meshBuilder.AdvanceVertex();

	meshBuilder.Position3fv (v[5].Base());
	meshBuilder.Color4fv( color );
	meshBuilder.AdvanceVertex();

	meshBuilder.Position3fv (v[3].Base());
	meshBuilder.Color4fv( color );
	meshBuilder.AdvanceVertex();

	meshBuilder.Position3fv (v[1].Base());
	meshBuilder.Color4fv( color );
	meshBuilder.AdvanceVertex();

	meshBuilder.End();
	pMesh->Draw();
}

//-----------------------------------------------------------------------------
// Draws the position and axies of a transformation matrix, x=red,y=green,z=blue
//-----------------------------------------------------------------------------
void StudioModel::drawTransform( matrix3x4_t& m, float flLength )
{
	IMesh* pMesh = g_pMaterialSystem->GetDynamicMesh( );
	CMeshBuilder meshBuilder;

	for (int k = 0; k < 3; k++)
	{
		static unsigned char color[3][3] =
		{
			{ 255, 0, 0 },
			{ 0, 255, 0 },
			{ 0, 0, 255 }
		};

		meshBuilder.Begin( pMesh, MATERIAL_LINES, 1 );

		meshBuilder.Color3ubv( color[k] );
		meshBuilder.Position3f( m[0][3], m[1][3], m[2][3]);
		meshBuilder.AdvanceVertex();

		meshBuilder.Color3ubv( color[k] );
		meshBuilder.Position3f( m[0][3] + m[0][k] * flLength, m[1][3] + m[1][k] * flLength, m[2][3] + m[2][k] * flLength);
		meshBuilder.AdvanceVertex();

		meshBuilder.End();
		pMesh->Draw();
	}
}

void StudioModel::drawLine( Vector const &p1, Vector const &p2, int r, int g, int b )
{
	g_pMaterialSystem->Bind( g_materialLines );

	IMesh* pMesh = g_pMaterialSystem->GetDynamicMesh( );
	CMeshBuilder meshBuilder;

	meshBuilder.Begin( pMesh, MATERIAL_LINES, 1 );

	meshBuilder.Color3ub( r, g, b );
	meshBuilder.Position3f( p1.x, p1.y, p1.z );
	meshBuilder.AdvanceVertex();

	meshBuilder.Color3ub( r, g, b );
	meshBuilder.Position3f(  p2.x, p2.y, p2.z );
	meshBuilder.AdvanceVertex();

	meshBuilder.End();
	pMesh->Draw();
}


//-----------------------------------------------------------------------------
// Draws a transparent box with a wireframe outline
//-----------------------------------------------------------------------------
void StudioModel::drawTransparentBox( Vector const &bbmin, Vector const &bbmax, 
					const matrix3x4_t& m, float const *color, float const *wirecolor )
{
	Vector v[8], v2[8];

	v[0][0] = bbmin[0];
	v[0][1] = bbmax[1];
	v[0][2] = bbmin[2];

	v[1][0] = bbmin[0];
	v[1][1] = bbmin[1];
	v[1][2] = bbmin[2];

	v[2][0] = bbmax[0];
	v[2][1] = bbmax[1];
	v[2][2] = bbmin[2];

	v[3][0] = bbmax[0];
	v[3][1] = bbmin[1];
	v[3][2] = bbmin[2];

	v[4][0] = bbmax[0];
	v[4][1] = bbmax[1];
	v[4][2] = bbmax[2];

	v[5][0] = bbmax[0];
	v[5][1] = bbmin[1];
	v[5][2] = bbmax[2];

	v[6][0] = bbmin[0];
	v[6][1] = bbmax[1];
	v[6][2] = bbmax[2];

	v[7][0] = bbmin[0];
	v[7][1] = bbmin[1];
	v[7][2] = bbmax[2];

	VectorTransform (v[0], m, v2[0]);
	VectorTransform (v[1], m, v2[1]);
	VectorTransform (v[2], m, v2[2]);
	VectorTransform (v[3], m, v2[3]);
	VectorTransform (v[4], m, v2[4]);
	VectorTransform (v[5], m, v2[5]);
	VectorTransform (v[6], m, v2[6]);
	VectorTransform (v[7], m, v2[7]);
	
	g_pMaterialSystem->Bind( g_pAlpha );
	drawBox( v2, color );

	g_pMaterialSystem->Bind( g_materialBones );
	drawWireframeBox( v2, wirecolor );
}


#define	MAXPRINTMSG	4096
static void StudioRender_Warning( const char *fmt, ... )
{
	va_list		argptr;
	char		msg[MAXPRINTMSG];
	
	va_start( argptr, fmt );
	vsprintf( msg, fmt, argptr );
	va_end( argptr );

//	Msg( mwWarning, "StudioRender: %s", msg );
	OutputDebugString( msg );
}

void StudioModel::UpdateStudioRenderConfig( bool bFlat, bool bWireframe, bool bNormals )
{
	StudioRenderConfig_t config;
	memset( &config, 0, sizeof( config ) );
	config.pConPrintf = StudioRender_Warning;
	config.pConDPrintf = StudioRender_Warning;
	config.fEyeShiftX = 0.0f;
	config.fEyeShiftY = 0.0f;
	config.fEyeShiftZ = 0.0f;
	config.fEyeSize = 0;
	config.gamma = 2.2f;
	config.texGamma = 2.2f;
	config.brightness = 0.0f;
	if( g_viewerSettings.overbright )
	{
//		OutputDebugString( "overbright 2\n" );
		config.overbrightFactor = 2.0f;
	}
	else
	{
//		OutputDebugString( "overbright 1\n" );
		config.overbrightFactor = 1.0f;
	}
	config.modelLightBias = 1.0f;
	config.eyeGloss = 1;
	config.drawEntities = 1;
	config.skin = 0;
	config.fullbright = 0;
	config.bEyeMove = true;
	if( g_viewerSettings.renderMode == RM_WIREFRAME || g_viewerSettings.softwareSkin )
	{
		config.bSoftwareSkin = true;
	}
	else
	{
		config.bSoftwareSkin = false;
	}
	config.bSoftwareLighting = false;
	config.bNoHardware = false;
	config.bNoSoftware = false;
	config.bTeeth = true;
	config.bEyes = true;
	config.bFlex = true;
	if( bWireframe )
	{
		config.bWireframe = true;
	}
	else
	{
		config.bWireframe = false;
	}
	if ( bNormals )
	{
		config.bNormals = true;
	}
	else
	{
		config.bNormals = false;
	}
	config.bUseAmbientCube = true;
	config.bShowEnvCubemapOnly = false;
	m_pStudioRender->UpdateConfig( config );

	MaterialSystem_Config_t matSysConfig;
	extern void InitMaterialSystemConfig(MaterialSystem_Config_t *pConfig);
	InitMaterialSystemConfig( &matSysConfig );
	if( g_viewerSettings.renderMode == RM_FLATSHADED ||
		g_viewerSettings.renderMode == RM_SMOOTHSHADED )
	{
		matSysConfig.bLightingOnly = true;
	}
	matSysConfig.dxSupportLevel = g_dxlevel;
	g_pMaterialSystem->UpdateConfig( &matSysConfig, false );
}


//-----------------------------------------------------------------------------
// Draws the skeleton
//-----------------------------------------------------------------------------

void StudioModel::DrawBones( )
{
	// draw bones
	if (!g_viewerSettings.showBones && (g_viewerSettings.highlightBone < 0))
		return;

	mstudiobone_t *pbones = m_pstudiohdr->pBone( 0 );

	g_pMaterialSystem->Bind( g_materialBones );

	IMesh* pMesh = g_pMaterialSystem->GetDynamicMesh( );
	CMeshBuilder meshBuilder;

	bool drawRed = (g_viewerSettings.highlightBone >= 0);

	for (int i = 0; i < m_pstudiohdr->numbones; i++)
	{
		if (pbones[i].parent >= 0)
		{
			int j = pbones[i].parent;
			if ((g_viewerSettings.highlightBone < 0 ) || (j == g_viewerSettings.highlightBone))
			{
				meshBuilder.Begin( pMesh, MATERIAL_LINES, 1 );

				if (drawRed)
					meshBuilder.Color3ub( 255, 255, 0 );
				else
					meshBuilder.Color3ub( 0, 255, 255 );
				meshBuilder.Position3f( (*m_pStudioRender->GetBoneToWorld( j ))[0][3], (*m_pStudioRender->GetBoneToWorld( j ))[1][3], (*m_pStudioRender->GetBoneToWorld( j ))[2][3]);
				meshBuilder.AdvanceVertex();

				if (drawRed)
					meshBuilder.Color3ub( 255, 255, 0 );
				else
					meshBuilder.Color3ub( 0, 255, 255 );
				meshBuilder.Position3f( (*m_pStudioRender->GetBoneToWorld( i ))[0][3], (*m_pStudioRender->GetBoneToWorld( i ))[1][3], (*m_pStudioRender->GetBoneToWorld( i ))[2][3]);
				meshBuilder.AdvanceVertex();

				meshBuilder.End();
				pMesh->Draw();
			}
		}

		if (g_viewerSettings.highlightBone >= 0)
		{
			if (i != g_viewerSettings.highlightBone)
				continue;
		}

		drawTransform( *m_pStudioRender->GetBoneToWorld( i ) );
	}


	if (g_viewerSettings.highlightBone >= 0)
	{
		int k, j, n;
		for (i = 0; i < m_pstudiohdr->numbodyparts; i++)
		{
			for (j = 0; j < m_pstudiohdr->pBodypart( i )->nummodels; j++)
			{
				mstudiomodel_t *pModel = m_pstudiohdr->pBodypart( i )->pModel( j );

				meshBuilder.Begin( pMesh, MATERIAL_POINTS, 1 );

				for (k = 0; k < pModel->numvertices; k++)
				{
					for (n = 0; n < pModel->BoneWeights( k )->numbones; n++)
					{
						if (pModel->BoneWeights( k )->bone[n] == g_viewerSettings.highlightBone)
						{
							Vector tmp;
							Transform( *pModel->Position( k ), pModel->BoneWeights( k ), tmp );

							meshBuilder.Color3ub( 0, 255, 255 );
							meshBuilder.Position3f( tmp.x, tmp.y, tmp.z );
							meshBuilder.AdvanceVertex();
							break;
						}
					}
				}

				meshBuilder.End();
				pMesh->Draw();
			}
		}
	}
}

//-----------------------------------------------------------------------------
// Draws attachments
//-----------------------------------------------------------------------------

void StudioModel::DrawAttachments( )
{
	if (!g_viewerSettings.showAttachments)
		return;

	g_pMaterialSystem->Bind( g_materialBones );

	for (int i = 0; i < m_pstudiohdr->numattachments; i++)
	{
		mstudioattachment_t *pattachments = m_pstudiohdr->pAttachment( 0 );

		matrix3x4_t world;
		ConcatTransforms( *m_pStudioRender->GetBoneToWorld( pattachments[i].bone ), pattachments[i].local, world );

		drawTransform( world );
	}
}


void StudioModel::DrawEditAttachment()
{
	int iEditAttachment = g_viewerSettings.m_iEditAttachment;
	if ( iEditAttachment >= 0 && iEditAttachment < m_pstudiohdr->numattachments )
	{
		g_pMaterialSystem->Bind( g_materialBones );
		
		mstudioattachment_t *pAttachment = m_pstudiohdr->pAttachment( iEditAttachment );

		matrix3x4_t world;
		ConcatTransforms( *m_pStudioRender->GetBoneToWorld( pAttachment->bone ), pAttachment->local, world );

		drawTransform( world );
	}
}


//-----------------------------------------------------------------------------
// Draws hitboxes
//-----------------------------------------------------------------------------


static float hullcolor[8][4] = 
{
	{ 1.0, 1.0, 1.0, 1.0 },
	{ 1.0, 0.5, 0.5, 1.0 },
	{ 0.5, 1.0, 0.5, 1.0 },
	{ 1.0, 1.0, 0.5, 1.0 },
	{ 0.5, 0.5, 1.0, 1.0 },
	{ 1.0, 0.5, 1.0, 1.0 },
	{ 0.5, 1.0, 1.0, 1.0 },
	{ 1.0, 1.0, 1.0, 1.0 }
};


void StudioModel::DrawHitboxes( )
{
	if (!g_pAlpha)
	{
		g_pAlpha = g_pMaterialSystem->FindMaterial("debug/debughitbox", NULL, false);
	}

	if (g_viewerSettings.showHitBoxes || (g_viewerSettings.highlightHitbox >= 0))
	{
		int hitboxset = g_MDLViewer->GetCurrentHitboxSet();

		for (unsigned short j = m_HitboxSets[ hitboxset ].Head(); j != m_HitboxSets[ hitboxset ].InvalidIndex(); j = m_HitboxSets[ hitboxset ].Next(j) )
		{
			// Only draw one hitbox if we've selected it.
			if ((g_viewerSettings.highlightHitbox >= 0) && 
				(g_viewerSettings.highlightHitbox != j))
				continue;

			mstudiobbox_t *pBBox = &m_HitboxSets[ hitboxset ][j];

			float interiorcolor[4];
			int c = pBBox->group % 8;
			interiorcolor[0] = hullcolor[c][0] * 0.7;
			interiorcolor[1] = hullcolor[c][1] * 0.7;
			interiorcolor[2] = hullcolor[c][2] * 0.7;
			interiorcolor[3] = hullcolor[c][3] * 0.4;

			drawTransparentBox( pBBox->bbmin, pBBox->bbmax, *m_pStudioRender->GetBoneToWorld( pBBox->bone ), interiorcolor, hullcolor[ c ] );
		}
	}

	/*
	float color2[] = { 0, 0.7, 1, 0.6 };
	float wirecolor2[] = { 0, 1, 1, 1.0 };
	drawTransparentBox( m_pstudiohdr->min, m_pstudiohdr->max, g_viewtransform, color2, wirecolor2 );
	*/

	if (g_viewerSettings.showSequenceBoxes)
	{
		float color[] = { 0.7, 1, 0, 0.6 };
		float wirecolor[] = { 1, 1, 0, 1.0 };

		drawTransparentBox( m_pstudiohdr->pSeqdesc( m_sequence )->bbmin, m_pstudiohdr->pSeqdesc( m_sequence )->bbmax, g_viewtransform, color, wirecolor );
	}
}

//-----------------------------------------------------------------------------
// Draws the physics model
//-----------------------------------------------------------------------------

void StudioModel::DrawPhysicsModel( )
{
	if (!g_viewerSettings.showPhysicsModel)
		return;

	if ( g_viewerSettings.renderMode == RM_WIREFRAME && m_pPhysics->Count() == 1 )
	{
		// show the convex pieces in solid
		DrawPhysConvex( m_pPhysics->GetMesh(0), g_materialFlatshaded );
	}
	else
	{
		for (int i = 0; i < m_pPhysics->Count(); i++)
		{
			float red[] = { 1.0, 0, 0, 0.25 };
			float yellow[] = { 1.0, 1.0, 0, 0.5 };

			CPhysmesh *pmesh = m_pPhysics->GetMesh(i);
			int boneIndex = FindBone(pmesh->m_boneName);

			if ( boneIndex >= 0 )
			{
				if ( (i+1) == g_viewerSettings.highlightPhysicsBone )
				{
					DrawPhysmesh( pmesh, boneIndex, g_materialBones, red );
				}
				else
				{
					if ( g_viewerSettings.highlightPhysicsBone < 1 )
					{
						// yellow for most
						DrawPhysmesh( pmesh, boneIndex, g_materialBones, yellow );
					}
				}
			}
			else
			{
				DrawPhysmesh( pmesh, -1, g_materialBones, red );
			}
		}
	}
}




void StudioModel::SetViewTarget( void )
{
	int iEyeUpdown = LookupFlexController( "eyes_updown" );

	int iEyeRightleft = LookupFlexController( "eyes_rightleft" );

	int iEyeAttachment = LookupAttachment( "eyes" );
	
	if (iEyeUpdown == -1 || iEyeRightleft == -1 || iEyeAttachment == -1)
		return;

	Vector local;
	Vector tmp;

	mstudioattachment_t *patt = m_pstudiohdr->pAttachment( iEyeAttachment );
	matrix3x4_t attToWorld;
	ConcatTransforms( *m_pStudioRender->GetBoneToWorld( patt->bone ), patt->local, attToWorld ); 

	// look forward
	local = Vector( 32, 0, 0 );
	if (g_viewerSettings.flHeadTurn != 0.0f)
	{
		// aim the eyes
		VectorITransform( g_viewerSettings.vecEyeTarget, attToWorld, local );
	}
	
	float flDist = local.Length();

	VectorNormalize( local );

	// calculate animated eye deflection
	Vector eyeDeflect;
	QAngle eyeAng( GetFlexController(iEyeUpdown), GetFlexController(iEyeRightleft), 0 );

	// debugoverlay->AddTextOverlay( m_vecOrigin + Vector( 0, 0, 64 ), 0, 0, "%.2f %.2f", eyeAng.x, eyeAng.y );

	AngleVectors( eyeAng, &eyeDeflect );
	eyeDeflect.x = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -