Implemented shader editor.

Add "-shaderedit" to startup line to use it.
See https://developer.valvesoftware.com/wiki/Category:SourceShaderEditor for details.
This commit is contained in:
hlstriker 2013-11-07 14:29:40 +00:00 committed by squeek
parent a9147a53bd
commit a7c5340a51
12 changed files with 4120 additions and 1 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,132 @@
#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();
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

View file

@ -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.

View file

@ -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 );
}

View file

@ -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

View file

@ -0,0 +1,128 @@
#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 )
#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
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 ) = 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;
};
#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

View file

@ -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;
}

View file

@ -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

View file

@ -0,0 +1,59 @@
#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( 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
};
extern ShaderEditorHandler *g_ShaderEditorSystem;
#endif

View file

@ -19,7 +19,7 @@ $Configuration
$Compiler
{
$AdditionalIncludeDirectories "$BASE;.\ff;$SRCDIR\game\shared\ff;$THIRDPARTYDIR\lua;$THIRDPARTYDIR"
$PreprocessorDefinitions "$BASE;FF;FF_CLIENT_DLL"
$PreprocessorDefinitions "$BASE;FF;FF_CLIENT_DLL;SOURCE_2013"
}
}
@ -73,5 +73,24 @@ $Project "Client (FF)"
-$File "$SRCDIR\game\shared\hl2mp\hl2mp_player_shared.cpp"
-$File "$SRCDIR\game\shared\hl2mp\hl2mp_player_shared.h"
}
$Folder "Shader Editor" [$WIN32]
{
$Folder "Header Files"
{
$File "$SRCDIR\game\client\ShaderEditor\ISEdit_ModelRender.h"
$File "$SRCDIR\game\client\ShaderEditor\IVShaderEditor.h"
$File "$SRCDIR\game\client\ShaderEditor\ShaderEditorSystem.h"
$File "$SRCDIR\game\client\ShaderEditor\SEdit_ModelRender.h"
//$File "$SRCDIR\game\client\ShaderEditor\Grass\CGrassCluster.h"
}
$Folder "Implementation Files"
{
$File "$SRCDIR\game\client\ShaderEditor\ShaderEditorSystem.cpp"
$File "$SRCDIR\game\client\ShaderEditor\SEdit_ModelRender.cpp"
//$File "$SRCDIR\game\client\ShaderEditor\Grass\CGrassCluster.cpp"
}
}
}
}

View file

@ -77,6 +77,8 @@
// Projective textures
#include "C_Env_Projected_Texture.h"
#include "ShaderEditor/ShaderEditorSystem.h" // FF --> hlstriker: Added
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
@ -1351,6 +1353,14 @@ void CViewRender::ViewDrawScene( bool bDrew3dSkybox, SkyboxVisibility_t nSkyboxV
DrawWorldAndEntities( drawSkybox, view, nClearFlags, pCustomVisibility );
// FF --> hlstriker: Added
VisibleFogVolumeInfo_t fogVolumeInfo;
render->GetVisibleFogVolume( view.origin, &fogVolumeInfo );
WaterRenderInfo_t info;
DetermineWaterRenderInfo( fogVolumeInfo, info );
g_ShaderEditorSystem->CustomViewRender( &g_CurrentViewID, fogVolumeInfo, info );
// <--
// Disable fog for the rest of the stuff
DisableFog();
@ -1969,6 +1979,7 @@ void CViewRender::RenderView( const CViewSetup &view, int nClearFlags, int whatT
if ( ( bDrew3dSkybox = pSkyView->Setup( view, &nClearFlags, &nSkyboxVisible ) ) != false )
{
AddViewToScene( pSkyView );
g_ShaderEditorSystem->UpdateSkymask(); // FF --> hlstriker: Added
}
SafeRelease( pSkyView );
@ -2026,6 +2037,8 @@ void CViewRender::RenderView( const CViewSetup &view, int nClearFlags, int whatT
// Now actually draw the viewmodel
DrawViewModels( view, whatToDraw & RENDERVIEW_DRAWVIEWMODEL );
g_ShaderEditorSystem->UpdateSkymask( bDrew3dSkybox ); // FF --> hlstriker: Added
DrawUnderwaterOverlay();
PixelVisibility_EndScene();
@ -2063,6 +2076,8 @@ void CViewRender::RenderView( const CViewSetup &view, int nClearFlags, int whatT
pRenderContext.SafeRelease();
}
g_ShaderEditorSystem->CustomPostRender(); // FF --> hlstriker: Added
// And here are the screen-space effects
if ( IsPC() )