Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

246 lines
12 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //===========================================================================//
  6. #ifndef STUDIORENDERCONTEXT_H
  7. #define STUDIORENDERCONTEXT_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "istudiorender.h"
  12. #include "tier3/tier3.h"
  13. #include "studio.h"
  14. #include "tier1/delegates.h"
  15. #include "tier1/memstack.h"
  16. #include "studiorender.h"
  17. //-----------------------------------------------------------------------------
  18. // Foward declarations
  19. //-----------------------------------------------------------------------------
  20. class IStudioDataCache;
  21. class CStudioRender;
  22. //-----------------------------------------------------------------------------
  23. // Global interfaces
  24. //-----------------------------------------------------------------------------
  25. extern IStudioDataCache *g_pStudioDataCache;
  26. extern CStudioRender *g_pStudioRenderImp;
  27. IMaterial* GetModelSpecificDecalMaterial( IMaterial* pDecalMaterial );
  28. //-----------------------------------------------------------------------------
  29. // Internal config structure
  30. //-----------------------------------------------------------------------------
  31. struct StudioRenderConfigInternal_t : public StudioRenderConfig_t
  32. {
  33. bool m_bSupportsVertexAndPixelShaders : 1;
  34. bool m_bSupportsOverbright : 1;
  35. bool m_bEnableHWMorph : 1;
  36. bool m_bStatsMode : 1;
  37. };
  38. //-----------------------------------------------------------------------------
  39. // All the data needed to render a studiomodel
  40. //-----------------------------------------------------------------------------
  41. struct FlexWeights_t
  42. {
  43. float *m_pFlexWeights;
  44. float *m_pFlexDelayedWeights;
  45. };
  46. struct StudioRenderContext_t
  47. {
  48. StudioRenderConfigInternal_t m_Config;
  49. Vector m_ViewTarget;
  50. Vector m_ViewOrigin;
  51. Vector m_ViewRight;
  52. Vector m_ViewUp;
  53. Vector m_ViewPlaneNormal;
  54. Vector4D m_LightBoxColors[6];
  55. LightDesc_t m_LocalLights[MAXLOCALLIGHTS];
  56. int m_NumLocalLights;
  57. float m_ColorMod[3];
  58. float m_AlphaMod;
  59. IMaterial* m_pForcedMaterial;
  60. OverrideType_t m_nForcedMaterialType;
  61. };
  62. //-----------------------------------------------------------------------------
  63. // Helper to queue up calls if necessary
  64. //-----------------------------------------------------------------------------
  65. #define QUEUE_STUDIORENDER_CALL( FuncName, ClassName, pObject, ... ) \
  66. CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); \
  67. ICallQueue *pCallQueue = pRenderContext->GetCallQueue(); \
  68. if ( !pCallQueue || studio_queue_mode.GetInt() == 0 ) \
  69. { \
  70. pObject->FuncName( __VA_ARGS__ ); \
  71. } \
  72. else \
  73. { \
  74. pCallQueue->QueueCall( pObject, &ClassName::FuncName, ##__VA_ARGS__ ); \
  75. }
  76. #define QUEUE_STUDIORENDER_CALL_RC( FuncName, ClassName, pObject, pRenderContext, ... ) \
  77. ICallQueue *pCallQueue = pRenderContext->GetCallQueue(); \
  78. if ( !pCallQueue || studio_queue_mode.GetInt() == 0 ) \
  79. { \
  80. pObject->FuncName( __VA_ARGS__ ); \
  81. } \
  82. else \
  83. { \
  84. pCallQueue->QueueCall( pObject, &ClassName::FuncName, ##__VA_ARGS__ ); \
  85. }
  86. //-----------------------------------------------------------------------------
  87. // Implementation of IStudioRender
  88. //-----------------------------------------------------------------------------
  89. class CStudioRenderContext : public CTier3AppSystem< IStudioRender >
  90. {
  91. typedef CTier3AppSystem< IStudioRender > BaseClass;
  92. // Methods of IAppSystem
  93. public:
  94. virtual bool Connect( CreateInterfaceFn factory );
  95. virtual void Disconnect();
  96. virtual void *QueryInterface( const char *pInterfaceName );
  97. virtual InitReturnVal_t Init();
  98. virtual void Shutdown();
  99. // Methods of IStudioRender
  100. public:
  101. virtual void BeginFrame( void );
  102. virtual void EndFrame( void );
  103. virtual void Mat_Stub( IMaterialSystem *pMatSys );
  104. virtual void UpdateConfig( const StudioRenderConfig_t& config );
  105. virtual void GetCurrentConfig( StudioRenderConfig_t& config );
  106. virtual bool LoadModel(studiohdr_t *pStudioHdr, void *pVtxData, studiohwdata_t *pHardwareData);
  107. virtual void UnloadModel( studiohwdata_t *pHardwareData );
  108. virtual void RefreshStudioHdr( studiohdr_t* pStudioHdr, studiohwdata_t* pHardwareData );
  109. virtual void SetEyeViewTarget( const studiohdr_t *pStudioHdr, int nBodyIndex, const Vector& worldPosition );
  110. virtual void SetAmbientLightColors( const Vector *pAmbientOnlyColors );
  111. virtual void SetAmbientLightColors( const Vector4D *pAmbientOnlyColors );
  112. virtual void SetLocalLights( int numLights, const LightDesc_t *pLights );
  113. virtual int GetNumAmbientLightSamples();
  114. virtual const Vector *GetAmbientLightDirections();
  115. virtual void SetViewState( const Vector& viewOrigin, const Vector& viewRight, const Vector& viewUp, const Vector& viewPlaneNormal );
  116. virtual int GetNumLODs( const studiohwdata_t &hardwareData ) const;
  117. virtual float GetLODSwitchValue( const studiohwdata_t &hardwareData, int lod ) const;
  118. virtual void SetLODSwitchValue( studiohwdata_t &hardwareData, int lod, float switchValue );
  119. virtual void SetColorModulation( const float* pColor );
  120. virtual void SetAlphaModulation( float alpha );
  121. virtual void DrawModel( DrawModelResults_t *pResults, const DrawModelInfo_t& info, matrix3x4_t *pCustomBoneToWorld, float *pFlexWeights, float *pFlexDelayedWeights, const Vector& origin, int flags = STUDIORENDER_DRAW_ENTIRE_MODEL );
  122. virtual void DrawModelArray( const DrawModelInfo_t &drawInfo, int arrayCount, model_array_instance_t *pInstanceData, int instanceStride, int flags = STUDIORENDER_DRAW_ENTIRE_MODEL );
  123. virtual void DrawModelStaticProp( const DrawModelInfo_t& info, const matrix3x4_t &modelToWorld, int flags = STUDIORENDER_DRAW_ENTIRE_MODEL );
  124. virtual void DrawStaticPropDecals( const DrawModelInfo_t &drawInfo, const matrix3x4_t &modelToWorld );
  125. virtual void DrawStaticPropShadows( const DrawModelInfo_t &drawInfo, const matrix3x4_t &modelToWorld, int flags );
  126. virtual void ForcedMaterialOverride( IMaterial *newMaterial, OverrideType_t nOverrideType = OVERRIDE_NORMAL );
  127. DELEGATE_TO_OBJECT_1( StudioDecalHandle_t, CreateDecalList, studiohwdata_t *, g_pStudioRenderImp );
  128. virtual void DestroyDecalList( StudioDecalHandle_t handle );
  129. virtual void AddDecal( StudioDecalHandle_t handle, studiohdr_t *pStudioHdr, matrix3x4_t *pBoneToWorld, const Ray_t & ray, const Vector& decalUp, IMaterial* pDecalMaterial, float radius, int body, bool noPokethru, int maxLODToDecal = ADDDECAL_TO_ALL_LODS );
  130. virtual void ComputeLighting( const Vector* pAmbient, int lightCount, LightDesc_t* pLights, const Vector& pt, const Vector& normal, Vector& lighting );
  131. virtual void ComputeLightingConstDirectional( const Vector* pAmbient, int lightCount, LightDesc_t* pLights, const Vector& pt, const Vector& normal, Vector& lighting, float flDirectionalAmount );
  132. virtual void AddShadow( IMaterial* pMaterial, void* pProxyData, FlashlightState_t *pFlashlightState, VMatrix *pWorldToTexture, ITexture *pFlashlightDepthTexture );
  133. virtual void ClearAllShadows();
  134. virtual int ComputeModelLod( studiohwdata_t* pHardwareData, float flUnitSphereSize, float *pMetric = NULL );
  135. virtual void GetPerfStats( DrawModelResults_t *pResults, const DrawModelInfo_t &info, CUtlBuffer *pSpewBuf = NULL ) const;
  136. virtual void GetTriangles( const DrawModelInfo_t& info, matrix3x4_t *pBoneToWorld, GetTriangles_Output_t &out );
  137. virtual int GetMaterialList( studiohdr_t *pStudioHdr, int count, IMaterial** ppMaterials );
  138. virtual int GetMaterialListFromBodyAndSkin( MDLHandle_t studio, int nSkin, int nBody, int nCountOutputMaterials, IMaterial** ppOutputMaterials );
  139. virtual matrix3x4_t* LockBoneMatrices( int nCount );
  140. virtual void UnlockBoneMatrices();
  141. virtual void LockFlexWeights( int nWeightCount, float **ppFlexWeights, float **ppFlexDelayedWeights = NULL );
  142. virtual void UnlockFlexWeights();
  143. virtual void GetMaterialOverride( IMaterial** ppOutForcedMaterial, OverrideType_t* pOutOverrideType );
  144. // Other public methods
  145. public:
  146. CStudioRenderContext();
  147. virtual ~CStudioRenderContext();
  148. private:
  149. // Load, unload materials
  150. void LoadMaterials( studiohdr_t *phdr, OptimizedModel::FileHeader_t *, studioloddata_t &lodData, int lodID );
  151. // Determines material flags
  152. void ComputeMaterialFlags( studiohdr_t *phdr, studioloddata_t &lodData, IMaterial *pMaterial );
  153. // Creates, destroys static meshes
  154. void R_StudioCreateStaticMeshes( studiohdr_t *pStudioHdr, OptimizedModel::FileHeader_t* pVtxHdr,
  155. studiohwdata_t *pStudioHWData, int lodID, int *pColorMeshID );
  156. void R_StudioCreateSingleMesh( studiohdr_t *pStudioHdr, studioloddata_t *pStudioLodData,
  157. mstudiomesh_t* pMesh, OptimizedModel::MeshHeader_t* pVtxMesh, int numBones,
  158. studiomeshdata_t* pMeshData, int *pColorMeshID );
  159. void R_StudioDestroyStaticMeshes( int numStudioMeshes, studiomeshdata_t **ppStudioMeshes );
  160. // Determine if any strip groups shouldn't be morphed
  161. void DetermineHWMorphing( mstudiomodel_t *pModel, OptimizedModel::ModelLODHeader_t *pVtxLOD );
  162. // Count deltas affecting a particular stripgroup
  163. int CountDeltaFlexedStripGroups( mstudiomodel_t *pModel, OptimizedModel::ModelLODHeader_t *pVtxLOD );
  164. // Count vertices affected by deltas in a particular strip group
  165. int CountFlexedVertices( mstudiomesh_t* pMesh, OptimizedModel::StripGroupHeader_t* pStripGroup );
  166. // Builds morph data
  167. void R_StudioBuildMorph( studiohdr_t *pStudioHdr, studiomeshgroup_t* pMeshGroup, mstudiomesh_t* pMesh,
  168. OptimizedModel::StripGroupHeader_t *pStripGroup );
  169. // Builds the decal bone remap for a particular mesh
  170. void ComputeHWMorphDecalBoneRemap( studiohdr_t *pStudioHdr, OptimizedModel::FileHeader_t *pVtxHdr, studiohwdata_t *pStudioHWData, int nLOD );
  171. void BuildDecalBoneMap( studiohdr_t *pStudioHdr, int *pUsedBones, int *pBoneRemap, int *pMaxBoneCount, mstudiomesh_t* pMesh, OptimizedModel::StripGroupHeader_t* pStripGroup );
  172. // Helper methods used to construct static meshes
  173. int GetNumBoneWeights( const OptimizedModel::StripGroupHeader_t *pGroup );
  174. VertexFormat_t CalculateVertexFormat( const studiohdr_t *pStudioHdr, const studioloddata_t *pStudioLodData,
  175. const mstudiomesh_t* pMesh, OptimizedModel::StripGroupHeader_t *pGroup, bool bIsHwSkinned );
  176. bool MeshNeedsTangentSpace( studiohdr_t *pStudioHdr, studioloddata_t *pStudioLodData, mstudiomesh_t* pMesh );
  177. void R_StudioBuildMeshGroup( const char *pModelName, bool bNeedsTangentSpace, studiomeshgroup_t* pMeshGroup,
  178. OptimizedModel::StripGroupHeader_t *pStripGroup, mstudiomesh_t* pMesh,
  179. studiohdr_t *pStudioHdr, VertexFormat_t vertexFormat );
  180. void R_StudioBuildMeshStrips( studiomeshgroup_t* pMeshGroup,
  181. OptimizedModel::StripGroupHeader_t *pStripGroup );
  182. template <VertexCompressionType_t T> bool R_AddVertexToMesh( const char *pModelName, bool bNeedsTangentSpace, CMeshBuilder& meshBuilder,
  183. OptimizedModel::Vertex_t* pVertex, mstudiomesh_t* pMesh, const mstudio_meshvertexdata_t *vertData, bool hwSkin );
  184. // This will generate random flex data that has a specified # of non-zero values
  185. void GenerateRandomFlexWeights( int nWeightCount, float* pWeights, float *pDelayedWeights );
  186. // Computes LOD
  187. int ComputeRenderLOD( IMatRenderContext *pRenderContext, const DrawModelInfo_t& info, const Vector &origin, float *pMetric );
  188. // This invokes proxies of all materials that are queued to be rendered
  189. void InvokeBindProxies( const DrawModelInfo_t &info );
  190. // Did this matrix come from our allocator?
  191. bool IsInternallyAllocated( const matrix3x4_t *pBoneToWorld );
  192. // Did this flex weights come from our allocator?
  193. bool IsInternallyAllocated( const float *pFlexWeights );
  194. private:
  195. StudioRenderContext_t m_RC;
  196. // Used by the lighting computation methods,
  197. // this is only here to prevent constructors in lightpos_t from being repeatedly run
  198. lightpos_t m_pLightPos[MAXLIGHTCOMPUTE];
  199. };
  200. //-----------------------------------------------------------------------------
  201. // Inline methods
  202. //-----------------------------------------------------------------------------
  203. inline int CStudioRenderContext::ComputeModelLod( studiohwdata_t *pHardwareData, float flUnitSphereSize, float *pMetric )
  204. {
  205. return ComputeModelLODAndMetric( pHardwareData, flUnitSphereSize, pMetric );
  206. }
  207. #endif // STUDIORENDERCONTEXT_H