DlgTerrainProperties.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  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. // DlgTerrainProperties.cpp : implementation file
  13. //
  14. #include "stdafx.h"
  15. #include "WorldEditor.h"
  16. #include "DlgTerrainProperties.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. static INDEX _iShadowMapShift=0;
  24. static INDEX _iShadingMapShift=1;
  25. static PIX _pixGlobalPretenderTextureWidth=64;
  26. /////////////////////////////////////////////////////////////////////////////
  27. // CDlgTerrainProperties dialog
  28. CDlgTerrainProperties::CDlgTerrainProperties(CWnd* pParent /*=NULL*/)
  29. : CDialog(CDlgTerrainProperties::IDD, pParent)
  30. {
  31. //{{AFX_DATA_INIT(CDlgTerrainProperties)
  32. m_strHeightmapSize = _T("");
  33. m_strShadowMapSize = _T("");
  34. m_strTerrainPretender = _T("");
  35. m_strTilePretender = _T("");
  36. m_fTerrainLength = 0.0f;
  37. m_fTerrainHeight = 0.0f;
  38. m_fTerrainWidth = 0.0f;
  39. m_fLODSwitch = 0.0f;
  40. m_strShadingMapSize = _T("");
  41. m_strMemoryConsumption = _T("");
  42. m_strLayerMemory = _T("");
  43. m_strEdgeMap = _T("");
  44. //}}AFX_DATA_INIT
  45. CTerrain *ptrTerrain=GetTerrain();
  46. if(ptrTerrain==NULL) return;
  47. _iShadowMapShift=ptrTerrain->tr_iShadowMapSizeAspect;
  48. _iShadingMapShift=ptrTerrain->tr_iShadingMapSizeAspect;
  49. _pixGlobalPretenderTextureWidth=ptrTerrain->tr_pixTopMapWidth;
  50. }
  51. void CDlgTerrainProperties::DoDataExchange(CDataExchange* pDX)
  52. {
  53. CTString strTemp;
  54. CTerrain *ptrTerrain=GetTerrain();
  55. if(ptrTerrain==NULL) return;
  56. // if dialog is recieving data
  57. if( pDX->m_bSaveAndValidate == FALSE && IsWindow(m_ctrlShadowMapSlider))
  58. {
  59. m_fTerrainWidth =ptrTerrain->tr_vTerrainSize(1);
  60. m_fTerrainHeight=ptrTerrain->tr_vTerrainSize(2);
  61. m_fTerrainLength=ptrTerrain->tr_vTerrainSize(3);
  62. INDEX iItemW=m_ctrlHeightMapWidth.GetCurSel();
  63. PIX pixW=m_ctrlHeightMapWidth.GetItemData( iItemW);
  64. INDEX iItemH=m_ctrlHeightMapHeight.GetCurSel();
  65. PIX pixH=m_ctrlHeightMapHeight.GetItemData( iItemH);
  66. INDEX iMemHeightMap=pixW*pixH*sizeof(UWORD)/1024;
  67. strTemp.PrintF("Height map size: %d x %d, Memory: %d KB", pixW, pixH, iMemHeightMap);
  68. m_strHeightmapSize=strTemp;
  69. PrepareGlobalPretenderCombo();
  70. INDEX iShadowMapShift=m_ctrlShadowMapSlider.GetPos();
  71. PIX pixSwW=Clamp(PIX((pixW-1)*pow(2.0f,iShadowMapShift)),PIX(4),PIX(2048));
  72. PIX pixSwH=Clamp(PIX((pixH-1)*pow(2.0f,iShadowMapShift)),PIX(4),PIX(2048));
  73. INDEX iMemShadowMap=pixSwW*pixSwH*sizeof(COLOR)/1024*1.333f;
  74. strTemp.PrintF("Size: %d x %d, Memory: %d KB", pixSwW, pixSwH, iMemShadowMap);
  75. m_strShadowMapSize=strTemp;
  76. INDEX iShadingMapShift=10-m_ctrlShadingMapSlider.GetPos();
  77. PIX pixSdW=Clamp(PIX(pixSwW*pow(2.0f,-iShadingMapShift)),PIX(4),PIX(pixSwW));
  78. PIX pixSdH=Clamp(PIX(pixSwH*pow(2.0f,-iShadingMapShift)),PIX(4),PIX(pixSwH));
  79. INDEX iMemShadingMap=pixSdW*pixSdW*sizeof(UWORD)/1024;
  80. strTemp.PrintF("Size: %d x %d, Memory: %d KB", pixSdW, pixSdH, iMemShadingMap);
  81. m_strShadingMapSize=strTemp;
  82. INDEX iGlobalPretender=m_ctrlGlobalPretenderTexture.GetCurSel();
  83. INDEX pixSize=m_ctrlGlobalPretenderTexture.GetItemData(iGlobalPretender);
  84. INDEX iMemTerrainPretender=pixSize*pixSize*sizeof(UWORD)/1024*1.333f;
  85. strTemp.PrintF("Size: %d x %d, Memory: %d KB", pixSize, pixSize, iMemTerrainPretender);
  86. m_strTerrainPretender=strTemp;
  87. INDEX iTlp=m_ctrlTilePretender.GetCurSel();
  88. PIX pixTlpW=m_ctrlTilePretender.GetItemData( iTlp);
  89. INDEX iMemTilePretender=pixTlpW*pixTlpW*sizeof(UWORD)/1024*1.333f;
  90. strTemp.PrintF("Tile pretender texture (%d KB)", iMemTilePretender);
  91. m_strTilePretender=strTemp;
  92. INDEX ctLayers=ptrTerrain->tr_atlLayers.Count();
  93. INDEX iMemLayers=(pixW*pixH*ctLayers)/1024;
  94. strTemp.PrintF("Layer memory consumption (%d layers): %d KB", ctLayers, iMemLayers);
  95. m_strLayerMemory=strTemp;
  96. INDEX iMemEdgeMap=(pixW*pixH)/1024;
  97. strTemp.PrintF("Edge map memory consumption: %d KB", iMemEdgeMap);
  98. m_strEdgeMap=strTemp;
  99. strTemp.PrintF("Terrain total uncompressed static data memory consumption (without tile pretender textures and geometry): %d KB",
  100. iMemHeightMap+iMemShadowMap+iMemShadingMap+iMemTerrainPretender+iMemLayers+iMemEdgeMap);
  101. m_strMemoryConsumption=strTemp;
  102. m_fLODSwitch=ptrTerrain->tr_fDistFactor;
  103. }
  104. CDialog::DoDataExchange(pDX);
  105. //{{AFX_DATA_MAP(CDlgTerrainProperties)
  106. DDX_Control(pDX, IDC_GLOBAL_PRETENDER, m_ctrlGlobalPretenderTexture);
  107. DDX_Control(pDX, IDC_TILE_PRETENDER, m_ctrlTilePretender);
  108. DDX_Control(pDX, IDC_SHADING_MAP, m_ctrlShadingMapSlider);
  109. DDX_Control(pDX, IDC_TERRAIN_QUADS_PER_TILE, m_ctrlQuadsPerTile);
  110. DDX_Control(pDX, IDC_TERRAIN_HM_WIDTH, m_ctrlHeightMapWidth);
  111. DDX_Control(pDX, IDC_TERRAIN_HM_HEIGHT, m_ctrlHeightMapHeight);
  112. DDX_Control(pDX, IDC_SHADOW_MAP, m_ctrlShadowMapSlider);
  113. DDX_Text(pDX, IDC_HEIGHTIMAP_SIZE_T, m_strHeightmapSize);
  114. DDX_Text(pDX, IDC_SHADOW_MAP_T, m_strShadowMapSize);
  115. DDX_Text(pDX, IDC_TERRAIN_PRETENDER_T, m_strTerrainPretender);
  116. DDX_Text(pDX, IDC_TILE_PRETENDER_T, m_strTilePretender);
  117. DDX_Text(pDX, IDC_TERRAIN_LENGTH, m_fTerrainLength);
  118. DDV_MinMaxFloat(pDX, m_fTerrainLength, 0.f, 1.e+007f);
  119. DDX_Text(pDX, IDC_TERRAIN_HEIGHT, m_fTerrainHeight);
  120. DDV_MinMaxFloat(pDX, m_fTerrainHeight, 0.f, 1.e+007f);
  121. DDX_Text(pDX, IDC_TERRAIN_WIDTH, m_fTerrainWidth);
  122. DDV_MinMaxFloat(pDX, m_fTerrainWidth, 0.f, 1.e+007f);
  123. DDX_Text(pDX, IDC_TERRAIN_LOD_SWITCH, m_fLODSwitch);
  124. DDV_MinMaxFloat(pDX, m_fLODSwitch, 0.f, 1.e+007f);
  125. DDX_Text(pDX, IDC_SHADING_MAP_T, m_strShadingMapSize);
  126. DDX_Text(pDX, IDC_TERRAIN_MEMORY_T, m_strMemoryConsumption);
  127. DDX_Text(pDX, IDC_LAYER_MEMORY_T, m_strLayerMemory);
  128. DDX_Text(pDX, IDC_TERRAIN_EDGE_MEMORY_T, m_strEdgeMap);
  129. //}}AFX_DATA_MAP
  130. // if dialog is giving data
  131. if( pDX->m_bSaveAndValidate != FALSE)
  132. {
  133. BOOL bUpdateTerrain=FALSE;
  134. // handle heightmap size change
  135. INDEX iItemW=m_ctrlHeightMapWidth.GetCurSel();
  136. PIX pixW=m_ctrlHeightMapWidth.GetItemData( iItemW);
  137. INDEX iItemH=m_ctrlHeightMapHeight.GetCurSel();
  138. PIX pixH=m_ctrlHeightMapHeight.GetItemData( iItemH);
  139. if( ptrTerrain->tr_pixHeightMapWidth != pixW ||
  140. ptrTerrain->tr_pixHeightMapHeight!= pixH )
  141. {
  142. ptrTerrain->ReAllocateHeightMap(pixW, pixH);
  143. bUpdateTerrain=TRUE;
  144. }
  145. // handle terrain size change
  146. if( ptrTerrain->tr_vTerrainSize(1)!=m_fTerrainWidth ||
  147. ptrTerrain->tr_vTerrainSize(2)!=m_fTerrainHeight||
  148. ptrTerrain->tr_vTerrainSize(3)!=m_fTerrainLength)
  149. {
  150. ptrTerrain->SetTerrainSize(FLOAT3D(m_fTerrainWidth,m_fTerrainHeight,m_fTerrainLength));
  151. bUpdateTerrain=TRUE;
  152. }
  153. // handle tile pretender texture size change
  154. INDEX iTlp=m_ctrlTilePretender.GetCurSel();
  155. PIX pixTlpW=m_ctrlTilePretender.GetItemData( iTlp);
  156. if( ptrTerrain->tr_pixFirstMipTopMapWidth != pixTlpW)
  157. {
  158. ptrTerrain->SetTileTopMapSize(pixTlpW);
  159. bUpdateTerrain=TRUE;
  160. }
  161. // handle quads per tile change
  162. INDEX iQuadItem=m_ctrlQuadsPerTile.GetCurSel();
  163. INDEX ctQuads=m_ctrlQuadsPerTile.GetItemData( iQuadItem);
  164. if(ctQuads!=ptrTerrain->tr_ctQuadsInTileRow)
  165. {
  166. ptrTerrain->SetQuadsPerTileRow(ctQuads);
  167. bUpdateTerrain=TRUE;
  168. }
  169. // handle LOD distance change
  170. if( m_fLODSwitch!=ptrTerrain->tr_fDistFactor)
  171. {
  172. ptrTerrain->SetLodDistanceFactor(m_fLODSwitch);
  173. }
  174. // handle global pretender texture change
  175. INDEX iGlobalPretender=m_ctrlGlobalPretenderTexture.GetCurSel();
  176. INDEX pixSize=m_ctrlGlobalPretenderTexture.GetItemData(iGlobalPretender);
  177. if(pixSize!=ptrTerrain->tr_pixTopMapWidth)
  178. {
  179. ptrTerrain->SetGlobalTopMapSize(pixSize);
  180. bUpdateTerrain=TRUE;
  181. }
  182. // handle shadow changes
  183. if( (m_ctrlShadowMapSlider.GetPos()!=_iShadowMapShift) ||
  184. (m_ctrlShadingMapSlider.GetPos()!=10-_iShadingMapShift) )
  185. {
  186. _iShadowMapShift=m_ctrlShadowMapSlider.GetPos();
  187. _iShadingMapShift=10-m_ctrlShadingMapSlider.GetPos();
  188. ptrTerrain->SetShadowMapsSize(_iShadowMapShift,_iShadingMapShift);
  189. bUpdateTerrain=TRUE;
  190. }
  191. // update terrain
  192. if(bUpdateTerrain)
  193. {
  194. ptrTerrain->tr_penEntity->TerrainChangeNotify();
  195. GenerateLayerDistribution(-1);
  196. ptrTerrain->RefreshTerrain();
  197. ptrTerrain->UpdateShadowMap();
  198. theApp.m_ctTerrainPage.MarkChanged();
  199. }
  200. }
  201. }
  202. BEGIN_MESSAGE_MAP(CDlgTerrainProperties, CDialog)
  203. //{{AFX_MSG_MAP(CDlgTerrainProperties)
  204. ON_WM_HSCROLL()
  205. ON_CBN_SELCHANGE(IDC_TERRAIN_HM_WIDTH, OnSelchangeTerrainHmWidth)
  206. ON_CBN_SELCHANGE(IDC_TERRAIN_HM_HEIGHT, OnSelchangeTerrainHmHeight)
  207. ON_CBN_SELCHANGE(IDC_TILE_PRETENDER, OnSelchangeTilePretender)
  208. ON_CBN_SELCHANGE(IDC_GLOBAL_PRETENDER, OnSelchangeGlobalPretender)
  209. //}}AFX_MSG_MAP
  210. END_MESSAGE_MAP()
  211. /////////////////////////////////////////////////////////////////////////////
  212. // CDlgTerrainProperties message handlers
  213. void CDlgTerrainProperties::InitComboBoxes(void)
  214. {
  215. INDEX iToSelect, iWidth;
  216. CTerrain *ptrTerrain=GetTerrain();
  217. if(ptrTerrain==NULL) return;
  218. // prepare quads per tile combo box
  219. m_ctrlQuadsPerTile.ResetContent();
  220. iToSelect=3;
  221. for(INDEX iQuads=4; iQuads<=2048; iQuads*=2)
  222. {
  223. CTString strItem;
  224. strItem.PrintF("%d x %d", iQuads, iQuads);
  225. INDEX iAddedAs=m_ctrlQuadsPerTile.AddString(CString(strItem));
  226. m_ctrlQuadsPerTile.SetItemData(iAddedAs,iQuads);
  227. if(ptrTerrain->tr_ctQuadsInTileRow==iQuads)
  228. {
  229. iToSelect=iAddedAs;
  230. }
  231. }
  232. m_ctrlQuadsPerTile.SetCurSel(iToSelect);
  233. // prepare heightmap size combo boxes
  234. m_ctrlHeightMapWidth.ResetContent();
  235. m_ctrlHeightMapHeight.ResetContent();
  236. INDEX iToSelectW=3;
  237. INDEX iToSelectH=3;
  238. for(iWidth=32; iWidth<=2048; iWidth*=2)
  239. {
  240. CTString strItem;
  241. strItem.PrintF("%d", iWidth+1);
  242. // width
  243. INDEX iW=m_ctrlHeightMapWidth.AddString(CString(strItem));
  244. m_ctrlHeightMapWidth.SetItemData(iW,iWidth+1);
  245. if(ptrTerrain->tr_pixHeightMapWidth==iWidth+1) iToSelectW=iW;
  246. // height
  247. INDEX iH=m_ctrlHeightMapHeight.AddString(CString(strItem));
  248. m_ctrlHeightMapHeight.SetItemData(iH,iWidth+1);
  249. if(ptrTerrain->tr_pixHeightMapHeight==iWidth+1) iToSelectH=iH;
  250. }
  251. m_ctrlHeightMapWidth.SetCurSel( iToSelectW);
  252. m_ctrlHeightMapHeight.SetCurSel(iToSelectH);
  253. PrepareTilePretenderCombo();
  254. PrepareGlobalPretenderCombo();
  255. }
  256. // prepare tile pretender combo boxes
  257. void CDlgTerrainProperties::PrepareTilePretenderCombo(void)
  258. {
  259. CTerrain *ptrTerrain=GetTerrain();
  260. if(ptrTerrain==NULL) return;
  261. m_ctrlTilePretender.ResetContent();
  262. INDEX iToSelect=6;
  263. for(INDEX iWidth=4; iWidth<=2048; iWidth*=2)
  264. {
  265. CTString strItem;
  266. strItem.PrintF("%d x %d", iWidth, iWidth);
  267. INDEX iAddedAs=m_ctrlTilePretender.AddString(CString(strItem));
  268. m_ctrlTilePretender.SetItemData(iAddedAs, iWidth);
  269. if(ptrTerrain->tr_pixFirstMipTopMapWidth==iWidth)
  270. {
  271. iToSelect=iAddedAs;
  272. }
  273. }
  274. m_ctrlTilePretender.SetCurSel(iToSelect);
  275. }
  276. // prepare tile pretender combo boxes
  277. void CDlgTerrainProperties::PrepareGlobalPretenderCombo(void)
  278. {
  279. CTerrain *ptrTerrain=GetTerrain();
  280. if(ptrTerrain==NULL) return;
  281. INDEX iHeightMapWidthItem=m_ctrlHeightMapWidth.GetCurSel();
  282. PIX pixHeightMapWidth=m_ctrlHeightMapWidth.GetItemData(iHeightMapWidthItem);
  283. INDEX iHeightMapHeightItem=m_ctrlHeightMapHeight.GetCurSel();
  284. PIX pixHeightMapHeight=m_ctrlHeightMapHeight.GetItemData(iHeightMapHeightItem);
  285. m_ctrlGlobalPretenderTexture.ResetContent();
  286. INDEX iToSelect=_pixGlobalPretenderTextureWidth;
  287. FLOAT fAspect=FLOAT(pixHeightMapWidth-1)/(pixHeightMapHeight-1);
  288. for(INDEX iWidth=4; iWidth<=2048; iWidth*=2)
  289. {
  290. CTString strItem;
  291. strItem.PrintF("%d x %d", iWidth, INDEX(iWidth/fAspect));
  292. INDEX iAddedAs=m_ctrlGlobalPretenderTexture.AddString(CString(strItem));
  293. m_ctrlGlobalPretenderTexture.SetItemData(iAddedAs, iWidth);
  294. if(_pixGlobalPretenderTextureWidth==iWidth)
  295. {
  296. iToSelect=iAddedAs;
  297. }
  298. }
  299. m_ctrlGlobalPretenderTexture.SetCurSel(iToSelect);
  300. }
  301. BOOL CDlgTerrainProperties::OnInitDialog()
  302. {
  303. CDialog::OnInitDialog();
  304. // initialize combo boxes
  305. InitComboBoxes();
  306. m_ctrlShadowMapSlider.SetRange(-10, 10, TRUE);
  307. m_ctrlShadingMapSlider.SetRange(0, 10, TRUE);
  308. m_ctrlShadowMapSlider.SetPos(_iShadowMapShift);
  309. m_ctrlShadowMapSlider.Invalidate(FALSE);
  310. m_ctrlShadingMapSlider.SetPos(10-_iShadingMapShift);
  311. m_ctrlShadingMapSlider.Invalidate(FALSE);
  312. UpdateData(FALSE);
  313. return TRUE;
  314. }
  315. BOOL _bUpdateDlg=TRUE;
  316. void CDlgTerrainProperties::OnSelchangeTerrainHmWidth()
  317. {
  318. if(_bUpdateDlg)
  319. {
  320. _bUpdateDlg=FALSE;
  321. m_ctrlHeightMapHeight.SetCurSel(m_ctrlHeightMapWidth.GetCurSel());
  322. PrepareGlobalPretenderCombo();
  323. UpdateData(FALSE);
  324. _bUpdateDlg=TRUE;
  325. }
  326. }
  327. void CDlgTerrainProperties::OnSelchangeTerrainHmHeight()
  328. {
  329. if(_bUpdateDlg)
  330. {
  331. _bUpdateDlg=FALSE;
  332. m_ctrlHeightMapWidth.SetCurSel(m_ctrlHeightMapHeight.GetCurSel());
  333. PrepareGlobalPretenderCombo();
  334. UpdateData(FALSE);
  335. _bUpdateDlg=TRUE;
  336. }
  337. }
  338. void CDlgTerrainProperties::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  339. {
  340. UpdateData( FALSE);
  341. }
  342. void CDlgTerrainProperties::OnOK()
  343. {
  344. CDialog::OnOK();
  345. }
  346. void CDlgTerrainProperties::OnSelchangeTilePretender()
  347. {
  348. UpdateData( FALSE);
  349. }
  350. void CDlgTerrainProperties::OnSelchangeGlobalPretender()
  351. {
  352. INDEX iItem=m_ctrlGlobalPretenderTexture.GetCurSel();
  353. PIX pixValue=m_ctrlGlobalPretenderTexture.GetItemData(iItem);
  354. _pixGlobalPretenderTextureWidth=pixValue;
  355. }