deargui-vpl/ref/virtools/Samples/Virtools Interface SDK/ShaderEditor/ShaderParameterDialog.cpp

418 lines
12 KiB
C++

#include "stdafx.h"
#include "VIControls.h"
#include "ParameterDialog.h"
#include "CKShader.h"
#include "CUIKNotificationReceiver.h"
//--- Include "GenericObjectParameterDialog.h" from CK2UI define IDDs to mak it compile
#define IDD_GENOBJECTDIALOG 2011
#define IDD_BASEPARAMDIALOG 2000
#include "Parameters\GenericObjectParameterDialog.h"
//--- Some constants
#define MFC_NAME_OF_DIALOG "#32770"
#define CHECK_MATERIAL_TIMER 57
/***********************************************/
// Parameter Dialog
/***********************************************/
class CShaderParameterDialog : public CParameterDialog
{
enum {
PARAMTYPE_SHADER = 0,
PARAMTYPE_TECHNIQUE,
PARAMTYPE_PASS
};
// Construction
public:
VIComboBox m_Combo;
CKShaderManager* m_ShaderManager;
int m_paramType;
CShaderParameterDialog* m_associatedShaderDlg;
CShaderParameterDialog* m_associatedTechniqueDlg;
CShaderParameterDialog* m_associatedPassDlg;
CGenericObjectParameterDialog* m_associatedMaterialDlg;
CString m_associatedMaterialCurStr;
CShaderParameterDialog(CKParameter* Parameter,CK_CLASSID Cid=CKCID_OBJECT) : CParameterDialog(Parameter,Cid) {
}
virtual ~CShaderParameterDialog() {
}
virtual void DoDataExchange(CDataExchange* pDX);
//_________________________________________
// Add Passes to Combo Box
void ParsePassesToComboBox( CKShader& iShader, int iTechIndex ){
CKShader::PassInfo passInfo;
const int passCount = iShader.GetPassCount( iTechIndex );
for( int c=0 ; c<passCount ; ++c ){
iShader.GetPassInfo( iTechIndex, c, passInfo );
m_Combo.AddString( passInfo.name.CStr() );
}
}
//_________________________________________
// Add Techniques to Combo Box
void ParseTechniquesToComboBox( CKShader& iShader ){
CKShader::TechniqueInfo techInfo;
const int techCount = iShader.GetTechniquesCount();
for( int b=0 ; b<techCount ; ++b ){
iShader.GetTechniqueInfo( b, techInfo );
//--- If Param is a Technique then simply add Techniques
if( m_paramType == PARAMTYPE_TECHNIQUE ){
m_Combo.AddString( techInfo.name.CStr() );
continue;
}
//--- Otherwise parse all Passes in this Technique
ParsePassesToComboBox( iShader, b );
}
}
//_________________________________________
// Add Shader to Combo Box
void ParseShadersToComboBox(){
const int shaderCount = m_ShaderManager->GetNumShaders();
for( int a=0 ; a<shaderCount ; ++a ){
CKShader* shader = m_ShaderManager->GetShader(a);
if( !shader ) continue;
if( shader!=m_ShaderManager->GetDefaultShader()
//&& shader!=m_ShaderManager->GetShadowShader()
){
//--- If Param is a Shader then simply add Shaders
if( m_paramType == PARAMTYPE_SHADER ){
//--- Fill with all Shader names otherwise
m_Combo.AddString( shader->GetName().CStr() );
continue;
};
//--- Otherwise parse all Techniques in this Shader
ParseTechniquesToComboBox( *shader );
}
}
}
//__________________________________________
// Get Techniques From Associated Shader Dlg
void GetTechniquesFromAssociatedShader()
{
CString cstr;
m_associatedShaderDlg->m_Combo.GetWindowText( cstr );
if( !m_ShaderManager ) return;
CKShader* shader = m_ShaderManager->GetShaderByName( (char*)(LPCTSTR)cstr );
if( shader ){
ParseTechniquesToComboBox( *shader );
}
}
//____________________________________________
// Get Shader from Associated Material
CKMaterialShader* GetMatShaderFromAssociatedMaterial()
{
//--- Tries to get the material
m_associatedMaterialCurStr = m_associatedMaterialDlg->m_ComboCurStr;
CKMaterial* mat = (CKMaterial*)m_ShaderManager->m_Context->
GetObjectByNameAndClass( (char*)(LPCTSTR)m_associatedMaterialCurStr, CKCID_MATERIAL );
if( !mat ) return NULL;
//--- Return the MaterialShader
return mat->GetMaterialShader( TRUE );
}
//____________________________________________
// Get Techniques From Associated Material Dlg
void GetTechniquesFromAssociatedMaterial()
{
CKMaterialShader* matShader = GetMatShaderFromAssociatedMaterial();
if( matShader && matShader->m_Shader ){
ParseTechniquesToComboBox( *matShader->m_Shader );
}
}
//_________________________________________
// Get Passes From Associated Material Dlg
void GetPassesFromAssociatedMaterial()
{
CKMaterialShader* matShader = GetMatShaderFromAssociatedMaterial();
if( matShader && matShader->m_Shader && (matShader->m_TechIndex>=0) ){
ParsePassesToComboBox( *matShader->m_Shader, matShader->m_TechIndex );
}
}
//_______________________________________
// Fill Combo Box
void FillComboBox()
{
//--- Fill Combo Box
m_Combo.ResetContent();
const int shaderCount = m_ShaderManager->GetNumShaders();
if( m_paramType==PARAMTYPE_PASS && m_associatedMaterialDlg ){
//--- Get Passes From Associated Material Dlg
GetPassesFromAssociatedMaterial();
} else
if( m_paramType==PARAMTYPE_TECHNIQUE && m_associatedShaderDlg ){
//--- Get Techniques From Associated Shader Dlg
GetTechniquesFromAssociatedShader();
} else
if( m_paramType==PARAMTYPE_TECHNIQUE && m_associatedMaterialDlg ){
GetTechniquesFromAssociatedMaterial();
} else {
//--- Otherwise parse all Shaders (possibly to show all Techniques or Passes)
m_Combo.AddString( "-- None --" );
ParseShadersToComboBox();
}
}
//_________________________________________
// Select Item By Name
void SelectItemByName( char *name )
{
//--- Select the item in combo box that matches the string
int curSel = -1;
if( name && name[0]!=0 ){
curSel = m_Combo.FindString( 0, name );
if( curSel<0 && m_paramType==PARAMTYPE_SHADER ) curSel=0;
}
m_Combo.SetCurSel( curSel );
}
//_________________________________________
// Set UI from CKParameter
virtual BOOL On_UpdateFromParameter(CKParameter* p){
if(!p) p = (CKParameterOut *)CKGetObject(m_EditedParameter);
if(!p) return FALSE;
//--- Fill Combo Box
FillComboBox();
SelectItemByName( (char*)p->GetReadDataPtr() );
return TRUE;
}
//_________________________________________
// Set CKParameter from UI
virtual BOOL On_UpdateToParameter(CKParameter* p){
if(!p) p = (CKParameterOut *)CKGetObject(m_EditedParameter);
if(!p) return FALSE;
CString cstr;
if( m_Combo.GetCurSel()<0 ){
cstr="";
} else {
if( m_paramType==PARAMTYPE_SHADER && m_Combo.GetCurSel()==0 ){
cstr="";
}
m_Combo.GetWindowText(cstr);
}
char *str = (char*)(LPCTSTR)cstr;
p->SetValue( str, cstr.GetLength()+1 );
return TRUE;
}
//_________________________________________
// Associated Combo Box Has Changed
void AssociatedComboBoxHasChanged( CShaderParameterDialog& callerDlg )
{
CKParameter* p = (CKParameterOut *)CKGetObject(m_EditedParameter);
if(!p) return;
FillComboBox();
SelectItemByName( (char*)p->GetReadDataPtr() );
}
//_________________________________________
// Find Associated Parameter Dialogs
void FindAssociatedParameterDialogs()
{
m_associatedShaderDlg = NULL;
m_associatedTechniqueDlg = NULL;
m_associatedPassDlg = NULL;
m_associatedMaterialDlg = NULL;
m_associatedMaterialCurStr = "";
char name[256];
CWnd* thisSubParentWindow = this->GetParent();
CWnd* bigParentWindow = thisSubParentWindow->GetParent();
for( CWnd* subParentWindow = bigParentWindow->GetWindow(GW_CHILD); subParentWindow ;
subParentWindow = subParentWindow->GetWindow(GW_HWNDNEXT) ){
//--- Don't parse any further if we reached THIS parameter
if( subParentWindow == thisSubParentWindow ) break;
GetClassName( subParentWindow->m_hWnd, name, sizeof(name) );
if( strcmp(name,MFC_NAME_OF_DIALOG) ) continue;
for( CWnd* child = subParentWindow->GetWindow(GW_CHILD) ; child ;
child = child->GetWindow(GW_HWNDNEXT) ){
GetClassName( child->m_hWnd, name, sizeof(name) );
if( strcmp(name,MFC_NAME_OF_DIALOG) ) continue;
//--- From this point it should be a CParameterDialog...
CParameterDialog* otherParamDialog = (CParameterDialog*)
(child->SendMessage( CKWM_GETPARAMDIALOG, 0, 0 ));
if( !otherParamDialog ) continue;
CK_CLASSID cid = otherParamDialog->m_EditedClassID;
CKClassDesc* cDesc = CKGetClassDesc( cid );
CKParameterOut* otherParam = (CKParameterOut*)CKGetObject( otherParamDialog->m_EditedParameter );
if( !otherParam ) continue;
switch( m_paramType ){
case PARAMTYPE_TECHNIQUE:
//--- Technique Param is interested by Shader Param and Material Param
if( otherParam->GetGUID() == CKPGUID_SHADER ){
m_associatedShaderDlg = (CShaderParameterDialog*)otherParamDialog;
m_associatedShaderDlg->m_associatedTechniqueDlg = this;
} else if( otherParam->GetGUID() == CKPGUID_MATERIAL ){
m_associatedMaterialDlg = (CGenericObjectParameterDialog*)otherParamDialog;
}
break;
case PARAMTYPE_PASS:
//--- Pass Param is only interested by Material Param
if( otherParam->GetGUID() == CKPGUID_MATERIAL ){
m_associatedMaterialDlg = (CGenericObjectParameterDialog*)otherParamDialog;
}
break;
}
}
}
}
//_________________________________________
// Initialization
virtual BOOL On_Init(){
//--- Some members initialization
m_paramType = PARAMTYPE_SHADER;
m_FocusWindow = &m_Combo;
m_ShaderManager = (CKShaderManager *) m_Context->GetManagerByGuid( ShaderManagerGUID );
CKParameter* p = (CKParameterOut *)CKGetObject( m_EditedParameter );
if( p->GetGUID() == CKPGUID_TECHNIQUE ){
//--- If it's a Technique Parameter
m_paramType = PARAMTYPE_TECHNIQUE;
} else if( p->GetGUID() == CKPGUID_PASS ){
//--- If it's a Pass Parameter
m_paramType = PARAMTYPE_PASS;
}
FindAssociatedParameterDialogs();
//---
if( m_associatedMaterialDlg ){
this->SetTimer( CHECK_MATERIAL_TIMER, 100, NULL );
}
return TRUE;
}
//_________________________________________
// WindowProc
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message){
//--- Called to check for Material's Combo Box Modifications
case WM_TIMER:
{
//--- Ensure it is the correct Timer
if( wParam != CHECK_MATERIAL_TIMER ) break;
//--- Retrieve Material's Combo box info
if( !m_associatedMaterialDlg ) break;
//--- Check if the Material Combo Box Current Selection has Changed
if( !m_associatedMaterialCurStr.Compare( m_associatedMaterialDlg->m_ComboCurStr ) ) break;
//--- If combo box changed, then update associated combo boxes
if( m_paramType==PARAMTYPE_TECHNIQUE || m_paramType==PARAMTYPE_PASS ){
AssociatedComboBoxHasChanged( *this );
}
} break;
case WM_NOTIFY:
{
int idCtrl = (int) wParam;
LPNMHDR pnmh = (LPNMHDR) lParam;
} break;
case WM_COMMAND:
{
int hparam = (int) HIWORD(wParam);
switch( hparam ){
case CBN_SELCHANGE:
{
int idComboBox = (int) LOWORD(wParam); // identifier of combo box
if( idComboBox == IDC_COMBOSHADER ){
CString cstr;
m_Combo.GetWindowText(cstr);
//--- If it's a Shader notify associated Techniques Dialog
if( m_paramType==PARAMTYPE_SHADER ){
if( m_associatedTechniqueDlg ){
m_associatedTechniqueDlg->AssociatedComboBoxHasChanged( *this );
}
}
}
return 1;
} break;
}
}
}
return CParameterDialog::WindowProc(message, wParam, lParam);
}
public:
};
void CShaderParameterDialog::DoDataExchange(CDataExchange* pDX)
{
CParameterDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CShaderParameterDialog)
DDX_Control(pDX, IDC_COMBOSHADER, m_Combo);
//}}AFX_DATA_MAP
}
WIN_HANDLE ShaderParamUIFunc(CKParameter*param,WIN_HANDLE parent,CKRECT *rect)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CShaderParameterDialog *Dlg = new CShaderParameterDialog(param);
Dlg->Create( IDD_SHADERDIALOG );
return CreateParameterDialog( (HWND)parent, Dlg, 0, PARAMETER_NOPICK, 0, PARAMETER_RESIZE );
}