ww3d.cpp 95 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : WW3D *
  23. * *
  24. * $Archive:: /Commando/Code/ww3d2/ww3d.cpp $*
  25. * *
  26. * Author:: Greg_h *
  27. * *
  28. * $Modtime:: 2/14/02 3:00p $*
  29. * *
  30. * $Revision:: 97 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * WW3D::Init -- Initialize the WW3D Library *
  35. * WW3D::Shutdown -- shutdown the WW3D Library *
  36. * WW3D::Set_Render_Device -- set the render device being currently used *
  37. * WW3D::Set_Next_Render_Device -- just go to the next device in the list *
  38. * WW3D::Set_Device_Resolution -- set the current resolution and bitdepth *
  39. * WW3D::Get_Render_Device -- Get the index of the current render device *
  40. * WW3D::Get_Render_Device_Desc -- returns description of the current render device *
  41. * WW3D::Get_Render_Device_Count -- returns the number of render devices available *
  42. * WW3D::Get_Render_Device_Name -- returns the name of the n-th render device *
  43. * WW3D::Get_Render_Target_Resolution -- get the resolution and bitdepth of the current target*
  44. * WW3D::Get_Device_Resolution -- get the current resolution and bitdepth *
  45. * WW3D::Begin_Render -- mark the start of rendering for a new frame *
  46. * WW3D::Render -- Render a 3D Scene using the given camera *
  47. * WW3D::Render -- Render a single render object *
  48. * WW3D::End_Render -- Mark the completion of a frame *
  49. * WW3D::Sync -- Time sychronization *
  50. * WW3D::Set_Ext_Swap_Interval -- Sets the swap interval the device should aim sync for. *
  51. * WW3D::Get_Ext_Swap_Interval -- Queries the swap interval the device is aiming sync for. *
  52. * WW3D::Get_Polygon_Mode -- returns the current rendering mode *
  53. * WW3D::Set_Collision_Box_Display_Mask -- control rendering of collision boxes *
  54. * WW3D::Get_Collision_Box_Display_Mask -- returns the current display mask for collision bo *
  55. * WW3D::Normalize_Coordinates -- Convert pixel coords to normalized screen coords 0..1 *
  56. * WW3D::Update_Render_Device_Description -- updates the description of the current render d *
  57. * WW3D::Make_Screen_Shot -- saves a screenshot with the given base filename *
  58. * WW3D::Start_Movie_Capture -- begins dumping frames to a movie *
  59. * WW3D::Stop_Movie_Capture -- ends dumping frames to a movie *
  60. * WW3D::Toggle_Movie_Capture -- toggles movie capture... *
  61. * WW3D::Start_Single_Frame_Movie_Capture -- starts capturing a single frame movie *
  62. * WW3D::Capture_Next_Movie_Frame -- tells ww3d to grab another frame for the movie *
  63. * WW3D::Pause_Movie -- pauses/unpauses movie capturing *
  64. * WW3D::Is_Movie_Paused -- returns whether the movie capture system is paused *
  65. * WW3D::Is_Recording_Next_Frame -- returns whether the next frame will be dumped to a movie *
  66. * WW3D::Is_Movie_Ready -- returns whether the movie capture system is ready *
  67. * WW3D::Update_Movie_Capture -- dumps the current frame into the movie *
  68. * WW3D::Get_Movie_Capture_Frame_Rate -- returns the framerate at which the movie is being c *
  69. * WW3D::Set_Texture_Reduction -- sets the (hacky) texture reduction factor *
  70. * WW3D::Get_Texture_Reduction -- gets the (hacky) texture reduction factor *
  71. * WW3D::Flush_Texture_Cache -- dump all textures from the texture cache *
  72. * WW3D::Allocate_Debug_Resources -- allocates the debug resources *
  73. * WW3D::Release_Debug_Resources -- releases the debug resources *
  74. * WW3D::Get_Last_Frame_Poly_Count -- returns the number of polys submitted in the previous *
  75. * WW3D::Flush -- Process all pending rendering tasks *
  76. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  77. #include "ww3d.h"
  78. #include "rinfo.h"
  79. #include "assetmgr.h"
  80. #include "boxrobj.h"
  81. #include "predlod.h"
  82. #include "camera.h"
  83. #include "scene.h"
  84. #include "texfcach.h"
  85. #include "registry.h"
  86. #include "segline.h"
  87. #include "shader.h"
  88. #include "vertmaterial.h"
  89. #include "wwdebug.h"
  90. #include "wwprofile.h"
  91. #include "wwmemlog.h"
  92. #include "shattersystem.h"
  93. #include "textureloader.h"
  94. #include "statistics.h"
  95. #include "pointgr.h"
  96. #include "ffactory.h"
  97. #include "ini.h"
  98. #include "dazzle.h"
  99. #include "meshmdl.h"
  100. #include "dx8renderer.h"
  101. #include "render2d.h"
  102. #include "bound.h"
  103. #include "rddesc.h"
  104. #include "vector3i.h"
  105. #include <cstdio>
  106. #include "dx8wrapper.h"
  107. #include "targa.h"
  108. #include "sortingrenderer.h"
  109. #include "thread.h"
  110. #include "cpudetect.h"
  111. #include "dx8texman.h"
  112. #include "formconv.h"
  113. #include "animatedsoundmgr.h"
  114. #ifndef _UNIX
  115. #include "framgrab.h"
  116. #endif
  117. const char* DAZZLE_INI_FILENAME="DAZZLE.INI";
  118. #define DEFAULT_DEBUG_SHADER_BITS ( SHADE_CNST(\
  119. ShaderClass::PASS_LEQUAL,\
  120. ShaderClass::DEPTH_WRITE_ENABLE,\
  121. ShaderClass::COLOR_WRITE_ENABLE,\
  122. ShaderClass::SRCBLEND_ONE,\
  123. ShaderClass::DSTBLEND_ZERO,\
  124. ShaderClass::FOG_DISABLE,\
  125. ShaderClass::GRADIENT_MODULATE,\
  126. ShaderClass::SECONDARY_GRADIENT_DISABLE,\
  127. ShaderClass::TEXTURING_DISABLE,\
  128. ShaderClass::ALPHATEST_DISABLE,\
  129. ShaderClass::CULL_MODE_ENABLE, \
  130. ShaderClass::DETAILCOLOR_DISABLE,\
  131. ShaderClass::DETAILALPHA_DISABLE) )
  132. #define LIGHTMAP_DEBUG_SHADER_BITS ( SHADE_CNST(\
  133. ShaderClass::PASS_LEQUAL,\
  134. ShaderClass::DEPTH_WRITE_ENABLE,\
  135. ShaderClass::COLOR_WRITE_ENABLE,\
  136. ShaderClass::SRCBLEND_ONE,\
  137. ShaderClass::DSTBLEND_ZERO,\
  138. ShaderClass::FOG_DISABLE,\
  139. ShaderClass::GRADIENT_DISABLE,\
  140. ShaderClass::SECONDARY_GRADIENT_DISABLE,\
  141. ShaderClass::TEXTURING_ENABLE,\
  142. ShaderClass::ALPHATEST_DISABLE,\
  143. ShaderClass::CULL_MODE_ENABLE, \
  144. ShaderClass::DETAILCOLOR_DISABLE,\
  145. ShaderClass::DETAILALPHA_DISABLE) )
  146. /**********************************************************************************
  147. **
  148. ** WW3D Static Globals
  149. **
  150. ***********************************************************************************/
  151. unsigned int WW3D::SyncTime = 0;
  152. unsigned int WW3D::PreviousSyncTime = 0;
  153. bool WW3D::IsSortingEnabled = true;
  154. float WW3D::PixelCenterX = 0.0f;
  155. float WW3D::PixelCenterY = 0.0f;
  156. bool WW3D::IsInitted = false;
  157. bool WW3D::IsRendering = false;
  158. bool WW3D::IsCapturing = false;
  159. bool WW3D::IsScreenUVBiased = false;
  160. bool WW3D::AreDecalsEnabled = true;
  161. float WW3D::DecalRejectionDistance = 1000000.0f;
  162. bool WW3D::AreStaticSortListsEnabled = false;
  163. bool WW3D::MungeSortOnLoad = false;
  164. FrameGrabClass * WW3D::Movie = NULL;
  165. bool WW3D::PauseRecord;
  166. bool WW3D::RecordNextFrame;
  167. int WW3D::FrameCount = 0;
  168. long WW3D::UserStat0 = 0;
  169. long WW3D::UserStat1 = 0;
  170. long WW3D::UserStat2 = 0;
  171. float WW3D::DefaultNativeScreenSize = 1.0f;
  172. RefRenderObjListClass * WW3D::DefaultStaticSortLists = NULL;
  173. RefRenderObjListClass * WW3D::CurrentStaticSortLists = NULL;
  174. unsigned int WW3D::MinStaticSortLevel = 1; // The 0 list is not used
  175. unsigned int WW3D::MaxStaticSortLevel = MAX_SORT_LEVEL;
  176. VertexMaterialClass * WW3D::DefaultDebugMaterial = NULL;
  177. ShaderClass WW3D::DefaultDebugShader(DEFAULT_DEBUG_SHADER_BITS);
  178. ShaderClass WW3D::LightmapDebugShader(LIGHTMAP_DEBUG_SHADER_BITS);
  179. WW3D::PrelitModeEnum WW3D::PrelitMode = PRELIT_MODE_LIGHTMAP_MULTI_PASS;
  180. bool WW3D::ExposePrelit = false;
  181. bool WW3D::SnapshotActivated=false;
  182. bool WW3D::ThumbnailEnabled=true;
  183. WW3D::MeshDrawModeEnum WW3D::MeshDrawMode = MESH_DRAW_MODE_OLD;
  184. WW3D::NPatchesGapFillingModeEnum WW3D::NPatchesGapFillingMode = NPATCHES_GAP_FILLING_ENABLED;
  185. unsigned WW3D::NPatchesLevel=1;
  186. bool WW3D::IsTexturingEnabled=true;
  187. static HWND _Hwnd = NULL; // Not a member to hide windows from WW3D users
  188. static int _TextureReduction = 0;
  189. int WW3D::LastFrameMemoryAllocations;
  190. int WW3D::LastFrameMemoryFrees;
  191. int WW3D::TextureFilter;
  192. bool WW3D::Lite = false;
  193. /**********************************************************************************
  194. **
  195. ** WW3D Static Functions
  196. **
  197. ***********************************************************************************/
  198. void WW3D::Set_NPatches_Gap_Filling_Mode(NPatchesGapFillingModeEnum mode)
  199. {
  200. if (NPatchesGapFillingMode!=mode) {
  201. NPatchesGapFillingMode=mode;
  202. TheDX8MeshRenderer.Invalidate();
  203. }
  204. }
  205. void WW3D::Set_NPatches_Level(unsigned level)
  206. {
  207. if (level>8) level=8;
  208. if (level<1) level=1;
  209. if (NPatchesLevel==1 && level>1) TheDX8MeshRenderer.Invalidate();
  210. if (NPatchesLevel>1 && level==1) TheDX8MeshRenderer.Invalidate();
  211. NPatchesLevel = level;
  212. }
  213. /***********************************************************************************************
  214. * WW3D::Init -- Initialize the WW3D Library *
  215. * *
  216. * INPUT: *
  217. * *
  218. * OUTPUT: *
  219. * *
  220. * WARNINGS: *
  221. * *
  222. * HISTORY: *
  223. * 3/24/98 GTH : Created. *
  224. *=============================================================================================*/
  225. WW3DErrorType WW3D::Init(void *hwnd, char *defaultpal, bool lite)
  226. {
  227. assert(IsInitted == false);
  228. WWDEBUG_SAY(("WW3D::Init hwnd = %p\n",hwnd));
  229. _Hwnd = (HWND)hwnd;
  230. Lite = lite;
  231. /*
  232. ** Initialize d3d, this also enumerates the available devices and resolutions.
  233. */
  234. Init_D3D_To_WW3_Conversion();
  235. WWDEBUG_SAY(("Init DX8Wrapper\n"));
  236. if (!DX8Wrapper::Init(_Hwnd, lite)) {
  237. return(WW3D_ERROR_DIRECTX8_INITIALIZATION_FAILED);
  238. }
  239. WWDEBUG_SAY(("Allocate Debug Resources\n"));
  240. Allocate_Debug_Resources();
  241. MMRESULT r=timeBeginPeriod(1);
  242. WWASSERT(r==TIMERR_NOERROR);
  243. /*
  244. ** Initialize the dazzle system
  245. */
  246. if (!lite) {
  247. WWDEBUG_SAY(("Init Dazzles\n"));
  248. FileClass * dazzle_ini_file = _TheFileFactory->Get_File(DAZZLE_INI_FILENAME);
  249. if (dazzle_ini_file) {
  250. INIClass dazzle_ini(*dazzle_ini_file);
  251. DazzleRenderObjClass::Init_From_INI(&dazzle_ini);
  252. _TheFileFactory->Return_File(dazzle_ini_file);
  253. }
  254. }
  255. /*
  256. ** Initialize the default static sort lists
  257. ** Note that DefaultStaticSortLists[0] is unused.
  258. */
  259. DefaultStaticSortLists = new RefRenderObjListClass[MAX_SORT_LEVEL + 1];
  260. Reset_Current_Static_Sort_Lists_To_Default();
  261. /*
  262. ** Initialize the animation-triggered sound system
  263. */
  264. if (!lite) {
  265. AnimatedSoundMgrClass::Initialize ();
  266. IsInitted = true;
  267. }
  268. WWDEBUG_SAY(("WW3D Init completed\n"));
  269. return WW3D_ERROR_OK;
  270. }
  271. /***********************************************************************************************
  272. * WW3D::Shutdown -- shutdown the WW3D Library *
  273. * *
  274. * INPUT: *
  275. * *
  276. * OUTPUT: *
  277. * *
  278. * WARNINGS: *
  279. * *
  280. * HISTORY: *
  281. * 3/24/98 GTH : Created. *
  282. *=============================================================================================*/
  283. WW3DErrorType WW3D::Shutdown(void)
  284. {
  285. assert(Lite || IsInitted == true);
  286. // WWDEBUG_SAY(("WW3D::Shutdown\n"));
  287. #ifdef WW3D_DX8
  288. if (IsCapturing) {
  289. Stop_Movie_Capture();
  290. }
  291. #endif //WW3D_DX8
  292. /*
  293. ** Free memory in predictive LOD optimizer
  294. */
  295. PredictiveLODOptimizerClass::Free();
  296. /*
  297. ** Free the DazzleRenderObject class stuff. Whatever it is. ST - 6/11/2001 8:20PM
  298. */
  299. if (!Lite) {
  300. DazzleRenderObjClass::Deinit ();
  301. }
  302. /*
  303. ** Release all of our assets
  304. */
  305. Release_Debug_Resources();
  306. if (WW3DAssetManager::Get_Instance()) {
  307. WW3DAssetManager::Get_Instance()->Free_Assets();
  308. }
  309. DX8TextureManagerClass::Shutdown();
  310. if (!Lite) {
  311. DX8Wrapper::Shutdown();
  312. }
  313. /*
  314. ** Clear the default static sort lists
  315. */
  316. delete [] DefaultStaticSortLists;
  317. /*
  318. ** Release the animation-triggered sound data
  319. */
  320. AnimatedSoundMgrClass::Shutdown ();
  321. IsInitted = false;
  322. return WW3D_ERROR_OK;
  323. }
  324. /***********************************************************************************************
  325. * WW3D::Set_Render_Device -- set the render device being currently used *
  326. * *
  327. * INPUT: *
  328. * *
  329. * OUTPUT: *
  330. * *
  331. * WARNINGS: *
  332. * *
  333. * HISTORY: *
  334. * 3/24/98 GTH : Created. *
  335. *=============================================================================================*/
  336. WW3DErrorType WW3D::Set_Render_Device( const char * dev_name, int width, int height, int bits, int windowed, bool resize_window )
  337. {
  338. bool success = DX8Wrapper::Set_Render_Device(dev_name,width,height,bits,windowed,resize_window);
  339. if (success) {
  340. return WW3D_ERROR_OK;
  341. } else {
  342. return WW3D_ERROR_INITIALIZATION_FAILED;
  343. }
  344. }
  345. /***********************************************************************************************
  346. * WW3D::Set_Any_Render_Device -- set any render device you can find *
  347. * *
  348. * INPUT: *
  349. * *
  350. * OUTPUT: *
  351. * *
  352. * WARNINGS: *
  353. * *
  354. * HISTORY: *
  355. * 3/24/98 GTH : Created. *
  356. *=============================================================================================*/
  357. WW3DErrorType WW3D::Set_Any_Render_Device( void )
  358. {
  359. bool success = DX8Wrapper::Set_Any_Render_Device();
  360. if (success) {
  361. return WW3D_ERROR_OK;
  362. } else {
  363. return WW3D_ERROR_INITIALIZATION_FAILED;
  364. }
  365. }
  366. /***********************************************************************************************
  367. * WW3D::Set_Render_Device -- set the render device being currently used *
  368. * *
  369. * INPUT: *
  370. * *
  371. * OUTPUT: *
  372. * *
  373. * WARNINGS: *
  374. * *
  375. * HISTORY: *
  376. * 3/24/98 GTH : Created. *
  377. *=============================================================================================*/
  378. WW3DErrorType WW3D::Set_Render_Device(int dev, int width, int height, int bits, int windowed, bool resize_window)
  379. {
  380. bool success = DX8Wrapper::Set_Render_Device(dev,width,height,bits,windowed,resize_window);
  381. if (success) {
  382. return WW3D_ERROR_OK;
  383. } else {
  384. return WW3D_ERROR_INITIALIZATION_FAILED;
  385. }
  386. }
  387. /***********************************************************************************************
  388. * WW3D::Set_Next_Render_Device -- just go to the next device in the list *
  389. * *
  390. * INPUT: *
  391. * *
  392. * OUTPUT: *
  393. * *
  394. * WARNINGS: *
  395. * *
  396. * HISTORY: *
  397. * 3/26/98 GTH : Created. *
  398. *=============================================================================================*/
  399. WW3DErrorType WW3D::Set_Next_Render_Device(void)
  400. {
  401. bool success = DX8Wrapper::Set_Next_Render_Device();
  402. if (success) {
  403. return WW3D_ERROR_OK;
  404. } else {
  405. return WW3D_ERROR_INITIALIZATION_FAILED;
  406. }
  407. }
  408. /***********************************************************************************************
  409. * WW3D::Get_Window -- returns the handle of the render window. *
  410. * *
  411. * INPUT: *
  412. * *
  413. * OUTPUT: *
  414. * *
  415. * WARNINGS: *
  416. * *
  417. * HISTORY: *
  418. * 3/28/2001 pds : Created. *
  419. *=============================================================================================*/
  420. void *WW3D::Get_Window( void )
  421. {
  422. return _Hwnd;
  423. }
  424. /***********************************************************************************************
  425. * WW3D::Is_Windowed -- returns wether we are currently in a windowed mode *
  426. * *
  427. * INPUT: *
  428. * *
  429. * OUTPUT: *
  430. * *
  431. * WARNINGS: *
  432. * *
  433. * HISTORY: *
  434. * 1/26/2001 gth : Created. *
  435. *=============================================================================================*/
  436. bool WW3D::Is_Windowed( void )
  437. {
  438. return DX8Wrapper::Is_Windowed();
  439. }
  440. /***********************************************************************************************
  441. * WW3D::Toggle_Windowed -- Toggle the current render device between fullscreen and windowed *
  442. * mode. Note: Its called '_Windowed' to be consistent with the *
  443. * other references inside WW3D, a more descriptive name would *
  444. * be Toggle_Fullscreen. *
  445. * *
  446. * INPUT: *
  447. * *
  448. * OUTPUT: *
  449. * *
  450. * WARNINGS: *
  451. * *
  452. * HISTORY: *
  453. * 1/11/99 PDS : Created. *
  454. *=============================================================================================*/
  455. WW3DErrorType WW3D::Toggle_Windowed (void)
  456. {
  457. bool success = DX8Wrapper::Toggle_Windowed();
  458. if (success) {
  459. return WW3D_ERROR_OK;
  460. } else {
  461. return WW3D_ERROR_INITIALIZATION_FAILED;
  462. }
  463. }
  464. /***********************************************************************************************
  465. * WW3D::Get_Render_Device -- Get the index of the current render device *
  466. * *
  467. * INPUT: *
  468. * *
  469. * OUTPUT: *
  470. * *
  471. * WARNINGS: *
  472. * *
  473. * HISTORY: *
  474. * 3/24/98 GTH : Created. *
  475. * 1/25/2001 gth : converted to dx8 *
  476. *=============================================================================================*/
  477. int WW3D::Get_Render_Device(void)
  478. {
  479. return DX8Wrapper::Get_Render_Device();
  480. }
  481. /***********************************************************************************************
  482. * WW3D::Get_Render_Device_Desc -- returns description of the current render device *
  483. * *
  484. * INPUT: *
  485. * *
  486. * OUTPUT: *
  487. * *
  488. * WARNINGS: *
  489. * *
  490. * HISTORY: *
  491. * 3/26/98 GTH : Created. *
  492. * 1/25/2001 gth : converted to dx8 *
  493. *=============================================================================================*/
  494. const RenderDeviceDescClass & WW3D::Get_Render_Device_Desc(int deviceidx)
  495. {
  496. return DX8Wrapper::Get_Render_Device_Desc(deviceidx);
  497. }
  498. /***********************************************************************************************
  499. * WW3D::Get_Render_Device_Count -- returns the number of render devices available *
  500. * *
  501. * INPUT: *
  502. * *
  503. * OUTPUT: *
  504. * *
  505. * WARNINGS: *
  506. * *
  507. * HISTORY: *
  508. * 5/19/99 GTH : Created. *
  509. * 1/25/2001 gth : converted to DX8 *
  510. *=============================================================================================*/
  511. const int WW3D::Get_Render_Device_Count(void)
  512. {
  513. return DX8Wrapper::Get_Render_Device_Count();
  514. }
  515. /***********************************************************************************************
  516. * WW3D::Get_Render_Device_Name -- returns the name of the n-th render device *
  517. * *
  518. * INPUT: *
  519. * *
  520. * OUTPUT: *
  521. * *
  522. * WARNINGS: *
  523. * *
  524. * HISTORY: *
  525. * 5/19/99 GTH : Created. *
  526. * 1/25/2001 gth : converted to dx8 *
  527. *=============================================================================================*/
  528. const char * WW3D::Get_Render_Device_Name(int device_index)
  529. {
  530. return DX8Wrapper::Get_Render_Device_Name(device_index);
  531. }
  532. /***********************************************************************************************
  533. * WW3D::Set_Device_Resolution -- set the current resolution and bitdepth *
  534. * *
  535. * INPUT: *
  536. * *
  537. * OUTPUT: *
  538. * *
  539. * WARNINGS: *
  540. * *
  541. * HISTORY: *
  542. * 3/24/98 GTH : Created. *
  543. *=============================================================================================*/
  544. WW3DErrorType WW3D::Set_Device_Resolution(int width,int height,int bits,int windowed, bool resize_window)
  545. {
  546. bool success = DX8Wrapper::Set_Device_Resolution(width,height,bits,windowed,resize_window);
  547. if (success) {
  548. return WW3D_ERROR_OK;
  549. } else {
  550. return WW3D_ERROR_INITIALIZATION_FAILED;
  551. }
  552. }
  553. /***********************************************************************************************
  554. * WW3D::Get_Render_Target_Resolution -- get the resolution and bitdepth of the current target *
  555. * *
  556. * INPUT: *
  557. * *
  558. * OUTPUT: *
  559. * *
  560. * WARNINGS: *
  561. * *
  562. * HISTORY: *
  563. * 3/24/98 GTH : Created. *
  564. * 1/25/2001 gth : converted to dx8 *
  565. *=============================================================================================*/
  566. void WW3D::Get_Render_Target_Resolution(int & set_w,int & set_h,int & set_bits,bool & set_windowed)
  567. {
  568. DX8Wrapper::Get_Render_Target_Resolution(set_w,set_h,set_bits,set_windowed);
  569. }
  570. /***********************************************************************************************
  571. * WW3D::Get_Device_Resolution -- get the current resolution and bitdepth *
  572. * *
  573. * INPUT: *
  574. * *
  575. * OUTPUT: *
  576. * *
  577. * WARNINGS: *
  578. * *
  579. * HISTORY: *
  580. * 3/24/98 GTH : Created. *
  581. * 1/25/2001 gth : converted to dx8 *
  582. *=============================================================================================*/
  583. void WW3D::Get_Device_Resolution(int & set_w,int & set_h,int & set_bits,bool & set_windowed)
  584. {
  585. DX8Wrapper::Get_Device_Resolution(set_w,set_h,set_bits,set_windowed);
  586. }
  587. /***********************************************************************************************
  588. * WW3D::Registry_Save_Render_Device -- Saves settings to Registry
  589. * *
  590. * INPUT: *
  591. * *
  592. * OUTPUT: *
  593. * *
  594. * WARNINGS: *
  595. * *
  596. * HISTORY: *
  597. * 12/3/98 BMG : Created. *
  598. * 1/25/2001 gth : converted to dx8 *
  599. *=============================================================================================*/
  600. WW3DErrorType WW3D::Registry_Save_Render_Device( const char * sub_key )
  601. {
  602. bool success = DX8Wrapper::Registry_Save_Render_Device(sub_key);
  603. if (success) {
  604. return WW3D_ERROR_OK;
  605. } else {
  606. return WW3D_ERROR_INITIALIZATION_FAILED;
  607. }
  608. }
  609. /***********************************************************************************************
  610. * WW3D::Registry_Save_Render_Device -- Saves settings to Registry
  611. * *
  612. * INPUT: *
  613. * *
  614. * OUTPUT: *
  615. * *
  616. * WARNINGS: *
  617. * *
  618. * HISTORY: *
  619. * 12/3/98 BMG : Created. *
  620. *=============================================================================================*/
  621. WW3DErrorType WW3D::Registry_Save_Render_Device( const char *sub_key, int device, int width, int height, int depth, bool windowed, int texture_depth )
  622. {
  623. bool success = DX8Wrapper::Registry_Save_Render_Device(sub_key,device,width,height,depth,windowed,texture_depth);
  624. if (success) {
  625. return WW3D_ERROR_OK;
  626. } else {
  627. return WW3D_ERROR_INITIALIZATION_FAILED;
  628. }
  629. }
  630. /***********************************************************************************************
  631. * WW3D::Registry_Load_Render_Device -- Loads settings from Registry
  632. * *
  633. * INPUT: *
  634. * *
  635. * OUTPUT: *
  636. * *
  637. * WARNINGS: *
  638. * *
  639. * HISTORY: *
  640. * 12/3/98 BMG : Created. *
  641. *=============================================================================================*/
  642. WW3DErrorType WW3D::Registry_Load_Render_Device( const char * sub_key, bool resize_window )
  643. {
  644. bool success = DX8Wrapper::Registry_Load_Render_Device(sub_key,resize_window);
  645. if (success) {
  646. return WW3D_ERROR_OK;
  647. } else {
  648. return WW3D_ERROR_INITIALIZATION_FAILED;
  649. }
  650. }
  651. bool WW3D::Registry_Load_Render_Device( const char * sub_key, char *device, int device_len, int &width, int &height, int &depth, int &windowed, int &texture_depth)
  652. {
  653. return DX8Wrapper::Registry_Load_Render_Device(sub_key,device,device_len,width,height,depth,windowed,texture_depth);
  654. }
  655. void WW3D::_Invalidate_Mesh_Cache()
  656. {
  657. TheDX8MeshRenderer.Invalidate();
  658. }
  659. void WW3D::_Invalidate_Textures()
  660. {
  661. if (!WW3DAssetManager::Get_Instance()) return;
  662. TextureLoader::Flush_Pending_Load_Tasks();
  663. HashTemplateIterator<StringClass,TextureClass*> ite(WW3DAssetManager::Get_Instance()->Texture_Hash());
  664. // Loop through all the textures in the manager
  665. for (ite.First();!ite.Is_Done();ite.Next()) {
  666. // Get the current texture
  667. TextureClass* tex=ite.Peek_Value();
  668. tex->Invalidate();
  669. }
  670. }
  671. void WW3D::Set_Texture_Filter(int texture_filter)
  672. {
  673. if (texture_filter<0) texture_filter=0;
  674. if (texture_filter>TextureClass::TEXTURE_FILTER_ANISOTROPIC) texture_filter=TextureClass::TEXTURE_FILTER_ANISOTROPIC;
  675. TextureFilter=texture_filter;
  676. TextureClass::_Init_Filters((TextureClass::TextureFilterMode)TextureFilter);
  677. }
  678. /***********************************************************************************************
  679. * WW3D::Begin_Render -- mark the start of rendering for a new frame *
  680. * *
  681. * INPUT: *
  682. * *
  683. * OUTPUT: *
  684. * *
  685. * WARNINGS: *
  686. * *
  687. * HISTORY: *
  688. * 3/24/98 GTH : Created. *
  689. *=============================================================================================*/
  690. WW3DErrorType WW3D::Begin_Render(bool clear,bool clearz,const Vector3 & color, void(*network_callback)(void))
  691. {
  692. if (!IsInitted) {
  693. return(WW3D_ERROR_OK);
  694. }
  695. WWPROFILE("WW3D::Begin_Render");
  696. WWASSERT(IsInitted);
  697. // Memory allocation statistics
  698. LastFrameMemoryAllocations=WWMemoryLogClass::Get_Allocate_Count();
  699. LastFrameMemoryFrees=WWMemoryLogClass::Get_Free_Count();
  700. WWMemoryLogClass::Reset_Counters();
  701. TextureLoader::Update(network_callback);
  702. // TextureClass::_Reset_Time_Stamp();
  703. DynamicVBAccessClass::_Reset(true);
  704. DynamicIBAccessClass::_Reset(true);
  705. #ifdef WW3D_DX8
  706. TextureFileClass::Update_Texture_Flash();
  707. #endif //WW3D_DX8
  708. Debug_Statistics::Begin_Statistics();
  709. if (IsCapturing && (!PauseRecord || RecordNextFrame)) {
  710. Update_Movie_Capture();
  711. RecordNextFrame = false;
  712. }
  713. WWASSERT(!IsRendering);
  714. IsRendering = true;
  715. // If we want to clear the screen, we need to set the viewport to include the entire screen:
  716. if (clear || clearz) {
  717. D3DVIEWPORT8 vp;
  718. int width, height, bits;
  719. bool windowed;
  720. WW3D::Get_Render_Target_Resolution(width, height, bits, windowed);
  721. vp.X = 0;
  722. vp.Y = 0;
  723. vp.Width = width;
  724. vp.Height = height;
  725. vp.MinZ = 0.0f;;
  726. vp.MaxZ = 1.0f;
  727. DX8Wrapper::Set_Viewport(&vp);
  728. DX8Wrapper::Clear(clear, clearz, color);
  729. }
  730. // Notify D3D that we are beginning to render the frame
  731. DX8Wrapper::Begin_Scene();
  732. return WW3D_ERROR_OK;
  733. }
  734. /***********************************************************************************************
  735. * WW3D::Render -- Render a list of layers, starting at the back. *
  736. * *
  737. * INPUT: *
  738. * *
  739. * OUTPUT: *
  740. * *
  741. * WARNINGS: *
  742. * *
  743. * HISTORY: *
  744. * 4/2/98 EHC : Created. *
  745. *=============================================================================================*/
  746. WW3DErrorType WW3D::Render(const LayerListClass &LayerList)
  747. {
  748. if (!IsInitted) {
  749. return(WW3D_ERROR_OK);
  750. }
  751. WWASSERT(IsRendering);
  752. LayerClass *layer = LayerList.Last();
  753. while (layer->Is_Valid()) {
  754. WW3DErrorType result = Render(*layer);
  755. if (result != WW3D_ERROR_OK) {
  756. return result;
  757. }
  758. layer = layer->Prev();
  759. }
  760. return WW3D_ERROR_OK;
  761. }
  762. /***********************************************************************************************
  763. * WW3D::Render -- Render a Layer *
  764. * *
  765. * INPUT: *
  766. * *
  767. * OUTPUT: *
  768. * *
  769. * WARNINGS: *
  770. * *
  771. * HISTORY: *
  772. * 4/2/98 EHC : Created. *
  773. *=============================================================================================*/
  774. WW3DErrorType WW3D::Render(const LayerClass &Layer)
  775. {
  776. if (!IsInitted) {
  777. return(WW3D_ERROR_OK);
  778. }
  779. WWASSERT(IsRendering);
  780. return Render(Layer.Scene, Layer.Camera, Layer.Clear, Layer.ClearZ, Layer.ClearColor);
  781. }
  782. /***********************************************************************************************
  783. * WW3D::Render -- Render a 3D Scene using the given camera *
  784. * *
  785. * INPUT: *
  786. * *
  787. * OUTPUT: *
  788. * *
  789. * WARNINGS: *
  790. * *
  791. * HISTORY: *
  792. * 3/24/98 GTH : Created. *
  793. *=============================================================================================*/
  794. WW3DErrorType WW3D::Render(SceneClass * scene,CameraClass * cam,bool clear,bool clearz,const Vector3 & color)
  795. {
  796. if (!IsInitted) {
  797. return(WW3D_ERROR_OK);
  798. }
  799. WWPROFILE("WW3D::Render");
  800. WWMEMLOG(MEM_GAMEDATA);
  801. WWASSERT(IsInitted);
  802. WWASSERT(IsRendering);
  803. WWASSERT(scene);
  804. WWASSERT(cam);
  805. cam->On_Frame_Update();
  806. RenderInfoClass rinfo(*cam);
  807. // Apply the camera and viewport (including depth range)
  808. cam->Apply();
  809. // Clear the viewport
  810. if (clear || clearz) {
  811. DX8Wrapper::Clear(clear, clearz, color);
  812. }
  813. // set the rendering mode
  814. switch(scene->Get_Polygon_Mode()) {
  815. case SceneClass::POINT:
  816. DX8Wrapper::Set_DX8_Render_State(D3DRS_FILLMODE,D3DFILL_POINT);
  817. break;
  818. case SceneClass::LINE:
  819. DX8Wrapper::Set_DX8_Render_State(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
  820. break;
  821. case SceneClass::FILL:
  822. DX8Wrapper::Set_DX8_Render_State(D3DRS_FILLMODE,D3DFILL_SOLID);
  823. break;
  824. }
  825. // Set the global ambient light value here. If the scene is using the LightEnvironment system
  826. // this setting will get overriden.
  827. Vector3 ambient = scene->Get_Ambient_Light();
  828. DX8Wrapper::Set_DX8_Render_State(D3DRS_AMBIENT, DX8Wrapper::Convert_Color(ambient,0.0f));
  829. // render the scene
  830. TheDX8MeshRenderer.Set_Camera(&rinfo.Camera);
  831. scene->Render(rinfo);
  832. Flush(rinfo);
  833. return WW3D_ERROR_OK;
  834. }
  835. /***********************************************************************************************
  836. * WW3D::Render -- Render a single render object *
  837. * *
  838. * INPUT: *
  839. * *
  840. * OUTPUT: *
  841. * *
  842. * WARNINGS: *
  843. * *
  844. * HISTORY: *
  845. * 4/4/2001 gth : Created. *
  846. *=============================================================================================*/
  847. WW3DErrorType WW3D::Render(
  848. RenderObjClass & obj,
  849. RenderInfoClass & rinfo
  850. )
  851. {
  852. if (!IsInitted) {
  853. return(WW3D_ERROR_OK);
  854. }
  855. WWPROFILE("WW3D::Render");
  856. WWASSERT(IsInitted);
  857. WWASSERT(IsRendering);
  858. {
  859. WWPROFILE("On_Frame_Update");
  860. rinfo.Camera.On_Frame_Update();
  861. }
  862. // Apply the camera and viewport (including depth range)
  863. rinfo.Camera.Apply();
  864. // set the rendering mode
  865. DX8Wrapper::Set_DX8_Render_State(D3DRS_FILLMODE,D3DFILL_SOLID);
  866. // Install the lighting environment if one is supplied
  867. if (rinfo.light_environment != NULL) {
  868. DX8Wrapper::Set_Light_Environment(rinfo.light_environment);
  869. }
  870. // Render the object
  871. TheDX8MeshRenderer.Set_Camera(&rinfo.Camera);
  872. obj.Render(rinfo);
  873. Flush(rinfo);
  874. return WW3D_ERROR_OK;
  875. }
  876. /***********************************************************************************************
  877. * WW3D::Flush -- Process all pending rendering tasks *
  878. * *
  879. * NOTE: This normally happens AUTOMATICALLY. The user should almost *NEVER* have to call *
  880. * this function. Anyway, this function causes all of the deferred rendering systems to *
  881. * actually perform all of their rendering tasks. This includes the DX8MeshRenderer and *
  882. * the sorting system. *
  883. * *
  884. * INPUT: *
  885. * *
  886. * OUTPUT: *
  887. * *
  888. * WARNINGS: *
  889. * Don't call this unless you know what you're doing *
  890. * *
  891. * HISTORY: *
  892. * 4/17/2001 gth : Created. *
  893. *=============================================================================================*/
  894. void WW3D::Flush(RenderInfoClass & rinfo)
  895. {
  896. TheDX8MeshRenderer.Flush();
  897. WW3D::Render_And_Clear_Static_Sort_Lists(rinfo);
  898. SortingRendererClass::Flush();
  899. TheDX8MeshRenderer.Clear_Pending_Delete_Lists();
  900. }
  901. /***********************************************************************************************
  902. * WW3D::End_Render -- Mark the completion of a frame *
  903. * *
  904. * INPUT: *
  905. * *
  906. * OUTPUT: *
  907. * *
  908. * WARNINGS: *
  909. * *
  910. * HISTORY: *
  911. * 3/24/98 GTH : Created. *
  912. *=============================================================================================*/
  913. WW3DErrorType WW3D::End_Render(bool flip_frame)
  914. {
  915. if (!IsInitted) {
  916. return(WW3D_ERROR_OK);
  917. }
  918. WWPROFILE("WW3D::End_Render");
  919. assert(IsRendering);
  920. assert(IsInitted);
  921. // If sorting renderer flush isn't called from within any of the render functions
  922. // the sorting arrays will overflow!
  923. SortingRendererClass::Flush();
  924. IsRendering = false;
  925. {
  926. WWPROFILE("DX8Wrapper::End_Scene");
  927. DX8Wrapper::End_Scene(flip_frame);
  928. }
  929. FrameCount++;
  930. {
  931. WWPROFILE("End_Statistics");
  932. Debug_Statistics::End_Statistics();
  933. }
  934. Activate_Snapshot(false);
  935. return WW3D_ERROR_OK;
  936. }
  937. /***********************************************************************************************
  938. * WW3D::Flip_To_Primary *
  939. * *
  940. * INPUT: *
  941. * *
  942. * OUTPUT: *
  943. * *
  944. * WARNINGS: *
  945. * *
  946. * HISTORY: *
  947. * 6/20/01 DEL : Created. *
  948. *=============================================================================================*/
  949. void WW3D::Flip_To_Primary(void)
  950. {
  951. DX8Wrapper::Flip_To_Primary();
  952. }
  953. /***********************************************************************************************
  954. * WW3D::Get_Last_Frame_Poly_Count -- returns the number of polys submitted in the previous fr *
  955. * *
  956. * INPUT: *
  957. * *
  958. * OUTPUT: *
  959. * *
  960. * WARNINGS: *
  961. * *
  962. * HISTORY: *
  963. * 7/28/99 GTH : Created. *
  964. *=============================================================================================*/
  965. unsigned int WW3D::Get_Last_Frame_Poly_Count(void)
  966. {
  967. return Debug_Statistics::Get_DX8_Polygons();
  968. }
  969. unsigned int WW3D::Get_Last_Frame_Vertex_Count(void)
  970. {
  971. return Debug_Statistics::Get_DX8_Vertices();
  972. }
  973. /***********************************************************************************************
  974. * WW3D::Sync -- Time sychronization *
  975. * *
  976. * INPUT: *
  977. * *
  978. * OUTPUT: *
  979. * *
  980. * WARNINGS: *
  981. * *
  982. * HISTORY: *
  983. * 3/24/98 GTH : Created. *
  984. *=============================================================================================*/
  985. void WW3D::Sync(unsigned int sync_time)
  986. {
  987. PreviousSyncTime = SyncTime;
  988. SyncTime = sync_time;
  989. }
  990. /***********************************************************************************************
  991. * WW3D::Set_Ext_Swap_Interval -- Sets the swap interval the device should aim sync for. *
  992. * *
  993. * INPUT: *
  994. * *
  995. * OUTPUT: *
  996. * *
  997. * WARNINGS: Not supported by all rendering devices. *
  998. * *
  999. * HISTORY: *
  1000. * 5/07/98 NH : Created. *
  1001. *=============================================================================================*/
  1002. void WW3D::Set_Ext_Swap_Interval(long swap)
  1003. {
  1004. DX8Wrapper::Set_Swap_Interval(swap);
  1005. }
  1006. /***********************************************************************************************
  1007. * WW3D::Get_Ext_Swap_Interval -- Queries the swap interval the device is aiming sync for. *
  1008. * *
  1009. * INPUT: *
  1010. * *
  1011. * OUTPUT: *
  1012. * *
  1013. * WARNINGS: Not supported by all rendering devices. *
  1014. * *
  1015. * HISTORY: *
  1016. * 5/07/98 NH : Created. *
  1017. *=============================================================================================*/
  1018. long WW3D::Get_Ext_Swap_Interval(void)
  1019. {
  1020. return DX8Wrapper::Get_Swap_Interval();
  1021. }
  1022. /***********************************************************************************************
  1023. * WW3D::Set_Collision_Box_Display_Mask -- control rendering of collision boxes *
  1024. * *
  1025. * INPUT: *
  1026. * *
  1027. * OUTPUT: *
  1028. * *
  1029. * WARNINGS: *
  1030. * *
  1031. * HISTORY: *
  1032. * 3/17/99 GTH : Created. *
  1033. *=============================================================================================*/
  1034. void WW3D::Set_Collision_Box_Display_Mask(int mask)
  1035. {
  1036. BoxRenderObjClass::Set_Box_Display_Mask(mask);
  1037. }
  1038. /***********************************************************************************************
  1039. * WW3D::Get_Collision_Box_Display_Mask -- returns the current display mask for collision boxe *
  1040. * *
  1041. * INPUT: *
  1042. * *
  1043. * OUTPUT: *
  1044. * *
  1045. * WARNINGS: *
  1046. * *
  1047. * HISTORY: *
  1048. * 6/1/99 GTH : Created. *
  1049. *=============================================================================================*/
  1050. int WW3D::Get_Collision_Box_Display_Mask(void)
  1051. {
  1052. return BoxRenderObjClass::Get_Box_Display_Mask();
  1053. }
  1054. /***********************************************************************************************
  1055. * WW3D::Normalize_Coordinates -- Convert pixel coords to normalized screen coords 0..1 *
  1056. * *
  1057. * *
  1058. * *
  1059. * *
  1060. * INPUT: *
  1061. * *
  1062. * OUTPUT: *
  1063. * *
  1064. * WARNINGS: *
  1065. * *
  1066. * HISTORY: *
  1067. * 7/27/99 EHC : Created. *
  1068. *=============================================================================================*/
  1069. void WW3D::Normalize_Coordinates(int x, int y, float &fx, float &fy)
  1070. {
  1071. // clip the coordinates back into the resolution of the screen
  1072. x = Bound(x, 0, DX8Wrapper::Get_Device_Resolution_Width());
  1073. y = Bound(y, 0, DX8Wrapper::Get_Device_Resolution_Height());
  1074. // now that the coordinates are clipped convert them to their normalized values.
  1075. fx = (float)x / DX8Wrapper::Get_Device_Resolution_Width();
  1076. fy = (float)y / DX8Wrapper::Get_Device_Resolution_Height();
  1077. }
  1078. /***********************************************************************************************
  1079. * WW3D::Make_Screen_Shot -- saves a screenshot with the given base filename *
  1080. * *
  1081. * INPUT: *
  1082. * *
  1083. * OUTPUT: *
  1084. * *
  1085. * WARNINGS: *
  1086. * *
  1087. * HISTORY: *
  1088. * 5/19/99 GTH : Created. *
  1089. * 2/26/2001 hy : Updated to DX8 *
  1090. *=============================================================================================*/
  1091. void WW3D::Make_Screen_Shot( const char * filename_base )
  1092. {
  1093. WWASSERT(!IsRendering);
  1094. char filename[80];
  1095. static int frame_number = 1;
  1096. bool done = false;
  1097. while (!done) {
  1098. sprintf( filename, "%s%.2d.tga", filename_base, frame_number++);
  1099. FileClass*file=_TheFileFactory->Get_File( filename );
  1100. if ( file ) {
  1101. file->Open();
  1102. done = !file->Is_Available();
  1103. _TheFileFactory->Return_File( file );
  1104. } else {
  1105. done = true;
  1106. }
  1107. }
  1108. WWDEBUG_SAY(( "Creating Screen Shot %s\n", filename ));
  1109. // Lock front buffer and copy
  1110. IDirect3DSurface8 *fb;
  1111. fb=DX8Wrapper::_Get_DX8_Front_Buffer();
  1112. D3DSURFACE_DESC desc;
  1113. fb->GetDesc(&desc);
  1114. RECT bounds;
  1115. GetWindowRect(_Hwnd,&bounds);
  1116. D3DLOCKED_RECT lrect;
  1117. DX8_ErrorCode(fb->LockRect(&lrect,&bounds,D3DLOCK_READONLY));
  1118. unsigned int x,y,index,index2,width,height;
  1119. width=bounds.right-bounds.left;
  1120. height=bounds.bottom-bounds.top;
  1121. char *image=new char[3*width*height];
  1122. for (y=0; y<height; y++)
  1123. {
  1124. for (x=0; x<width; x++)
  1125. {
  1126. // index for image
  1127. index=3*(x+y*width);
  1128. // index for fb
  1129. index2=y*lrect.Pitch+4*x;
  1130. image[index]=*((char *) lrect.pBits + index2+2);
  1131. image[index+1]=*((char *) lrect.pBits + index2+1);
  1132. image[index+2]=*((char *) lrect.pBits + index2+0);
  1133. }
  1134. }
  1135. fb->Release();
  1136. Targa targ;
  1137. memset(&targ.Header,0,sizeof(targ.Header));
  1138. targ.Header.Width=width;
  1139. targ.Header.Height=height;
  1140. targ.Header.PixelDepth=24;
  1141. targ.Header.ImageType=TGA_TRUECOLOR;
  1142. targ.SetImage(image);
  1143. targ.YFlip();
  1144. FileClass*file=_TheWritingFileFactory->Get_File( filename );
  1145. if ( file ) {
  1146. file->Create();
  1147. file->Close();
  1148. _TheWritingFileFactory->Return_File( file );
  1149. }
  1150. targ.Save(filename,TGAF_IMAGE,false);
  1151. delete [] image;
  1152. }
  1153. /***********************************************************************************************
  1154. * WW3D::Start_Movie_Capture -- begins dumping frames to a movie *
  1155. * *
  1156. * INPUT: *
  1157. * *
  1158. * OUTPUT: *
  1159. * *
  1160. * WARNINGS: *
  1161. * *
  1162. * HISTORY: *
  1163. * 5/19/99 GTH : Created. *
  1164. * 2/26/2001 hy : updated to dx8 *
  1165. *=============================================================================================*/
  1166. void WW3D::Start_Movie_Capture( const char * filename_base, float frame_rate )
  1167. {
  1168. #ifdef _WINDOWS
  1169. if (IsCapturing) {
  1170. Stop_Movie_Capture();
  1171. }
  1172. WWASSERT( !IsCapturing);
  1173. IsCapturing = true;
  1174. RECT bounds;
  1175. GetWindowRect(_Hwnd,&bounds);
  1176. int height=bounds.bottom-bounds.top;
  1177. int width=bounds.right-bounds.left;
  1178. int depth=24;
  1179. WWASSERT( Movie == NULL);
  1180. if (frame_rate == 0.0f) {
  1181. frame_rate = 1.0f;
  1182. PauseRecord = true;
  1183. } else {
  1184. PauseRecord = false;
  1185. }
  1186. Movie = new FrameGrabClass( filename_base, FrameGrabClass::AVI, width, height, depth, frame_rate);
  1187. WWDEBUG_SAY(( "Starting Movie %s\n", filename_base ));
  1188. #endif
  1189. }
  1190. /***********************************************************************************************
  1191. * WW3D::Stop_Movie_Capture -- ends dumping frames to a movie *
  1192. * *
  1193. * INPUT: *
  1194. * *
  1195. * OUTPUT: *
  1196. * *
  1197. * WARNINGS: *
  1198. * *
  1199. * HISTORY: *
  1200. * 5/19/99 GTH : Created. *
  1201. *=============================================================================================*/
  1202. void WW3D::Stop_Movie_Capture( void )
  1203. {
  1204. #ifdef _WINDOWS
  1205. if (IsCapturing) {
  1206. IsCapturing = false;
  1207. WWDEBUG_SAY(( "Stoping Movie\n" ));
  1208. WWASSERT( Movie != NULL);
  1209. delete Movie;
  1210. Movie = NULL;
  1211. }
  1212. #endif
  1213. }
  1214. /***********************************************************************************************
  1215. * WW3D::Toggle_Movie_Capture -- toggles movie capture... *
  1216. * *
  1217. * INPUT: *
  1218. * *
  1219. * OUTPUT: *
  1220. * *
  1221. * WARNINGS: *
  1222. * *
  1223. * HISTORY: *
  1224. * 5/19/99 GTH : Created. *
  1225. *=============================================================================================*/
  1226. void WW3D::Toggle_Movie_Capture( const char * filename_base, float frame_rate )
  1227. {
  1228. if (IsCapturing) {
  1229. Stop_Movie_Capture();
  1230. } else {
  1231. Start_Movie_Capture( filename_base, frame_rate);
  1232. }
  1233. }
  1234. /***********************************************************************************************
  1235. * WW3D::Start_Single_Frame_Movie_Capture -- starts capturing a single frame movie *
  1236. * *
  1237. * INPUT: *
  1238. * *
  1239. * OUTPUT: *
  1240. * *
  1241. * WARNINGS: *
  1242. * *
  1243. * HISTORY: *
  1244. * 5/19/99 GTH : Created. *
  1245. *=============================================================================================*/
  1246. void WW3D::Start_Single_Frame_Movie_Capture(const char *filename_base)
  1247. {
  1248. Start_Movie_Capture(filename_base, 0.0f);
  1249. }
  1250. /***********************************************************************************************
  1251. * WW3D::Capture_Next_Movie_Frame -- tells ww3d to grab another frame for the movie *
  1252. * *
  1253. * INPUT: *
  1254. * *
  1255. * OUTPUT: *
  1256. * *
  1257. * WARNINGS: *
  1258. * *
  1259. * HISTORY: *
  1260. * 5/19/99 GTH : Created. *
  1261. *=============================================================================================*/
  1262. void WW3D::Capture_Next_Movie_Frame()
  1263. {
  1264. RecordNextFrame = true;
  1265. }
  1266. /***********************************************************************************************
  1267. * WW3D::Pause_Movie -- pauses/unpauses movie capturing *
  1268. * *
  1269. * INPUT: *
  1270. * *
  1271. * OUTPUT: *
  1272. * *
  1273. * WARNINGS: *
  1274. * *
  1275. * HISTORY: *
  1276. * 5/19/99 GTH : Created. *
  1277. *=============================================================================================*/
  1278. void WW3D::Pause_Movie(bool mode)
  1279. {
  1280. PauseRecord = mode;
  1281. }
  1282. /***********************************************************************************************
  1283. * WW3D::Is_Movie_Paused -- returns whether the movie capture system is paused *
  1284. * *
  1285. * INPUT: *
  1286. * *
  1287. * OUTPUT: *
  1288. * *
  1289. * WARNINGS: *
  1290. * *
  1291. * HISTORY: *
  1292. * 5/19/99 GTH : Created. *
  1293. *=============================================================================================*/
  1294. bool WW3D::Is_Movie_Paused()
  1295. {
  1296. return PauseRecord;
  1297. }
  1298. /***********************************************************************************************
  1299. * WW3D::Is_Recording_Next_Frame -- returns whether the next frame will be dumped to a movie *
  1300. * *
  1301. * INPUT: *
  1302. * *
  1303. * OUTPUT: *
  1304. * *
  1305. * WARNINGS: *
  1306. * *
  1307. * HISTORY: *
  1308. * 5/19/99 GTH : Created. *
  1309. *=============================================================================================*/
  1310. bool WW3D::Is_Recording_Next_Frame()
  1311. {
  1312. return (Movie != 0) && (!PauseRecord || RecordNextFrame);
  1313. }
  1314. /***********************************************************************************************
  1315. * WW3D::Is_Movie_Ready -- returns whether the movie capture system is ready *
  1316. * *
  1317. * INPUT: *
  1318. * *
  1319. * OUTPUT: *
  1320. * *
  1321. * WARNINGS: *
  1322. * *
  1323. * HISTORY: *
  1324. * 5/19/99 GTH : Created. *
  1325. *=============================================================================================*/
  1326. bool WW3D::Is_Movie_Ready()
  1327. {
  1328. return Movie != 0;
  1329. }
  1330. /***********************************************************************************************
  1331. * WW3D::Update_Movie_Capture -- dumps the current frame into the movie *
  1332. * *
  1333. * INPUT: *
  1334. * *
  1335. * OUTPUT: *
  1336. * *
  1337. * WARNINGS: *
  1338. * *
  1339. * HISTORY: *
  1340. * 5/19/99 GTH : Created. *
  1341. * 2/26/2001 hy : Updated to dx8 *
  1342. *=============================================================================================*/
  1343. void WW3D::Update_Movie_Capture( void )
  1344. {
  1345. #ifdef _WINDOWS
  1346. WWASSERT( IsCapturing);
  1347. WWPROFILE("WW3D::Update_Movie_Capture");
  1348. WWDEBUG_SAY(( "Updating\n"));
  1349. // Lock front buffer and copy
  1350. IDirect3DSurface8 *fb;
  1351. fb=DX8Wrapper::_Get_DX8_Front_Buffer();
  1352. D3DSURFACE_DESC desc;
  1353. fb->GetDesc(&desc);
  1354. RECT bounds;
  1355. GetWindowRect(_Hwnd,&bounds);
  1356. D3DLOCKED_RECT lrect;
  1357. DX8_ErrorCode(fb->LockRect(&lrect,&bounds,D3DLOCK_READONLY));
  1358. unsigned int x,y,index,index2,width,height;
  1359. width=bounds.right-bounds.left;
  1360. height=bounds.bottom-bounds.top;
  1361. char *image=(char *)Movie->GetBuffer();
  1362. for (y=0; y<height; y++)
  1363. {
  1364. for (x=0; x<width; x++)
  1365. {
  1366. // index for image
  1367. index=3*(x+(height-y-1)*width);
  1368. // index for fb
  1369. index2=y*lrect.Pitch+4*x;
  1370. image[index]=*((char *) lrect.pBits + index2+0);
  1371. image[index+1]=*((char *) lrect.pBits + index2+1);
  1372. image[index+2]=*((char *) lrect.pBits + index2+2);
  1373. }
  1374. }
  1375. fb->Release();
  1376. Movie->Grab(image);
  1377. #endif
  1378. }
  1379. /***********************************************************************************************
  1380. * WW3D::Get_Movie_Capture_Frame_Rate -- returns the framerate at which the movie is being cap *
  1381. * *
  1382. * INPUT: *
  1383. * *
  1384. * OUTPUT: *
  1385. * *
  1386. * WARNINGS: *
  1387. * *
  1388. * HISTORY: *
  1389. * 5/19/99 GTH : Created. *
  1390. *=============================================================================================*/
  1391. float WW3D::Get_Movie_Capture_Frame_Rate( void )
  1392. {
  1393. #ifdef _WINDOWS
  1394. if (IsCapturing) {
  1395. return Movie->GetFrameRate();
  1396. }
  1397. #endif
  1398. return 0;
  1399. }
  1400. /***********************************************************************************************
  1401. * WW3D::Set_Texture_Reduction -- sets the (hacky) texture reduction factor *
  1402. * *
  1403. * INPUT: *
  1404. * *
  1405. * OUTPUT: *
  1406. * *
  1407. * WARNINGS: *
  1408. * *
  1409. * HISTORY: *
  1410. * 5/19/99 GTH : Created. *
  1411. *=============================================================================================*/
  1412. void WW3D::Set_Texture_Reduction( int value )
  1413. {
  1414. if (_TextureReduction != value) {
  1415. _TextureReduction=value;
  1416. _Invalidate_Textures();
  1417. }
  1418. }
  1419. void WW3D::Enable_Texturing(bool b)
  1420. {
  1421. if (b==IsTexturingEnabled) return;
  1422. IsTexturingEnabled=b;
  1423. // _Invalidate_Textures();
  1424. }
  1425. /***********************************************************************************************
  1426. * WW3D::Get_Texture_Reduction -- gets the (hacky) texture reduction factor *
  1427. * *
  1428. * INPUT: *
  1429. * *
  1430. * OUTPUT: *
  1431. * *
  1432. * WARNINGS: *
  1433. * *
  1434. * HISTORY: *
  1435. * 11/25/99 TSS : Created. *
  1436. *=============================================================================================*/
  1437. int WW3D::Get_Texture_Reduction( void )
  1438. {
  1439. return _TextureReduction;
  1440. }
  1441. /***********************************************************************************************
  1442. * WW3D::Peek_Default_Debug_Material -- returns a pointer to the default debug mtl *
  1443. * *
  1444. * INPUT: *
  1445. * *
  1446. * OUTPUT: *
  1447. * *
  1448. * WARNINGS: *
  1449. * *
  1450. * HISTORY: *
  1451. * 7/21/99 GTH : Created. *
  1452. *=============================================================================================*/
  1453. VertexMaterialClass * WW3D::Peek_Default_Debug_Material(void)
  1454. {
  1455. #ifdef WWDEBUG
  1456. WWASSERT(DefaultDebugMaterial);
  1457. return DefaultDebugMaterial;
  1458. #else
  1459. return NULL;
  1460. #endif
  1461. }
  1462. /***********************************************************************************************
  1463. * WW3D::Peek_Default_Debug_Shader -- returns the default shader for debugging. *
  1464. * *
  1465. * INPUT: *
  1466. * *
  1467. * OUTPUT: *
  1468. * *
  1469. * WARNINGS: *
  1470. * *
  1471. * HISTORY: *
  1472. * 7/21/99 GTH : Created. *
  1473. *=============================================================================================*/
  1474. ShaderClass WW3D::Peek_Default_Debug_Shader(void)
  1475. {
  1476. return DefaultDebugShader;
  1477. }
  1478. /***********************************************************************************************
  1479. * WW3D::Peek_Lightmap_Debug_Shader -- returns the shader for lightmap debugging. *
  1480. * *
  1481. * INPUT: *
  1482. * *
  1483. * OUTPUT: *
  1484. * *
  1485. * WARNINGS: *
  1486. * *
  1487. * HISTORY: *
  1488. * 7/21/99 GTH : Created. *
  1489. *=============================================================================================*/
  1490. ShaderClass WW3D::Peek_Lightmap_Debug_Shader(void)
  1491. {
  1492. return LightmapDebugShader;
  1493. }
  1494. /***********************************************************************************************
  1495. * WW3D::Allocate_Debug_Resources -- allocates the debug resources *
  1496. * *
  1497. * INPUT: *
  1498. * *
  1499. * OUTPUT: *
  1500. * *
  1501. * WARNINGS: *
  1502. * *
  1503. * HISTORY: *
  1504. * 7/21/99 GTH : Created. *
  1505. *=============================================================================================*/
  1506. void WW3D::Allocate_Debug_Resources(void)
  1507. {
  1508. #ifdef WWDEBUG
  1509. WWASSERT(DefaultDebugMaterial == NULL);
  1510. DefaultDebugMaterial = new VertexMaterialClass;
  1511. DefaultDebugMaterial->Set_Shininess(0.0f);
  1512. DefaultDebugMaterial->Set_Opacity(1.0f);
  1513. DefaultDebugMaterial->Set_Ambient(0,0,0);
  1514. DefaultDebugMaterial->Set_Diffuse(0,0,0);
  1515. DefaultDebugMaterial->Set_Specular(0,0,0);
  1516. DefaultDebugMaterial->Set_Emissive(0,0,0);
  1517. #endif
  1518. }
  1519. /***********************************************************************************************
  1520. * WW3D::Release_Debug_Resources -- releases the debug resources *
  1521. * *
  1522. * INPUT: *
  1523. * *
  1524. * OUTPUT: *
  1525. * *
  1526. * WARNINGS: *
  1527. * *
  1528. * HISTORY: *
  1529. * 7/21/99 GTH : Created. *
  1530. *=============================================================================================*/
  1531. void WW3D::Release_Debug_Resources(void)
  1532. {
  1533. #ifdef WWDEBUG
  1534. WWASSERT(DefaultDebugMaterial);
  1535. REF_PTR_RELEASE(DefaultDebugMaterial);
  1536. #endif
  1537. }
  1538. WW3DErrorType WW3D::On_Deactivate_App(void)
  1539. {
  1540. #ifdef WW3D_DX8
  1541. assert(!IsRendering);
  1542. if ( Gerd == NULL )
  1543. return WW3D_ERROR_OK;
  1544. if ( IsWindowed )
  1545. return WW3D_ERROR_OK;
  1546. if ( !Gerd->isWindowOpen() )
  1547. return WW3D_ERROR_OK;
  1548. Gerd->closeWindow();
  1549. #endif //WW3D_DX8
  1550. return WW3D_ERROR_OK;
  1551. }
  1552. WW3DErrorType WW3D::On_Activate_App(void)
  1553. {
  1554. #ifdef WW3D_DX8
  1555. if ( Gerd == NULL)
  1556. return WW3D_ERROR_OK;
  1557. if ( IsWindowed )
  1558. return WW3D_ERROR_OK;
  1559. assert( !Gerd->isWindowOpen() );
  1560. srGERD::DisplayMode disp_mode;
  1561. disp_mode = Gerd->getDisplayMode(ResolutionWidth,ResolutionHeight,BitDepth);
  1562. if (Gerd->openWindow(disp_mode) != srGERD::ERROR_NONE) {
  1563. return WW3D_ERROR_WINDOW_NOT_OPEN;
  1564. }
  1565. #endif //WW3D_DX8
  1566. return WW3D_ERROR_OK;
  1567. }
  1568. void WW3D::Get_Pixel_Center(float &x, float &y)
  1569. {
  1570. x = PixelCenterX; y = PixelCenterY;
  1571. }
  1572. void WW3D::Update_Pixel_Center(void)
  1573. {
  1574. #ifdef WW3D_DX8
  1575. const char *name = _RenderDeviceShortNameTable.getString(CurRenderDevice);
  1576. if ( strstr(name, "OpenGL") ) {
  1577. PixelCenterX = 0.0f; PixelCenterY = 0.0f;
  1578. } else if ( strstr(name, "Glide") ) {
  1579. PixelCenterX = 0.0f; PixelCenterY = 0.0f;
  1580. } else if ( strstr(name, "DirectX") ) {
  1581. PixelCenterX = 0.5f; PixelCenterY = 0.5f;
  1582. } else if ( strstr(name, "Software") ) {
  1583. PixelCenterX = 0.0f; PixelCenterY = 0.0f;
  1584. } else if ( strstr(name, "Null") ) {
  1585. PixelCenterX = 0.0f; PixelCenterY = 0.0f;
  1586. } else {
  1587. // unknown device
  1588. PixelCenterX = 0.0f; PixelCenterY = 0.0f;
  1589. }
  1590. #endif //WW3D_DX8
  1591. }
  1592. void WW3D::Set_Texture_Bitdepth(int bitdepth)
  1593. {
  1594. DX8Wrapper::Set_Texture_Bitdepth(bitdepth);
  1595. }
  1596. int WW3D::Get_Texture_Bitdepth()
  1597. {
  1598. return DX8Wrapper::Get_Texture_Bitdepth();
  1599. }
  1600. void WW3D::Add_To_Static_Sort_List(RenderObjClass *robj, unsigned int sort_level)
  1601. {
  1602. if(sort_level < 1 || sort_level > MAX_SORT_LEVEL) {
  1603. WWASSERT(0);
  1604. return;
  1605. }
  1606. CurrentStaticSortLists[sort_level].Add_Tail(robj, false);
  1607. }
  1608. void WW3D::Render_And_Clear_Static_Sort_Lists(RenderInfoClass & rinfo)
  1609. {
  1610. // The ststic sort lists need to be disabled while we are rendering from them otherwise the
  1611. // Render() function will just dump the objects right back on the same lists.
  1612. bool old_enable = AreStaticSortListsEnabled;
  1613. AreStaticSortListsEnabled = false;
  1614. // We go from higher sort level to lower, since lower sort level means higher priority (in
  1615. // front), so lower sort level meshes need to be rendered later.
  1616. for(unsigned int sort_level = MaxStaticSortLevel; sort_level >= MinStaticSortLevel; sort_level--)
  1617. {
  1618. bool render=false;
  1619. for ( RenderObjClass *robj = CurrentStaticSortLists[sort_level].Remove_Head(); robj;
  1620. robj->Release_Ref(), robj = CurrentStaticSortLists[sort_level].Remove_Head())
  1621. {
  1622. robj->Render(rinfo);
  1623. render=true;
  1624. }
  1625. if (render) TheDX8MeshRenderer.Flush();
  1626. }
  1627. AreStaticSortListsEnabled = old_enable;
  1628. }
  1629. void WW3D::Enable_Sorting(bool onoff)
  1630. {
  1631. IsSortingEnabled = onoff;
  1632. // Have to invalidate mesh rendering system because
  1633. // meshes are put into different fvfs depending on their sort state
  1634. TheDX8MeshRenderer.Invalidate();
  1635. }
  1636. void WW3D::Override_Current_Static_Sort_Lists(RefRenderObjListClass *sort_list, unsigned int min_sort, unsigned int max_sort)
  1637. {
  1638. CurrentStaticSortLists = sort_list;
  1639. if (min_sort <= max_sort) {
  1640. MinStaticSortLevel = min_sort;
  1641. MaxStaticSortLevel = max_sort;
  1642. } else {
  1643. WWASSERT(0);
  1644. MinStaticSortLevel = max_sort;
  1645. MaxStaticSortLevel = min_sort;
  1646. }
  1647. }
  1648. void WW3D::Reset_Current_Static_Sort_Lists_To_Default(void)
  1649. {
  1650. CurrentStaticSortLists = DefaultStaticSortLists;
  1651. MinStaticSortLevel = 1; // The 0 list is not used
  1652. MaxStaticSortLevel = MAX_SORT_LEVEL;
  1653. }