DlgGenerateFBM.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /* Copyright (c) 2002-2012 Croteam Ltd.
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of version 2 of the GNU General Public License as published by
  4. the Free Software Foundation
  5. This program is distributed in the hope that it will be useful,
  6. but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8. GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License along
  10. with this program; if not, write to the Free Software Foundation, Inc.,
  11. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
  12. // DlgGenerateFBM.cpp : implementation file
  13. //
  14. #include "stdafx.h"
  15. #include "WorldEditor.h"
  16. #include "DlgGenerateFBM.h"
  17. #ifdef _DEBUG
  18. #undef new
  19. #define new DEBUG_NEW
  20. #undef THIS_FILE
  21. static char THIS_FILE[] = __FILE__;
  22. #endif
  23. /////////////////////////////////////////////////////////////////////////////
  24. // CDlgGenerateFBM dialog
  25. INDEX _iFBMOctaves;
  26. FLOAT _fFBMHighFrequencyStep;
  27. FLOAT _fFBMStepFactor;
  28. FLOAT _fFBMMaxAmplitude;
  29. FLOAT _fFBMfAmplitudeDecreaser;
  30. BOOL _bFBMAddNegativeValues;
  31. BOOL _bFBMRandomOffset;
  32. CDlgGenerateFBM::CDlgGenerateFBM(CWnd* pParent /*=NULL*/)
  33. : CDialog(CDlgGenerateFBM::IDD, pParent)
  34. {
  35. //{{AFX_DATA_INIT(CDlgGenerateFBM)
  36. m_fMaxAltitude = 0.0f;
  37. m_fOctaveAmplitudeDecreaser = 0.0f;
  38. m_fOctaveAmplitudeStep = 0.0f;
  39. m_fHighFrequencyStep = 0.0f;
  40. m_ctOctaves = 0;
  41. m_bAddNegativeValues = FALSE;
  42. m_bRandomOffset = FALSE;
  43. //}}AFX_DATA_INIT
  44. m_bCustomWindowCreated = FALSE;
  45. m_pdp=NULL;
  46. m_pvp=NULL;
  47. _iFBMOctaves=theApp.m_iFBMOctaves;
  48. _fFBMHighFrequencyStep=theApp.m_fFBMHighFrequencyStep;
  49. _fFBMStepFactor=theApp.m_fFBMStepFactor;
  50. _fFBMMaxAmplitude=theApp.m_fFBMMaxAmplitude;
  51. _fFBMfAmplitudeDecreaser=theApp.m_fFBMfAmplitudeDecreaser;
  52. _bFBMAddNegativeValues=theApp.m_bFBMAddNegativeValues;
  53. _bFBMRandomOffset=theApp.m_bFBMRandomOffset;
  54. }
  55. void CDlgGenerateFBM::DoDataExchange(CDataExchange* pDX)
  56. {
  57. // if dialog is recieving data
  58. if(pDX->m_bSaveAndValidate == FALSE)
  59. {
  60. m_ctOctaves=_iFBMOctaves;
  61. m_fHighFrequencyStep=_fFBMHighFrequencyStep;
  62. m_fOctaveAmplitudeStep=_fFBMStepFactor;
  63. m_fMaxAltitude=_fFBMMaxAmplitude;
  64. m_fOctaveAmplitudeDecreaser=_fFBMfAmplitudeDecreaser;
  65. m_bAddNegativeValues=_bFBMAddNegativeValues;
  66. m_bRandomOffset=_bFBMRandomOffset;
  67. }
  68. else if( !::IsWindow(m_ctrlCtOctavesSpin.m_hWnd)) return;
  69. CDialog::DoDataExchange(pDX);
  70. //{{AFX_DATA_MAP(CDlgGenerateFBM)
  71. DDX_Control(pDX, IDC_CT_OCTAVES_SPIN, m_ctrlCtOctavesSpin);
  72. DDX_Text(pDX, IDC_FBM_MAX_ALTITUDE, m_fMaxAltitude);
  73. DDV_MinMaxFloat(pDX, m_fMaxAltitude, 0.f, 65535.f);
  74. DDX_Text(pDX, IDC_FBM_OCTAVE_AMPLITUDE_DECREASE, m_fOctaveAmplitudeDecreaser);
  75. DDV_MinMaxFloat(pDX, m_fOctaveAmplitudeDecreaser, 0.f, 16.f);
  76. DDX_Text(pDX, IDC_FBM_OCTAVE_STEP, m_fOctaveAmplitudeStep);
  77. DDV_MinMaxFloat(pDX, m_fOctaveAmplitudeStep, 0.f, 128.f);
  78. DDX_Text(pDX, IDC_FBM_HIGH_FREQUENCY_STEP, m_fHighFrequencyStep);
  79. DDV_MinMaxFloat(pDX, m_fHighFrequencyStep, 0.f, 16.f);
  80. DDX_Text(pDX, IDC_FBM_OCTAVES, m_ctOctaves);
  81. DDV_MinMaxInt(pDX, m_ctOctaves, 0, 16);
  82. DDX_Check(pDX, IDC_ADD_NEGATIVE_VALUES, m_bAddNegativeValues);
  83. DDX_Check(pDX, IDC_RANDOM_OFFSET, m_bRandomOffset);
  84. //}}AFX_DATA_MAP
  85. // if dialog is giving data
  86. if(pDX->m_bSaveAndValidate != FALSE)
  87. {
  88. _iFBMOctaves=m_ctOctaves;
  89. _fFBMHighFrequencyStep=m_fHighFrequencyStep;
  90. _fFBMStepFactor=m_fOctaveAmplitudeStep;
  91. _fFBMMaxAmplitude=m_fMaxAltitude;
  92. _fFBMfAmplitudeDecreaser=m_fOctaveAmplitudeDecreaser;
  93. }
  94. }
  95. BEGIN_MESSAGE_MAP(CDlgGenerateFBM, CDialog)
  96. //{{AFX_MSG_MAP(CDlgGenerateFBM)
  97. ON_WM_PAINT()
  98. ON_BN_CLICKED(IDC_FBM_RANDOMIZE, OnFbmRandomize)
  99. ON_EN_CHANGE(IDC_FBM_HIGH_FREQUENCY_STEP, OnChangeFbmHighFrequencyStep)
  100. ON_EN_CHANGE(IDC_FBM_MAX_ALTITUDE, OnChangeFbmMaxAltitude)
  101. ON_EN_CHANGE(IDC_FBM_OCTAVE_AMPLITUDE_DECREASE, OnChangeFbmOctaveAmplitudeDecrease)
  102. ON_EN_CHANGE(IDC_FBM_OCTAVE_STEP, OnChangeFbmOctaveStep)
  103. ON_EN_CHANGE(IDC_FBM_OCTAVES, OnChangeFbmOctaves)
  104. ON_BN_CLICKED(IDC_ADD_NEGATIVE_VALUES, OnAddNegativeValues)
  105. ON_BN_CLICKED(IDC_FBM_EXPORT, OnFbmExport)
  106. ON_BN_CLICKED(IDC_RANDOM_OFFSET, OnRandomOffset)
  107. //}}AFX_MSG_MAP
  108. END_MESSAGE_MAP()
  109. /////////////////////////////////////////////////////////////////////////////
  110. // CDlgGenerateFBM message handlers
  111. BOOL CreateFBMTexture(PIX pixW, PIX pixH, CTFileName fnFBMFile)
  112. {
  113. FLOAT fMin, fMax;
  114. FLOAT *pafFBM=GenerateTerrain_FBMBuffer( pixW, pixH, _iFBMOctaves,
  115. _fFBMHighFrequencyStep, _fFBMStepFactor, _fFBMMaxAmplitude,
  116. _fFBMfAmplitudeDecreaser, _bFBMAddNegativeValues, _bFBMRandomOffset, fMin, fMax);
  117. CImageInfo ii;
  118. ii.ii_Width=pixW;
  119. ii.ii_Height=pixH;
  120. ii.ii_BitsPerPixel=32;
  121. ii.ii_Picture=(UBYTE*) AllocMemory(ii.ii_Width*ii.ii_Height*sizeof(COLOR));
  122. COLOR *pcol=(COLOR *)ii.ii_Picture;
  123. // convert buffer to equalized color map
  124. FLOAT fConvertFactor=MAX_UBYTE/(fMax-fMin);
  125. // pixelate preview area
  126. for(INDEX y=0; y<pixH; y++)
  127. {
  128. for(INDEX x=0; x<pixW; x++)
  129. {
  130. INDEX iOffset=y*pixW+x;
  131. FLOAT fValue=pafFBM[iOffset];
  132. UBYTE ub=(fValue-fMin)*fConvertFactor;
  133. COLOR col=RGBToColor(ub,ub,ub)|CT_OPAQUE;
  134. *pcol=ByteSwap(col);
  135. pcol++;
  136. }
  137. }
  138. CTextureData tdFBM;
  139. try
  140. {
  141. tdFBM.Create_t( &ii, pixW, 16, TRUE);
  142. tdFBM.Save_t( fnFBMFile);
  143. }
  144. catch( char *strError)
  145. {
  146. (void) strError;
  147. WarningMessage("Unable to create FBM preview texture!");
  148. FreeMemory( pafFBM);
  149. return FALSE;
  150. }
  151. FreeMemory( pafFBM);
  152. return TRUE;
  153. }
  154. void CDlgGenerateFBM::OnPaint()
  155. {
  156. CPaintDC dc(this); // device context for painting
  157. if( !m_bCustomWindowCreated)
  158. {
  159. // obtain window position
  160. CWnd *pwndTexture = GetDlgItem(IDC_FBM_PREVIEW_FRAME);
  161. ASSERT(pwndTexture!= NULL);
  162. CRect rect;
  163. pwndTexture->GetWindowRect(&rect);
  164. ScreenToClient(&rect);
  165. m_wndTexture.Create( NULL, NULL, WS_BORDER|WS_VISIBLE, rect, this, IDW_FBM_PREVIEW);
  166. // mark that custom window is created
  167. m_bCustomWindowCreated = TRUE;
  168. }
  169. // ******** Render preview texture
  170. if (m_pdp==NULL)
  171. {
  172. _pGfx->CreateWindowCanvas( m_wndTexture.m_hWnd, &m_pvp, &m_pdp);
  173. }
  174. if( (m_pdp!=NULL) && (m_pdp->Lock()) )
  175. {
  176. PIX pixW=256;
  177. PIX pixH=256;
  178. CTFileName fnFBMFile=CTString("Textures\\Editor\\FMPPreview.tex");
  179. if(CreateFBMTexture(pixW, pixH, fnFBMFile))
  180. {
  181. try
  182. {
  183. CTextureObject to;
  184. to.SetData_t(fnFBMFile);
  185. CTextureData *ptd=(CTextureData *)to.GetData();
  186. ptd->Reload();
  187. m_pdp->PutTexture( &to, PIXaabbox2D(PIX2D(0,0),PIX2D(m_pdp->GetWidth(),m_pdp->GetHeight())));
  188. }
  189. catch( char *strError)
  190. {
  191. (void) strError;
  192. WarningMessage("Unable to create FBM preview texture!");
  193. }
  194. m_pdp->Unlock();
  195. }
  196. }
  197. if (m_pvp!=NULL)
  198. {
  199. m_pvp->SwapBuffers();
  200. }
  201. }
  202. void CDlgGenerateFBM::OnFbmRandomize()
  203. {
  204. RandomizeWhiteNoise();
  205. Invalidate(FALSE);
  206. }
  207. void CDlgGenerateFBM::OnChangeFbmHighFrequencyStep()
  208. {
  209. UpdateData(TRUE);
  210. Invalidate(FALSE);
  211. }
  212. void CDlgGenerateFBM::OnChangeFbmMaxAltitude()
  213. {
  214. UpdateData(TRUE);
  215. Invalidate(FALSE);
  216. }
  217. void CDlgGenerateFBM::OnChangeFbmOctaveAmplitudeDecrease()
  218. {
  219. UpdateData(TRUE);
  220. Invalidate(FALSE);
  221. }
  222. void CDlgGenerateFBM::OnChangeFbmOctaveStep()
  223. {
  224. UpdateData(TRUE);
  225. Invalidate(FALSE);
  226. }
  227. void CDlgGenerateFBM::OnChangeFbmOctaves()
  228. {
  229. UpdateData(TRUE);
  230. Invalidate(FALSE);
  231. }
  232. void CDlgGenerateFBM::OnOK()
  233. {
  234. theApp.m_iFBMOctaves=_iFBMOctaves;
  235. theApp.m_fFBMHighFrequencyStep=_fFBMHighFrequencyStep;
  236. theApp.m_fFBMStepFactor=_fFBMStepFactor;
  237. theApp.m_fFBMMaxAmplitude=_fFBMMaxAmplitude;
  238. theApp.m_fFBMfAmplitudeDecreaser=_fFBMfAmplitudeDecreaser;
  239. theApp.m_bFBMAddNegativeValues=_bFBMAddNegativeValues;
  240. theApp.m_bFBMRandomOffset=_bFBMRandomOffset;
  241. CDialog::OnOK();
  242. }
  243. BOOL CDlgGenerateFBM::OnInitDialog()
  244. {
  245. CDialog::OnInitDialog();
  246. m_ctrlCtOctavesSpin.SetRange(0,16);
  247. m_ctrlCtOctavesSpin.SetPos(_iFBMOctaves);
  248. return TRUE;
  249. }
  250. void CDlgGenerateFBM::OnAddNegativeValues()
  251. {
  252. _bFBMAddNegativeValues=!_bFBMAddNegativeValues;
  253. UpdateData(TRUE);
  254. Invalidate(FALSE);
  255. }
  256. void CDlgGenerateFBM::OnRandomOffset()
  257. {
  258. _bFBMRandomOffset=!_bFBMRandomOffset;
  259. UpdateData(TRUE);
  260. Invalidate(FALSE);
  261. }
  262. void CDlgGenerateFBM::OnFbmExport()
  263. {
  264. CTFileName fnFBM=_EngineGUI.FileRequester(
  265. "Export FBM texture", FILTER_TEX FILTER_PCX FILTER_ALL FILTER_END,
  266. "Layer mask directory", "Textures\\");
  267. if( fnFBM=="") return;
  268. CDlgEditFloat dlg;
  269. dlg.m_fEditFloat=256.0f;
  270. dlg.m_strVarName = "Width (pixels)";
  271. dlg.m_strTitle = "Texture size";
  272. if(dlg.DoModal()!=IDOK) return;
  273. PIX pixW=dlg.m_fEditFloat;
  274. if(pixW!=1<<((INDEX)Log2( (FLOAT)pixW)))
  275. {
  276. WarningMessage("Size must be power of 2!");
  277. }
  278. else
  279. {
  280. CreateFBMTexture(pixW, pixW, fnFBM);
  281. }
  282. }