/* ================ StudioModel::DrawModel inputs: currententity r_entorigin ================ */ void StudioModel::DrawModel( ) { int i; g_smodels_total++; // render data cache cookie g_pxformverts = &g_xformverts[0]; g_pvlightvalues = &g_lightvalues[0]; if (m_pstudiohdr->numbodyparts == 0) return; glPushMatrix (); glTranslatef (m_origin[0], m_origin[1], m_origin[2]); glRotatef (m_angles[1], 0, 0, 1); glRotatef (m_angles[0], 0, 1, 0); glRotatef (m_angles[2], 1, 0, 0); // glShadeModel (GL_SMOOTH); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); SetUpBones ( ); SetupLighting( ); for (i=0 ; i < m_pstudiohdr->numbodyparts ; i++) { SetupModel( i ); DrawPoints( ); } glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); // glShadeModel (GL_FLAT); // glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glPopMatrix (); }
//----------------------------------------------------------------------------- // Draws the mesh //----------------------------------------------------------------------------- void CDmeMDL::Draw( const matrix3x4_t &shapeToWorld, CDmeDrawSettings *pDrawSettings /* = NULL */ ) { if ( !g_pMaterialSystem || !g_pMDLCache || !g_pStudioRender ) return; if ( m_MDLHandle == MDLHANDLE_INVALID ) return; // Color + alpha modulation Vector white( m_Color.r() / 255.0f, m_Color.g() / 255.0f, m_Color.b() / 255.0f ); g_pStudioRender->SetColorModulation( white.Base() ); g_pStudioRender->SetAlphaModulation( m_Color.a() / 255.0f ); DrawModelInfo_t info; info.m_pStudioHdr = g_pMDLCache->GetStudioHdr( m_MDLHandle ); info.m_pHardwareData = g_pMDLCache->GetHardwareData( m_MDLHandle ); info.m_Decals = STUDIORENDER_DECAL_INVALID; info.m_Skin = m_nSkin; info.m_Body = m_nBody; info.m_HitboxSet = 0; info.m_pClientEntity = NULL; info.m_pColorMeshes = NULL; info.m_bStaticLighting = false; info.m_Lod = m_nLOD; // FIXME: Deal with lighting for ( int i = 0; i < 6; ++ i ) { info.m_vecAmbientCube[i].Init( 1, 1, 1 ); } info.m_nLocalLightCount = 0; // info.m_LocalLightDescs; matrix3x4_t *pBoneToWorld = g_pStudioRender->LockBoneMatrices( info.m_pStudioHdr->numbones ); SetUpBones( shapeToWorld, info.m_pStudioHdr->numbones, pBoneToWorld ); g_pStudioRender->UnlockBoneMatrices(); Vector vecWorldViewTarget; if ( m_bWorldSpaceViewTarget ) { vecWorldViewTarget = m_vecViewTarget; } else { VectorTransform( m_vecViewTarget, shapeToWorld, vecWorldViewTarget ); } g_pStudioRender->SetEyeViewTarget( info.m_pStudioHdr, info.m_Body, vecWorldViewTarget ); // FIXME: Why is this necessary!?!?!? CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); if ( !m_bDrawInEngine ) { pRenderContext->CullMode(MATERIAL_CULLMODE_CCW); } // Set default flex values float *pFlexWeights = NULL; const int nFlexDescCount = info.m_pStudioHdr->numflexdesc; if ( nFlexDescCount ) { CStudioHdr cStudioHdr( info.m_pStudioHdr, g_pMDLCache ); float flexDefaults[ MAXSTUDIOFLEXCTRL * 4 ]; memset( flexDefaults, 0, MAXSTUDIOFLEXCTRL * 4 * sizeof( float ) ); g_pStudioRender->LockFlexWeights( info.m_pStudioHdr->numflexdesc, &pFlexWeights ); cStudioHdr.RunFlexRules( flexDefaults, pFlexWeights ); g_pStudioRender->UnlockFlexWeights(); } Vector vecModelOrigin; MatrixGetColumn( shapeToWorld, 3, vecModelOrigin ); g_pStudioRender->DrawModel( NULL, info, pBoneToWorld, pFlexWeights, NULL, vecModelOrigin, STUDIORENDER_DRAW_ENTIRE_MODEL ); // FIXME: Why is this necessary!?!?!? if ( !m_bDrawInEngine ) { pRenderContext->CullMode( MATERIAL_CULLMODE_CW ); } }
void CDmeMDL::SetUpBones( const matrix3x4_t& shapeToWorld, int nMaxBoneCount, matrix3x4_t *pOutputMatrices ) { CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( m_MDLHandle ), g_pMDLCache ); SetUpBones( studioHdr, shapeToWorld, nMaxBoneCount, pOutputMatrices ); }
//----------------------------------------------------------------------------- // Render a frame //----------------------------------------------------------------------------- void CIHVTestApp::RenderFrame( void ) { VPROF( "RenderFrame" ); IHVTestModel *pModel = NULL; static int currentRun = 0; static int currentFrame = 0; static int currentLightCombo = 0; int modelAlternator = 0; if (g_bInError) { // error context is active // error may be renderer based, avoid re-entrant render to fatal crash return; } if( g_BenchMode ) { if( currentFrame > g_BenchRuns[currentRun].numFrames ) { currentLightCombo++; if( currentLightCombo >= LIGHTING_COMBINATION_COUNT ) { currentRun++; currentLightCombo = 0; if( currentRun >= NUM_BENCH_RUNS ) { g_BenchFinished = true; return; } } currentFrame = 0; } } if( g_BenchMode ) { pModel = &g_BenchModels[currentRun][0]; g_NumCols = g_BenchRuns[currentRun].cols; g_NumRows = g_BenchRuns[currentRun].rows; } else { pModel = m_pIHVTestModel; } Assert( pModel ); g_EngineStats.BeginFrame(); g_pMaterialSystem->BeginFrame( 0 ); g_pStudioRender->BeginFrame(); CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); pRenderContext->ClearColor3ub( 0, 0, 0 ); pRenderContext->ClearBuffers( true, true ); pRenderContext->Viewport( 0, 0, g_RenderWidth, g_RenderHeight ); pRenderContext->MatrixMode( MATERIAL_PROJECTION ); pRenderContext->LoadIdentity(); pRenderContext->PerspectiveX( 90.0f, ( g_RenderWidth / g_RenderHeight), 1.0f, 500000.0f ); pRenderContext->MatrixMode( MATERIAL_VIEW ); pRenderContext->LoadIdentity(); if( g_BenchMode ) { pRenderContext->Translate( 0.0f, 0.0f, ( float )-( g_NumCols * g_BenchRuns[currentRun].modelSize * 0.6f ) ); } else { pRenderContext->Translate( 0.0f, 0.0f, ( float )-( g_NumCols * 80.0f * 0.5f ) ); } pRenderContext->MatrixMode( MATERIAL_MODEL ); pRenderContext->LoadIdentity(); QAngle angles; angles[YAW] = -90.0f; angles[PITCH] = -90.0f; angles[ROLL] = 0.0f; matrix3x4_t cameraMatrix; AngleMatrix( angles, cameraMatrix ); int r, c; int trisRendered = 0; float boneSetupTime = 0.0f; for( r = 0; r < g_NumRows; r++ ) { for( c = 0; c < g_NumCols; c++ ) { // If we are alternating models, select the next valid model. if( g_BenchMode ) { do { // If I pass my maximum number of models, wrap around to model 0, which must always be valid. if( ++modelAlternator >= g_nMaxModels ) { modelAlternator = 0; break; } } while( !g_BenchRuns[currentRun].pModelName[modelAlternator] ); pModel = &g_BenchModels[currentRun][modelAlternator]; Assert( pModel ); } if( g_BenchMode ) { cameraMatrix[0][3] = ( ( c + 0.5f ) - ( g_NumCols * .5f ) ) * g_BenchRuns[currentRun].modelSize; cameraMatrix[1][3] = ( ( float )r - ( g_NumCols * .5f ) ) * g_BenchRuns[currentRun].modelSize; } else { cameraMatrix[0][3] = ( ( c + 0.5f ) - ( g_NumCols * .5f ) ) * 75.0f; cameraMatrix[1][3] = ( ( float )r - ( g_NumCols * .5f ) ) * 75.0f; } Vector modelOrigin( cameraMatrix[0][3], cameraMatrix[1][3], 0.0f ); Vector lightOffset( cameraMatrix[0][3], cameraMatrix[1][3], 0.0f ); if (g_LightingCombination < 0) { SetupLighting( g_BenchMode ? currentLightCombo : 0, lightOffset ); } else { SetupLighting( g_LightingCombination, lightOffset ); } float startBoneSetupTime = Sys_FloatTime(); int lod = g_LOD; lod = clamp( lod, pModel->pHardwareData->m_RootLOD, pModel->pHardwareData->m_NumLODs-1 ); int boneMask = BONE_USED_BY_VERTEX_AT_LOD( lod ); matrix3x4_t *pBoneToWorld = SetUpBones( pModel->pStudioHdr, cameraMatrix, currentRun, modelAlternator, boneMask ); boneSetupTime += Sys_FloatTime() - startBoneSetupTime; pRenderContext->MatrixMode( MATERIAL_MODEL ); pRenderContext->PushMatrix(); DrawModelInfo_t modelInfo; memset( &modelInfo, 0, sizeof( modelInfo ) ); modelInfo.m_pStudioHdr = pModel->pStudioHdr; modelInfo.m_pHardwareData = pModel->pHardwareData; modelInfo.m_Decals = STUDIORENDER_DECAL_INVALID; modelInfo.m_Skin = 0; modelInfo.m_Body = g_BodyGroup; modelInfo.m_HitboxSet = 0; modelInfo.m_pClientEntity = NULL; modelInfo.m_Lod = lod; modelInfo.m_pColorMeshes = NULL; g_pStudioRender->DrawModel( NULL, modelInfo, pBoneToWorld, NULL, NULL, modelOrigin ); DrawModelResults_t results; g_pStudioRender->GetPerfStats( &results, modelInfo, NULL ); trisRendered += results.m_ActualTriCount; pRenderContext->MatrixMode( MATERIAL_MODEL ); pRenderContext->PopMatrix(); } } pRenderContext->Flush( true ); g_EngineStats.EndFrame(); g_pStudioRender->EndFrame(); g_pMaterialSystem->EndFrame(); // hack - don't count the first frame in case there are any state // transitions computed on that frame. if( currentFrame != 0 ) { g_BenchResults[currentRun][currentLightCombo].totalTime += g_EngineStats.GetCurrentSystemFrameTime(); g_BenchResults[currentRun][currentLightCombo].totalTris += trisRendered; } for ( int model = 0; model < g_nMaxModels; ++model ) { CStudioHdr studioHdr( g_BenchModels[currentRun][model].pStudioHdr, g_pMDLCache ); AdvanceFrame( &studioHdr, currentRun, model, g_EngineStats.GetCurrentSystemFrameTime() ); } g_pMaterialSystem->SwapBuffers(); #ifdef USE_VPROF g_VProfCurrentProfile.MarkFrame(); static bool bBeenHere = false; if( !bBeenHere ) { bBeenHere = true; g_VProfCurrentProfile.Reset(); } #endif currentFrame++; }