texproject.cpp 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337
  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:: /Commando/Code/ww3d2/texproject.cpp $*
  25. * *
  26. * Original Author:: Greg Hjelstrom *
  27. * *
  28. * $Author:: Jani_p $*
  29. * *
  30. * $Modtime:: 7/23/01 5:31p $*
  31. * *
  32. * $Revision:: 15 $*
  33. * *
  34. *---------------------------------------------------------------------------------------------*
  35. * Functions: *
  36. * TexProjectClass::TexProjectClass -- Constructor *
  37. * TexProjectClass::~TexProjectClass -- Destructor *
  38. * TexProjectClass::Set_Texture_Size -- Set the size of texture to use *
  39. * TexProjectClass::Get_Texture_Size -- Returns the stored texture size *
  40. * TexProjectClass::Set_Flag -- Turn specified flag on or off *
  41. * TexProjectClass::Get_Flag -- Get the current state of specified flag *
  42. * TexProjectClass::Set_Intensity -- Set the intensity of this projector *
  43. * TexProjectClass::Get_Intensity -- returns the current "desired" intensity *
  44. * TexProjectClass::Set_Attenuation -- Set the attenuation factor *
  45. * TexProjectClass::Get_Attenuation -- Returns the attenuation value *
  46. * TexProjectClass::Enable_Attenuation -- Set the state of the ATTENUATE flag *
  47. * TexProjectClass::Is_Attenuation_Enabled -- Get the state of the ATTENUATE flag *
  48. * TexProjectClass::Is_Depth_Gradient_Enabled -- returns whether the depth gradient is enabl *
  49. * TexProjectClass::Enable_Depth_Gradient -- enable/disable depth gradient *
  50. * TexProjectClass::Init_Multiplicative -- Initialize this to be a multiplicative texture pr *
  51. * TexProjectClass::Is_Intensity_Zero -- check if we can eliminate this projector *
  52. * TexProjectClass::Init_Additive -- Set up the projector to be additive *
  53. * TexProjectClass::Set_Perspective_Projection -- Set up a perspective projection *
  54. * TexProjectClass::Set_Ortho_Projection -- Set up an orthographic projection *
  55. * TexProjectClass::Set_Texture -- Set the texture to be projected *
  56. * TexProjectClass::Get_Texture -- Returns the texture being projected *
  57. * TexProjectClass::Peek_Texture -- Returns the texture being projected *
  58. * TexProjectClass::Peek_Material_Pass -- Returns the material pass object *
  59. * TexProjectClass::Compute_Perspective_Projection -- Set up a perspective projection of an *
  60. * TexProjectClass::Compute_Perspective_Projection -- Set up a perspective projection of an *
  61. * TexProjectClass::Compute_Ortho_Projection -- Automatic Orthographic projection *
  62. * TexProjectClass::Compute_Ortho_Projection -- Automatic Orthographic projection *
  63. * TexProjectClass::Compute_Texture -- Generates texture by rendering an object *
  64. * TexProjectClass::Configure_Camera -- setup a camera to match this projector *
  65. * TexProjectClass::Pre_Render_Update -- Prepare the projector for rendering *
  66. * TexProjectClass::Update_WS_Bounding_Volume -- Recalculate the world-space bounding box *
  67. * TexProjectClass::Get_Surface -- Returns pointer to the texture surface *
  68. * TexProjectClass::Set_Render_Target -- Install a render target for this projector to use *
  69. * TexProjectClass::Needs_Render_Target -- returns wheter this projector needs a render targ *
  70. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  71. #include "texproject.h"
  72. #include "vertmaterial.h"
  73. #include "shader.h"
  74. #include "texture.h"
  75. #include "rendobj.h"
  76. #include "rinfo.h"
  77. #include "camera.h"
  78. #include "matpass.h"
  79. #include "bwrender.h"
  80. #include "assetmgr.h"
  81. #include "dx8wrapper.h"
  82. // DEBUG DEBUG
  83. #include "mpu.h"
  84. #define DEBUG_SHADOW_RENDERING 0
  85. #define DEFAULT_TEXTURE_SIZE 64
  86. const float INTENSITY_RATE_OF_CHANGE = 1.0f; // change in intensity per second
  87. /*
  88. **
  89. ** Shadow mapping: from pre-projected view coordinates back to world space
  90. ** then to shadow space
  91. **
  92. ** (1) Vshadow = PShadow * Mwrld-shadow * Vwrld
  93. **
  94. ** (2) Vview = Mwrld-camera * Vwrld
  95. **
  96. ** Using (2) to solve for Vwrld in terms of Vview
  97. ** -1
  98. ** (3) Mwrld-camera * Vview = Vwrld
  99. **
  100. ** Substituting (3) into (1)
  101. ** -1
  102. ** (4) Vshadow = Pshadow * Mwrld-shadow * Mwrld-camera * Vview
  103. **
  104. ** ---------------------------------------------------------------------------------
  105. **
  106. ** Shadow mapping: from pre-projected view space to world space, to shadow space,
  107. ** then projecting.
  108. **
  109. ** (1) Vshadow = Mwrld-shadow * Vwrld
  110. **
  111. ** (2) Vview = Mwrld-camera * Vwrld
  112. **
  113. ** solving (2) for Vwrld:
  114. ** -1
  115. ** (3) Mwrld-camera * Vview = Vwrld
  116. **
  117. ** substitute into (1)
  118. ** -1
  119. ** (4) Vshadow = Mwrld-shadow * Mwrld-camera * Vview
  120. **
  121. ** project shadow
  122. ** -1
  123. ** (5) Vproj-shadow = Pshadow * (Mwrld-shadow * Mwrld-camera ) * Vview
  124. **
  125. ** aaah! same thing :-)
  126. **
  127. ** ---------------------------------------------------------------------------------
  128. **
  129. ** Shadow mapping: from pre-projected view coordinates back to obj space
  130. ** then to shadow space
  131. **
  132. ** (1) Vshadow = PShadow * Mwrld-shadow * Mobj-wrld * Vobj
  133. **
  134. ** (2) Vview = Mwrld-camera * Mobj-wrld * Vobj
  135. ** -1 -1
  136. ** (3) Mobj-wrld * Mwrld-camera * Vview = Vobj
  137. ** -1 -1
  138. ** (4) Vshadow = PShadow * Mwrld-shadow * Mobj-wrld * Mobj-wrld * Mwrld-camera * Vview
  139. ** -1
  140. ** (5) Vshadow = PShadow * Mwrld-shadow * Mvrld-camera * Vview
  141. **
  142. **
  143. ** Ideas:
  144. ** - Use Texture Projectors to implement spot lights and stained glass windows
  145. ** - Attenuate texture projections with distance from the projector
  146. ** - Should be able to handle lots of pre-calculated static texture projectors. They
  147. ** should cull well and we can pre-generate the textures.
  148. **
  149. ** Ideas maybe used in conjunction with texture projections:
  150. ** - Light volumes: the problem is when the volume is cliped it looks funny, we can
  151. ** fill in the clipped face of a non-translucent object by rendering the backfaces
  152. ** - Use the backface-fill to make the camera slicing through the commando look like
  153. ** its *really* slicing through the commando :-)
  154. ** - The back-face-fill trick might be able to use el-cheapo screen mapping!
  155. **
  156. */
  157. /***********************************************************************************************
  158. * TexProjectClass::TexProjectClass -- Constructor *
  159. * *
  160. * INPUT: *
  161. * *
  162. * OUTPUT: *
  163. * *
  164. * WARNINGS: *
  165. * *
  166. * HISTORY: *
  167. * 1/4/00 gth : Created. *
  168. *=============================================================================================*/
  169. TexProjectClass::TexProjectClass(void) :
  170. Flags(DEFAULT_FLAGS),
  171. DesiredIntensity(1.0f),
  172. Intensity(1.0f),
  173. Attenuation(1.0f),
  174. MaterialPass(NULL),
  175. Mapper1(NULL),
  176. RenderTarget(NULL),
  177. HFov(90.0f),
  178. VFov(90.0f),
  179. XMin(-10.0f),
  180. XMax(10.0f),
  181. YMin(-10.0f),
  182. YMax(10.0f),
  183. ZNear(1.0f),
  184. ZFar(1000.0f)
  185. {
  186. // set a default texture size
  187. Set_Texture_Size(DEFAULT_TEXTURE_SIZE);
  188. // create a material pass class
  189. MaterialPass = NEW_REF(MaterialPassClass,());
  190. MaterialPass->Set_Cull_Volume(&WorldBoundingVolume);
  191. // create a vertex material
  192. VertexMaterialClass * vmtl = NEW_REF(VertexMaterialClass,());
  193. WWASSERT(vmtl != NULL);
  194. // Plug our parent's mapper into our vertex material
  195. // the mapper for stage1 will be allocated as needed
  196. vmtl->Set_Mapper(Mapper);
  197. MaterialPass->Set_Material(vmtl);
  198. vmtl->Release_Ref();
  199. vmtl = NULL;
  200. // by default init our material pass to be multiplicative (shadow)
  201. Init_Multiplicative();
  202. }
  203. /***********************************************************************************************
  204. * TexProjectClass::~TexProjectClass -- Destructor *
  205. * *
  206. * INPUT: *
  207. * *
  208. * OUTPUT: *
  209. * *
  210. * WARNINGS: *
  211. * *
  212. * HISTORY: *
  213. * 1/4/00 gth : Created. *
  214. *=============================================================================================*/
  215. TexProjectClass::~TexProjectClass(void)
  216. {
  217. REF_PTR_RELEASE(Mapper1);
  218. REF_PTR_RELEASE(MaterialPass);
  219. REF_PTR_RELEASE(RenderTarget);
  220. }
  221. /***********************************************************************************************
  222. * TexProjectClass::Set_Texture_Size -- Set the size of texture to use *
  223. * *
  224. * This function stores the desired texture size in this TexProjectClass. Note that *
  225. * this size is only used if you have the TexProjectClass generate a texture. *
  226. * *
  227. * INPUT: *
  228. * size - dimension of the texture in pixels *
  229. * *
  230. * OUTPUT: *
  231. * *
  232. * WARNINGS: *
  233. * *
  234. * HISTORY: *
  235. * 1/4/00 gth : Created. *
  236. *=============================================================================================*/
  237. void TexProjectClass::Set_Texture_Size(int size)
  238. {
  239. WWASSERT(size > 0);
  240. WWASSERT(size <= 512);
  241. Flags &= ~SIZE_MASK;
  242. Flags |= (size << SIZE_SHIFT);
  243. }
  244. /***********************************************************************************************
  245. * TexProjectClass::Get_Texture_Size -- Returns the stored texture size *
  246. * *
  247. * Returns the size stored in the flags variable. This can be different than the actual *
  248. * texture's size if you manually installed a texture. This size is only used when *
  249. * automatically generating a texture as is the case when creating shadows. *
  250. * *
  251. * INPUT: *
  252. * *
  253. * OUTPUT: *
  254. * *
  255. * WARNINGS: *
  256. * *
  257. * HISTORY: *
  258. * 1/4/00 gth : Created. *
  259. *=============================================================================================*/
  260. int TexProjectClass::Get_Texture_Size(void)
  261. {
  262. return (Flags & SIZE_MASK) >> SIZE_SHIFT;
  263. }
  264. /***********************************************************************************************
  265. * TexProjectClass::Set_Flag -- Turn specified flag on or off *
  266. * *
  267. * See the TexProjectClass header file for valid flags *
  268. * *
  269. * INPUT: *
  270. * *
  271. * OUTPUT: *
  272. * *
  273. * WARNINGS: *
  274. * *
  275. * HISTORY: *
  276. * 1/4/00 gth : Created. *
  277. *=============================================================================================*/
  278. void TexProjectClass::Set_Flag(uint32 flag,bool onoff)
  279. {
  280. if (onoff) {
  281. Flags |= flag;
  282. } else {
  283. Flags &= ~flag;
  284. }
  285. }
  286. /***********************************************************************************************
  287. * TexProjectClass::Get_Flag -- Get the current state of specified flag *
  288. * *
  289. * See the TexProjectClass header file for valid flags *
  290. * *
  291. * INPUT: *
  292. * *
  293. * OUTPUT: *
  294. * *
  295. * WARNINGS: *
  296. * *
  297. * HISTORY: *
  298. * 1/4/00 gth : Created. *
  299. *=============================================================================================*/
  300. bool TexProjectClass::Get_Flag(uint32 flag) const
  301. {
  302. return (Flags & flag) == flag;
  303. }
  304. /***********************************************************************************************
  305. * TexProjectClass::Set_Intensity -- Set the intensity of this projector *
  306. * *
  307. * The "intensity" is a value between 0 and 1. At 0, the projector will have no effect *
  308. * At 1, the projector will be at its highest strength. The intensity will automatically *
  309. * smoothly interpolate towards the value specified unless you use the immediate option. *
  310. * *
  311. * INPUT: *
  312. * intensity - desired intensity, 0 <= intensity <= 1 *
  313. * immediate - should the intensity be immediately set to the desired value? (default = false) *
  314. * *
  315. * OUTPUT: *
  316. * *
  317. * WARNINGS: *
  318. * *
  319. * HISTORY: *
  320. * 1/4/00 gth : Created. *
  321. *=============================================================================================*/
  322. void TexProjectClass::Set_Intensity(float intensity,bool immediate)
  323. {
  324. WWASSERT(intensity <= 1.0f);
  325. WWASSERT(intensity >= 0.0f);
  326. DesiredIntensity = intensity;
  327. if (immediate) {
  328. Intensity = DesiredIntensity;
  329. }
  330. }
  331. /***********************************************************************************************
  332. * TexProjectClass::Get_Intensity -- returns the current "desired" intensity *
  333. * *
  334. * This will return the last value that was sent into this object through Set_Intensity. *
  335. * Note however that the actual intensity used in rendering may not have arrived at *
  336. * that value yet. *
  337. * *
  338. * INPUT: *
  339. * *
  340. * OUTPUT: *
  341. * *
  342. * WARNINGS: *
  343. * *
  344. * HISTORY: *
  345. * 1/4/00 gth : Created. *
  346. *=============================================================================================*/
  347. float TexProjectClass::Get_Intensity(void)
  348. {
  349. return DesiredIntensity;
  350. }
  351. /***********************************************************************************************
  352. * TexProjectClass::Is_Intensity_Zero -- check if we can eliminate this projector *
  353. * *
  354. * Only returns true if the current intensity is zero AND the target intensity is zero *
  355. * *
  356. * INPUT: *
  357. * *
  358. * OUTPUT: *
  359. * *
  360. * WARNINGS: *
  361. * *
  362. * HISTORY: *
  363. * 1/4/00 gth : Created. *
  364. *=============================================================================================*/
  365. bool TexProjectClass::Is_Intensity_Zero(void)
  366. {
  367. return ((Intensity == 0.0f) && (DesiredIntensity == 0.0f));
  368. }
  369. /***********************************************************************************************
  370. * TexProjectClass::Set_Attenuation -- Set the attenuation factor *
  371. * *
  372. * Attenuation scales the intensity. I use attenuation to make shadows fade away as they *
  373. * get farther away from the light source or from the viewer. *
  374. * *
  375. * INPUT: *
  376. * *
  377. * OUTPUT: *
  378. * *
  379. * WARNINGS: *
  380. * *
  381. * HISTORY: *
  382. * 1/4/00 gth : Created. *
  383. *=============================================================================================*/
  384. void TexProjectClass::Set_Attenuation(float attenuation)
  385. {
  386. WWASSERT(attenuation >= 0.0f);
  387. WWASSERT(attenuation <= 1.0f);
  388. Attenuation = attenuation;
  389. }
  390. /***********************************************************************************************
  391. * TexProjectClass::Get_Attenuation -- Returns the attenuation value *
  392. * *
  393. * INPUT: *
  394. * *
  395. * OUTPUT: *
  396. * *
  397. * WARNINGS: *
  398. * *
  399. * HISTORY: *
  400. * 1/4/00 gth : Created. *
  401. *=============================================================================================*/
  402. float TexProjectClass::Get_Attenuation(void)
  403. {
  404. return Attenuation;
  405. }
  406. /***********************************************************************************************
  407. * TexProjectClass::Enable_Attenuation -- Set the state of the ATTENUATE flag *
  408. * *
  409. * INPUT: *
  410. * *
  411. * OUTPUT: *
  412. * *
  413. * WARNINGS: *
  414. * *
  415. * HISTORY: *
  416. * 1/4/00 gth : Created. *
  417. *=============================================================================================*/
  418. void TexProjectClass::Enable_Attenuation(bool onoff)
  419. {
  420. Set_Flag(ATTENUATE,onoff);
  421. }
  422. /***********************************************************************************************
  423. * TexProjectClass::Is_Attenuation_Enabled -- Get the state of the ATTENUATE flag *
  424. * *
  425. * INPUT: *
  426. * *
  427. * OUTPUT: *
  428. * *
  429. * WARNINGS: *
  430. * *
  431. * HISTORY: *
  432. * 1/4/00 gth : Created. *
  433. *=============================================================================================*/
  434. bool TexProjectClass::Is_Attenuation_Enabled(void)
  435. {
  436. return Get_Flag(ATTENUATE);
  437. }
  438. /***********************************************************************************************
  439. * TexProjectClass::Enable_Depth_Gradient -- enable/disable depth gradient *
  440. * *
  441. * INPUT: *
  442. * *
  443. * OUTPUT: *
  444. * *
  445. * WARNINGS: *
  446. * *
  447. * HISTORY: *
  448. * 2/25/2000 gth : Created. *
  449. *=============================================================================================*/
  450. void TexProjectClass::Enable_Depth_Gradient(bool onoff)
  451. {
  452. Set_Flag(USE_DEPTH_GRADIENT,onoff);
  453. // re-setup the shader settings
  454. if (Get_Flag(ADDITIVE)) {
  455. Init_Additive();
  456. } else {
  457. Init_Multiplicative();
  458. }
  459. }
  460. /***********************************************************************************************
  461. * TexProjectClass::Is_Depth_Gradient_Enabled -- returns whether the depth gradient is enabled *
  462. * *
  463. * INPUT: *
  464. * *
  465. * OUTPUT: *
  466. * *
  467. * WARNINGS: *
  468. * *
  469. * HISTORY: *
  470. * 2/25/2000 gth : Created. *
  471. *=============================================================================================*/
  472. bool TexProjectClass::Is_Depth_Gradient_Enabled(bool onoff)
  473. {
  474. return Get_Flag(USE_DEPTH_GRADIENT);
  475. }
  476. /***********************************************************************************************
  477. * TexProjectClass::Init_Multiplicative -- Initialize this to be a multiplicative texture proj *
  478. * *
  479. * Set up the internal materials so that the texture is multiplied with whatever it is *
  480. * projected onto. *
  481. * *
  482. * INPUT: *
  483. * *
  484. * OUTPUT: *
  485. * *
  486. * WARNINGS: *
  487. * *
  488. * HISTORY: *
  489. * 1/4/00 gth : Created. *
  490. *=============================================================================================*/
  491. void TexProjectClass::Init_Multiplicative(void)
  492. {
  493. Set_Flag(ADDITIVE,false);
  494. /*
  495. ** Set up the shader
  496. */
  497. static ShaderClass mult_shader( SHADE_CNST( ShaderClass::PASS_LEQUAL, //depth_compare,
  498. ShaderClass::DEPTH_WRITE_DISABLE, //depth_mask,
  499. ShaderClass::COLOR_WRITE_ENABLE, //color_mask,
  500. ShaderClass::SRCBLEND_ZERO, //src_blend,
  501. ShaderClass::DSTBLEND_SRC_COLOR, //dst_blend,
  502. ShaderClass::FOG_DISABLE, //fog,
  503. ShaderClass::GRADIENT_ADD, //pri_grad,
  504. ShaderClass::SECONDARY_GRADIENT_DISABLE, //sec_grad,
  505. ShaderClass::TEXTURING_ENABLE, //texture,
  506. ShaderClass::ALPHATEST_DISABLE, //alpha_test,
  507. ShaderClass::CULL_MODE_ENABLE, //cull mode
  508. 0, //post_det_color,
  509. 0) ); //post_det_alpha
  510. if (WW3DAssetManager::Get_Instance()->Get_Activate_Fog_On_Load()) {
  511. mult_shader.Enable_Fog ("TexProjectClass");
  512. }
  513. if (Get_Flag(USE_DEPTH_GRADIENT)) {
  514. /*
  515. ** enable multi-texturing
  516. */
  517. mult_shader.Set_Post_Detail_Color_Func(ShaderClass::DETAILCOLOR_ADD);
  518. /*
  519. ** plug the gradient texture into the second stage
  520. */
  521. TextureClass * grad_tex = WW3DAssetManager::Get_Instance()->Get_Texture("MultProjectorGradient.tga");
  522. if (grad_tex) {
  523. grad_tex->Set_U_Addr_Mode(TextureClass::TEXTURE_ADDRESS_CLAMP);
  524. grad_tex->Set_V_Addr_Mode(TextureClass::TEXTURE_ADDRESS_CLAMP);
  525. MaterialPass->Set_Texture(grad_tex,1);
  526. grad_tex->Release_Ref();
  527. } else {
  528. WWDEBUG_SAY(("Could not find texture: MultProjectorGradient.tga!\n"));
  529. }
  530. } else {
  531. /*
  532. ** disable multi-texturing
  533. */
  534. mult_shader.Set_Post_Detail_Color_Func(ShaderClass::DETAILCOLOR_DISABLE);
  535. /*
  536. ** remove the texture from the second stage
  537. */
  538. MaterialPass->Set_Texture(NULL,1);
  539. }
  540. #if (DEBUG_SHADOW_RENDERING)
  541. // invert the shader so we can see what polygons it is hitting
  542. mult_shader.Set_Dst_Blend_Func(ShaderClass::DSTBLEND_ONE);
  543. mult_shader.Set_Src_Blend_Func(ShaderClass::SRCBLEND_ONE);
  544. #endif
  545. MaterialPass->Set_Shader(mult_shader);
  546. /*
  547. ** Set up the Vertex Material parameters
  548. */
  549. VertexMaterialClass * vmtl = MaterialPass->Peek_Material();
  550. vmtl->Set_Ambient(0,0,0);
  551. vmtl->Set_Diffuse(0,0,0);
  552. vmtl->Set_Specular(0,0,0);
  553. vmtl->Set_Emissive(0.0f,0.0f,0.0f);
  554. vmtl->Set_Opacity(1.0f);
  555. vmtl->Set_Lighting(true); // I need the emissive value to scale the intensity of the shadow
  556. /*
  557. ** Set up some mapper settings related to depth gradient
  558. */
  559. if (Get_Flag(USE_DEPTH_GRADIENT)) {
  560. if (Mapper1 == NULL) {
  561. Mapper1 = NEW_REF(MatrixMapperClass,(1));
  562. }
  563. Mapper1->Set_Type(MatrixMapperClass::DEPTH_GRADIENT);
  564. vmtl->Set_Mapper(Mapper1,1);
  565. } else {
  566. vmtl->Set_Mapper(NULL,1);
  567. }
  568. }
  569. /***********************************************************************************************
  570. * TexProjectClass::Init_Additive -- Set up the projector to be additive *
  571. * *
  572. * INPUT: *
  573. * *
  574. * OUTPUT: *
  575. * *
  576. * WARNINGS: *
  577. * *
  578. * HISTORY: *
  579. * 1/11/00 gth : Created. *
  580. *=============================================================================================*/
  581. void TexProjectClass::Init_Additive(void)
  582. {
  583. Set_Flag(ADDITIVE,true);
  584. /*
  585. ** Set up the shader
  586. */
  587. static ShaderClass add_shader( SHADE_CNST( ShaderClass::PASS_LEQUAL, //depth_compare,
  588. ShaderClass::DEPTH_WRITE_DISABLE, //depth_mask,
  589. ShaderClass::COLOR_WRITE_ENABLE, //color_mask,
  590. ShaderClass::SRCBLEND_ONE, //src_blend,
  591. ShaderClass::DSTBLEND_ONE, //dst_blend,
  592. ShaderClass::FOG_DISABLE, //fog,
  593. ShaderClass::GRADIENT_MODULATE, //pri_grad,
  594. ShaderClass::SECONDARY_GRADIENT_DISABLE, //sec_grad,
  595. ShaderClass::TEXTURING_ENABLE, //texture,
  596. ShaderClass::ALPHATEST_DISABLE, //alpha_test,
  597. ShaderClass::CULL_MODE_ENABLE, //cullmode,
  598. ShaderClass::DETAILCOLOR_DISABLE, //post_det_color,
  599. ShaderClass::DETAILALPHA_DISABLE) ); //post_det_alpha
  600. if (WW3DAssetManager::Get_Instance()->Get_Activate_Fog_On_Load()) {
  601. add_shader.Enable_Fog ("TexProjectClass");
  602. }
  603. /*
  604. ** Additive projectors always use the normal gradient so they need multi-texturing
  605. */
  606. add_shader.Set_Post_Detail_Color_Func(ShaderClass::DETAILCOLOR_SCALE);
  607. /*
  608. ** plug in the gradient texture
  609. */
  610. TextureClass * grad_tex = WW3DAssetManager::Get_Instance()->Get_Texture("AddProjectorGradient.tga");
  611. if (grad_tex) {
  612. grad_tex->Set_U_Addr_Mode(TextureClass::TEXTURE_ADDRESS_CLAMP);
  613. grad_tex->Set_V_Addr_Mode(TextureClass::TEXTURE_ADDRESS_CLAMP);
  614. MaterialPass->Set_Texture(grad_tex,1);
  615. grad_tex->Release_Ref();
  616. } else {
  617. WWDEBUG_SAY(("Could not find texture: AddProjectorGradient.tga!\n"));
  618. }
  619. #if (DEBUG_SHADOW_RENDERING)
  620. // invert the shader so we can see what polygons it is hitting
  621. add_shader.Set_Dst_Blend_Func(ShaderClass::DSTBLEND_SRC_COLOR);
  622. add_shader.Set_Src_Blend_Func(ShaderClass::SRCBLEND_ZERO);
  623. #endif
  624. MaterialPass->Set_Shader(add_shader);
  625. /*
  626. ** Set up the Vertex Material parameters
  627. */
  628. VertexMaterialClass * vmtl = MaterialPass->Peek_Material();
  629. vmtl->Set_Ambient(0,0,0);
  630. vmtl->Set_Diffuse(0,0,0);
  631. vmtl->Set_Specular(0,0,0);
  632. vmtl->Set_Emissive(1,1,1);
  633. vmtl->Set_Opacity(1.0f);
  634. vmtl->Set_Lighting(true); //need emissive to scale the intensity of the projector
  635. /*
  636. ** Set up some mapper settings related to depth gradient
  637. ** Additive texture projections always use the normal gradient
  638. */
  639. if (Mapper1 == NULL) {
  640. Mapper1 = NEW_REF(MatrixMapperClass,(1));
  641. }
  642. Mapper1->Set_Type(MatrixMapperClass::NORMAL_GRADIENT);
  643. vmtl->Set_Mapper(Mapper1,1);
  644. }
  645. /***********************************************************************************************
  646. * TexProjectClass::Set_Texture -- Set the texture to be projected *
  647. * *
  648. * INPUT: *
  649. * *
  650. * OUTPUT: *
  651. * *
  652. * WARNINGS: *
  653. * *
  654. * HISTORY: *
  655. * 1/11/00 gth : Created. *
  656. *=============================================================================================*/
  657. void TexProjectClass::Set_Texture(TextureClass * texture)
  658. {
  659. if (texture != NULL) {
  660. texture->Set_U_Addr_Mode(TextureClass::TEXTURE_ADDRESS_CLAMP);
  661. texture->Set_V_Addr_Mode(TextureClass::TEXTURE_ADDRESS_CLAMP);
  662. MaterialPass->Set_Texture(texture);
  663. SurfaceClass::SurfaceDescription surface_desc;
  664. texture->Get_Level_Description(surface_desc);
  665. Set_Texture_Size(surface_desc.Width);
  666. }
  667. }
  668. /***********************************************************************************************
  669. * TexProjectClass::Get_Texture -- Returns the texture being projected *
  670. * *
  671. * INPUT: *
  672. * *
  673. * OUTPUT: *
  674. * *
  675. * WARNINGS: *
  676. * the pointer is ref-counted! make sure to keep track of your references *
  677. * *
  678. * HISTORY: *
  679. * 1/11/00 gth : Created. *
  680. *=============================================================================================*/
  681. TextureClass * TexProjectClass::Get_Texture(void) const
  682. {
  683. return MaterialPass->Get_Texture();
  684. }
  685. /***********************************************************************************************
  686. * TexProjectClass::Peek_Texture -- Returns the texture being projected *
  687. * *
  688. * INPUT: *
  689. * *
  690. * OUTPUT: *
  691. * *
  692. * WARNINGS: *
  693. * *
  694. * HISTORY: *
  695. * 1/11/00 gth : Created. *
  696. *=============================================================================================*/
  697. TextureClass * TexProjectClass::Peek_Texture(void) const
  698. {
  699. return MaterialPass->Peek_Texture();
  700. }
  701. /***********************************************************************************************
  702. * TexProjectClass::Peek_Material_Pass -- Returns the material pass object *
  703. * *
  704. * INPUT: *
  705. * *
  706. * OUTPUT: *
  707. * *
  708. * WARNINGS: *
  709. * *
  710. * HISTORY: *
  711. * 1/11/00 gth : Created. *
  712. *=============================================================================================*/
  713. MaterialPassClass * TexProjectClass::Peek_Material_Pass(void)
  714. {
  715. return MaterialPass;
  716. }
  717. /***********************************************************************************************
  718. * TexProjectClass::Set_Perspective_Projection -- set up a perspective projection *
  719. * *
  720. * INPUT: *
  721. * *
  722. * OUTPUT: *
  723. * *
  724. * WARNINGS: *
  725. * *
  726. * HISTORY: *
  727. * 1/27/00 gth : Created. *
  728. *=============================================================================================*/
  729. void TexProjectClass::Set_Perspective_Projection(float hfov,float vfov,float znear,float zfar)
  730. {
  731. HFov = hfov;
  732. VFov = vfov;
  733. ZNear = znear;
  734. ZFar = zfar;
  735. ProjectorClass::Set_Perspective_Projection(hfov,vfov,znear,zfar);
  736. Set_Flag(PERSPECTIVE,true);
  737. }
  738. /***********************************************************************************************
  739. * TexProjectClass::Set_Ortho_Projection -- set up an orthographic projection *
  740. * *
  741. * INPUT: *
  742. * *
  743. * OUTPUT: *
  744. * *
  745. * WARNINGS: *
  746. * *
  747. * HISTORY: *
  748. * 1/27/00 gth : Created. *
  749. *=============================================================================================*/
  750. void TexProjectClass::Set_Ortho_Projection(float xmin,float xmax,float ymin,float ymax,float znear,float zfar)
  751. {
  752. XMin = xmin;
  753. XMax = xmax;
  754. YMin = ymin;
  755. YMax = ymax;
  756. ZNear = znear;
  757. ZFar = zfar;
  758. ProjectorClass::Set_Ortho_Projection(xmin,xmax,ymin,ymax,znear,zfar);
  759. Set_Flag(PERSPECTIVE,false);
  760. }
  761. /***********************************************************************************************
  762. * TexProjectClass::Compute_Perspective_Projection -- Set up a perspective projection of an ob *
  763. * *
  764. * This function automates the process of generating the perspective parameters needed to *
  765. * tightly bound the projection of an object. *
  766. * *
  767. * INPUT: *
  768. * model - object which we are created a projection of *
  769. * lightpos - positional light source *
  770. * znear - distance to near clipping plane for the projection (if -1.0, will be generated) *
  771. * zfar - distance to far clipping plane for the projection (if -1.0, will be generated) *
  772. * *
  773. * OUTPUT: *
  774. * *
  775. * WARNINGS: *
  776. * *
  777. * HISTORY: *
  778. * 1/11/00 gth : Created. *
  779. *=============================================================================================*/
  780. bool TexProjectClass::Compute_Perspective_Projection
  781. (
  782. RenderObjClass * model,
  783. const Vector3 & lightpos,
  784. float znear,
  785. float zfar
  786. )
  787. {
  788. if (model == NULL) {
  789. WWDEBUG_SAY(("Attempting to generate projection for a NULL model\r\n"));
  790. return false;
  791. }
  792. AABoxClass box;
  793. model->Get_Obj_Space_Bounding_Box(box);
  794. const Matrix3D & tm = model->Get_Transform();
  795. return Compute_Perspective_Projection(box,tm,lightpos,znear,zfar);
  796. }
  797. /***********************************************************************************************
  798. * TexProjectClass::Compute_Perspective_Projection -- Set up a perspective projection of an ob *
  799. * *
  800. * This function automates the process of generating the perspective parameters needed to *
  801. * tightly bound the projection of an object. *
  802. * *
  803. * INPUT: *
  804. * obj_box - object space bounding box of the object we are projecting *
  805. * tm - transform of the object we are projecting *
  806. * lightpos - positional light source *
  807. * user_znear - distance to near clipping plane for the projection (if -1.0, will be generated)*
  808. * user_zfar - distance to far clipping plane for the projection (if -1.0, will be generated) *
  809. * *
  810. * OUTPUT: *
  811. * *
  812. * WARNINGS: *
  813. * *
  814. * HISTORY: *
  815. * 1/11/00 gth : Created. *
  816. *=============================================================================================*/
  817. bool TexProjectClass::Compute_Perspective_Projection
  818. (
  819. const AABoxClass & obj_box,
  820. const Matrix3D & tm,
  821. const Vector3 & lightpos,
  822. float user_znear,
  823. float user_zfar
  824. )
  825. {
  826. /*
  827. ** Compute the center of the box in world-space
  828. */
  829. Vector3 wrld_center;
  830. Matrix3D::Transform_Vector(tm,obj_box.Center,&wrld_center);
  831. /*
  832. ** Create a camera transform looking at the object.
  833. ** Set this as our transform later in this routine.
  834. */
  835. Matrix3D texture_tm,texture_tm_inv;
  836. texture_tm.Look_At(lightpos,wrld_center,0.0f);
  837. texture_tm.Get_Orthogonal_Inverse(texture_tm_inv);
  838. /*
  839. ** Calculate the axis-aligned bounding box of the model in the camera's coordinate system.
  840. */
  841. AABoxClass box = obj_box;
  842. Matrix3D obj_to_world = tm;
  843. Matrix3D obj_to_texture;
  844. Matrix3D::Multiply(texture_tm_inv,obj_to_world,&obj_to_texture);
  845. box.Transform(obj_to_texture);
  846. /*
  847. ** If the box is behind the viewpoint or the viewpoint is inside the box
  848. ** our FOV will be > 180 degrees. Have to give up
  849. */
  850. if ((box.Center.Z > 0.0f) || (box.Extent.Z > WWMath::Fabs(box.Center.Z))) {
  851. return false;
  852. }
  853. /*
  854. ** Compute the frustum parameters. Remember that our z coordinates are negative but the
  855. ** projection code needs positive z distances.
  856. */
  857. float znear = -box.Center.Z; //-(box.Center.Z + obj_box.Extent.Quick_Length());
  858. float zfar = -(box.Center.Z - obj_box.Extent.Quick_Length()) * 2.0f;
  859. if (user_znear != -1.0f) {
  860. znear = box.Center.Z + user_znear;
  861. }
  862. if (user_zfar != -1.0f) {
  863. zfar = box.Center.Z + user_zfar;
  864. }
  865. float tan_hfov2 = WWMath::Fabs(box.Extent.X / (box.Center.Z + box.Extent.Z));
  866. float tan_vfov2 = WWMath::Fabs(box.Extent.Y / (box.Center.Z + box.Extent.Z));
  867. float hfov = 2.0f * WWMath::Atan(tan_hfov2);
  868. float vfov = 2.0f * WWMath::Atan(tan_vfov2);
  869. /*
  870. ** Plug in the results.
  871. */
  872. Set_Perspective_Projection(hfov,vfov,znear,zfar);
  873. Set_Transform(texture_tm);
  874. return true;
  875. }
  876. /***********************************************************************************************
  877. * TexProjectClass::Compute_Ortho_Projection -- Automatic Orthographic projection *
  878. * *
  879. * Generates the orthographic projection parameters to tightly bound an object *
  880. * *
  881. * INPUT: *
  882. * model - object which we are created a projection of *
  883. * lightdir - directional light source *
  884. * znear - distance to near clipping plane for the projection (if -1.0, will be generated) *
  885. * zfar - distance to far clipping plane for the projection (if -1.0, will be generated) *
  886. * *
  887. * OUTPUT: *
  888. * *
  889. * WARNINGS: *
  890. * *
  891. * HISTORY: *
  892. * 1/11/00 gth : Created. *
  893. *=============================================================================================*/
  894. bool TexProjectClass::Compute_Ortho_Projection
  895. (
  896. RenderObjClass * model,
  897. const Vector3 & lightdir,
  898. float znear,
  899. float zfar
  900. )
  901. {
  902. if (model == NULL) {
  903. WWDEBUG_SAY(("Attempting to generate projection for a NULL model\r\n"));
  904. return false;
  905. }
  906. AABoxClass box;
  907. model->Get_Obj_Space_Bounding_Box(box);
  908. const Matrix3D & tm = model->Get_Transform();
  909. return Compute_Ortho_Projection(box,tm,lightdir,znear,zfar);
  910. }
  911. /***********************************************************************************************
  912. * TexProjectClass::Compute_Ortho_Projection -- Automatic Orthographic projection *
  913. * *
  914. * Generates the orthographic projection parameters to tightly bound an object *
  915. * *
  916. * INPUT: *
  917. * obj_box - object space bounding box of the object we are projecting *
  918. * tm - transform of the object we are projecting *
  919. * lightdir - directional light *
  920. * user_znear - distance to near clipping plane for the projection (if -1.0, will be generated)*
  921. * user_zfar - distance to far clipping plane for the projection (if -1.0, will be generated) *
  922. * *
  923. * OUTPUT: *
  924. * *
  925. * WARNINGS: *
  926. * *
  927. * HISTORY: *
  928. * 1/11/00 gth : Created. *
  929. *=============================================================================================*/
  930. bool TexProjectClass::Compute_Ortho_Projection
  931. (
  932. const AABoxClass & obj_box,
  933. const Matrix3D & tm,
  934. const Vector3 & lightdir,
  935. float user_znear,
  936. float user_zfar
  937. )
  938. {
  939. /*
  940. ** Compute the center of the box in world-space
  941. */
  942. AABoxClass wrldbox = obj_box;
  943. wrldbox.Transform(tm);
  944. /*
  945. ** Create a camera transform looking at the object.
  946. ** Set this as our transform later in this routine.
  947. */
  948. Vector3 camera_target = wrldbox.Center;
  949. Vector3 camera_position = camera_target - 2.0f * wrldbox.Extent.Length() * lightdir;
  950. Matrix3D texture_tm,texture_tm_inv;
  951. texture_tm.Look_At(camera_position,camera_target,0.0f);
  952. texture_tm.Get_Orthogonal_Inverse(texture_tm_inv);
  953. /*
  954. ** Calculate the axis-aligned bounding box of the model in the camera's coordinate system.
  955. */
  956. AABoxClass box = obj_box;
  957. Matrix3D obj_to_world = tm;
  958. Matrix3D obj_to_texture;
  959. Matrix3D::Multiply(texture_tm_inv,obj_to_world,&obj_to_texture);
  960. box.Transform(obj_to_texture);
  961. /*
  962. ** Expand the box to help with bounding box errors
  963. */
  964. box.Extent *= 1.0f;
  965. /*
  966. ** Compute the frustum parameters. Note that znear and zfar are supposed to
  967. ** be positive distances for the projection code.
  968. */
  969. float znear = -box.Center.Z; //-(box.Center.Z + obj_box.Extent.Quick_Length());
  970. float zfar = -(box.Center.Z - obj_box.Extent.Quick_Length()) * 2.0f;
  971. if (user_znear != -1.0f) {
  972. znear = -box.Center.Z + user_znear;
  973. }
  974. if (user_zfar != -1.0f) {
  975. zfar = -box.Center.Z + user_zfar;
  976. }
  977. /*
  978. ** All done!
  979. */
  980. Set_Ortho_Projection( box.Center.X - box.Extent.X,
  981. box.Center.X + box.Extent.X,
  982. box.Center.Y - box.Extent.Y,
  983. box.Center.Y + box.Extent.Y,
  984. znear,
  985. zfar );
  986. Set_Transform(texture_tm);
  987. return true;
  988. }
  989. /***********************************************************************************************
  990. * TexProjectClass::Compute_Texture -- Generates texture by rendering an object *
  991. * *
  992. * INPUT: *
  993. * model - pointer to the render object to generate a shadow texture for *
  994. * context - shadow render context which has been initialized to <TextureSize> resolution *
  995. * *
  996. * OUTPUT: *
  997. * *
  998. * WARNINGS: *
  999. * *
  1000. * HISTORY: *
  1001. * 1/11/00 gth : Created. *
  1002. *=============================================================================================*/
  1003. bool TexProjectClass::Compute_Texture(RenderObjClass * model,SpecialRenderInfoClass * context)
  1004. {
  1005. if ((model == NULL) || (context == NULL)) {
  1006. return false;
  1007. }
  1008. /*
  1009. ** Render to texture
  1010. */
  1011. TextureClass * rtarget = Peek_Render_Target();
  1012. if (rtarget != NULL) {
  1013. /*
  1014. ** Set the render target
  1015. */
  1016. DX8Wrapper::Set_Render_Target(rtarget);
  1017. /*
  1018. ** Set up the camera
  1019. */
  1020. Configure_Camera(context->Camera);
  1021. /*
  1022. ** Render the object
  1023. */
  1024. Vector3 color(0.0f,0.0f,0.0f);
  1025. if (Get_Flag(ADDITIVE) == false) {
  1026. color.Set(1.0f,1.0f,1.0f);
  1027. }
  1028. WW3D::Begin_Render(true,true,color);
  1029. WW3D::Render(*model,*context);
  1030. WW3D::End_Render(false);
  1031. DX8Wrapper::Set_Render_Target((IDirect3DSurface8 *)NULL);
  1032. }
  1033. #if 0
  1034. /*
  1035. ** Render the object with the BW Renderer into our color surface
  1036. */
  1037. BWRenderClass bwr((unsigned char*)shadow_surface->getDataPtr(),tex_size);
  1038. bwr.Fill(0xff);
  1039. context->BWRenderer = &bwr;
  1040. model->Special_Render(*context);
  1041. context->BWRenderer = NULL;
  1042. #endif
  1043. return true;
  1044. }
  1045. /***********************************************************************************************
  1046. * TexProjectClass::Needs_Render_Target -- returns wheter this projector needs a render target *
  1047. * *
  1048. * INPUT: *
  1049. * *
  1050. * OUTPUT: *
  1051. * *
  1052. * WARNINGS: *
  1053. * *
  1054. * HISTORY: *
  1055. * 4/17/2001 gth : Created. *
  1056. *=============================================================================================*/
  1057. bool TexProjectClass::Needs_Render_Target(void)
  1058. {
  1059. return Get_Flag(TEXTURE_DIRTY);
  1060. }
  1061. /***********************************************************************************************
  1062. * TexProjectClass::Set_Render_Target -- Install a render target for this projector to use *
  1063. * *
  1064. * INPUT: *
  1065. * *
  1066. * OUTPUT: *
  1067. * *
  1068. * WARNINGS: *
  1069. * *
  1070. * HISTORY: *
  1071. * 4/16/2001 gth : Created. *
  1072. *=============================================================================================*/
  1073. void TexProjectClass::Set_Render_Target(TextureClass * render_target)
  1074. {
  1075. REF_PTR_SET(RenderTarget,render_target);
  1076. Set_Texture(RenderTarget);
  1077. }
  1078. /***********************************************************************************************
  1079. * TexProjectClass::Peek_Render_Target -- Returns pointer to the render target if we have one *
  1080. * *
  1081. * INPUT: *
  1082. * *
  1083. * OUTPUT: *
  1084. * *
  1085. * WARNINGS: *
  1086. * *
  1087. * HISTORY: *
  1088. * 4/5/2001 gth : Created. *
  1089. *=============================================================================================*/
  1090. TextureClass * TexProjectClass::Peek_Render_Target(void)
  1091. {
  1092. return RenderTarget;
  1093. }
  1094. /***********************************************************************************************
  1095. * TexProjectClass::Configure_Camera -- set up a camera to match this projector *
  1096. * *
  1097. * INPUT: *
  1098. * *
  1099. * OUTPUT: *
  1100. * *
  1101. * WARNINGS: *
  1102. * *
  1103. * HISTORY: *
  1104. * 1/11/00 gth : Created. *
  1105. *=============================================================================================*/
  1106. void TexProjectClass::Configure_Camera(CameraClass & camera)
  1107. {
  1108. camera.Set_Transform(Transform);
  1109. camera.Set_Clip_Planes(0.01f,ZFar);
  1110. if (Get_Flag(PERSPECTIVE)) {
  1111. camera.Set_Projection_Type(CameraClass::PERSPECTIVE);
  1112. camera.Set_View_Plane(HFov,VFov);
  1113. } else {
  1114. camera.Set_Projection_Type(CameraClass::ORTHO);
  1115. camera.Set_View_Plane(Vector2(XMin,YMin),Vector2(XMax,YMax));
  1116. }
  1117. }
  1118. /***********************************************************************************************
  1119. * TexProjectClass::Pre_Render_Update -- Prepare the projector for rendering *
  1120. * *
  1121. * INPUT: *
  1122. * *
  1123. * OUTPUT: *
  1124. * *
  1125. * WARNINGS: *
  1126. * *
  1127. * HISTORY: *
  1128. * 1/11/00 gth : Created. *
  1129. *=============================================================================================*/
  1130. void TexProjectClass::Pre_Render_Update(const Matrix3D & camera)
  1131. {
  1132. /*
  1133. ** Mview-texture = PShadow * Mwrld-texture * Mcamera-vrld
  1134. */
  1135. Matrix3D world_to_texture;
  1136. Matrix3D tmp;
  1137. Matrix4 view_to_texture;
  1138. Transform.Get_Orthogonal_Inverse(world_to_texture);
  1139. Matrix3D::Multiply(world_to_texture,camera,&tmp);
  1140. Matrix4::Multiply(Projection,tmp,&view_to_texture);
  1141. /*
  1142. ** update the current intensity by iterating it towards the desired intensity
  1143. */
  1144. float frame_time = (float)WW3D::Get_Frame_Time() / 1000.0f;
  1145. float intensity_delta = DesiredIntensity - Intensity;
  1146. float max_intensity_delta = INTENSITY_RATE_OF_CHANGE * frame_time;
  1147. if (intensity_delta > max_intensity_delta) {
  1148. Intensity += max_intensity_delta;
  1149. } else if (intensity_delta < -max_intensity_delta) {
  1150. Intensity -= max_intensity_delta;
  1151. } else {
  1152. Intensity = DesiredIntensity;
  1153. }
  1154. float actual_intensity = Intensity * Attenuation;
  1155. /*
  1156. ** install the current intensity
  1157. */
  1158. VertexMaterialClass * vmat = MaterialPass->Peek_Material();
  1159. if (Get_Flag(ADDITIVE)) {
  1160. vmat->Set_Emissive(actual_intensity,actual_intensity,actual_intensity);
  1161. } else {
  1162. vmat->Set_Emissive(1.0f - actual_intensity,1.0f - actual_intensity,1.0f - actual_intensity);
  1163. }
  1164. /*
  1165. ** update the mappers
  1166. */
  1167. if (Get_Flag(PERSPECTIVE)) {
  1168. Mapper->Set_Type(MatrixMapperClass::PERSPECTIVE_PROJECTION);
  1169. } else {
  1170. Mapper->Set_Type(MatrixMapperClass::ORTHO_PROJECTION);
  1171. }
  1172. Mapper->Set_Texture_Transform(view_to_texture,Get_Texture_Size());
  1173. if (Mapper1) {
  1174. Mapper1->Set_Texture_Transform(view_to_texture,Get_Texture_Size());
  1175. }
  1176. }
  1177. /***********************************************************************************************
  1178. * TexProjectClass::Update_WS_Bounding_Volume -- Recalculate the world-space bounding box *
  1179. * *
  1180. * INPUT: *
  1181. * *
  1182. * OUTPUT: *
  1183. * *
  1184. * WARNINGS: *
  1185. * *
  1186. * HISTORY: *
  1187. * 1/11/00 gth : Created. *
  1188. *=============================================================================================*/
  1189. void TexProjectClass::Update_WS_Bounding_Volume(void)
  1190. {
  1191. ProjectorClass::Update_WS_Bounding_Volume();
  1192. /*
  1193. ** Tell our culling system that we've changed
  1194. */
  1195. Vector3 extent;
  1196. WorldBoundingVolume.Compute_Axis_Aligned_Extent(&extent);
  1197. Set_Cull_Box(AABoxClass(WorldBoundingVolume.Center,extent));
  1198. }