context.cpp 64 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222
  1. #include "pch.h"
  2. //////////////////////////////////////////////////////////////////////////////
  3. //
  4. // Plane
  5. //
  6. //////////////////////////////////////////////////////////////////////////////
  7. float Plane::Distance(const HVector& vec) const
  8. {
  9. return
  10. vec.X() * m_hvec.X()
  11. + vec.Y() * m_hvec.Y()
  12. + vec.Z() * m_hvec.Z()
  13. + vec.W() * m_hvec.W();
  14. }
  15. float Plane::Intersect(const HVector& v0, const HVector& v1) const
  16. {
  17. HVector vd = v1 - v0;
  18. float a = m_hvec * v0;
  19. float b = m_hvec * vd;
  20. float alpha = -a / b;
  21. return bound(alpha, 0.0f, 1.0f);
  22. }
  23. //////////////////////////////////////////////////////////////////////////////
  24. //
  25. // State
  26. //
  27. //////////////////////////////////////////////////////////////////////////////
  28. class StateChangeBase {};
  29. typedef TBitMask<StateChangeBase, DWORD> StateChange;
  30. class StateChangeMatrix : public StateChange { public: StateChangeMatrix () : StateChange(0x000001) {} };
  31. class StateChangePerspectiveMatrix : public StateChange { public: StateChangePerspectiveMatrix () : StateChange(0x000002) {} };
  32. class StateChangeMaterial : public StateChange { public: StateChangeMaterial () : StateChange(0x000004) {} };
  33. class StateChangeTexture : public StateChange { public: StateChangeTexture () : StateChange(0x000008) {} };
  34. class StateChangeShadeMode : public StateChange { public: StateChangeShadeMode () : StateChange(0x000010) {} };
  35. class StateChangeBlendMode : public StateChange { public: StateChangeBlendMode () : StateChange(0x000020) {} };
  36. class StateChangeZTest : public StateChange { public: StateChangeZTest () : StateChange(0x000040) {} };
  37. class StateChangeZWrite : public StateChange { public: StateChangeZWrite () : StateChange(0x000080) {} };
  38. class StateChangeLinearFilter : public StateChange { public: StateChangeLinearFilter () : StateChange(0x000100) {} };
  39. class StateChangePerspectiveCorrection : public StateChange { public: StateChangePerspectiveCorrection() : StateChange(0x000200) {} };
  40. class StateChangeDither : public StateChange { public: StateChangeDither () : StateChange(0x000400) {} };
  41. class StateChangeWrapMode : public StateChange { public: StateChangeWrapMode () : StateChange(0x000800) {} };
  42. class StateChangeCullMode : public StateChange { public: StateChangeCullMode () : StateChange(0x001000) {} };
  43. class StateChangeClipRect : public StateChange { public: StateChangeClipRect () : StateChange(0x002000) {} };
  44. class StateChangeClipPlanes : public StateChange { public: StateChangeClipPlanes () : StateChange(0x004000) {} };
  45. class StateChangeColor : public StateChange { public: StateChangeColor () : StateChange(0x008000) {} };
  46. class StateChangeAmbientLevel : public StateChange { public: StateChangeAmbientLevel () : StateChange(0x010000) {} };
  47. class StateChangeLineWidth : public StateChange { public: StateChangeLineWidth () : StateChange(0x020000) {} };
  48. class StateChangeColorKey : public StateChange { public: StateChangeColorKey () : StateChange(0x040000) {} };
  49. class StateChangeDeformation : public StateChange { public: StateChangeDeformation () : StateChange(0x080000) {} };
  50. class StateChangeAll : public StateChange { public: StateChangeAll () : StateChange(0xffffff) {} };
  51. const StateChange stCommon =
  52. StateChangeMatrix()
  53. | StateChangeMaterial()
  54. | StateChangeTexture();
  55. const StateChange stUncommon = StateChangeAll().Clear(stCommon);
  56. class State : public IObjectSingle {
  57. public:
  58. TRef<State> m_pnext;
  59. TRef<Material> m_pmaterial;
  60. TRef<Surface> m_psurfaceTexture;
  61. TRef<Deformation> m_pdeform;
  62. Matrix m_mat;
  63. Matrix m_matPerspective;
  64. Rect m_rectClip;
  65. int m_countClipPlanes;
  66. bool m_bZTest;
  67. bool m_bZWrite;
  68. bool m_bDither;
  69. bool m_bColorKey;
  70. bool m_bLinearFilter;
  71. bool m_bPerspectiveCorrection;
  72. ShadeMode m_shadeMode;
  73. BlendMode m_blendMode;
  74. WrapMode m_wrapMode;
  75. CullMode m_cullMode;
  76. Color m_color;
  77. float m_ambientLevel;
  78. float m_lineWidth;
  79. StateChange m_maskChanges;
  80. StateChange m_maskOverride;
  81. State()
  82. {
  83. }
  84. State(State* pstate) :
  85. m_pnext(pstate),
  86. m_maskChanges(),
  87. m_maskOverride()
  88. {
  89. }
  90. };
  91. //////////////////////////////////////////////////////////////////////////////
  92. //
  93. // Drawing Context
  94. //
  95. //////////////////////////////////////////////////////////////////////////////
  96. class ContextImpl : public PrivateContext {
  97. private:
  98. //////////////////////////////////////////////////////////////////////////////
  99. //
  100. // types
  101. //
  102. //////////////////////////////////////////////////////////////////////////////
  103. class WhiteSurfaceSite : public SurfaceSite {
  104. public:
  105. void UpdateSurface(Surface* psurface)
  106. {
  107. psurface->FillSurface(Color::White());
  108. }
  109. };
  110. //////////////////////////////////////////////////////////////////////////////
  111. //
  112. // members
  113. //
  114. //////////////////////////////////////////////////////////////////////////////
  115. TRef<IDevice3D> m_pdevice3D;
  116. TRef<State> m_pstate;
  117. TRef<State> m_pstateDevice;
  118. PrivateSurface* m_psurface;
  119. //
  120. // Vertex buffers
  121. //
  122. Vertex* m_pvertexBuffer;
  123. int m_countVertexBuffer;
  124. MeshIndex* m_pindexBuffer;
  125. int m_countIndexBuffer;
  126. //
  127. // What mode is the device in?
  128. //
  129. bool m_bRendering;
  130. bool m_bIn3DLayer;
  131. bool m_bInScene;
  132. bool m_bRenderingCallbacks;
  133. //
  134. // Culling
  135. //
  136. float m_focus;
  137. float m_near;
  138. float m_far;
  139. float m_aspect;
  140. float m_rxscale;
  141. float m_ryscale;
  142. float m_yscale;
  143. //
  144. // Level of detail
  145. //
  146. float m_lod;
  147. //////////////////////////////////////////////////////////////////////////////
  148. //
  149. // Decal Data
  150. //
  151. //////////////////////////////////////////////////////////////////////////////
  152. class Decal {
  153. public:
  154. Vector m_position;
  155. Color m_color;
  156. float m_scale;
  157. float m_angle;
  158. Vector m_forward;
  159. Vector m_right;
  160. bool GetVertices(VertexL* pvertex) const
  161. {
  162. Vector v0;
  163. Vector v1;
  164. Vector v2;
  165. Vector v3;
  166. if (m_forward.IsZero()) {
  167. float c = cos(m_angle) * m_scale;
  168. float s = sin(m_angle) * m_scale;
  169. float dx = c - s;
  170. float dy = c + s;
  171. float x = m_position.X();
  172. float y = m_position.Y();
  173. float z = m_position.Z();
  174. v0 = Vector(x - dy, y + dx, z);
  175. v1 = Vector(x - dx, y - dy, z);
  176. v2 = Vector(x + dy, y - dx, z);
  177. v3 = Vector(x + dx, y + dy, z);
  178. } else {
  179. v0 = m_position - m_forward - m_right;
  180. v1 = m_position + m_forward - m_right;
  181. v2 = m_position + m_forward + m_right;
  182. v3 = m_position - m_forward + m_right;
  183. }
  184. float r = m_color.R();
  185. float g = m_color.G();
  186. float b = m_color.B();
  187. float a = m_color.A();
  188. pvertex[0] = VertexL(v0.X(), v0.Y(), v0.Z(), r, g, b, a, 0, 1);
  189. pvertex[1] = VertexL(v1.X(), v1.Y(), v1.Z(), r, g, b, a, 0, 0);
  190. pvertex[2] = VertexL(v2.X(), v2.Y(), v2.Z(), r, g, b, a, 1, 0);
  191. pvertex[3] = VertexL(v3.X(), v3.Y(), v3.Z(), r, g, b, a, 1, 1);
  192. return true;
  193. }
  194. };
  195. //////////////////////////////////////////////////////////////////////////////
  196. //
  197. // Decal Sets
  198. //
  199. //////////////////////////////////////////////////////////////////////////////
  200. class DecalSet {
  201. public:
  202. TRef<Surface> m_psurface;
  203. TVector<Decal> m_vdecal;
  204. };
  205. TVector<DecalSet> m_vdecalSet;
  206. TVector<DecalSet> m_vdecalSetOpaque;
  207. //
  208. // Delayed 3D Rendering
  209. //
  210. class GeoCallbackData {
  211. public:
  212. TRef<IGeoCallback> m_pgeoCallback;
  213. Matrix m_mat;
  214. float m_distance;
  215. };
  216. class CompareDistance {
  217. public:
  218. bool operator () (const GeoCallbackData& value1, const GeoCallbackData& value2)
  219. {
  220. return value1.m_distance < value2.m_distance;
  221. }
  222. };
  223. typedef TList<GeoCallbackData, DefaultNoEquals, CompareDistance> GeoCallbackDataList;
  224. GeoCallbackDataList m_listGeoCallbacks;
  225. GeoCallbackDataList m_listGeoCallbacksSorted;
  226. //
  227. // Counters
  228. //
  229. #ifdef EnablePerformanceCounters
  230. int m_countDrawString;
  231. int m_countDrawStringChars;
  232. #endif
  233. public:
  234. //////////////////////////////////////////////////////////////////////////////
  235. //
  236. // Constructor
  237. //
  238. //////////////////////////////////////////////////////////////////////////////
  239. ContextImpl(PrivateSurface* psurface) :
  240. #ifdef EnablePerformanceCounters
  241. m_countDrawString(0),
  242. m_countDrawStringChars(0),
  243. #endif
  244. m_pvertexBuffer(NULL),
  245. m_countVertexBuffer(0),
  246. m_pindexBuffer(NULL),
  247. m_countIndexBuffer(0),
  248. m_psurface(psurface),
  249. m_bRendering(false),
  250. m_bIn3DLayer(false),
  251. m_bInScene(false),
  252. m_bRenderingCallbacks(false)
  253. {
  254. //
  255. // Create a rasterizer and a 3D device
  256. //
  257. if (psurface->GetSurfaceType().Test(SurfaceType3D())) {
  258. TRef<Engine> pengine = psurface->GetEngine();
  259. TRef<Rasterizer> prasterizer;
  260. bool bAlwaysUseD3D = false;
  261. if (
  262. bAlwaysUseD3D
  263. || (
  264. pengine->GetUsing3DAcceleration()
  265. && psurface->GetSurfaceType().Test(SurfaceTypeVideo())
  266. )
  267. ) {
  268. prasterizer = CreateD3DRasterizer(m_psurface);
  269. } else {
  270. prasterizer = CreateSoftwareRasterizer(m_psurface);
  271. }
  272. if (prasterizer == NULL) {
  273. return;
  274. }
  275. m_pdevice3D = CreateDevice3D(prasterizer);
  276. }
  277. //
  278. // Setup the initial state
  279. //
  280. m_pstateDevice = new State();
  281. m_pstateDevice->m_mat.SetIdentity();
  282. m_pstateDevice->m_matPerspective.SetIdentity();
  283. m_pstateDevice->m_pmaterial = NULL;
  284. m_pstateDevice->m_bZTest = false;
  285. m_pstateDevice->m_bZWrite = false;
  286. m_pstateDevice->m_bPerspectiveCorrection = false;
  287. m_pstateDevice->m_bDither = true;
  288. m_pstateDevice->m_bColorKey = true;
  289. m_pstateDevice->m_bLinearFilter = true;
  290. m_pstateDevice->m_shadeMode = ShadeModeGouraud;
  291. m_pstateDevice->m_blendMode = BlendModeSource;
  292. m_pstateDevice->m_wrapMode = WrapModeNone;
  293. m_pstateDevice->m_cullMode = CullModeCCW;
  294. m_pstateDevice->m_maskChanges = StateChangeAll();
  295. m_pstateDevice->m_maskOverride = StateChange();
  296. m_pstateDevice->m_countClipPlanes = 0;
  297. m_pstateDevice->m_rectClip =
  298. Rect(
  299. Point(0, 0),
  300. Point::Cast(m_psurface->GetSize())
  301. );
  302. m_pstateDevice->m_color = Color::White();
  303. m_pstateDevice->m_lineWidth = 1;
  304. }
  305. bool IsValid()
  306. {
  307. return m_pdevice3D != NULL && m_pdevice3D->IsValid();
  308. }
  309. //////////////////////////////////////////////////////////////////////////////
  310. //
  311. // Destructor
  312. //
  313. //////////////////////////////////////////////////////////////////////////////
  314. ~ContextImpl()
  315. {
  316. if (m_pvertexBuffer) {
  317. free(m_pvertexBuffer);
  318. }
  319. if (m_pindexBuffer) {
  320. free(m_pindexBuffer);
  321. }
  322. }
  323. //////////////////////////////////////////////////////////////////////////////
  324. //
  325. // Capabilities
  326. //
  327. //////////////////////////////////////////////////////////////////////////////
  328. bool Has3DAcceleration()
  329. {
  330. return m_pdevice3D->Has3DAcceleration();
  331. }
  332. //////////////////////////////////////////////////////////////////////////////
  333. //
  334. // Rendering Initialization
  335. //
  336. //////////////////////////////////////////////////////////////////////////////
  337. void BeginRendering()
  338. {
  339. ZAssert(!m_bRendering);
  340. ZAssert(!m_bInScene);
  341. ZAssert(!m_bIn3DLayer);
  342. m_bRendering = true;
  343. PushState();
  344. }
  345. void EndRendering()
  346. {
  347. ZAssert(m_bRendering);
  348. PopState();
  349. if (m_bIn3DLayer) {
  350. End3DLayer();
  351. }
  352. EndScene();
  353. m_bRendering = false;
  354. }
  355. PrivateSurface* GetSurface()
  356. {
  357. return m_psurface;
  358. }
  359. //////////////////////////////////////////////////////////////////////////////
  360. //
  361. // Attributes
  362. //
  363. //////////////////////////////////////////////////////////////////////////////
  364. bool GetClipping()
  365. {
  366. return m_pdevice3D->GetClipping();
  367. }
  368. void SetClipping(bool bClip)
  369. {
  370. m_pdevice3D->SetClipping(bClip);
  371. }
  372. bool IsCulled(
  373. const Vector& vecOrigin,
  374. float radius,
  375. bool& bNotClipped
  376. ) {
  377. // , this code assumes there are no non-uniform scales
  378. // actualy it doesn't handle scales at all since radius isn't
  379. // scaled.
  380. Vector vecEye = TransformLocalToEye(vecOrigin);
  381. float x = vecEye.X();
  382. float y = vecEye.Y();
  383. float z = vecEye.Z();
  384. float back = z - m_far;
  385. float front = m_near - z;
  386. float rx;
  387. float ry;
  388. float left;
  389. float right;
  390. float bottom;
  391. float top;
  392. if (m_focus == 0) {
  393. rx = radius;
  394. ry = radius;
  395. left = x - 1;
  396. right = -x - 1;
  397. bottom = y - 1;
  398. top = -y - 1;
  399. } else {
  400. rx = radius * m_rxscale;
  401. ry = radius * m_ryscale;
  402. left = m_focus * x - z;
  403. right = -m_focus * x - z;
  404. bottom = m_yscale * y - z;
  405. top = -m_yscale * y - z;
  406. }
  407. //
  408. // Is the sphere completely outside the frustum?
  409. //
  410. if (
  411. left < -rx
  412. || right < -rx
  413. || bottom < -ry
  414. || top < -ry
  415. || back < -radius
  416. || front < -radius
  417. ) {
  418. bNotClipped = false;
  419. return true;
  420. }
  421. //
  422. // Is the sphere completely inside the frustum?
  423. //
  424. if (
  425. left > rx
  426. && right > rx
  427. && bottom > ry
  428. && top > ry
  429. && back > radius
  430. && front > radius
  431. ) {
  432. bNotClipped = true;
  433. return false;
  434. }
  435. //
  436. // The sphere intersects the frustum's boundary.
  437. //
  438. bNotClipped = false;
  439. return false;
  440. }
  441. //////////////////////////////////////////////////////////////////////////////
  442. //
  443. // 2D Image Rendering
  444. //
  445. //////////////////////////////////////////////////////////////////////////////
  446. void DrawImage(
  447. Surface* psurface,
  448. const Rect& rectSource,
  449. bool bCentered,
  450. const Point& point
  451. ) {
  452. // !!! should really look at the device mode and the current transform
  453. // !!! this uses upper left as (0, 0) on psurface and DrawImage3D() uses lower left as (0, 0)
  454. // !!! this doesn't scale or rotate the image
  455. ZAssert(!m_bIn3DLayer);
  456. ZAssert(m_pstateDevice->m_matPerspective.GetType() < TransformRotate);
  457. DD2D();
  458. Point pointImage;
  459. if (TransformLocalToImage(Vector(point.X(), point.Y(), 0), pointImage)) {
  460. WinPoint pointScreen = TransformImageToSurface(pointImage);
  461. if (bCentered) {
  462. pointScreen.SetX(pointScreen.X() - (int)(rectSource.XSize() / 2.0f));
  463. pointScreen.SetY(pointScreen.Y() - (int)(rectSource.YSize() / 2.0f));
  464. } else {
  465. pointScreen.SetY(pointScreen.Y() - (int)rectSource.YSize());
  466. }
  467. m_psurface->BitBlt(
  468. pointScreen,
  469. psurface,
  470. WinRect::Cast(rectSource)
  471. );
  472. };
  473. }
  474. void DrawImage(
  475. Surface* psurface,
  476. bool bCentered,
  477. const Point& point
  478. ) {
  479. DrawImage(
  480. psurface,
  481. WinRect(
  482. WinPoint(0, 0),
  483. psurface->GetSize()
  484. ),
  485. bCentered,
  486. point
  487. );
  488. }
  489. //////////////////////////////////////////////////////////////////////////////
  490. //
  491. // 3D Image Rendering
  492. //
  493. //////////////////////////////////////////////////////////////////////////////
  494. void DrawImage3D(
  495. Surface* psurface,
  496. const Rect& rectSource,
  497. const Color& color,
  498. bool bCentered,
  499. const Point& point
  500. ) {
  501. ZAssert(m_bRendering);
  502. if (!m_bInScene) {
  503. Texture2D();
  504. }
  505. Point sizeSource(Point::Cast(psurface->GetSize()));
  506. float xOffset = point.X() - (bCentered ? rectSource.XSize() / 2 : 0);
  507. float yOffset = point.Y() - (bCentered ? rectSource.YSize() / 2 : 0);
  508. float xmin = xOffset ;
  509. float xmax = xOffset + rectSource.XSize();
  510. float ymin = yOffset;
  511. float ymax = yOffset + rectSource.YSize();
  512. float xt;
  513. float yt;
  514. //if (psurface->GetSurfaceType().Test(SurfaceTypeTile())) {
  515. xt = 1.0f / sizeSource.X();
  516. yt = 1.0f / sizeSource.Y();
  517. //} else {
  518. // // , this is broken if the texture size is smaller that the surface size
  519. // Point pointTextureSize(Point::Cast(psurface->GetTextureRect().Size()));
  520. //
  521. // xt = 1.0f / pointTextureSize.X();
  522. // yt = 1.0f / pointTextureSize.Y();
  523. //}
  524. float xtmin = xt * rectSource.XMin();
  525. float xtmax = xt * rectSource.XMax();
  526. float ytmin = yt * (sizeSource.Y() - rectSource.YMin());
  527. float ytmax = yt * (sizeSource.Y() - rectSource.YMax());
  528. static MeshIndex indices[6] = { 0, 2, 1, 0, 3, 2 };
  529. UpdateState();
  530. m_pdevice3D->SetTexture(psurface);
  531. switch (GetShadeMode()) {
  532. case ShadeModeCopy:
  533. {
  534. Vertex vertices[4] = {
  535. Vertex(xmin, ymax, 0, 0, 0, 1, xtmin, ytmax),
  536. Vertex(xmin, ymin, 0, 0, 0, 1, xtmin, ytmin),
  537. Vertex(xmax, ymin, 0, 0, 0, 1, xtmax, ytmin),
  538. Vertex(xmax, ymax, 0, 0, 0, 1, xtmax, ytmax)
  539. };
  540. m_pdevice3D->DrawTriangles(vertices, 4, indices, 6);
  541. }
  542. break;
  543. case ShadeModeFlat:
  544. case ShadeModeGouraud:
  545. {
  546. float r = color.R();
  547. float g = color.G();
  548. float b = color.B();
  549. float a = color.A();
  550. VertexL vertices[4] = {
  551. VertexL(xmin, ymax, 0, r, g, b, a, xtmin, ytmax),
  552. VertexL(xmin, ymin, 0, r, g, b, a, xtmin, ytmin),
  553. VertexL(xmax, ymin, 0, r, g, b, a, xtmax, ytmin),
  554. VertexL(xmax, ymax, 0, r, g, b, a, xtmax, ytmax)
  555. };
  556. m_pdevice3D->SetShadeMode(ShadeModeFlat);
  557. m_pdevice3D->DrawTriangles(vertices, 4, indices, 6);
  558. m_pdevice3D->SetShadeMode(m_pstateDevice->m_shadeMode);
  559. }
  560. break;
  561. default:
  562. ZError("Invalid shade mode");
  563. break;
  564. }
  565. m_pdevice3D->SetTexture(m_pstateDevice->m_psurfaceTexture);
  566. }
  567. void DrawImage3D(
  568. Surface* psurface,
  569. const Color& color,
  570. bool bCentered,
  571. const Point& point
  572. ) {
  573. DrawImage3D(
  574. psurface,
  575. Rect(
  576. Point(0, 0),
  577. Point::Cast(psurface->GetSize())
  578. ),
  579. color,
  580. bCentered,
  581. point
  582. );
  583. }
  584. //////////////////////////////////////////////////////////////////////////////
  585. //
  586. // Text Rendering
  587. //
  588. //////////////////////////////////////////////////////////////////////////////
  589. void DrawString(
  590. IEngineFont* pfont,
  591. const Color& color,
  592. const Point& point,
  593. const ZString& str
  594. ) {
  595. #ifdef EnablePerformanceCounters
  596. m_countDrawString++;
  597. m_countDrawStringChars += str.GetLength();
  598. #endif
  599. DD2D();
  600. Point pointImage;
  601. if (TransformLocalToImage(Vector(point.X(), point.Y(), 0), pointImage)) {
  602. WinPoint pointScreen = TransformImageToSurface(pointImage);
  603. WinPoint size = pfont->GetTextExtent(str);
  604. pointScreen.SetY(pointScreen.Y() - size.Y());
  605. m_psurface->DrawString(pfont, color, pointScreen, str);
  606. };
  607. }
  608. void DrawRectangle(const Rect& rect, const Color& color)
  609. {
  610. Texture2D();
  611. static MeshIndex indices[8] = { 0, 1, 1, 2, 2, 3, 3, 0 };
  612. float xmin = rect.XMin();
  613. float xmax = rect.XMax();
  614. float ymin = rect.YMin();
  615. float ymax = rect.YMax();
  616. float r = color.R();
  617. float g = color.G();
  618. float b = color.B();
  619. float a = color.A();
  620. VertexL vertices[4] = {
  621. VertexL(xmin, ymax, 0, r, g, b, a, 0, 0),
  622. VertexL(xmin, ymin, 0, r, g, b, a, 0, 0),
  623. VertexL(xmax, ymin, 0, r, g, b, a, 0, 0),
  624. VertexL(xmax, ymax, 0, r, g, b, a, 0, 0)
  625. };
  626. m_pdevice3D->DrawLines(vertices, 4, indices, 8);
  627. }
  628. void FillRect(const Rect& rect, const Color& color)
  629. {
  630. Texture2D();
  631. static MeshIndex indices[6] = { 0, 2, 1, 0, 3, 2 };
  632. float xmin = rect.XMin();
  633. float xmax = rect.XMax();
  634. float ymin = rect.YMin();
  635. float ymax = rect.YMax();
  636. float r = color.R();
  637. float g = color.G();
  638. float b = color.B();
  639. float a = color.A();
  640. VertexL vertices[4] = {
  641. VertexL(xmin, ymax, 0, r, g, b, a, 0, 1),
  642. VertexL(xmin, ymin, 0, r, g, b, a, 0, 0),
  643. VertexL(xmax, ymin, 0, r, g, b, a, 1, 0),
  644. VertexL(xmax, ymax, 0, r, g, b, a, 1, 1)
  645. };
  646. UpdateState();
  647. m_pdevice3D->SetShadeMode(ShadeModeFlat);
  648. m_pdevice3D->DrawTriangles(vertices, 4, indices, 6);
  649. m_pdevice3D->SetShadeMode(m_pstateDevice->m_shadeMode);
  650. }
  651. void FillInfinite(const Color& color)
  652. {
  653. DD2D();
  654. m_psurface->FillSurface(color);
  655. }
  656. //////////////////////////////////////////////////////////////////////////////
  657. //
  658. // 3D Layers
  659. //
  660. //////////////////////////////////////////////////////////////////////////////
  661. void Begin3DLayer(Camera* pcamera, bool bZBuffer)
  662. {
  663. ZEnter("Context::Begin3DLayer");
  664. ZAssert(m_bRendering);
  665. ZAssert(!m_bIn3DLayer);
  666. //
  667. // Push the state so we can undo all the state changes
  668. //
  669. PushState();
  670. //
  671. // Integrate the 2D transforms up until this point with the 3D transform
  672. //
  673. pcamera->Update();
  674. SetPerspectiveMatrix(pcamera->GetPerspectiveMatrix());
  675. //
  676. // Change this flag after we change the prespective matrix
  677. //
  678. m_bIn3DLayer = true;
  679. //
  680. // Apply the camera's transform
  681. //
  682. SetTransform(pcamera->GetModelMatrix());
  683. //
  684. // start the 3D Layer
  685. //
  686. BeginScene();
  687. //
  688. // Save some information needed for culling
  689. //
  690. WinPoint point = m_psurface->GetSize();
  691. m_focus = pcamera->GetFocus();
  692. m_near = pcamera->GetNear();
  693. m_far = pcamera->GetFar();
  694. m_aspect = float(point.Y()) / float(point.X());
  695. m_yscale = m_focus / m_aspect;
  696. m_rxscale = sqrt(m_focus * m_focus + 1.0f);
  697. m_ryscale = sqrt(m_yscale * m_yscale + 1.0f);
  698. //
  699. // Default to being frustum clipped
  700. //
  701. SetClipping(true);
  702. //
  703. // Initialize state
  704. //
  705. m_lod = FLT_MAX;
  706. //
  707. // Clear the ZBuffer
  708. //
  709. if (bZBuffer) {
  710. ZTrace("Clearing ZBuffer");
  711. UpdateState();
  712. m_pdevice3D->ClearZBuffer();
  713. SetZWrite(true, false);
  714. SetZTest(true, false);
  715. } else {
  716. //
  717. // turn off zbuffering for any future drawing
  718. //
  719. SetZWrite(false, false);
  720. SetZTest(false, false);
  721. }
  722. PushState();
  723. }
  724. void RenderCallbackGeos(GeoCallbackDataList& list)
  725. {
  726. GeoCallbackDataList::Iterator iter(list);
  727. while (!iter.End()) {
  728. GeoCallbackData& data = iter.Value();
  729. PushState();
  730. SetTransform(data.m_mat);
  731. data.m_pgeoCallback->RenderCallback(this);
  732. PopState();
  733. iter.Next();
  734. }
  735. list.SetEmpty();
  736. }
  737. void End3DLayer()
  738. {
  739. ZExit("Context::Begin3DLayer");
  740. ZAssert(m_bRendering);
  741. ZAssert(m_bIn3DLayer);
  742. ZAssert(m_bInScene);
  743. //
  744. // Restore the original state
  745. //
  746. PopState();
  747. //
  748. // Render any GeoCallbacks
  749. //
  750. m_bRenderingCallbacks = true;
  751. RenderCallbackGeos(m_listGeoCallbacksSorted);
  752. RenderCallbackGeos(m_listGeoCallbacks);
  753. m_bRenderingCallbacks = false;
  754. //
  755. // Draw decals
  756. //
  757. DrawCachedDecals();
  758. //
  759. // End the 3D layer
  760. //
  761. PopState();
  762. m_bIn3DLayer = false;
  763. }
  764. void BeginScene()
  765. {
  766. if (!m_bInScene) {
  767. m_pdevice3D->BeginScene();
  768. m_bInScene = true;
  769. }
  770. }
  771. void EndScene()
  772. {
  773. if (m_bInScene) {
  774. m_pdevice3D->EndScene();
  775. m_bInScene = false;
  776. }
  777. }
  778. //////////////////////////////////////////////////////////////////////////////
  779. //
  780. // Level of detail
  781. //
  782. //////////////////////////////////////////////////////////////////////////////
  783. void SetLOD(float lod)
  784. {
  785. m_lod = lod;
  786. }
  787. float GetLOD()
  788. {
  789. return m_lod;
  790. }
  791. //////////////////////////////////////////////////////////////////////////////
  792. //
  793. // Get State
  794. //
  795. //////////////////////////////////////////////////////////////////////////////
  796. const Color& GetGlobalColor() const { return m_pstateDevice->m_color ; }
  797. bool GetZTest() const { return m_pstateDevice->m_bZTest ; }
  798. bool GetZWrite() const { return m_pstateDevice->m_bZWrite ; }
  799. bool GetPerspectiveCorrection() const { return m_pstateDevice->m_bPerspectiveCorrection; }
  800. bool GetDither() const { return m_pstateDevice->m_bDither ; }
  801. bool GetColorKey() const { return m_pstateDevice->m_bColorKey ; }
  802. bool GetLinearFilter() const { return m_pstateDevice->m_bLinearFilter ; }
  803. ShadeMode GetShadeMode() const { return m_pstateDevice->m_shadeMode ; }
  804. BlendMode GetBlendMode() const { return m_pstateDevice->m_blendMode ; }
  805. WrapMode GetWrapMode() const { return m_pstateDevice->m_wrapMode ; }
  806. CullMode GetCullMode() const { return m_pstateDevice->m_cullMode ; }
  807. Surface* GetTexture() const { return m_pstateDevice->m_psurfaceTexture ; }
  808. Material* GetMaterial() const { return m_pstateDevice->m_pmaterial ; }
  809. Deformation* GetDeformation() const { return m_pstateDevice->m_pdeform ; }
  810. //////////////////////////////////////////////////////////////////////////////
  811. //
  812. // Efficient State Changes
  813. //
  814. //////////////////////////////////////////////////////////////////////////////
  815. template<class ValueType>
  816. void DoSetState(
  817. const ValueType& value,
  818. ValueType& valueDevice,
  819. ValueType& valueState,
  820. bool bOverride,
  821. const StateChange& st
  822. ) {
  823. if (!m_pstateDevice->m_maskOverride.Test(st)) {
  824. if (value != valueDevice) {
  825. if (!m_pstate->m_maskChanges.Test(st)) {
  826. valueState = valueDevice;
  827. m_pstate->m_maskChanges.Set(st);
  828. }
  829. valueDevice = value;
  830. m_pstateDevice->m_maskChanges.Set(st);
  831. }
  832. if (bOverride) {
  833. m_pstate->m_maskOverride.Set(st);
  834. m_pstateDevice->m_maskOverride.Set(st);
  835. }
  836. }
  837. }
  838. //////////////////////////////////////////////////////////////////////////////
  839. //
  840. // Efficient State Changes
  841. //
  842. //////////////////////////////////////////////////////////////////////////////
  843. void SetGlobalColor(const Color& color, bool bOverride)
  844. {
  845. DoSetState(
  846. color,
  847. m_pstateDevice->m_color,
  848. m_pstate->m_color,
  849. bOverride,
  850. StateChangeColor()
  851. );
  852. }
  853. void SetLinearFilter(bool b, bool bOverride)
  854. {
  855. DoSetState(
  856. b,
  857. m_pstateDevice->m_bLinearFilter,
  858. m_pstate->m_bLinearFilter,
  859. bOverride,
  860. StateChangeLinearFilter()
  861. );
  862. }
  863. void SetPerspectiveCorrection(bool b, bool bOverride)
  864. {
  865. DoSetState(
  866. b,
  867. m_pstateDevice->m_bPerspectiveCorrection,
  868. m_pstate->m_bPerspectiveCorrection,
  869. bOverride,
  870. StateChangePerspectiveCorrection()
  871. );
  872. }
  873. void SetDither(bool b, bool bOverride)
  874. {
  875. DoSetState(
  876. b,
  877. m_pstateDevice->m_bDither,
  878. m_pstate->m_bDither,
  879. bOverride,
  880. StateChangeDither()
  881. );
  882. }
  883. void SetColorKey(bool b, bool bOverride)
  884. {
  885. DoSetState(
  886. b,
  887. m_pstateDevice->m_bColorKey,
  888. m_pstate->m_bColorKey,
  889. bOverride,
  890. StateChangeColorKey()
  891. );
  892. }
  893. void SetZTest(bool b, bool bOverride)
  894. {
  895. DoSetState(
  896. b,
  897. m_pstateDevice->m_bZTest,
  898. m_pstate->m_bZTest,
  899. bOverride,
  900. StateChangeZTest()
  901. );
  902. }
  903. void SetZWrite(bool b, bool bOverride)
  904. {
  905. DoSetState(
  906. b,
  907. m_pstateDevice->m_bZWrite,
  908. m_pstate->m_bZWrite,
  909. bOverride,
  910. StateChangeZWrite()
  911. );
  912. }
  913. void SetShadeMode(ShadeMode shadeMode, bool bOverride)
  914. {
  915. DoSetState(
  916. shadeMode,
  917. m_pstateDevice->m_shadeMode,
  918. m_pstate->m_shadeMode,
  919. bOverride,
  920. StateChangeShadeMode()
  921. );
  922. }
  923. void SetBlendMode(BlendMode blendMode, bool bOverride)
  924. {
  925. DoSetState(
  926. blendMode,
  927. m_pstateDevice->m_blendMode,
  928. m_pstate->m_blendMode,
  929. bOverride,
  930. StateChangeBlendMode()
  931. );
  932. }
  933. void SetWrapMode(WrapMode wrapMode, bool bOverride)
  934. {
  935. DoSetState(
  936. wrapMode,
  937. m_pstateDevice->m_wrapMode,
  938. m_pstate->m_wrapMode,
  939. bOverride,
  940. StateChangeWrapMode()
  941. );
  942. }
  943. void SetCullMode(CullMode cullMode, bool bOverride)
  944. {
  945. DoSetState(
  946. cullMode,
  947. m_pstateDevice->m_cullMode,
  948. m_pstate->m_cullMode,
  949. bOverride,
  950. StateChangeCullMode()
  951. );
  952. }
  953. void SetMaterial(Material* pmaterial, bool bOverride)
  954. {
  955. DoSetState(
  956. TRef<Material>(pmaterial),
  957. m_pstateDevice->m_pmaterial,
  958. m_pstate->m_pmaterial,
  959. bOverride,
  960. StateChangeMaterial()
  961. );
  962. }
  963. void SetTexture(Surface* psurface, bool bOverride)
  964. {
  965. DoSetState(
  966. TRef<Surface>(psurface),
  967. m_pstateDevice->m_psurfaceTexture,
  968. m_pstate->m_psurfaceTexture,
  969. bOverride,
  970. StateChangeTexture()
  971. );
  972. }
  973. void SetDeformation(Deformation* pdeform, bool bOverride)
  974. {
  975. DoSetState(
  976. TRef<Deformation>(pdeform),
  977. m_pstateDevice->m_pdeform,
  978. m_pstate->m_pdeform,
  979. bOverride,
  980. StateChangeDeformation()
  981. );
  982. }
  983. void SetLineWidth(float width, bool bOverride = false)
  984. {
  985. DoSetState(
  986. width,
  987. m_pstateDevice->m_lineWidth,
  988. m_pstate->m_lineWidth,
  989. bOverride,
  990. StateChangeLineWidth()
  991. );
  992. }
  993. //////////////////////////////////////////////////////////////////////////////
  994. //
  995. // Update the device states
  996. //
  997. //////////////////////////////////////////////////////////////////////////////
  998. void UpdateState()
  999. {
  1000. const StateChange& maskChanges = m_pstateDevice->m_maskChanges;
  1001. if (maskChanges.Test(stCommon)) {
  1002. if (maskChanges.Test(StateChangeMatrix())) {
  1003. m_pdevice3D->SetMatrix(m_pstateDevice->m_mat);
  1004. }
  1005. if (maskChanges.Test(StateChangeMaterial())) {
  1006. m_pdevice3D->SetMaterial(m_pstateDevice->m_pmaterial);
  1007. }
  1008. if (maskChanges.Test(StateChangeTexture())) {
  1009. m_pdevice3D->SetTexture(m_pstateDevice->m_psurfaceTexture);
  1010. }
  1011. }
  1012. if (maskChanges.Test(stUncommon)) {
  1013. if (maskChanges.Test(StateChangeDeformation())) {
  1014. m_pdevice3D->SetDeformation(m_pstateDevice->m_pdeform);
  1015. }
  1016. if (maskChanges.Test(StateChangePerspectiveMatrix())) {
  1017. m_pdevice3D->SetPerspectiveMatrix(m_pstateDevice->m_matPerspective);
  1018. }
  1019. if (maskChanges.Test(StateChangeColor())) {
  1020. m_pdevice3D->SetGlobalColor(m_pstateDevice->m_color);
  1021. }
  1022. if (maskChanges.Test(StateChangeClipRect())) {
  1023. m_pdevice3D->SetClipRect(m_pstateDevice->m_rectClip);
  1024. }
  1025. if (maskChanges.Test(StateChangeShadeMode())) {
  1026. m_pdevice3D->SetShadeMode(m_pstateDevice->m_shadeMode);
  1027. }
  1028. if (maskChanges.Test(StateChangeBlendMode())) {
  1029. m_pdevice3D->SetBlendMode(m_pstateDevice->m_blendMode);
  1030. }
  1031. if (maskChanges.Test(StateChangeWrapMode())) {
  1032. m_pdevice3D->SetWrapMode(m_pstateDevice->m_wrapMode);
  1033. }
  1034. if (maskChanges.Test(StateChangeCullMode())) {
  1035. m_pdevice3D->SetCullMode(m_pstateDevice->m_cullMode);
  1036. }
  1037. if (maskChanges.Test(StateChangeZTest())) {
  1038. m_pdevice3D->SetZTest(m_pstateDevice->m_bZTest);
  1039. }
  1040. if (maskChanges.Test(StateChangeZWrite())) {
  1041. m_pdevice3D->SetZWrite(m_pstateDevice->m_bZWrite);
  1042. }
  1043. if (maskChanges.Test(StateChangeLinearFilter())) {
  1044. m_pdevice3D->SetLinearFilter(m_pstateDevice->m_bLinearFilter);
  1045. }
  1046. if (maskChanges.Test(StateChangePerspectiveCorrection())) {
  1047. m_pdevice3D->SetPerspectiveCorrection(m_pstateDevice->m_bPerspectiveCorrection);
  1048. }
  1049. if (maskChanges.Test(StateChangeDither())) {
  1050. m_pdevice3D->SetDither(m_pstateDevice->m_bDither);
  1051. }
  1052. if (maskChanges.Test(StateChangeColorKey())) {
  1053. m_pdevice3D->SetColorKey(m_pstateDevice->m_bColorKey);
  1054. }
  1055. if (maskChanges.Test(StateChangeLineWidth())) {
  1056. m_pdevice3D->SetLineWidth(m_pstateDevice->m_lineWidth);
  1057. }
  1058. }
  1059. m_pstateDevice->m_maskChanges.Clear(StateChangeAll());
  1060. }
  1061. //////////////////////////////////////////////////////////////////////////////
  1062. //
  1063. // Push and Pop
  1064. //
  1065. //////////////////////////////////////////////////////////////////////////////
  1066. void PushState()
  1067. {
  1068. m_pstate = new State(m_pstate);
  1069. }
  1070. void PopState()
  1071. {
  1072. const StateChange& maskChanges = m_pstate->m_maskChanges;
  1073. if (maskChanges.Test(stCommon)) {
  1074. if (maskChanges.Test(StateChangeMatrix())) {
  1075. m_pstateDevice->m_mat = m_pstate->m_mat;
  1076. }
  1077. if (maskChanges.Test(StateChangeMaterial())) {
  1078. m_pstateDevice->m_pmaterial = m_pstate->m_pmaterial;
  1079. }
  1080. if (maskChanges.Test(StateChangeTexture())) {
  1081. m_pstateDevice->m_psurfaceTexture = m_pstate->m_psurfaceTexture;
  1082. }
  1083. }
  1084. if (maskChanges.Test(stUncommon)) {
  1085. if (maskChanges.Test(StateChangeDeformation())) {
  1086. m_pstateDevice->m_pdeform = m_pstate->m_pdeform;
  1087. }
  1088. if (maskChanges.Test(StateChangeClipPlanes())) {
  1089. while (m_pstateDevice->m_countClipPlanes > m_pstate->m_countClipPlanes) {
  1090. m_pdevice3D->RemoveClipPlane(0);
  1091. m_pstateDevice->m_countClipPlanes--;
  1092. }
  1093. }
  1094. if (maskChanges.Test(StateChangeColor())) {
  1095. m_pstateDevice->m_color = m_pstate->m_color;
  1096. }
  1097. if (maskChanges.Test(StateChangeClipRect())) {
  1098. m_pstateDevice->m_rectClip = m_pstate->m_rectClip;
  1099. }
  1100. if (maskChanges.Test(StateChangePerspectiveMatrix())) {
  1101. m_pstateDevice->m_matPerspective = m_pstate->m_matPerspective;
  1102. }
  1103. if (maskChanges.Test(StateChangeShadeMode())) {
  1104. m_pstateDevice->m_shadeMode = m_pstate->m_shadeMode;
  1105. }
  1106. if (maskChanges.Test(StateChangeBlendMode())) {
  1107. m_pstateDevice->m_blendMode = m_pstate->m_blendMode;
  1108. }
  1109. if (maskChanges.Test(StateChangeWrapMode())) {
  1110. m_pstateDevice->m_wrapMode = m_pstate->m_wrapMode;
  1111. }
  1112. if (maskChanges.Test(StateChangeCullMode())) {
  1113. m_pstateDevice->m_cullMode = m_pstate->m_cullMode;
  1114. }
  1115. if (maskChanges.Test(StateChangeZTest())) {
  1116. m_pstateDevice->m_bZTest = m_pstate->m_bZTest;
  1117. }
  1118. if (maskChanges.Test(StateChangeZWrite())) {
  1119. m_pstateDevice->m_bZWrite = m_pstate->m_bZWrite;
  1120. }
  1121. if (maskChanges.Test(StateChangeLinearFilter())) {
  1122. m_pstateDevice->m_bLinearFilter = m_pstate->m_bLinearFilter;
  1123. }
  1124. if (maskChanges.Test(StateChangePerspectiveCorrection())) {
  1125. m_pstateDevice->m_bPerspectiveCorrection = m_pstate->m_bPerspectiveCorrection;
  1126. }
  1127. if (maskChanges.Test(StateChangeDither())) {
  1128. m_pstateDevice->m_bDither = m_pstate->m_bDither;
  1129. }
  1130. if (maskChanges.Test(StateChangeColorKey())) {
  1131. m_pstateDevice->m_bColorKey = m_pstate->m_bColorKey;
  1132. }
  1133. if (maskChanges.Test(StateChangeLineWidth())) {
  1134. m_pstateDevice->m_lineWidth = m_pstate->m_lineWidth;
  1135. }
  1136. }
  1137. m_pstateDevice->m_maskChanges.Set(m_pstate->m_maskChanges);
  1138. m_pstateDevice->m_maskOverride.Clear(m_pstate->m_maskOverride);
  1139. m_pstate = m_pstate->m_pnext;
  1140. }
  1141. //////////////////////////////////////////////////////////////////////////////
  1142. //
  1143. // Clipping Rect
  1144. //
  1145. //////////////////////////////////////////////////////////////////////////////
  1146. Point Transform2D(const Point& point)
  1147. {
  1148. Point pointImage;
  1149. ZVerify(TransformLocalToImage(Vector(point.X(), point.Y(), 0), pointImage));
  1150. return pointImage;
  1151. }
  1152. WinRect GetSurfaceClipRect()
  1153. {
  1154. return
  1155. WinRect(
  1156. int(m_pstateDevice->m_rectClip.XMin()),
  1157. m_psurface->GetSize().Y() - int(m_pstateDevice->m_rectClip.YMax()),
  1158. int(m_pstateDevice->m_rectClip.XMax()),
  1159. m_psurface->GetSize().Y() - int(m_pstateDevice->m_rectClip.YMin())
  1160. );
  1161. }
  1162. void Clip(const Rect& rect)
  1163. {
  1164. ZAssert(!m_bIn3DLayer);
  1165. if (!m_pstate->m_maskChanges.Test(StateChangeClipRect())) {
  1166. m_pstate->m_rectClip = m_pstateDevice->m_rectClip;
  1167. m_pstate->m_maskChanges.Set(StateChangeClipRect());
  1168. }
  1169. m_pstateDevice->m_rectClip.Intersect(
  1170. Rect(
  1171. Transform2D(rect.Min()),
  1172. Transform2D(rect.Max())
  1173. )
  1174. );
  1175. m_pstateDevice->m_maskChanges.Set(StateChangeClipRect());
  1176. }
  1177. //////////////////////////////////////////////////////////////////////////////
  1178. //
  1179. // Clipping planes
  1180. //
  1181. //////////////////////////////////////////////////////////////////////////////
  1182. void AddClipPlane(const Plane& plane)
  1183. {
  1184. if (!m_pstate->m_maskChanges.Test(StateChangeClipPlanes())) {
  1185. m_pstate->m_countClipPlanes = m_pstateDevice->m_countClipPlanes;
  1186. m_pstate->m_maskChanges.Set(StateChangeClipPlanes());
  1187. }
  1188. UpdateState();
  1189. m_pdevice3D->AddClipPlane(plane);
  1190. m_pstateDevice->m_countClipPlanes++;
  1191. }
  1192. //////////////////////////////////////////////////////////////////////////////
  1193. //
  1194. // 3D Modeling Transforms
  1195. //
  1196. //////////////////////////////////////////////////////////////////////////////
  1197. void PreMatrixChanged()
  1198. {
  1199. ZAssert(m_bIn3DLayer);
  1200. if (!m_pstate->m_maskChanges.Test(StateChangeMatrix())) {
  1201. m_pstate->m_mat = m_pstateDevice->m_mat;
  1202. m_pstate->m_maskChanges.Set(StateChangeMatrix());
  1203. }
  1204. m_pstateDevice->m_maskChanges.Set(StateChangeMatrix());
  1205. }
  1206. void SetTransform(const Matrix& mat)
  1207. {
  1208. PreMatrixChanged();
  1209. m_pstateDevice->m_mat = mat;
  1210. }
  1211. void Multiply(const Matrix& mat)
  1212. {
  1213. PreMatrixChanged();
  1214. m_pstateDevice->m_mat.PreMultiply(mat);
  1215. }
  1216. void Rotate(const Vector& vec, float angle)
  1217. {
  1218. PreMatrixChanged();
  1219. m_pstateDevice->m_mat.PreRotate(vec, angle);
  1220. }
  1221. void Translate(const Vector& vec)
  1222. {
  1223. PreMatrixChanged();
  1224. m_pstateDevice->m_mat.PreTranslate(vec);
  1225. }
  1226. void Scale(const Vector& vec)
  1227. {
  1228. PreMatrixChanged();
  1229. m_pstateDevice->m_mat.PreScale(vec);
  1230. }
  1231. void Scale3(float scale)
  1232. {
  1233. PreMatrixChanged();
  1234. m_pstateDevice->m_mat.PreScale(scale);
  1235. }
  1236. //////////////////////////////////////////////////////////////////////////////
  1237. //
  1238. // 2D Modeling Transforms
  1239. //
  1240. //////////////////////////////////////////////////////////////////////////////
  1241. void PrePerspectiveMatrixChanged()
  1242. {
  1243. ZAssert(!m_bIn3DLayer);
  1244. if (!m_pstate->m_maskChanges.Test(StateChangePerspectiveMatrix())) {
  1245. m_pstate->m_matPerspective = m_pstateDevice->m_matPerspective;
  1246. m_pstate->m_maskChanges.Set(StateChangePerspectiveMatrix());
  1247. }
  1248. m_pstateDevice->m_maskChanges.Set(StateChangePerspectiveMatrix());
  1249. }
  1250. void SetMatrix(const Matrix2& mat)
  1251. {
  1252. PrePerspectiveMatrixChanged();
  1253. m_pstateDevice->m_matPerspective = mat;
  1254. }
  1255. void Multiply(const Matrix2& mat)
  1256. {
  1257. PrePerspectiveMatrixChanged();
  1258. m_pstateDevice->m_matPerspective.PreMultiply(mat);
  1259. }
  1260. void Rotate(float angle)
  1261. {
  1262. PrePerspectiveMatrixChanged();
  1263. m_pstateDevice->m_matPerspective.PreRotate(Vector(0, 0, 1), angle);
  1264. }
  1265. void Translate(const Point& point)
  1266. {
  1267. PrePerspectiveMatrixChanged();
  1268. m_pstateDevice->m_matPerspective.PreTranslate(Vector(point.X(), point.Y(), 0));
  1269. }
  1270. void Scale(const Point& point)
  1271. {
  1272. PrePerspectiveMatrixChanged();
  1273. m_pstateDevice->m_matPerspective.PreScale(Vector(point.X(), point.Y(), 0));
  1274. }
  1275. void Scale2(float scale)
  1276. {
  1277. PrePerspectiveMatrixChanged();
  1278. m_pstateDevice->m_matPerspective.PreScale(Vector(scale, scale, 1));
  1279. }
  1280. void SetPerspectiveMatrix(const Matrix& mat)
  1281. {
  1282. PrePerspectiveMatrixChanged();
  1283. m_pstateDevice->m_matPerspective.PreMultiply(mat);
  1284. }
  1285. //////////////////////////////////////////////////////////////////////////////
  1286. //
  1287. // Transform Operations
  1288. //
  1289. //////////////////////////////////////////////////////////////////////////////
  1290. const Matrix& GetLocalToEyeMatrix()
  1291. {
  1292. return m_pstateDevice->m_mat;
  1293. }
  1294. const Matrix& GetEyeToLocalMatrix()
  1295. {
  1296. UpdateState();
  1297. return m_pdevice3D->GetInverseModelMatrix();
  1298. }
  1299. Vector TransformEyeToLocal(const Vector& vec)
  1300. {
  1301. return GetEyeToLocalMatrix().Transform(vec);
  1302. }
  1303. Vector TransformLocalToEye(const Vector& vec)
  1304. {
  1305. return GetLocalToEyeMatrix().Transform(vec);
  1306. }
  1307. Vector TransformDirectionToEye(const Vector& vec)
  1308. {
  1309. HVector hvec = m_pstateDevice->m_mat.Transform(HVector(vec.X(), vec.Y(), vec.Z(), 0));
  1310. return Vector(hvec.X(), hvec.Y(), hvec.Z());
  1311. }
  1312. bool TransformEyeToImage(const Vector& vecEye, Point& point)
  1313. {
  1314. HVector hvecImage = m_pstateDevice->m_matPerspective.Transform(HVector(vecEye));
  1315. if (hvecImage.W() < 0) {
  1316. return false;
  1317. }
  1318. float rhw = 1.0f / hvecImage.W();
  1319. point =
  1320. Point(
  1321. rhw * hvecImage.X(),
  1322. rhw * hvecImage.Y()
  1323. );
  1324. return true;
  1325. }
  1326. bool TransformDirectionToImage(const Vector& vec, Point& point)
  1327. {
  1328. return TransformEyeToImage(TransformDirectionToEye(vec), point);
  1329. }
  1330. bool TransformLocalToImage(const Vector& vec, Point& point)
  1331. {
  1332. return TransformEyeToImage(TransformLocalToEye(vec), point);
  1333. }
  1334. WinPoint TransformImageToSurface(const Point& point)
  1335. {
  1336. const WinPoint& size = m_psurface->GetSize();
  1337. return
  1338. WinPoint(
  1339. MakeInt(point.X()),
  1340. size.Y() - MakeInt(point.Y())
  1341. );
  1342. }
  1343. float GetImageRadius(const Vector& vec, float radius)
  1344. {
  1345. Vector vecEye = TransformLocalToEye(vec);
  1346. Point point;
  1347. if (TransformEyeToImage(vecEye, point)) {
  1348. Point pointRadius;
  1349. if (TransformEyeToImage(vecEye + Vector(radius, 0, 0), pointRadius)) {
  1350. return pointRadius.X() - point.X();
  1351. }
  1352. }
  1353. return radius;
  1354. }
  1355. //////////////////////////////////////////////////////////////////////////////
  1356. //
  1357. // Lighting
  1358. //
  1359. //////////////////////////////////////////////////////////////////////////////
  1360. void DirectionalLight(const Vector& vec, const Color& color)
  1361. {
  1362. UpdateState();
  1363. m_pdevice3D->DirectionalLight(vec, color);
  1364. }
  1365. void BidirectionalLight(const Vector& direction, const Color& color, const Color& colorAlt)
  1366. {
  1367. UpdateState();
  1368. m_pdevice3D->BidirectionalLight(direction, color, colorAlt);
  1369. }
  1370. void SetAmbientLevel(float ambientLevel)
  1371. {
  1372. // , this should be on the state stack
  1373. m_pdevice3D->SetAmbientLevel(ambientLevel);
  1374. }
  1375. //////////////////////////////////////////////////////////////////////////////
  1376. //
  1377. // Callbacks
  1378. //
  1379. //////////////////////////////////////////////////////////////////////////////
  1380. void DrawCallbackGeo(IGeoCallback* pgeoCallback, bool bSortObject)
  1381. {
  1382. if (m_bIn3DLayer) {
  1383. if (m_bRenderingCallbacks) {
  1384. PushState();
  1385. pgeoCallback->RenderCallback(this);
  1386. PopState();
  1387. } else {
  1388. if (bSortObject) {
  1389. GeoCallbackData dataNew;
  1390. dataNew.m_mat = m_pstateDevice->m_mat;
  1391. dataNew.m_pgeoCallback = pgeoCallback;
  1392. dataNew.m_distance = m_pstateDevice->m_mat.GetTranslate().LengthSquared();
  1393. m_listGeoCallbacksSorted.InsertSorted(dataNew);
  1394. } else {
  1395. m_listGeoCallbacks.PushFront();
  1396. GeoCallbackData& data = m_listGeoCallbacks.GetFront();
  1397. data.m_mat = m_pstateDevice->m_mat;
  1398. data.m_pgeoCallback = pgeoCallback;
  1399. }
  1400. }
  1401. } else {
  1402. //
  1403. // Drawing a geo in 2D. Draw it now even though it is a callback geo
  1404. //
  1405. pgeoCallback->RenderCallback(this);
  1406. }
  1407. }
  1408. //////////////////////////////////////////////////////////////////////////////
  1409. //
  1410. // Buffers
  1411. //
  1412. //////////////////////////////////////////////////////////////////////////////
  1413. void SizeVertexBuffer(int count)
  1414. {
  1415. if (m_countVertexBuffer < count) {
  1416. m_countVertexBuffer = count;
  1417. m_pvertexBuffer = (Vertex*)realloc(m_pvertexBuffer, sizeof(Vertex) * count);
  1418. }
  1419. }
  1420. void SizeIndexBuffer(int count)
  1421. {
  1422. if (m_countIndexBuffer < count) {
  1423. m_countIndexBuffer = count;
  1424. m_pindexBuffer = (MeshIndex*)realloc(m_pindexBuffer, sizeof(MeshIndex) * count);
  1425. }
  1426. }
  1427. Vertex* GetVertexBuffer(int count)
  1428. {
  1429. SizeVertexBuffer(count);
  1430. return m_pvertexBuffer;
  1431. }
  1432. MeshIndex* GetIndexBuffer(int count)
  1433. {
  1434. SizeIndexBuffer(count);
  1435. return m_pindexBuffer;
  1436. }
  1437. //////////////////////////////////////////////////////////////////////////////
  1438. //
  1439. // Buffers implemented by Device3D
  1440. //
  1441. //////////////////////////////////////////////////////////////////////////////
  1442. VertexL* GetVertexLBuffer(int count)
  1443. {
  1444. return m_pdevice3D->GetVertexLBuffer(count);
  1445. }
  1446. VertexScreen* GetVertexScreenBuffer(int count)
  1447. {
  1448. return m_pdevice3D->GetVertexScreenBuffer(count);
  1449. }
  1450. //////////////////////////////////////////////////////////////////////////////
  1451. //
  1452. // Context Drawing modes
  1453. //
  1454. //////////////////////////////////////////////////////////////////////////////
  1455. void DD2D()
  1456. {
  1457. ZAssert(m_bRendering);
  1458. ZAssert(!m_bIn3DLayer);
  1459. EndScene();
  1460. UpdateState();
  1461. }
  1462. void Texture2D()
  1463. {
  1464. ZAssert(m_bRendering);
  1465. ZAssert(!m_bIn3DLayer);
  1466. BeginScene();
  1467. UpdateState();
  1468. }
  1469. void Mode3D()
  1470. {
  1471. ZAssert(m_bRendering);
  1472. if (!m_bIn3DLayer) {
  1473. Texture2D();
  1474. } else {
  1475. ZAssert(m_bInScene);
  1476. UpdateState();
  1477. }
  1478. }
  1479. //////////////////////////////////////////////////////////////////////////////
  1480. //
  1481. // External Rendering Calls
  1482. //
  1483. //////////////////////////////////////////////////////////////////////////////
  1484. void DrawTriangles(const Vertex* pvertex, int vcount, const MeshIndex* pindex, int icount)
  1485. {
  1486. if (icount != 0) {
  1487. Mode3D();
  1488. m_pdevice3D->DrawTriangles(pvertex, vcount, pindex, icount);
  1489. }
  1490. }
  1491. void DrawTriangles(const VertexL* pvertex, int vcount, const MeshIndex* pindex, int icount)
  1492. {
  1493. if (icount != 0) {
  1494. Mode3D();
  1495. m_pdevice3D->DrawTriangles(pvertex, vcount, pindex, icount);
  1496. }
  1497. }
  1498. void DrawTriangles(const VertexScreen* pvertex, int vcount, const MeshIndex* pindex, int icount)
  1499. {
  1500. if (icount != 0) {
  1501. Mode3D();
  1502. m_pdevice3D->DrawTriangles(pvertex, vcount, pindex, icount);
  1503. }
  1504. }
  1505. void DrawTriangles(const D3DVertex* pvertex, int vcount, const MeshIndex* pindex, int icount)
  1506. {
  1507. Mode3D();
  1508. m_pdevice3D->DrawTriangles(pvertex, vcount, pindex, icount);
  1509. }
  1510. void DrawLineStrip(const Vertex* pvertex, int vcount)
  1511. {
  1512. int icount = (vcount - 1) * 2;
  1513. MeshIndex* pindex = GetIndexBuffer(icount);
  1514. for (int index = 0; index < vcount - 1; index++) {
  1515. pindex[index * 2 ] = index;
  1516. pindex[index * 2 + 1] = index + 1;
  1517. }
  1518. DrawLines(pvertex, vcount, pindex, icount);
  1519. }
  1520. void DrawLineStrip(const VertexL* pvertex, int vcount)
  1521. {
  1522. int icount = (vcount - 1) * 2;
  1523. MeshIndex* pindex = GetIndexBuffer(icount);
  1524. for (int index = 0; index < vcount - 1; index++) {
  1525. pindex[index * 2 ] = index;
  1526. pindex[index * 2 + 1] = index + 1;
  1527. }
  1528. DrawLines(pvertex, vcount, pindex, icount);
  1529. }
  1530. void DrawLineStrip(const VertexScreen* pvertex, int vcount)
  1531. {
  1532. int icount = (vcount - 1) * 2;
  1533. MeshIndex* pindex = GetIndexBuffer(icount);
  1534. for (int index = 0; index < vcount - 1; index++) {
  1535. pindex[index * 2 ] = index;
  1536. pindex[index * 2 + 1] = index + 1;
  1537. }
  1538. DrawLines(pvertex, vcount, pindex, icount);
  1539. }
  1540. void DrawLineStrip(const D3DVertex* pvertex, int vcount)
  1541. {
  1542. int icount = (vcount - 1) * 2;
  1543. MeshIndex* pindex = GetIndexBuffer(icount);
  1544. for (int index = 0; index < vcount - 1; index++) {
  1545. pindex[index * 2 ] = index;
  1546. pindex[index * 2 + 1] = index + 1;
  1547. }
  1548. DrawLines(pvertex, vcount, pindex, icount);
  1549. }
  1550. void DrawLines(const Vertex* pvertex, int vcount, const MeshIndex* pindex, int icount)
  1551. {
  1552. if (icount != 0) {
  1553. Mode3D();
  1554. m_pdevice3D->DrawLines(pvertex, vcount, pindex, icount);
  1555. }
  1556. }
  1557. void DrawLines(const VertexL* pvertex, int vcount, const MeshIndex* pindex, int icount)
  1558. {
  1559. if (icount != 0) {
  1560. Mode3D();
  1561. m_pdevice3D->DrawLines(pvertex, vcount, pindex, icount);
  1562. }
  1563. }
  1564. void DrawLines(const VertexScreen* pvertex, int vcount, const MeshIndex* pindex, int icount)
  1565. {
  1566. if (icount != 0) {
  1567. Mode3D();
  1568. m_pdevice3D->DrawLines(pvertex, vcount, pindex, icount);
  1569. }
  1570. }
  1571. void DrawLines(const D3DVertex* pvertex, int vcount, const MeshIndex* pindex, int icount)
  1572. {
  1573. Mode3D();
  1574. m_pdevice3D->DrawLines(pvertex, vcount, pindex, icount);
  1575. }
  1576. void DrawPoints(const Vertex* pvertex, int vcount)
  1577. {
  1578. if (vcount != 0) {
  1579. Mode3D();
  1580. m_pdevice3D->DrawPoints(pvertex, vcount);
  1581. }
  1582. }
  1583. void DrawPoints(const VertexL* pvertex, int vcount)
  1584. {
  1585. if (vcount != 0) {
  1586. Mode3D();
  1587. m_pdevice3D->DrawPoints(pvertex, vcount);
  1588. }
  1589. }
  1590. void DrawPoints(const VertexScreen* pvertex, int vcount)
  1591. {
  1592. if (vcount != 0) {
  1593. Mode3D();
  1594. m_pdevice3D->DrawPoints(pvertex, vcount);
  1595. }
  1596. }
  1597. void DrawPoints(const D3DVertex* pvertex, int vcount)
  1598. {
  1599. Mode3D();
  1600. m_pdevice3D->DrawPoints(pvertex, vcount);
  1601. }
  1602. //////////////////////////////////////////////////////////////////////////////
  1603. //
  1604. // Vector Rendering Calls
  1605. //
  1606. //////////////////////////////////////////////////////////////////////////////
  1607. void DrawTriangles(const TVector<Vertex>& vertices, const TVector<MeshIndex>& indices)
  1608. {
  1609. DrawTriangles(&(vertices[0]), vertices.GetCount(), &(indices[0]), indices.GetCount());
  1610. }
  1611. void DrawTriangles(const TVector<VertexL>& vertices, const TVector<MeshIndex>& indices)
  1612. {
  1613. DrawTriangles(&(vertices[0]), vertices.GetCount(), &(indices[0]), indices.GetCount());
  1614. }
  1615. void DrawTriangles(const TVector<D3DVertex>& vertices, const TVector<MeshIndex>& indices)
  1616. {
  1617. DrawTriangles(&(vertices[0]), vertices.GetCount(), &(indices[0]), indices.GetCount());
  1618. }
  1619. void DrawLines(const TVector<Vertex>& vertices, const TVector<MeshIndex>& indices)
  1620. {
  1621. DrawLines(&(vertices[0]), vertices.GetCount(), &(indices[0]), indices.GetCount());
  1622. }
  1623. void DrawLines(const TVector<VertexL>& vertices, const TVector<MeshIndex>& indices)
  1624. {
  1625. DrawLines(&(vertices[0]), vertices.GetCount(), &(indices[0]), indices.GetCount());
  1626. }
  1627. void DrawLines(const TVector<D3DVertex>& vertices, const TVector<MeshIndex>& indices)
  1628. {
  1629. DrawLines(&(vertices[0]), vertices.GetCount(), &(indices[0]), indices.GetCount());
  1630. }
  1631. void DrawPoints(const TVector<Vertex>& vertices)
  1632. {
  1633. DrawPoints(&(vertices[0]), vertices.GetCount());
  1634. }
  1635. void DrawPoints(const TVector<VertexL>& vertices)
  1636. {
  1637. DrawPoints(&(vertices[0]), vertices.GetCount());
  1638. }
  1639. void DrawPoints(const TVector<D3DVertex>& vertices)
  1640. {
  1641. DrawPoints(&(vertices[0]), vertices.GetCount());
  1642. }
  1643. //////////////////////////////////////////////////////////////////////////////
  1644. //
  1645. // Add a new Decal
  1646. //
  1647. //////////////////////////////////////////////////////////////////////////////
  1648. Decal& AddDecal(TVector<DecalSet>& vdecalSet, Surface* psurface)
  1649. {
  1650. //
  1651. // find the associated decal set
  1652. //
  1653. int countDecalSets = vdecalSet.GetCount();
  1654. for(int indexSet = 0; indexSet < countDecalSets; indexSet++) {
  1655. const DecalSet& set = vdecalSet[indexSet];
  1656. if (psurface == set.m_psurface) {
  1657. break;
  1658. }
  1659. }
  1660. //
  1661. // Add a new decal set
  1662. //
  1663. if (indexSet == countDecalSets) {
  1664. vdecalSet.PushEnd();
  1665. vdecalSet.Get(indexSet).m_psurface = psurface;
  1666. }
  1667. DecalSet& set = vdecalSet.Get(indexSet);
  1668. //
  1669. // Return a reference to the newly created decal
  1670. //
  1671. set.m_vdecal.PushEnd();
  1672. return set.m_vdecal.Get(set.m_vdecal.GetCount() - 1);
  1673. }
  1674. //////////////////////////////////////////////////////////////////////////////
  1675. //
  1676. // Draw a Decal so that it faces the eye point and lies along a direction vector
  1677. //
  1678. //////////////////////////////////////////////////////////////////////////////
  1679. float DrawDecal(
  1680. Surface* psurface,
  1681. const Color& color,
  1682. const Vector& positionLocal,
  1683. const Vector& forwardLocal,
  1684. const Vector& rightLocal,
  1685. float scale,
  1686. float angle,
  1687. BlendMode blendMode
  1688. ) {
  1689. ZAssert(
  1690. blendMode == BlendModeSource
  1691. || blendMode == BlendModeAdd
  1692. );
  1693. const Matrix& mat = GetLocalToEyeMatrix();
  1694. Vector position = mat.Transform(positionLocal);
  1695. if (position.Z() < 0) {
  1696. Decal& decal =
  1697. AddDecal(
  1698. blendMode == BlendModeSource
  1699. ? m_vdecalSetOpaque
  1700. : m_vdecalSet,
  1701. psurface
  1702. );
  1703. float sizeScale = 4.0f / (position.Z() * position.Z());
  1704. float scaleMat = mat.GetScale();
  1705. decal.m_position = position;
  1706. decal.m_color = color;
  1707. decal.m_angle = angle;
  1708. decal.m_scale = scaleMat * scale;
  1709. if (forwardLocal.IsZero()) {
  1710. decal.m_forward = Vector(0, 0, 0);
  1711. return sizeScale * decal.m_scale * decal.m_scale;
  1712. } else {
  1713. decal.m_forward = scaleMat * mat.TransformDirection(forwardLocal);
  1714. if (rightLocal.IsZero()) {
  1715. Vector right = decal.m_forward.GetOrthogonalVector();
  1716. float lengthForward = forwardLocal.Length();
  1717. float lengthRight = decal.m_scale * lengthForward;
  1718. decal.m_right = lengthRight * right.Normalize();
  1719. return sizeScale * lengthForward * lengthRight;
  1720. } else {
  1721. decal.m_right = scaleMat * mat.TransformDirection(rightLocal);
  1722. return sizeScale * decal.m_right.Length() * decal.m_forward.Length();
  1723. }
  1724. }
  1725. }
  1726. return 0;
  1727. }
  1728. //////////////////////////////////////////////////////////////////////////////
  1729. //
  1730. // Decal Drawing
  1731. //
  1732. //////////////////////////////////////////////////////////////////////////////
  1733. void DrawVDecalSet(TVector<DecalSet>& vdecalSet)
  1734. {
  1735. //
  1736. // Iterate through the decal sets
  1737. //
  1738. int countDecalSets = vdecalSet.GetCount();
  1739. for(int indexSet = 0; indexSet < countDecalSets; indexSet++) {
  1740. DecalSet& set = vdecalSet.Get(indexSet);
  1741. int countDecal = set.m_vdecal.GetCount();
  1742. if (countDecal > 0) {
  1743. SetTexture(set.m_psurface, false);
  1744. VertexL* pvertex = GetVertexLBuffer(countDecal * 4);
  1745. MeshIndex* pindex = GetIndexBuffer(countDecal * 6);
  1746. for (int index = 0; index < countDecal; index++) {
  1747. set.m_vdecal[index].GetVertices(pvertex + index * 4);
  1748. pindex[index * 6 + 0] = index * 4 + 0;
  1749. pindex[index * 6 + 1] = index * 4 + 2;
  1750. pindex[index * 6 + 2] = index * 4 + 1;
  1751. pindex[index * 6 + 3] = index * 4 + 0;
  1752. pindex[index * 6 + 4] = index * 4 + 3;
  1753. pindex[index * 6 + 5] = index * 4 + 2;
  1754. }
  1755. UpdateState();
  1756. m_pdevice3D->DrawTriangles(
  1757. &pvertex[0],
  1758. index * 4,
  1759. &pindex[0],
  1760. index * 6
  1761. );
  1762. set.m_vdecal.SetCount(0);
  1763. }
  1764. }
  1765. }
  1766. void DrawCachedDecals()
  1767. {
  1768. //
  1769. // Render States
  1770. //
  1771. SetCullMode(CullModeNone, false);
  1772. SetShadeMode(ShadeModeFlat, false);
  1773. SetTransform(Matrix::GetIdentity());
  1774. //
  1775. // Opaque decals first
  1776. //
  1777. SetBlendMode(BlendModeSource, false);
  1778. SetZWrite(true, false);
  1779. DrawVDecalSet(m_vdecalSetOpaque);
  1780. //
  1781. // Emissive Transparent decals
  1782. //
  1783. SetBlendMode(BlendModeAdd, false);
  1784. SetZWrite(false, false);
  1785. DrawVDecalSet(m_vdecalSet);
  1786. }
  1787. //////////////////////////////////////////////////////////////////////////////
  1788. //
  1789. // Performance Counters
  1790. //
  1791. //////////////////////////////////////////////////////////////////////////////
  1792. #ifdef EnablePerformanceCounters
  1793. int GetPerformanceCounter(Counter counter)
  1794. {
  1795. if (counter == CounterDrawStrings)
  1796. return m_countDrawString;
  1797. else if (counter == CounterDrawStringChars)
  1798. return m_countDrawStringChars;
  1799. return m_pdevice3D->GetPerformanceCounter(counter);
  1800. }
  1801. void ResetPerformanceCounters()
  1802. {
  1803. m_countDrawString = 0;
  1804. m_countDrawStringChars = 0;
  1805. m_pdevice3D->ResetPerformanceCounters();
  1806. }
  1807. #endif
  1808. };
  1809. //////////////////////////////////////////////////////////////////////////////
  1810. //
  1811. // Constructor
  1812. //
  1813. //////////////////////////////////////////////////////////////////////////////
  1814. TRef<PrivateContext> CreateContextImpl(PrivateSurface* psurface)
  1815. {
  1816. return new ContextImpl(psurface);
  1817. }