1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#ifndef ISTUDIORENDER_H
#define ISTUDIORENDER_H
#ifdef _WIN32
#pragma once
#endif
#include "tier1/interface.h"
#include "mathlib/vector.h"
#include "mathlib/vector4d.h"
#include "tier1/utlbuffer.h"
#include "tier1/utlvector.h"
#include "materialsystem/imaterial.h"
#include "materialsystem/imaterialsystem.h"
#include "appframework/IAppSystem.h"
#include "datacache/imdlcache.h"
#include "studio.h"
//-----------------------------------------------------------------------------
// forward declarations
//-----------------------------------------------------------------------------
struct studiohdr_t;
struct studiomeshdata_t;
class Vector;
struct LightDesc_t;
class IMaterial;
struct studiohwdata_t;
struct Ray_t;
class Vector4D;
class IMaterialSystem;
struct matrix3x4_t;
class IMesh;
struct vertexFileHeader_t;
struct FlashlightState_t;
class VMatrix;
namespace OptimizedModel { struct FileHeader_t; }
class IPooledVBAllocator;
// undone: what's the standard for function type naming?
typedef void (*StudioRender_Printf_t)( PRINTF_FORMAT_STRING const char *fmt, ... );
struct StudioRenderConfig_t
{
float fEyeShiftX; // eye X position
float fEyeShiftY; // eye Y position
float fEyeShiftZ; // eye Z position
float fEyeSize; // adjustment to iris textures
float fEyeGlintPixelWidthLODThreshold;
int maxDecalsPerModel;
int drawEntities;
int skin;
int fullbright;
bool bEyeMove : 1; // look around
bool bSoftwareSkin : 1;
bool bNoHardware : 1;
bool bNoSoftware : 1;
bool bTeeth : 1;
bool bEyes : 1;
bool bFlex : 1;
bool bWireframe : 1;
bool bDrawNormals : 1;
bool bDrawTangentFrame : 1;
bool bDrawZBufferedWireframe : 1;
bool bSoftwareLighting : 1;
bool bShowEnvCubemapOnly : 1;
bool bWireframeDecals : 1;
// Reserved for future use
int m_nReserved[4];
};
//-----------------------------------------------------------------------------
// Studio render interface
//-----------------------------------------------------------------------------
DECLARE_POINTER_HANDLE( StudioDecalHandle_t );
#define STUDIORENDER_DECAL_INVALID ( (StudioDecalHandle_t)0 )
enum
{
ADDDECAL_TO_ALL_LODS = -1
};
//-----------------------------------------------------------------------------
// DrawModel flags
//-----------------------------------------------------------------------------
enum
{
STUDIORENDER_DRAW_ENTIRE_MODEL = 0,
STUDIORENDER_DRAW_OPAQUE_ONLY = 0x01,
STUDIORENDER_DRAW_TRANSLUCENT_ONLY = 0x02,
STUDIORENDER_DRAW_GROUP_MASK = 0x03,
STUDIORENDER_DRAW_NO_FLEXES = 0x04,
STUDIORENDER_DRAW_STATIC_LIGHTING = 0x08,
STUDIORENDER_DRAW_ACCURATETIME = 0x10, // Use accurate timing when drawing the model.
STUDIORENDER_DRAW_NO_SHADOWS = 0x20,
STUDIORENDER_DRAW_GET_PERF_STATS = 0x40,
STUDIORENDER_DRAW_WIREFRAME = 0x80,
STUDIORENDER_DRAW_ITEM_BLINK = 0x100,
STUDIORENDER_SHADOWDEPTHTEXTURE = 0x200,
STUDIORENDER_SSAODEPTHTEXTURE = 0x1000,
STUDIORENDER_GENERATE_STATS = 0x8000,
};
//-----------------------------------------------------------------------------
// Standard model vertex formats
//-----------------------------------------------------------------------------
// FIXME: remove these (materials/shaders should drive vertex format). Need to
// list required forcedmaterialoverrides in models/bsps (rather than
// all models supporting all possible overrides, as they do currently).
#define VERTEX_TEXCOORD0_2D ( ( (uint64) 2 ) << ( TEX_COORD_SIZE_BIT + ( 3*0 ) ) )
enum MaterialVertexFormat_t
{
MATERIAL_VERTEX_FORMAT_MODEL_SKINNED = (VertexFormat_t) VERTEX_POSITION | VERTEX_COLOR | VERTEX_NORMAL | VERTEX_TEXCOORD0_2D | VERTEX_BONEWEIGHT(2) | VERTEX_BONE_INDEX | VERTEX_USERDATA_SIZE(4),
MATERIAL_VERTEX_FORMAT_MODEL_SKINNED_DX7 = (VertexFormat_t) VERTEX_POSITION | VERTEX_COLOR | VERTEX_NORMAL | VERTEX_TEXCOORD0_2D | VERTEX_BONEWEIGHT(2) | VERTEX_BONE_INDEX,
MATERIAL_VERTEX_FORMAT_MODEL = (VertexFormat_t) VERTEX_POSITION | VERTEX_COLOR | VERTEX_NORMAL | VERTEX_TEXCOORD0_2D | VERTEX_USERDATA_SIZE(4),
MATERIAL_VERTEX_FORMAT_MODEL_DX7 = (VertexFormat_t) VERTEX_POSITION | VERTEX_COLOR | VERTEX_NORMAL | VERTEX_TEXCOORD0_2D,
MATERIAL_VERTEX_FORMAT_COLOR = (VertexFormat_t) VERTEX_SPECULAR
};
//-----------------------------------------------------------------------------
// What kind of material override is it?
//-----------------------------------------------------------------------------
enum OverrideType_t
{
OVERRIDE_NORMAL = 0,
OVERRIDE_BUILD_SHADOWS,
OVERRIDE_DEPTH_WRITE,
OVERRIDE_SSAO_DEPTH_WRITE,
};
//-----------------------------------------------------------------------------
// DrawModel info
//-----------------------------------------------------------------------------
// Special flag for studio models that have a compiled in shadow lod version
// It's negative 2 since positive numbers == use a regular slot and -1 means
// have studiorender compute a value instead
enum
{
USESHADOWLOD = -2,
};
// beyond this number of materials, you won't get info back from DrawModel
#define MAX_DRAW_MODEL_INFO_MATERIALS 8
struct DrawModelResults_t
{
int m_ActualTriCount;
int m_TextureMemoryBytes;
int m_NumHardwareBones;
int m_NumBatches;
int m_NumMaterials;
int m_nLODUsed;
int m_flLODMetric;
CFastTimer m_RenderTime;
CUtlVectorFixed<IMaterial *,MAX_DRAW_MODEL_INFO_MATERIALS> m_Materials;
};
struct ColorTexelsInfo_t
{
int m_nWidth;
int m_nHeight;
int m_nMipmapCount;
ImageFormat m_ImageFormat;
int m_nByteCount;
byte* m_pTexelData;
};
struct ColorMeshInfo_t
{
// A given color mesh can own a unique Mesh, or it can use a shared Mesh
// (in which case it uses a sub-range defined by m_nVertOffset and m_nNumVerts)
IMesh * m_pMesh;
IPooledVBAllocator * m_pPooledVBAllocator;
int m_nVertOffsetInBytes;
int m_nNumVerts;
ITexture * m_pLightmap;
ColorTexelsInfo_t * m_pLightmapData;
};
struct DrawModelInfo_t
{
studiohdr_t *m_pStudioHdr;
studiohwdata_t *m_pHardwareData;
StudioDecalHandle_t m_Decals;
int m_Skin;
int m_Body;
int m_HitboxSet;
void *m_pClientEntity;
int m_Lod;
ColorMeshInfo_t *m_pColorMeshes;
bool m_bStaticLighting;
Vector m_vecAmbientCube[6]; // ambient, and lights that aren't in locallight[]
int m_nLocalLightCount;
LightDesc_t m_LocalLightDescs[4];
};
struct GetTriangles_Vertex_t
{
Vector m_Position;
Vector m_Normal;
Vector4D m_TangentS;
Vector2D m_TexCoord;
Vector4D m_BoneWeight;
int m_BoneIndex[4];
int m_NumBones;
};
struct GetTriangles_MaterialBatch_t
{
IMaterial *m_pMaterial;
CUtlVector<GetTriangles_Vertex_t> m_Verts;
CUtlVector<int> m_TriListIndices;
};
struct GetTriangles_Output_t
{
CUtlVector<GetTriangles_MaterialBatch_t> m_MaterialBatches;
matrix3x4_t m_PoseToWorld[MAXSTUDIOBONES];
};
struct model_array_instance_t
{
matrix3x4_t modelToWorld;
// UNDONE: Per instance lighting values?
};
//-----------------------------------------------------------------------------
// Cache Callback Function
// implementation can either statically persist data (tools) or lru cache (engine) it.
// caller returns base pointer to resident data.
// code expectes data to be dynamic and invokes cache callback prior to iterative access.
// virtualModel is member passed in via studiohdr_t and passed back for model identification.
//-----------------------------------------------------------------------------
#define STUDIO_DATA_CACHE_INTERFACE_VERSION "VStudioDataCache005"
abstract_class IStudioDataCache : public IAppSystem
{
public:
virtual bool VerifyHeaders( studiohdr_t *pStudioHdr ) = 0;
virtual vertexFileHeader_t *CacheVertexData( studiohdr_t *pStudioHdr ) = 0;
};
//-----------------------------------------------------------------------------
// Studio render interface
//-----------------------------------------------------------------------------
#define STUDIO_RENDER_INTERFACE_VERSION "VStudioRender025"
abstract_class IStudioRender : public IAppSystem
{
public:
virtual void BeginFrame( void ) = 0;
virtual void EndFrame( void ) = 0;
// Used for the mat_stub console command.
virtual void Mat_Stub( IMaterialSystem *pMatSys ) = 0;
// Updates the rendering configuration
virtual void UpdateConfig( const StudioRenderConfig_t& config ) = 0;
virtual void GetCurrentConfig( StudioRenderConfig_t& config ) = 0;
// Load, unload model data
virtual bool LoadModel( studiohdr_t *pStudioHdr, void *pVtxData, studiohwdata_t *pHardwareData ) = 0;
virtual void UnloadModel( studiohwdata_t *pHardwareData ) = 0;
// Refresh the studiohdr since it was lost...
virtual void RefreshStudioHdr( studiohdr_t* pStudioHdr, studiohwdata_t* pHardwareData ) = 0;
// This is needed to do eyeglint and calculate the correct texcoords for the eyes.
virtual void SetEyeViewTarget( const studiohdr_t *pStudioHdr, int nBodyIndex, const Vector& worldPosition ) = 0;
// Methods related to lighting state
// NOTE: SetAmbientLightColors assumes that the arraysize is the same as
// returned from GetNumAmbientLightSamples
virtual int GetNumAmbientLightSamples() = 0;
virtual const Vector *GetAmbientLightDirections() = 0;
virtual void SetAmbientLightColors( const Vector4D *pAmbientOnlyColors ) = 0;
virtual void SetAmbientLightColors( const Vector *pAmbientOnlyColors ) = 0;
virtual void SetLocalLights( int numLights, const LightDesc_t *pLights ) = 0;
// Sets information about the camera location + orientation
virtual void SetViewState( const Vector& viewOrigin, const Vector& viewRight,
const Vector& viewUp, const Vector& viewPlaneNormal ) = 0;
// Allocates flex weights for use in rendering
// NOTE: Pass in a non-null second parameter to lock delayed flex weights
virtual void LockFlexWeights( int nWeightCount, float **ppFlexWeights, float **ppFlexDelayedWeights = NULL ) = 0;
virtual void UnlockFlexWeights() = 0;
// Used to allocate bone matrices to be used to pass into DrawModel
virtual matrix3x4_t* LockBoneMatrices( int nBoneCount ) = 0;
virtual void UnlockBoneMatrices() = 0;
// LOD stuff
virtual int GetNumLODs( const studiohwdata_t &hardwareData ) const = 0;
virtual float GetLODSwitchValue( const studiohwdata_t &hardwareData, int lod ) const = 0;
virtual void SetLODSwitchValue( studiohwdata_t &hardwareData, int lod, float switchValue ) = 0;
// Sets the color/alpha modulation
virtual void SetColorModulation( float const* pColor ) = 0;
virtual void SetAlphaModulation( float flAlpha ) = 0;
// Draws the model
virtual void DrawModel( DrawModelResults_t *pResults, const DrawModelInfo_t& info,
matrix3x4_t *pBoneToWorld, float *pFlexWeights, float *pFlexDelayedWeights, const Vector &modelOrigin, int flags = STUDIORENDER_DRAW_ENTIRE_MODEL ) = 0;
// Methods related to static prop rendering
virtual void DrawModelStaticProp( const DrawModelInfo_t& drawInfo, const matrix3x4_t &modelToWorld, int flags = STUDIORENDER_DRAW_ENTIRE_MODEL ) = 0;
virtual void DrawStaticPropDecals( const DrawModelInfo_t &drawInfo, const matrix3x4_t &modelToWorld ) = 0;
virtual void DrawStaticPropShadows( const DrawModelInfo_t &drawInfo, const matrix3x4_t &modelToWorld, int flags ) = 0;
// Causes a material to be used instead of the materials the model was compiled with
virtual void ForcedMaterialOverride( IMaterial *newMaterial, OverrideType_t nOverrideType = OVERRIDE_NORMAL ) = 0;
// Create, destroy list of decals for a particular model
virtual StudioDecalHandle_t CreateDecalList( studiohwdata_t *pHardwareData ) = 0;
virtual void DestroyDecalList( StudioDecalHandle_t handle ) = 0;
// Add decals to a decal list by doing a planar projection along the ray
// The BoneToWorld matrices must be set before this is called
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 = false, int maxLODToDecal = ADDDECAL_TO_ALL_LODS ) = 0;
// Compute the lighting at a point and normal
virtual void ComputeLighting( const Vector* pAmbient, int lightCount,
LightDesc_t* pLights, const Vector& pt, const Vector& normal, Vector& lighting ) = 0;
// Compute the lighting at a point, constant directional component is passed
// as flDirectionalAmount
virtual void ComputeLightingConstDirectional( const Vector* pAmbient, int lightCount,
LightDesc_t* pLights, const Vector& pt, const Vector& normal, Vector& lighting, float flDirectionalAmount ) = 0;
// Shadow state (affects the models as they are rendered)
virtual void AddShadow( IMaterial* pMaterial, void* pProxyData, FlashlightState_t *m_pFlashlightState = NULL, VMatrix *pWorldToTexture = NULL, ITexture *pFlashlightDepthTexture = NULL ) = 0;
virtual void ClearAllShadows() = 0;
// Gets the model LOD; pass in the screen size in pixels of a sphere
// of radius 1 that has the same origin as the model to get the LOD out...
virtual int ComputeModelLod( studiohwdata_t* pHardwareData, float unitSphereSize, float *pMetric = NULL ) = 0;
// Return a number that is usable for budgets, etc.
// Things that we care about:
// 1) effective triangle count (factors in batch sizes, state changes, etc)
// 2) texture memory usage
// Get Triangles returns the LOD used
virtual void GetPerfStats( DrawModelResults_t *pResults, const DrawModelInfo_t &info, CUtlBuffer *pSpewBuf = NULL ) const = 0;
virtual void GetTriangles( const DrawModelInfo_t& info, matrix3x4_t *pBoneToWorld, GetTriangles_Output_t &out ) = 0;
// Returns materials used by a particular model
virtual int GetMaterialList( studiohdr_t *pStudioHdr, int count, IMaterial** ppMaterials ) = 0;
virtual int GetMaterialListFromBodyAndSkin( MDLHandle_t studio, int nSkin, int nBody, int nCountOutputMaterials, IMaterial** ppOutputMaterials ) = 0;
// draw an array of models with the same state
virtual void DrawModelArray( const DrawModelInfo_t &drawInfo, int arrayCount, model_array_instance_t *pInstanceData, int instanceStride, int flags = STUDIORENDER_DRAW_ENTIRE_MODEL ) = 0;
};
extern IStudioRender *g_pStudioRender;
#endif // ISTUDIORENDER_H
|