Init commit
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,133 @@
|
||||
#ifndef GRASS_CLUSTER_H
|
||||
#define GRASS_CLUSTER_H
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
class CFastTimer;
|
||||
|
||||
struct _grassPressureData
|
||||
{
|
||||
_grassPressureData();
|
||||
~_grassPressureData();
|
||||
|
||||
void Init(int num);
|
||||
|
||||
int iNumGrassObjects;
|
||||
|
||||
Vector *vecPos;
|
||||
Vector *vecDir;
|
||||
float *flAmt;
|
||||
float *flHeight;
|
||||
float *flLastMoveTime;
|
||||
float *flLastUpdateTime;
|
||||
bool *bDirty;
|
||||
};
|
||||
|
||||
struct _grassClusterInfo
|
||||
{
|
||||
public:
|
||||
_grassClusterInfo();
|
||||
|
||||
Vector orig;
|
||||
Vector4D color;
|
||||
Vector2D uv_min, uv_max;
|
||||
float flSortDist;
|
||||
};
|
||||
|
||||
struct _grassClusterData
|
||||
{
|
||||
public:
|
||||
_grassClusterData();
|
||||
~_grassClusterData();
|
||||
// flat copy on purpose!!!
|
||||
|
||||
void Destroy();
|
||||
int Draw();
|
||||
|
||||
IMesh *pGrassMesh;
|
||||
_grassPressureData *pPressureInfo;
|
||||
Vector pos;
|
||||
|
||||
int iNumQuads;
|
||||
Vector extents_min, extents_max;
|
||||
|
||||
int iNextLodThreshold;
|
||||
_grassClusterData *pLOD;
|
||||
|
||||
|
||||
void CreateLightingPatch(const CUtlVector< _grassClusterInfo > &hints);
|
||||
const Vector GetLightingForPoint(const Vector &pos);
|
||||
void DestroyLightingPatch();
|
||||
int iLPatchSize_x, iLPatchSize_y;
|
||||
float flLPatchStep_x, flLPatchStep_y;
|
||||
Vector *lighting;
|
||||
};
|
||||
|
||||
struct clusterMaterial
|
||||
{
|
||||
clusterMaterial();
|
||||
void Init(const char *pszMat);
|
||||
void Shutdown();
|
||||
bool IsValid();
|
||||
|
||||
IMaterialVar *GetVarDir();
|
||||
IMaterialVar *GetVarAng();
|
||||
IMaterialVar *GetTimeScale();
|
||||
IMaterial *GetMaterial();
|
||||
|
||||
CMaterialReference mat;
|
||||
unsigned int ivar_dir;
|
||||
unsigned int ivar_ang;
|
||||
};
|
||||
|
||||
class CGrassClusterManager : public CAutoGameSystemPerFrame
|
||||
{
|
||||
public:
|
||||
|
||||
CGrassClusterManager();
|
||||
~CGrassClusterManager();
|
||||
|
||||
static CGrassClusterManager *GetInstance();
|
||||
|
||||
bool Init();
|
||||
void Shutdown();
|
||||
void LevelInitPostEntity();
|
||||
void LevelShutdownPostEntity();
|
||||
|
||||
void Update(float frametime);
|
||||
void PreRender();
|
||||
void PostRender();
|
||||
void RenderClusters(bool bShadowDepth);
|
||||
|
||||
void AddClusterHint(_grassClusterInfo hint);
|
||||
void ClearClusterData();
|
||||
|
||||
private:
|
||||
|
||||
void GenerateClusterData();
|
||||
void BuildClusterMesh(_grassClusterData &data, const CUtlVector< _grassClusterInfo > &hints, int iObjectMultiplier, _grassPressureData *pMorphInfo = NULL);
|
||||
void BuildSingleGrassObject(CMeshBuilder &builder, _grassClusterData &clusterData, const _grassClusterInfo &hint,
|
||||
const float avgDist, const int grassObjectIndex, _grassPressureData *pMorphInfo = NULL);
|
||||
|
||||
void UpdateMorphInfo();
|
||||
void InjectMorph(int i);
|
||||
|
||||
CUtlVector< _grassClusterInfo >m_hClusterInfo;
|
||||
CUtlVector< _grassClusterData >m_hClusterData;
|
||||
|
||||
IMaterial *GetActiveMaterial();
|
||||
//CMaterialReference *m_refMaterial;
|
||||
clusterMaterial *m_refMaterials;
|
||||
int m_iCurrentMaterial;
|
||||
|
||||
int m_iCurObjectsPerHint;
|
||||
int m_iDrawnQuads;
|
||||
int m_iDrawnCluster;
|
||||
int m_iDrawnPerDrawcall;
|
||||
int m_iDrawnEngineMax;
|
||||
|
||||
double m_flMorphTime;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,144 @@
|
||||
//**********************************************//
|
||||
// //
|
||||
// Installation instructions for grass clusters //
|
||||
// //
|
||||
//**********************************************//
|
||||
|
||||
*** ONLY TESTED WITH SOURCE 2007, SO DON'T EXPECT SWARM COMPATIBILITY ***
|
||||
|
||||
The grass clusters are meant to replace the existing detail props. They'll use
|
||||
the lighting and positioning information from them to generate their geometry.
|
||||
Do not use a huge texture atlas for them from which you only read some parts but
|
||||
use actual unique materials for each type of grass (PERFO), note that you have
|
||||
to add any map dependent functionality yourself for that matter!
|
||||
Also, don't use alpha blending on them, it WON'T WORK. And that won't change because
|
||||
grass objects should stay batched. If you can't stand alpha testing use alpha to coverage,
|
||||
which requires more performance.
|
||||
|
||||
|
||||
|
||||
Make sure to have the shader editor and its example materials and shaders installed too
|
||||
or export them and update all references accordingly. VERIFY THAT YOU HAVE THE SHADER 'detail_prop_shader'
|
||||
COMPILED AND IN YOUR PRECACHE LIST.
|
||||
|
||||
|
||||
|
||||
In case you're experiencing errors that you don't understand, go there: http://www.learncpp.com/
|
||||
and READ it. 'Reading' in a sense of actually understanding what's written there. That includes the possibility
|
||||
of iteratively examining a passage for a variable number of times until comprehension has been acquired.
|
||||
|
||||
|
||||
|
||||
If you're using the source sdk base 2007 you can apply the subversion patch (dprop_and_shadow_patch.patch)
|
||||
and skip to step 5 now, other branches MIGHT NOT BE COMPATIBLE.
|
||||
|
||||
|
||||
|
||||
Step 1.
|
||||
|
||||
client/clientshadowmgr.cpp
|
||||
|
||||
|
||||
Find this line:
|
||||
|
||||
ShadowType_t GetActualShadowCastType( ClientShadowHandle_t handle ) const;
|
||||
|
||||
|
||||
Replace it with these:
|
||||
|
||||
public:
|
||||
ShadowHandle_t GetShadowHandle( ClientShadowHandle_t clienthandle ){ return m_Shadows[ clienthandle ].m_ShadowHandle; };
|
||||
int GetNumShadowDepthtextures(){ return m_DepthTextureCache.Count(); };
|
||||
CTextureReference GetShadowDepthTex( int num ){ return m_DepthTextureCache[num]; };
|
||||
|
||||
ShadowType_t GetActualShadowCastType( ClientShadowHandle_t handle ) const;
|
||||
private:
|
||||
|
||||
|
||||
Step 2.
|
||||
|
||||
client/detailobjectsystem.cpp
|
||||
|
||||
|
||||
Find this line:
|
||||
|
||||
#include "c_world.h"
|
||||
|
||||
|
||||
Add this line below:
|
||||
|
||||
#include "ShaderEditor/Grass/CGrassCluster.h"
|
||||
|
||||
|
||||
Find this line:
|
||||
|
||||
pSpritex4->m_pSpriteDefs[nSubField] = pSDef;
|
||||
|
||||
|
||||
Add these lines below:
|
||||
|
||||
_grassClusterInfo clusterHint;
|
||||
clusterHint.orig = pos;
|
||||
clusterHint.color.Init( color[0], color[1], color[2], 1 );
|
||||
clusterHint.uv_min = pSDef->m_TexLR;
|
||||
clusterHint.uv_max = pSDef->m_TexUL;
|
||||
CGrassClusterManager::GetInstance()->AddClusterHint( clusterHint );
|
||||
|
||||
|
||||
Step 3.
|
||||
|
||||
client/iclientshadowmgr.h
|
||||
|
||||
|
||||
Find this line:
|
||||
|
||||
virtual void ComputeShadowDepthTextures( const CViewSetup &pView ) = 0;
|
||||
|
||||
|
||||
Add these lines below:
|
||||
|
||||
virtual ShadowHandle_t GetShadowHandle( ClientShadowHandle_t clienthandle ) = 0;
|
||||
virtual ShadowType_t GetActualShadowCastType( ClientShadowHandle_t handle ) const = 0;
|
||||
virtual int GetNumShadowDepthtextures() = 0;
|
||||
virtual CTextureReference GetShadowDepthTex( int num ) = 0;
|
||||
|
||||
|
||||
Step 4.
|
||||
|
||||
client/viewrender.cpp
|
||||
|
||||
|
||||
Find this line:
|
||||
|
||||
#include "con_nprint.h"
|
||||
|
||||
|
||||
Add this line below:
|
||||
|
||||
#include "ShaderEditor/Grass/CGrassCluster.h"
|
||||
|
||||
|
||||
Find this line in the function void CRendering3dView::DrawOpaqueRenderables( bool bShadowDepth ):
|
||||
|
||||
g_pParticleSystemMgr->DrawRenderCache( bShadowDepth );
|
||||
|
||||
|
||||
Add this line below for 2007 / swarm:
|
||||
|
||||
CGrassClusterManager::GetInstance()->RenderClusters( bShadowDepth );
|
||||
|
||||
OR this line for 2013:
|
||||
|
||||
CGrassClusterManager::GetInstance()->RenderClusters( DepthMode == DEPTH_MODE_SHADOW );
|
||||
|
||||
|
||||
Step 5.
|
||||
|
||||
Copy the folder 'Grass' and both files to /client/ShaderEditor/. If you want to put them elsewhere,
|
||||
you'll have to change the include paths in the respective files.
|
||||
|
||||
|
||||
Step 6.
|
||||
|
||||
Add both files in /Grass/ to your client project and compile it. Grass clusters will now be
|
||||
created wherever you placed standard simple detail sprites.
|
||||
@@ -0,0 +1,80 @@
|
||||
Index: client/clientshadowmgr.cpp
|
||||
===================================================================
|
||||
--- client/clientshadowmgr.cpp (revision 1)
|
||||
+++ client/clientshadowmgr.cpp (working copy)
|
||||
@@ -853,7 +853,13 @@
|
||||
void RemoveShadowFromDirtyList( ClientShadowHandle_t handle );
|
||||
|
||||
// NOTE: this will ONLY return SHADOWS_NONE, SHADOWS_SIMPLE, or SHADOW_RENDER_TO_TEXTURE.
|
||||
+public:
|
||||
+ ShadowHandle_t GetShadowHandle( ClientShadowHandle_t clienthandle ){ return m_Shadows[ clienthandle ].m_ShadowHandle; };
|
||||
+ int GetNumShadowDepthtextures(){ return m_DepthTextureCache.Count(); };
|
||||
+ CTextureReference GetShadowDepthTex( int num ){ return m_DepthTextureCache[num]; };
|
||||
+
|
||||
ShadowType_t GetActualShadowCastType( ClientShadowHandle_t handle ) const;
|
||||
+private:
|
||||
ShadowType_t GetActualShadowCastType( IClientRenderable *pRenderable ) const;
|
||||
|
||||
// Builds a simple blobby shadow
|
||||
Index: client/detailobjectsystem.cpp
|
||||
===================================================================
|
||||
--- client/detailobjectsystem.cpp (revision 1)
|
||||
+++ client/detailobjectsystem.cpp (working copy)
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "env_detail_controller.h"
|
||||
#include "tier0/icommandline.h"
|
||||
#include "c_world.h"
|
||||
+#include "ShaderEditor/Grass/CGrassCluster.h"
|
||||
|
||||
//Tony; add the SDK into this as well by default.
|
||||
#if defined(DOD_DLL) || defined(CSTRIKE_DLL) || defined( SDK_DLL )
|
||||
@@ -1940,6 +1941,13 @@
|
||||
pSpritex4->m_RGBColor[nSubField][3] = 255;
|
||||
|
||||
pSpritex4->m_pSpriteDefs[nSubField] = pSDef;
|
||||
+
|
||||
+ _grassClusterInfo clusterHint;
|
||||
+ clusterHint.orig = pos;
|
||||
+ clusterHint.color.Init( color[0], color[1], color[2], 1 );
|
||||
+ clusterHint.uv_min = pSDef->m_TexLR;
|
||||
+ clusterHint.uv_max = pSDef->m_TexUL;
|
||||
+ CGrassClusterManager::GetInstance()->AddClusterHint( clusterHint );
|
||||
}
|
||||
|
||||
|
||||
Index: client/iclientshadowmgr.h
|
||||
===================================================================
|
||||
--- client/iclientshadowmgr.h (revision 1)
|
||||
+++ client/iclientshadowmgr.h (working copy)
|
||||
@@ -101,6 +100,10 @@
|
||||
|
||||
virtual void ComputeShadowDepthTextures( const CViewSetup &pView ) = 0;
|
||||
|
||||
+ virtual ShadowHandle_t GetShadowHandle( ClientShadowHandle_t clienthandle ) = 0;
|
||||
+ virtual ShadowType_t GetActualShadowCastType( ClientShadowHandle_t handle ) const = 0;
|
||||
+ virtual int GetNumShadowDepthtextures() = 0;
|
||||
+ virtual CTextureReference GetShadowDepthTex( int num ) = 0;
|
||||
};
|
||||
|
||||
|
||||
Index: client/viewrender.cpp
|
||||
===================================================================
|
||||
--- client/viewrender.cpp (revision 1)
|
||||
+++ client/viewrender.cpp (working copy)
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "keyvalues.h"
|
||||
#include "renderparm.h"
|
||||
#include "con_nprint.h"
|
||||
+#include "ShaderEditor/Grass/CGrassCluster.h"
|
||||
|
||||
#ifdef PORTAL
|
||||
//#include "C_Portal_Player.h"
|
||||
@@ -3856,6 +3870,8 @@
|
||||
//
|
||||
RopeManager()->DrawRenderCache( bShadowDepth );
|
||||
g_pParticleSystemMgr->DrawRenderCache( bShadowDepth );
|
||||
+
|
||||
+ CGrassClusterManager::GetInstance()->RenderClusters( bShadowDepth );
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#ifndef IV_SHADEREDITOR_MRENDER
|
||||
#define IV_SHADEREDITOR_MRENDER
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif // _WIN32
|
||||
|
||||
#ifdef SHADER_EDITOR_DLL
|
||||
#include "../public/tier1/interface.h"
|
||||
#else
|
||||
#include "interface.h"
|
||||
#include "shadereditor/shadereditorsystem.h"
|
||||
#endif // NOT SHADER_EDITOR_DLL
|
||||
|
||||
|
||||
class ISEditModelRender
|
||||
{
|
||||
public:
|
||||
virtual bool LoadModel(const char *localPath) = 0;
|
||||
virtual void DestroyModel() = 0;
|
||||
virtual void GetModelCenter(float *pFl3_ViewOffset) = 0;
|
||||
|
||||
virtual int QuerySequences(char ***list) = 0;
|
||||
virtual void SetSequence(const char *name) = 0;
|
||||
|
||||
virtual void ExecRender() = 0;
|
||||
virtual void DoPostProc(int x, int y, int w, int h) = 0;
|
||||
virtual int MaterialPicker(char ***szMat) = 0;
|
||||
|
||||
virtual void DestroyCharPtrList(char ***szList) = 0;
|
||||
};
|
||||
|
||||
|
||||
#ifdef SHADER_EDITOR_DLL
|
||||
extern ISEditModelRender *sEditMRender;
|
||||
#else
|
||||
class SEditModelRender;
|
||||
extern SEditModelRender *sEditMRender;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,148 @@
|
||||
#ifndef IV_SHADEREDITOR
|
||||
#define IV_SHADEREDITOR
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif // _WIN32
|
||||
|
||||
#define pFnClCallback( x ) void(* x )( float *pfl4 )
|
||||
#define pFnClCallback_Declare( x ) void x( float *pfl4 )
|
||||
|
||||
#define pFnVrCallback( x ) void(* x )( bool * const pbOptions, int * const piOptions,\
|
||||
float * const pflOptions, char ** const pszOptions )
|
||||
#define pFnVrCallback_Declare( x ) void x( bool * const pbOptions, int * const piOptions,\
|
||||
float * const pflOptions, char ** const pszOptions )
|
||||
|
||||
#define DEFINE_SHADEREDITOR_MATERIALVAR( effectName, nodeName, materialVarName, localVarName ) \
|
||||
static ShaderEditVarToken token_ ## localVarName = SHADEREDIT_MVAR_TOKEN_INVALID; \
|
||||
IMaterialVar *localVarName = shaderEdit->GetPPEMaterialVarFast( \
|
||||
token_ ## localVarName, effectName, nodeName, materialVarName )
|
||||
|
||||
#ifndef PROCSHADER_DLL
|
||||
|
||||
#ifdef SHADER_EDITOR_DLL
|
||||
#include "../public/tier1/interface.h"
|
||||
#include "view_shared.h"
|
||||
#else
|
||||
#include "interface.h"
|
||||
#include "shadereditor/shadereditorsystem.h"
|
||||
#endif // NOT SHADER_EDITOR_DLL
|
||||
|
||||
class IMaterial;
|
||||
class IMaterialVar;
|
||||
|
||||
typedef unsigned int ShaderEditVarToken;
|
||||
|
||||
enum SEDIT_SKYMASK_MODE
|
||||
{
|
||||
SKYMASK_OFF = 0,
|
||||
SKYMASK_QUARTER, // render at 1/4 fb size where possible
|
||||
SKYMASK_FULL, // render at full fb size
|
||||
};
|
||||
|
||||
class CViewSetup_SEdit_Shared
|
||||
{
|
||||
public:
|
||||
CViewSetup_SEdit_Shared()
|
||||
{
|
||||
Q_memset(this, 0, sizeof(CViewSetup_SEdit_Shared));
|
||||
};
|
||||
CViewSetup_SEdit_Shared(const CViewSetup &o)
|
||||
{
|
||||
x = o.x;
|
||||
y = o.y;
|
||||
width = o.width;
|
||||
height = o.height;
|
||||
fov = o.fov;
|
||||
fovViewmodel = o.fovViewmodel;
|
||||
origin = o.origin;
|
||||
angles = o.angles;
|
||||
zNear = o.zNear;
|
||||
zFar = o.zFar;
|
||||
zNearViewmodel = o.zNearViewmodel;
|
||||
zFarViewmodel = o.zFarViewmodel;
|
||||
m_flAspectRatio = o.m_flAspectRatio;
|
||||
};
|
||||
int x, y, width, height;
|
||||
float fov, fovViewmodel;
|
||||
Vector origin;
|
||||
QAngle angles;
|
||||
float zNear, zFar, zNearViewmodel, zFarViewmodel;
|
||||
float m_flAspectRatio;
|
||||
};
|
||||
|
||||
|
||||
class IVShaderEditor : public IBaseInterface
|
||||
{
|
||||
public:
|
||||
virtual bool Init(CreateInterfaceFn appSystemFactory, CGlobalVarsBase *pGlobals,
|
||||
void *pSEditMRender,
|
||||
bool bCreateEditor, bool bEnablePrimaryDebug, int iSkymaskMode) = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
virtual void PrecacheData() = 0;
|
||||
|
||||
// call before Init() to overwrite any paths, pass in NULL for the ones that shouldn't be overwritten
|
||||
virtual void OverridePaths(const char *pszWorkingDirectory,
|
||||
const char *pszCompilePath = NULL, // abs path to compiler binaries
|
||||
const char *pszLocalCompilePath = NULL, // local path to compiler binaries, relative to shader source directory
|
||||
const char *pszGamePath = NULL,
|
||||
const char *pszCanvas = NULL, // path to canvas files
|
||||
const char *pszShaderSource = NULL, // path to shader source files
|
||||
const char *pszDumps = NULL, // path to shader configuration files
|
||||
const char *pszUserFunctions = NULL, // path to custom function bodies
|
||||
const char *pszEditorRoot = NULL) = 0; // path to 'shadereditorui' home directory
|
||||
|
||||
// update the lib
|
||||
virtual void OnFrame(float frametime) = 0;
|
||||
virtual void OnPreRender(void *viewsetup) = 0;
|
||||
virtual void OnSceneRender() = 0;
|
||||
virtual void OnUpdateSkymask(bool bCombineMode, int x, int y, int w, int h) = 0;
|
||||
virtual void OnPostRender(bool bUpdateFB) = 0;
|
||||
|
||||
// data callbacks for hlsl constants
|
||||
virtual void RegisterClientCallback(const char *name, pFnClCallback(callback), int numComponents) = 0;
|
||||
virtual void LockClientCallbacks() = 0;
|
||||
|
||||
// view render callbacks for post processing graphs
|
||||
virtual void RegisterViewRenderCallback(const char *pszVrCName, pFnVrCallback(callback),
|
||||
const char **pszBoolNames = NULL, const bool *pBoolDefaults = NULL, const int numBoolParams = 0,
|
||||
const char **pszIntNames = NULL, const int *pIntDefaults = NULL, const int numIntParams = 0,
|
||||
const char **pszFloatNames = NULL, const float *pFloatDefaults = NULL, const int numFloatParams = 0,
|
||||
const char **pszStringNames = NULL, const char **pStringDefaults = NULL, const int numStringParams = 0) = 0;
|
||||
virtual void LockViewRenderCallbacks() = 0;
|
||||
|
||||
// post processing effect manipulation (precached effects accessible)
|
||||
// the index becomes invalid when editing the precache list
|
||||
virtual int GetPPEIndex(const char *pszName) = 0; // returns -1 when not found, case insensitive
|
||||
virtual bool IsPPEEnabled(const int &index) = 0;
|
||||
virtual void SetPPEEnabled(const int &index, const bool &bEnabled) = 0;
|
||||
virtual IMaterial *GetPPEMaterial(const int &index, const char *pszNodeName) = 0;
|
||||
|
||||
// Draws a PPE graph right now or adds it to the render queue (r_queued_post_processing!)
|
||||
// Does not push a new RT but uses the current one
|
||||
// If you have 'during scene' nodes, make sure to call it twice in the appropriate places
|
||||
virtual void DrawPPEOnDemand(const int &index, const bool bInScene = false) = 0;
|
||||
virtual void DrawPPEOnDemand(const int &index, int x, int y, int w, int h, const bool bInScene = false) = 0;
|
||||
|
||||
// access a materialvar based on an incrementing token
|
||||
// you don't need to cache the returned value, it's okay to call this each frame
|
||||
// initialize the token with SHADEREDIT_MVAR_TOKEN_INVALID
|
||||
virtual IMaterialVar *GetPPEMaterialVarFast(ShaderEditVarToken &token,
|
||||
const char *pszPPEName, const char *pszNodeName, const char *pszVarName) = 0;
|
||||
};
|
||||
|
||||
#define SHADEREDIT_MVAR_TOKEN_INVALID 0
|
||||
#define SHADEREDIT_MVAR_TOKEN_FAILED 0xFFFFFFFF
|
||||
|
||||
#define SHADEREDIT_INTERFACE_VERSION "ShaderEditor005"
|
||||
|
||||
#ifdef SHADER_EDITOR_DLL
|
||||
class ShaderEditorInterface;
|
||||
extern ShaderEditorInterface *shaderEdit;
|
||||
#else
|
||||
extern IVShaderEditor *shaderEdit;
|
||||
#endif // NOT SHADER_EDITOR_DLL
|
||||
|
||||
#endif // NOT PROCSHADER_DLL
|
||||
|
||||
#endif // NOT IV_SHADEREDITOR
|
||||
@@ -0,0 +1,424 @@
|
||||
// ******************************************************
|
||||
//
|
||||
// Purpose:
|
||||
// - Handles model rendering requests from the
|
||||
// shader editor library
|
||||
//
|
||||
// ******************************************************
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
#include "vgui/IInput.h"
|
||||
#include "vgui_controls/Controls.h"
|
||||
|
||||
#include "shadereditor/sedit_modelrender.h"
|
||||
#include "model_types.h"
|
||||
|
||||
#ifndef SOURCE_2006
|
||||
#include "viewpostprocess.h"
|
||||
#endif
|
||||
|
||||
#include "view.h"
|
||||
#include "input.h"
|
||||
|
||||
#include "beamdraw.h"
|
||||
|
||||
#ifdef SOURCE_2006
|
||||
void ScreenToWorld(int mousex, int mousey, float fov,
|
||||
const Vector& vecRenderOrigin,
|
||||
const QAngle& vecRenderAngles,
|
||||
Vector& vecPickingRay)
|
||||
{
|
||||
float dx, dy;
|
||||
float c_x, c_y;
|
||||
float dist;
|
||||
Vector vpn, vup, vright;
|
||||
|
||||
float scaled_fov = ScaleFOVByWidthRatio(fov, engine->GetScreenAspectRatio() * 0.75f);
|
||||
|
||||
c_x = ScreenWidth() / 2;
|
||||
c_y = ScreenHeight() / 2;
|
||||
|
||||
dx = (float)mousex - c_x;
|
||||
dy = c_y - (float)mousey;
|
||||
|
||||
float dist_denom = tan(M_PI * scaled_fov / 360.0f);
|
||||
dist = c_x / dist_denom;
|
||||
AngleVectors(vecRenderAngles, &vpn, &vright, &vup);
|
||||
vecPickingRay = vpn * dist + vright * (dx)+vup * (dy);
|
||||
VectorNormalize(vecPickingRay);
|
||||
}
|
||||
#else
|
||||
extern void ScreenToWorld(int mousex, int mousey, float fov,
|
||||
const Vector& vecRenderOrigin,
|
||||
const QAngle& vecRenderAngles,
|
||||
Vector& vecPickingRay);
|
||||
#endif
|
||||
|
||||
SEditModelRender __g_ShaderEditorMReder("ShEditMRender");
|
||||
SEditModelRender *sEditMRender = &__g_ShaderEditorMReder;
|
||||
|
||||
SEditModelRender::SEditModelRender(char const *name) : CAutoGameSystemPerFrame(name)
|
||||
{
|
||||
pModelInstance = NULL;
|
||||
m_iNumPoseParams = 0;
|
||||
DestroyModel();
|
||||
}
|
||||
SEditModelRender::~SEditModelRender()
|
||||
{
|
||||
DestroyModel();
|
||||
}
|
||||
|
||||
bool SEditModelRender::Init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
void SEditModelRender::Shutdown()
|
||||
{
|
||||
}
|
||||
void SEditModelRender::Update(float frametime)
|
||||
{
|
||||
if (!IsModelReady())
|
||||
return;
|
||||
|
||||
pModelInstance->StudioFrameAdvance();
|
||||
if (pModelInstance->GetCycle() >= 1.0f)
|
||||
pModelInstance->SetCycle(pModelInstance->GetCycle() - 1.0f);
|
||||
}
|
||||
void SEditModelRender::LevelInitPostEntity()
|
||||
{
|
||||
ResetModel();
|
||||
}
|
||||
void SEditModelRender::LevelShutdownPostEntity()
|
||||
{
|
||||
ResetModel();
|
||||
}
|
||||
void SEditModelRender::ResetModel()
|
||||
{
|
||||
if (!IsModelReady())
|
||||
return;
|
||||
pModelInstance->m_flAnimTime = gpGlobals->curtime;
|
||||
pModelInstance->m_flOldAnimTime = gpGlobals->curtime;
|
||||
}
|
||||
bool SEditModelRender::IsModelReady()
|
||||
{
|
||||
if (!pModelInstance)
|
||||
return false;
|
||||
|
||||
bool bValid = !!pModelInstance->GetModel();
|
||||
|
||||
if (bValid && Q_strlen(m_szModelPath))
|
||||
{
|
||||
const model_t *pMdl = modelinfo ? modelinfo->FindOrLoadModel(m_szModelPath) : NULL;
|
||||
if (pMdl)
|
||||
pModelInstance->SetModelPointer(pMdl);
|
||||
bValid = !!pMdl;
|
||||
}
|
||||
|
||||
if (!bValid)
|
||||
DestroyModel();
|
||||
|
||||
return bValid;
|
||||
}
|
||||
bool SEditModelRender::LoadModel(const char *localPath)
|
||||
{
|
||||
DestroyModel();
|
||||
|
||||
const model_t *mdl = modelinfo->FindOrLoadModel(localPath);
|
||||
if (!mdl)
|
||||
return false;
|
||||
|
||||
Q_strcpy(m_szModelPath, localPath);
|
||||
|
||||
C_BaseFlex *pEnt = new C_BaseFlex();
|
||||
pEnt->InitializeAsClientEntity(NULL,
|
||||
#if SWARM_DLL
|
||||
false
|
||||
#else
|
||||
RENDER_GROUP_OPAQUE_ENTITY
|
||||
#endif
|
||||
);
|
||||
MDLCACHE_CRITICAL_SECTION();
|
||||
pEnt->SetModelPointer(mdl);
|
||||
pEnt->Spawn();
|
||||
|
||||
pEnt->SetAbsAngles(vec3_angle);
|
||||
pEnt->SetAbsOrigin(vec3_origin);
|
||||
|
||||
pEnt->AddEffects(EF_NODRAW | EF_NOINTERP);
|
||||
pEnt->m_EntClientFlags |= ENTCLIENTFLAG_DONTUSEIK;
|
||||
|
||||
// leave it alone.
|
||||
pEnt->RemoveFromLeafSystem();
|
||||
cl_entitylist->RemoveEntity(pEnt->GetRefEHandle());
|
||||
pEnt->CollisionProp()->DestroyPartitionHandle();
|
||||
|
||||
CStudioHdr *pHdr = pEnt->GetModelPtr();
|
||||
m_iNumPoseParams = pHdr ? pHdr->GetNumPoseParameters() : 0;
|
||||
|
||||
pModelInstance = pEnt;
|
||||
return true;
|
||||
}
|
||||
void SEditModelRender::DestroyModel()
|
||||
{
|
||||
if (pModelInstance)
|
||||
pModelInstance->Remove();
|
||||
|
||||
pModelInstance = NULL;
|
||||
m_szModelPath[0] = '\0';
|
||||
m_iNumPoseParams = 0;
|
||||
}
|
||||
void SEditModelRender::GetModelCenter(float *pFl3_ViewOffset)
|
||||
{
|
||||
Q_memset(pFl3_ViewOffset, 0, sizeof(float) * 3);
|
||||
if (IsModelReady())
|
||||
{
|
||||
MDLCACHE_CRITICAL_SECTION();
|
||||
if (pModelInstance->GetModelPtr())
|
||||
{
|
||||
const Vector &vecMin = pModelInstance->GetModelPtr()->hull_min();
|
||||
const Vector &vecMax = pModelInstance->GetModelPtr()->hull_max();
|
||||
Vector vecPos = (vecMin + (vecMax - vecMin) * 0.5f);
|
||||
if (pFl3_ViewOffset)
|
||||
Q_memcpy(pFl3_ViewOffset, vecPos.Base(), sizeof(float) * 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
void SEditModelRender::DestroyCharPtrList(char ***szList)
|
||||
{
|
||||
Assert(szList);
|
||||
if (*szList)
|
||||
{
|
||||
delete[](**szList);
|
||||
delete[](*szList);
|
||||
*szList = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int SequenceSort(mstudioseqdesc_t *const *seq1, mstudioseqdesc_t *const *seq2)
|
||||
{
|
||||
return Q_stricmp((*seq1)->pszLabel(), (*seq2)->pszLabel());
|
||||
}
|
||||
int SEditModelRender::QuerySequences(char ***list)
|
||||
{
|
||||
if (!IsModelReady())
|
||||
return 0;
|
||||
|
||||
MDLCACHE_CRITICAL_SECTION();
|
||||
CStudioHdr *pHdr = pModelInstance->GetModelPtr();
|
||||
if (!pHdr)
|
||||
return 0;
|
||||
|
||||
CUtlVector< mstudioseqdesc_t* >hSeqs;
|
||||
for (int i = 0; i < pHdr->GetNumSeq(); i++)
|
||||
if (!(pHdr->pSeqdesc(i).flags & STUDIO_HIDDEN))
|
||||
hSeqs.AddToTail(&pHdr->pSeqdesc(i));
|
||||
|
||||
int numSequences = hSeqs.Count();
|
||||
|
||||
if (!numSequences)
|
||||
return 0;
|
||||
|
||||
hSeqs.Sort(SequenceSort);
|
||||
|
||||
CUtlVector< const char* >hNameList;
|
||||
for (int i = 0; i < numSequences; i++)
|
||||
{
|
||||
const char *seqName = NULL;
|
||||
const mstudioseqdesc_t &seqPtr = *hSeqs[i];
|
||||
if (seqPtr.pszLabel())
|
||||
seqName = seqPtr.pszLabel();
|
||||
else
|
||||
seqName = "Unknown Sequence";
|
||||
|
||||
hNameList.AddToTail(seqName);
|
||||
}
|
||||
|
||||
*list = new char*[numSequences];
|
||||
|
||||
int iTotalLength = 0;
|
||||
for (int i = 0; i < numSequences; i++)
|
||||
iTotalLength += Q_strlen(hNameList[i]) + 1;
|
||||
|
||||
**list = new char[iTotalLength];
|
||||
|
||||
int curpos = 0;
|
||||
for (int i = 0; i < numSequences; i++)
|
||||
{
|
||||
int curLength = Q_strlen(hNameList[i]) + 1;
|
||||
(*list)[i] = **list + curpos;
|
||||
Q_strcpy((*list)[i], hNameList[i]);
|
||||
curpos += curLength;
|
||||
}
|
||||
|
||||
hNameList.Purge();
|
||||
hSeqs.Purge();
|
||||
return numSequences;
|
||||
}
|
||||
void SEditModelRender::SetSequence(const char *name)
|
||||
{
|
||||
if (!IsModelReady())
|
||||
return;
|
||||
|
||||
MDLCACHE_CRITICAL_SECTION();
|
||||
pModelInstance->ResetSequence(pModelInstance->LookupSequence(name));
|
||||
}
|
||||
void SEditModelRender::ExecRender()
|
||||
{
|
||||
if (!IsModelReady())
|
||||
return;
|
||||
|
||||
MDLCACHE_CRITICAL_SECTION();
|
||||
for (int i = 0; i < m_iNumPoseParams; i++)
|
||||
pModelInstance->SetPoseParameter(i, 0);
|
||||
|
||||
#if SWARM_DLL
|
||||
RenderableInstance_t instance;
|
||||
instance.m_nAlpha = 255;
|
||||
#endif
|
||||
pModelInstance->DrawModel(STUDIO_RENDER
|
||||
#if SWARM_DLL
|
||||
, instance
|
||||
#endif
|
||||
);
|
||||
}
|
||||
void SEditModelRender::DoPostProc(int x, int y, int w, int h)
|
||||
{
|
||||
#ifndef SOURCE_2006
|
||||
if (view && view->GetPlayerViewSetup()->m_bDoBloomAndToneMapping)
|
||||
DoEnginePostProcessing(x, y, w, h, false, false);
|
||||
#endif
|
||||
}
|
||||
int SEditModelRender::MaterialPicker(char ***szMat)
|
||||
{
|
||||
int mx, my;
|
||||
#ifdef SOURCE_2006
|
||||
vgui::input()->GetCursorPos(mx, my);
|
||||
#else
|
||||
vgui::input()->GetCursorPosition(mx, my);
|
||||
#endif
|
||||
|
||||
Vector ray;
|
||||
const CViewSetup *pViewSetup = view->GetPlayerViewSetup();
|
||||
float ratio = engine->GetScreenAspectRatio(
|
||||
#if SWARM_DLL
|
||||
pViewSetup->width, pViewSetup->height
|
||||
#endif
|
||||
);
|
||||
|
||||
ratio = (1.0f / ratio) * (4.0f / 3.0f);
|
||||
float flFov = ScaleFOVByWidthRatio(pViewSetup->fov, ratio);
|
||||
ScreenToWorld(mx, my, flFov, pViewSetup->origin, pViewSetup->angles, ray);
|
||||
|
||||
Vector start = pViewSetup->origin;
|
||||
Vector end = start + ray * MAX_TRACE_LENGTH;
|
||||
trace_t tr;
|
||||
C_BaseEntity *pIgnore = input->CAM_IsThirdPerson() ? NULL : C_BasePlayer::GetLocalPlayer();
|
||||
UTIL_TraceLine(start, end, MASK_SOLID, pIgnore, COLLISION_GROUP_NONE, &tr);
|
||||
|
||||
if (!tr.DidHit())
|
||||
return 0;
|
||||
|
||||
int numMaterials = 0;
|
||||
IMaterial **MatList = NULL;
|
||||
studiohdr_t *pSHdr = NULL;
|
||||
|
||||
if (tr.DidHitWorld())
|
||||
{
|
||||
if (tr.hitbox == 0)
|
||||
{
|
||||
Vector dummy;
|
||||
IMaterial *pMat = engine->TraceLineMaterialAndLighting(start, end, dummy, dummy);
|
||||
if (pMat)
|
||||
{
|
||||
numMaterials = 1;
|
||||
MatList = new IMaterial*[1];
|
||||
MatList[0] = pMat;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ICollideable *prop = staticpropmgr->GetStaticPropByIndex(tr.hitbox - 1);
|
||||
if (prop)
|
||||
{
|
||||
IClientRenderable *pRenderProp = prop->GetIClientUnknown()->GetClientRenderable();
|
||||
if (pRenderProp)
|
||||
{
|
||||
const model_t *pModel = pRenderProp->GetModel();
|
||||
if (pModel)
|
||||
pSHdr = modelinfo->GetStudiomodel(pModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (tr.m_pEnt)
|
||||
{
|
||||
const model_t *pModel = tr.m_pEnt->GetModel();
|
||||
if (pModel)
|
||||
pSHdr = modelinfo->GetStudiomodel(pModel);
|
||||
}
|
||||
|
||||
if (pSHdr)
|
||||
{
|
||||
Assert(!numMaterials && !MatList);
|
||||
numMaterials = pSHdr->numtextures;
|
||||
const int numPaths = pSHdr->numcdtextures;
|
||||
|
||||
if (numMaterials)
|
||||
{
|
||||
CUtlVector< IMaterial* >hValidMaterials;
|
||||
for (int i = 0; i < numMaterials; i++)
|
||||
{
|
||||
mstudiotexture_t *pStudioTex = pSHdr->pTexture(i);
|
||||
const char *matName = pStudioTex->pszName();
|
||||
|
||||
for (int p = 0; p < numPaths; p++)
|
||||
{
|
||||
char tmpPath[MAX_PATH];
|
||||
Q_snprintf(tmpPath, MAX_PATH, "%s%s\0", pSHdr->pCdtexture(p), matName);
|
||||
Q_FixSlashes(tmpPath);
|
||||
IMaterial *pTempMat = materials->FindMaterial(tmpPath, TEXTURE_GROUP_MODEL);
|
||||
if (!IsErrorMaterial(pTempMat))
|
||||
{
|
||||
hValidMaterials.AddToTail(pTempMat);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
numMaterials = hValidMaterials.Count();
|
||||
if (numMaterials)
|
||||
{
|
||||
MatList = new IMaterial*[numMaterials];
|
||||
for (int i = 0; i < numMaterials; i++)
|
||||
MatList[i] = hValidMaterials[i];
|
||||
}
|
||||
|
||||
hValidMaterials.Purge();
|
||||
}
|
||||
}
|
||||
|
||||
*szMat = new char*[numMaterials];
|
||||
|
||||
int iTotalLength = 0;
|
||||
for (int i = 0; i < numMaterials; i++)
|
||||
iTotalLength += Q_strlen(MatList[i]->GetName()) + 1;
|
||||
|
||||
**szMat = new char[iTotalLength];
|
||||
|
||||
int curpos = 0;
|
||||
for (int i = 0; i < numMaterials; i++)
|
||||
{
|
||||
const char *pszName = MatList[i]->GetName();
|
||||
|
||||
int curLength = Q_strlen(pszName) + 1;
|
||||
(*szMat)[i] = **szMat + curpos;
|
||||
Q_strcpy((*szMat)[i], pszName);
|
||||
curpos += curLength;
|
||||
}
|
||||
|
||||
if (MatList)
|
||||
delete[] MatList;
|
||||
|
||||
return numMaterials;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#ifndef SHEDITMRENDER_H
|
||||
#define SHEDITMRENDER_H
|
||||
|
||||
#include "cbase.h"
|
||||
#include "shadereditor/isedit_modelrender.h"
|
||||
|
||||
class C_BaseFlex_OverrideLod;
|
||||
|
||||
class SEditModelRender : public ISEditModelRender, public CAutoGameSystemPerFrame
|
||||
{
|
||||
public:
|
||||
SEditModelRender(char const *name);
|
||||
~SEditModelRender();
|
||||
|
||||
// autogamesystem
|
||||
virtual bool Init();
|
||||
virtual void Shutdown();
|
||||
virtual void Update(float frametime);
|
||||
|
||||
virtual void LevelInitPostEntity();
|
||||
virtual void LevelShutdownPostEntity();
|
||||
|
||||
// interface
|
||||
virtual bool LoadModel(const char *localPath);
|
||||
virtual void DestroyModel();
|
||||
virtual void GetModelCenter(float *pFl3_ViewOffset);
|
||||
|
||||
virtual int QuerySequences(char ***list);
|
||||
virtual void SetSequence(const char *name);
|
||||
|
||||
virtual void ExecRender();
|
||||
virtual void DoPostProc(int x, int y, int w, int h);
|
||||
|
||||
virtual int MaterialPicker(char ***szMat);
|
||||
|
||||
virtual void DestroyCharPtrList(char ***szList);
|
||||
|
||||
private:
|
||||
|
||||
bool IsModelReady();
|
||||
void ResetModel();
|
||||
|
||||
C_BaseFlex *pModelInstance;
|
||||
char m_szModelPath[MAX_PATH];
|
||||
int m_iNumPoseParams;
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,62 @@
|
||||
#ifndef SHEDITSYSTEM_H
|
||||
#define SHEDITSYSTEM_H
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
#include "datacache/imdlcache.h"
|
||||
|
||||
#include "iviewrender.h"
|
||||
#include "view_shared.h"
|
||||
#include "viewrender.h"
|
||||
|
||||
|
||||
class ShaderEditorHandler : public CAutoGameSystemPerFrame
|
||||
{
|
||||
public:
|
||||
ShaderEditorHandler(char const *name);
|
||||
~ShaderEditorHandler();
|
||||
|
||||
virtual bool Init();
|
||||
virtual void Shutdown();
|
||||
|
||||
virtual void Update(float frametime);
|
||||
virtual void PreRender();
|
||||
virtual void PostRender();
|
||||
|
||||
#ifdef SOURCE_2006
|
||||
void CustomViewRender(int *viewId, const VisibleFogVolumeInfo_t &fogVolumeInfo);
|
||||
#else
|
||||
void CustomViewRender(int *viewId, const VisibleFogVolumeInfo_t &fogVolumeInfo, const WaterRenderInfo_t &waterRenderInfo);
|
||||
#endif
|
||||
void CustomPostRender();
|
||||
void UpdateSkymask(int x, int y, int w, int h, bool bCombineMode = false);
|
||||
|
||||
const bool IsReady();
|
||||
int &GetViewIdForModify();
|
||||
const VisibleFogVolumeInfo_t &GetFogVolumeInfo();
|
||||
#ifndef SOURCE_2006
|
||||
const WaterRenderInfo_t &GetWaterRenderInfo();
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool m_bReady;
|
||||
|
||||
void RegisterCallbacks();
|
||||
void PrepareCallbackData();
|
||||
|
||||
void RegisterViewRenderCallbacks();
|
||||
|
||||
int *m_piCurrentViewId;
|
||||
VisibleFogVolumeInfo_t m_tFogVolumeInfo;
|
||||
#ifndef SOURCE_2006
|
||||
WaterRenderInfo_t m_tWaterRenderInfo;
|
||||
#endif
|
||||
|
||||
float m_flNextAlpha;
|
||||
float m_flAlpha;
|
||||
};
|
||||
|
||||
extern ShaderEditorHandler *g_ShaderEditorSystem;
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user