ww3d.cpp 96 KB

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