#include "dxstdafx.h" #include "Parameters.h" float noconvert(float a) { return a; } void OnChange() { } //-------------------------------------------------------------------------------------- /// \brief You can set the dialog that manages input and rendering for the GUI controls. //-------------------------------------------------------------------------------------- void Parameters::Setup( CDXUTDialog* g_HUD ) { Setup(g_HUD, OnChange, OnChange, OnChange); } //-------------------------------------------------------------------------------------- /// \brief You can set the dialog that manages input and rendering for the GUI controls. /// /// Additionally, you can specify actions (#ONCHANGE_CALLBACK) to the standard buttons /// Reset, Save and Load. //-------------------------------------------------------------------------------------- void Parameters::Setup( CDXUTDialog* g_HUD, ONCHANGE_CALLBACK OnReset, ONCHANGE_CALLBACK OnSave, ONCHANGE_CALLBACK OnLoad ) { assert( g_HUD != NULL ); this->g_HUD = g_HUD; g_HUD->GetDefaultElement( DXUT_CONTROL_STATIC, 0 )->dwTextFormat = DT_VCENTER | DT_LEFT; for (int i=0; iAddButton( IDC_RESET_BUTTON, L"[R] Reset", posX, posY += 30, 60, 16, 'R' ); g_HUD->AddButton( IDC_SAVE_BUTTON, L"[S] Save", posX + 70, posY, 60, 16, 'S' ); g_HUD->AddButton( IDC_LOAD_BUTTON, L"[L] Load", posX + 140, posY, 60, 16, 'L' ); chfunc[ LAST_NUMBER ] = OnReset; chfunc[ LAST_NUMBER+1 ] = OnSave; chfunc[ LAST_NUMBER+2 ] = OnLoad; } //-------------------------------------------------------------------------------------- /// \brief Adds a boolean parameter represented by a GUI radio button. Specifies hotkey and callback function. /// /// \param radiogroupID id of radio button group. /// Checking a radio button will clear all other radio buttons with the same radiogroupID. /// \param ID id of the given boolean parameter /// \param label label to be displayed for the control /// \param cHotkey Hotkey to change parameter value. (Note: keys R, S, L are reserved.) /// \param bchf callback to an action to be performed when the parameter changes //-------------------------------------------------------------------------------------- void Parameters::Add( int radiogroupID, bool_t ID, char* label, char cHotKey, ONCHANGE_CALLBACK bchf ) { assert( cHotKey != 'R' && cHotKey != 'S' && cHotKey != 'L' ); mbstowcs( bname[ID], label, CHARBUFFER_SIZE ); int posX = 380; int posY = 50; if (radiogroupID >=0) g_HUD->AddRadioButton( ID+checkboxID0, 0, bname[ID], posX, posY + ID*16, 220, 16, false, cHotKey, 0 ); else g_HUD->AddCheckBox( ID+checkboxID0, bname[ID], posX, posY + ID*16, 220, 16, false, cHotKey, 0 ); // checked=false bchfunc[ID] = bchf; radiogroup[ ID ] = radiogroupID; } //-------------------------------------------------------------------------------------- /// \brief Adds a boolean parameter represented by a GUI checkbox. Specifies hotkey and callback function. /// /// \param ID id of the given boolean parameter /// \param label label to be displayed for the control /// \param cHotkey Hotkey to change parameter value. (Note: keys R, S, L are reserved.) /// \param bchf callback to an action to be performed when the parameter changes //-------------------------------------------------------------------------------------- void Parameters::Add( bool_t ID, char* label, char cHotKey, ONCHANGE_CALLBACK bchf ) { // not a radio button Add( -1, ID, label, cHotKey, bchf ); } //-------------------------------------------------------------------------------------- /// \brief Adds a numeric parameter represented by a GUI slider. /// /// \param ID id of the given numeric parameter /// \param label label to be displayed for the slider /// \param num_steps number of possible parameter values //-------------------------------------------------------------------------------------- void Parameters::Add( number_t ID, char* label, int num_steps) { Add( ID, label, num_steps, noconvert ); } //-------------------------------------------------------------------------------------- /// \brief Adds a numeric parameter represented by a GUI slider. Specifies callback functions. /// /// \param ID id of the given numeric parameter /// \param label label to be displayed for the slider /// \param num_steps number of possible parameter values /// \param ff converter function to transform the parameter value /// \param chf callback to an action to be performed when the parameter changes //-------------------------------------------------------------------------------------- void Parameters::Add( number_t ID, char* label, int num_steps, CONVERTER ff, ONCHANGE_CALLBACK chf ) { char cKeyDown = 0; char cKeyUp = 0; Add( ID, label, num_steps, cKeyDown, cKeyUp, ff, chf); } //-------------------------------------------------------------------------------------- /// \brief Adds a numeric parameter represented by a GUI slider. Specifies hotkeys and callback functions. /// /// \param ID id of the given numeric parameter /// \param label label to be displayed for the slider /// \param num_steps number of possible parameter values /// \param cKeyDecr Hotkey to decrease parameter value. (Note: keys R, S, L are reserved.) /// \param cKeyIncr Hotkey to increase parameter value. (Note: keys R, S, L are reserved.) /// If 0, the slider will only have one hotkey that circulates between values min, min+1, ..., max-1, max, min, ... /// /// \param ff converter function to transform the parameter value /// \param chf callback to an action to be performed when the parameter changes //-------------------------------------------------------------------------------------- void Parameters::Add( number_t ID, char* label, int num_steps, char cKeyDecr, char cKeyIncr, CONVERTER ff, ONCHANGE_CALLBACK chf ) { assert( cKeyDecr != 'R' && cKeyDecr != 'S' && cKeyDecr != 'L' ); assert( cKeyIncr != 'R' && cKeyIncr != 'S' && cKeyIncr != 'L' ); if (cKeyIncr == 0) { cKeyIncr = cKeyDecr; cKeyDecr = 0; // swap rotate[ID] = true; // slider acts as a modulus } mbstowcs( name[ID], label, CHARBUFFER_SIZE ); /*wchar_t val[30]; _sntprintf( val, 30, L"%.2f", param[ID] / 100.0f ); // nem kell */ //cHotKey ffunc[ID] = ff; chfunc[ID] = chf; numsteps[ID] = num_steps; int posX = 210; int posY = 50; g_HUD->AddStatic( 0, name[ID], posX-180, posY + ID*16, 120, 14 ); g_HUD->AddStatic( ID+staticID0, L"", posX-50, posY + ID*16, 120, 14 ); g_HUD->GetStatic( ID+staticID0 )->SetTextColor( D3DCOLOR_ARGB(128,178,178,178) ); g_HUD->AddSlider( ID+sliderID0, posX, posY + ID*16, 120, 14, 0, num_steps ); //UpdateFromHUD( ID+sliderID0 ); // hogy ne kelljen azt eltárolni, hogy melyik hotkey melyik sliderhez tartozik, // 2 láthatatlan checkboxot hozok létre ezekkel a hotkeyekkel. // a checkbox id alapján azonosíthatom az érintett slidert. CDXUTCheckBox* c; g_HUD->AddCheckBox( ID+downID0, L"d", posX-20, posY + ID*16, 200, 16, 0, cKeyDecr, 0, &c ); c->m_bVisible = false; g_HUD->AddCheckBox( ID+upID0, L"u", posX-20, posY + ID*16, 200, 16, 0, cKeyIncr, 0, &c ); c->m_bVisible = false; } /// \brief Returns value of the specified boolean parameter, e.g. Get( #bShowHelp ). bool Parameters::Get( bool_t i ) { return bparam[i]; } /// \brief Returns float value of the specified numeric parameter, in range 0..1. /// /// Example: Get( refractionIndex ). Converter functions (if present) are applied to the result. float Parameters::Get( number_t i ) { //assert( ffunc[i] != NULL ); return ffunc[i]( (float)param[i] / numsteps[i] ); // 0..1 } /// \brief Returns integer value of the specified numeric parameter, in range 0...number-of-steps /// /// Example: Get( fIntensity ) = 0..100. Converter functions (if present) are applied to the result. int Parameters::GetInt( number_t i ) { //assert( ffunc[i] != NULL ); float r = ffunc[i]( param[i] ); return (int)(r+0.5); // 0..numsteps[i] } void Parameters::SetBool( bool_t ID, bool b ) { bparam[ID] = b; CDXUTCheckBox* checkBox; if ( radiogroup[ID] >= 0) checkBox = g_HUD->GetRadioButton( ID+checkboxID0 ); else checkBox = g_HUD->GetCheckBox( ID+checkboxID0 ); bSilent = true; if( checkBox != NULL ) checkBox->SetChecked( bparam[ID] ); bSilent = false; bchfunc[ID](); } void Parameters::SetFloat( number_t ID, float v ) { SetInt( ID, (int)( v*numsteps[ID] + 0.5 )); } void Parameters::SetInt( number_t ID, int v ) { param[ID] = v; if ( param[ID] < 0 ) param[ID] = 0; else if ( param[ID] > numsteps[ID] ) { if (rotate[ID]) param[ID] = 0; else param[ID] = numsteps[ID]; } bSilent = true; // everything is updated if( g_HUD->GetSlider( ID+sliderID0 ) != NULL ) g_HUD->GetSlider( ID+sliderID0 )->SetValue( param[ID] ); wchar_t text[30]; _sntprintf( text, 30, L"%.2f", Get( (number_t)ID ) ); if( g_HUD->GetStatic( ID+staticID0 ) != NULL ) g_HUD->GetStatic( ID+staticID0 )->SetText( text ); // user-defined callback //assert( chfunc[ID] != NULL ); chfunc[ID](); bSilent = false; } void Parameters::SetEnabled( bool_t ID, bool bEnabled ) { CDXUTCheckBox* checkBox; if ( radiogroup[ID] >= 0) checkBox = g_HUD->GetRadioButton( ID+checkboxID0 ); else checkBox = g_HUD->GetCheckBox( ID+checkboxID0 ); checkBox->SetEnabled( bEnabled ); } void Parameters::SetEnabled( number_t ID, bool bEnabled ) { g_HUD->GetSlider( ID+sliderID0 )->SetEnabled( bEnabled ); g_HUD->GetCheckBox( ID+downID0 )->SetEnabled( bEnabled ); g_HUD->GetCheckBox( ID+upID0 )->SetEnabled( bEnabled ); } /// \brief Updates the specified parameter from the GUI. /// /// Since a GUI event provides the id of the sender (see OnGUIEvent() in Main.cpp), /// we can update the parameter value belonging to that control. /// /// In case of Load/Save, parameters are loaded from/saved to the file called .params. /// In case of Reset, parameters are loaded from the file called .params0. void Parameters::UpdateFromHUD( int controlID ) { //if (bSilent) return; // Reset, Save & Load buttons if (controlID == IDC_RESET_BUTTON ) { LoadFromFile( ".params0" ); chfunc[ LAST_NUMBER ](); } else if (controlID == IDC_SAVE_BUTTON ) { SaveToFile( ".params" ); chfunc[ LAST_NUMBER+1 ](); } else if (controlID == IDC_LOAD_BUTTON ) { LoadFromFile( ".params" ); chfunc[ LAST_NUMBER+2 ](); } // a checkbox or radio button else if (controlID >= checkboxID0 && controlID < checkboxID0+LAST_BOOL) { int ID = controlID - checkboxID0; CDXUTCheckBox* checkBox; // radio button if ( radiogroup[ID] >= 0) { checkBox = g_HUD->GetRadioButton( controlID ); // get radio button... if (checkBox->GetChecked()) { for (int i=0; iGetCheckBox( controlID ); } if ( checkBox->GetEnabled() ) SetBool( (bool_t)ID, checkBox->GetChecked()); } // a slider else if (controlID >= sliderID0 && controlID < sliderID0+LAST_NUMBER) { int v = g_HUD->GetSlider( controlID )->GetValue(); int ID = controlID - sliderID0; if ( g_HUD->GetSlider( controlID )->GetEnabled() ) SetInt( (number_t)ID, v); } // a hotkey (bound to an invisible checkbox) that decrements a slider else if (controlID >= downID0 && controlID < downID0+LAST_NUMBER) { // down int ID = controlID-downID0; if ( g_HUD->GetSlider( ID+sliderID0 )->GetEnabled() ) SetInt( (number_t)ID, param[ID]-1 ); } // a hotkey (bound to an invisible checkbox) that increments a slider else if (controlID >= upID0 && controlID < upID0+LAST_NUMBER) { // up int ID = controlID-upID0; if ( g_HUD->GetSlider( ID+sliderID0 )->GetEnabled() ) SetInt( (number_t)ID, param[ID]+1 ); } } /// \brief Writes all parameter values into the specified file. void Parameters::SaveToFile( char* fileName ) { FILE* fileS; if( ( fileS = fopen( fileName, "wt" ) ) == NULL ) { wchar_t wbuf[ CHARBUFFER_SIZE ]; mbstowcs( wbuf, fileName, CHARBUFFER_SIZE ); MessageBox( NULL, wbuf, L"File creation failed!", MB_ICONERROR ); // show error message return; } fwprintf( fileS, L"----- RayTraceEffects: Saved parameters of the algorithm -----\n" ); fwprintf( fileS, L"Bool values:\n" ); for ( int i=0; i 0 ); } fgets( buf, CHARBUFFER_SIZE, fileL ); // skip line fgets( buf, CHARBUFFER_SIZE, fileL ); // skip comment fgets( buf, CHARBUFFER_SIZE, fileL ); // skip comment for ( int i=0; i