📄 studio_render.cpp
字号:
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 + -