device3d.cpp 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280
  1. #include "pch.h"
  2. // compile this file for speed
  3. #pragma optimize("t", on)
  4. // #pragma optimize("s", on)
  5. //////////////////////////////////////////////////////////////////////////////
  6. //
  7. // Clipping Planes
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. const int g_maxCountPlanes = 8;
  11. typedef BYTE Code;
  12. const Code ClipFront = 0x01;
  13. const Code ClipBack = 0x02;
  14. const Code ClipLeft = 0x04;
  15. const Code ClipRight = 0x08;
  16. const Code ClipBottom = 0x10;
  17. const Code ClipTop = 0x20;
  18. const Code ClipPlane = 0x40;
  19. //////////////////////////////////////////////////////////////////////////////
  20. //
  21. // Transformed and Lit Vertex
  22. //
  23. //////////////////////////////////////////////////////////////////////////////
  24. class VertexTL {
  25. public:
  26. HVector m_pos;
  27. Color m_color;
  28. Point m_pointTexture;
  29. MeshIndex m_index;
  30. Code m_code;
  31. VertexTL()
  32. {
  33. }
  34. VertexTL(const VertexTL& v) :
  35. m_pos(v.m_pos),
  36. m_color(v.m_color),
  37. m_pointTexture(v.m_pointTexture),
  38. m_index(v.m_index),
  39. m_code(v.m_code)
  40. {
  41. }
  42. void Interpolate(const VertexTL& vertex0, const VertexTL& vertex1, float alpha)
  43. {
  44. float beta = 1 - alpha;
  45. m_pos = ::Interpolate(vertex0.m_pos, vertex1.m_pos, alpha);
  46. m_color =
  47. Color(
  48. alpha * vertex1.m_color.GetRed() + beta * vertex0.m_color.GetRed() ,
  49. alpha * vertex1.m_color.GetGreen() + beta * vertex0.m_color.GetGreen(),
  50. alpha * vertex1.m_color.GetBlue() + beta * vertex0.m_color.GetBlue() ,
  51. alpha * vertex1.m_color.GetAlpha() + beta * vertex0.m_color.GetAlpha()
  52. );
  53. m_pointTexture = ::Interpolate(vertex0.m_pointTexture, vertex1.m_pointTexture, alpha);
  54. }
  55. void UpdateClipCode()
  56. {
  57. m_code = 0;
  58. if (m_pos.x < -m_pos.w) m_code |= ClipLeft;
  59. if (m_pos.x > m_pos.w) m_code |= ClipRight;
  60. if (m_pos.y < -m_pos.w) m_code |= ClipBottom;
  61. if (m_pos.y > m_pos.w) m_code |= ClipTop;
  62. if (m_pos.z < 0 ) m_code |= ClipFront;
  63. if (m_pos.z > m_pos.w) m_code |= ClipBack;
  64. }
  65. void UpdateClipCode(const Plane& plane, Code code)
  66. {
  67. if (plane.Distance(m_pos) <= 0) {
  68. m_code |= code;
  69. }
  70. }
  71. };
  72. //////////////////////////////////////////////////////////////////////////////
  73. //
  74. // Device3D
  75. //
  76. //////////////////////////////////////////////////////////////////////////////
  77. class Device3D : public IDevice3D {
  78. //
  79. // Types
  80. //
  81. typedef void (Device3D::*PFNClip)(VertexTL* pvertex, int vcount, const MeshIndex* pindex, int icount);
  82. typedef void (Device3D::*PFNDraw)(const VertexScreen* pvertex, int vcount, const MeshIndex* pindex, int icount);
  83. typedef void (Device3D::*PFNVertex)(const Vertex* pvertex, int vcount, const MeshIndex* pindex, int icount, PFNClip pfnClip, PFNDraw pfnDraw);
  84. typedef void (Device3D::*PFNVertexL)(const VertexL* pvertex, int vcount, const MeshIndex* pindex, int icount, PFNClip pfnClip, PFNDraw pfnDraw);
  85. //
  86. // Interfaces
  87. //
  88. TRef<Rasterizer> m_prasterizer;
  89. //
  90. // Current state
  91. //
  92. Point m_sizeSurface;
  93. Rect m_rectClip;
  94. Rect m_rectClipScreen;
  95. bool m_bClip;
  96. bool m_bZTest;
  97. bool m_bZWrite;
  98. ShadeMode m_shadeMode;
  99. BlendMode m_blendMode;
  100. PFNVertexL m_pfnTransform;
  101. PFNVertex m_pfnLightVertex;
  102. PFNVertexL m_pfnLightVertexL;
  103. PFNDraw m_pfnDrawLines;
  104. Matrix m_mat;
  105. Matrix m_matPerspective;
  106. Matrix m_matFull;
  107. Matrix m_matInverse;
  108. bool m_bUpdateMatFull;
  109. bool m_bUpdateLighting;
  110. bool m_bUpdatePointers;
  111. bool m_bUpdateInverse;
  112. TRef<Material> m_pmaterial;
  113. TRef<Deformation> m_pdeform;
  114. //
  115. // Line drawing attributes
  116. //
  117. float m_lineWidth;
  118. //
  119. // Lighting
  120. //
  121. float m_brightAmbient;
  122. Vector m_vecLight;
  123. Vector m_vecLightWorld;
  124. Color m_color;
  125. Color m_colorAlt;
  126. Color m_colorGlobal;
  127. bool m_bBidirectional;
  128. //
  129. // Clipping
  130. //
  131. float m_scalex;
  132. float m_scaley;
  133. float m_xoffset;
  134. float m_yoffset;
  135. int m_countPlanes;
  136. Plane m_pplane[g_maxCountPlanes];
  137. //
  138. // Temporary vertex and index buffers
  139. //
  140. VertexL* m_pvertexLBuffer;
  141. int m_countVertexLBuffer;
  142. VertexTL* m_pvertexTLBuffer;
  143. int m_countVertexTLBuffer;
  144. VertexScreen* m_pvertexScreenBuffer;
  145. int m_countVertexScreenBuffer;
  146. int m_indexVertexScreenBuffer;
  147. MeshIndex* m_pindexBuffer;
  148. int m_countIndexBuffer;
  149. int m_indexIndexBuffer;
  150. //
  151. // Performance counters
  152. //
  153. #ifdef EnablePerformanceCounters
  154. int m_countPoints;
  155. int m_countLines;
  156. int m_countTriangles;
  157. int m_countMeshes;
  158. int m_countObjects;
  159. int m_countObjectsRendered;
  160. int m_countMatrixLoads;
  161. #endif
  162. public:
  163. //////////////////////////////////////////////////////////////////////////////
  164. //
  165. // Constructor
  166. //
  167. //////////////////////////////////////////////////////////////////////////////
  168. Device3D(Rasterizer* prasterizer) :
  169. m_prasterizer(prasterizer),
  170. m_pvertexLBuffer(NULL),
  171. m_countVertexLBuffer(0),
  172. m_pvertexTLBuffer(NULL),
  173. m_countVertexTLBuffer(0),
  174. m_pvertexScreenBuffer(NULL),
  175. m_countVertexScreenBuffer(0),
  176. m_indexVertexScreenBuffer(0),
  177. m_pindexBuffer(NULL),
  178. m_countIndexBuffer(0),
  179. m_indexIndexBuffer(0),
  180. m_bClip(true),
  181. m_shadeMode(ShadeModeGouraud),
  182. m_bUpdateMatFull(true),
  183. m_bUpdateLighting(true),
  184. m_bUpdatePointers(true),
  185. m_brightAmbient(0.0f),
  186. m_vecLightWorld(1, 0, 0),
  187. m_color(Color::White()),
  188. m_colorAlt(Color::White()),
  189. m_colorGlobal(Color::White()),
  190. m_pfnDrawLines(DrawLinesRasterizer),
  191. m_lineWidth(0.5f)
  192. {
  193. m_sizeSurface = prasterizer->GetSurfaceSize();
  194. m_mat.SetIdentity();
  195. m_matPerspective.SetIdentity();
  196. //
  197. // Setup the clipping planes
  198. //
  199. m_countPlanes = 6;
  200. m_pplane[0] = Plane(HVector( 0, 0, 1, 0));
  201. m_pplane[1] = Plane(HVector( 0, 0, 1, -1));
  202. m_pplane[2] = Plane(HVector( 1, 0, 0, 1));
  203. m_pplane[3] = Plane(HVector(-1, 0, 0, 1));
  204. m_pplane[4] = Plane(HVector( 0, 1, 0, 1));
  205. m_pplane[5] = Plane(HVector( 0,-1, 0, 1));
  206. //
  207. // Initialize Performance counters
  208. //
  209. #ifdef EnablePerformanceCounters
  210. ResetPerformanceCounters();
  211. #endif
  212. }
  213. bool IsValid()
  214. {
  215. return m_prasterizer->IsValid();
  216. }
  217. //////////////////////////////////////////////////////////////////////////////
  218. //
  219. // Performance counters
  220. //
  221. //////////////////////////////////////////////////////////////////////////////
  222. #ifdef EnablePerformanceCounters
  223. void ResetPerformanceCounters()
  224. {
  225. m_countPoints = 0;
  226. m_countLines = 0;
  227. m_countTriangles = 0;
  228. m_countMeshes = 0;
  229. m_countObjects = 0;
  230. m_countObjectsRendered = 0;
  231. m_countMatrixLoads = 0;
  232. }
  233. int GetPerformanceCounter(Counter counter)
  234. {
  235. switch (counter) {
  236. case CounterPoints : return m_countPoints ;
  237. case CounterLines : return m_countLines ;
  238. case CounterTriangles : return m_countTriangles ;
  239. case CounterMeshes : return m_countMeshes ;
  240. case CounterObjects : return m_countObjects ;
  241. case CounterObjectsRendered : return m_countObjectsRendered;
  242. case CounterMatrixLoads : return m_countMatrixLoads ;
  243. }
  244. ZError("Unknown counter");
  245. return 0;
  246. }
  247. #endif
  248. //////////////////////////////////////////////////////////////////////////////
  249. //
  250. // Destructor
  251. //
  252. //////////////////////////////////////////////////////////////////////////////
  253. ~Device3D()
  254. {
  255. if (m_pvertexLBuffer) {
  256. free(m_pvertexLBuffer);
  257. }
  258. if (m_pvertexTLBuffer) {
  259. free(m_pvertexTLBuffer);
  260. }
  261. if (m_pvertexScreenBuffer) {
  262. free(m_pvertexScreenBuffer);
  263. }
  264. if (m_pindexBuffer) {
  265. free(m_pindexBuffer);
  266. }
  267. }
  268. //////////////////////////////////////////////////////////////////////////////
  269. //
  270. // Capabilities
  271. //
  272. //////////////////////////////////////////////////////////////////////////////
  273. bool Has3DAcceleration()
  274. {
  275. return m_prasterizer->Has3DAcceleration();
  276. }
  277. //////////////////////////////////////////////////////////////////////////////
  278. //
  279. // Device
  280. //
  281. //////////////////////////////////////////////////////////////////////////////
  282. void BeginScene()
  283. {
  284. m_prasterizer->BeginScene();
  285. }
  286. void EndScene()
  287. {
  288. m_prasterizer->EndScene();
  289. }
  290. void ClearZBuffer()
  291. {
  292. m_prasterizer->ClearZBuffer();
  293. }
  294. //////////////////////////////////////////////////////////////////////////////
  295. //
  296. // View Rect
  297. //
  298. //////////////////////////////////////////////////////////////////////////////
  299. void SetClipRect(const Rect& rectClip)
  300. {
  301. m_rectClip = rectClip;
  302. m_rectClipScreen =
  303. Rect(
  304. rectClip.XMin(),
  305. m_sizeSurface.Y() - rectClip.YMax(),
  306. rectClip.XMax(),
  307. m_sizeSurface.Y() - rectClip.YMin()
  308. );
  309. m_bUpdateMatFull = true;
  310. m_prasterizer->SetClipRect(m_rectClipScreen);
  311. }
  312. //////////////////////////////////////////////////////////////////////////////
  313. //
  314. // Lighting
  315. //
  316. //////////////////////////////////////////////////////////////////////////////
  317. void DirectionalLight(const Vector& vec, const Color& color)
  318. {
  319. m_vecLightWorld = m_mat.TransformDirection(vec);
  320. m_bBidirectional = false;
  321. }
  322. void BidirectionalLight(const Vector& vec, const Color& color, const Color& colorAlt)
  323. {
  324. m_vecLightWorld = m_mat.TransformDirection(vec);
  325. m_color = color;
  326. m_colorAlt = colorAlt;
  327. m_bBidirectional = true;
  328. }
  329. void SetAmbientLevel(float level)
  330. {
  331. m_brightAmbient = level;
  332. }
  333. void SetGlobalColor(const Color& color)
  334. {
  335. m_colorGlobal = color;
  336. }
  337. //////////////////////////////////////////////////////////////////////////////
  338. //
  339. //
  340. //
  341. //////////////////////////////////////////////////////////////////////////////
  342. const Matrix& GetFullMatrix()
  343. {
  344. if (m_bUpdateMatFull) {
  345. m_bUpdateMatFull = false;
  346. m_matFull = m_mat;
  347. m_matFull.Multiply(m_matPerspective);
  348. // !!! In D3D pixels centers are on integer boundaries
  349. // The device clips to integer boundaries
  350. // subtract 0.25 to move the first row of pixels centers into the clip rect
  351. if (m_bClip) {
  352. Point pointCenter = m_rectClip.Center();
  353. //
  354. // move view rect into NDC
  355. //
  356. float scalex = 0.5f * m_rectClip.XSize();
  357. float scaley = 0.5f * m_rectClip.YSize();
  358. m_matFull.Translate(
  359. Vector(
  360. -pointCenter.X(),
  361. -pointCenter.Y(),
  362. 0
  363. )
  364. );
  365. m_matFull.Scale(
  366. Vector(
  367. 1 / scalex,
  368. 1 / scaley,
  369. 1.0f
  370. )
  371. );
  372. //
  373. // these are the scales and translates to go from NDC back to the screen
  374. //
  375. m_xoffset = pointCenter.X(); // !!! - 0.25f;
  376. m_yoffset = m_sizeSurface.Y() - pointCenter.Y(); // !!! - 0.25f;
  377. m_scalex = 0.5f * m_rectClip.XSize();
  378. m_scaley = -0.5f * m_rectClip.YSize();
  379. } else {
  380. //
  381. // Flip the y coordinate
  382. //
  383. m_matFull.Translate(Vector(0, -m_sizeSurface.Y(), 0));
  384. m_matFull.Scale(Vector(1, -1, 1));
  385. }
  386. }
  387. return m_matFull;
  388. }
  389. void UpdateLighting()
  390. {
  391. if (m_bUpdateLighting) {
  392. m_bUpdateLighting = false;
  393. m_vecLight = GetInverseModelMatrix().TransformDirection(m_vecLightWorld);
  394. m_vecLight.SetNormalize();
  395. }
  396. }
  397. //////////////////////////////////////////////////////////////////////////////
  398. //
  399. // Update Pointers
  400. //
  401. //////////////////////////////////////////////////////////////////////////////
  402. void UpdatePointers()
  403. {
  404. if (m_bUpdatePointers) {
  405. m_bUpdatePointers = false;
  406. bool bClip = m_bClip || m_countPlanes > 6;
  407. if (m_pdeform != NULL) {
  408. bClip = true;
  409. m_pfnTransform = TransformDeformClip;
  410. } else if (bClip) {
  411. m_pfnTransform = TransformClip;
  412. } else {
  413. m_pfnTransform = TransformNoClip;
  414. }
  415. m_pfnLightVertexL = m_pfnTransform;
  416. switch (m_shadeMode) {
  417. case ShadeModeNone:
  418. case ShadeModeCopy:
  419. if (bClip) {
  420. m_pfnLightVertex = LightVertexCopy;
  421. } else {
  422. m_pfnLightVertex = TransformNoClipNoLight;
  423. }
  424. break;
  425. case ShadeModeGlobalColor:
  426. m_pfnLightVertex = LightVertexGlobalColor;
  427. break;
  428. case ShadeModeFlat:
  429. case ShadeModeGouraud:
  430. if (m_pmaterial) {
  431. m_pfnLightVertex = MaterialLightVertex;
  432. } else if (m_bBidirectional) {
  433. m_pfnLightVertex = BidirectionalLightVertex;
  434. } else {
  435. if (bClip) {
  436. m_pfnLightVertex = LightVertex;
  437. } else {
  438. m_pfnLightVertex = TransformAndLightNoClip;
  439. }
  440. }
  441. break;
  442. default:
  443. ZError("Invalid ShadeMode");
  444. }
  445. //
  446. // Lines
  447. //
  448. if (
  449. (m_lineWidth == 0.5f)
  450. && (
  451. m_prasterizer->Has3DAcceleration()
  452. || (
  453. (m_lineWidth == 0.5f)
  454. && (!m_bZTest)
  455. && (!m_bZWrite)
  456. && (m_shadeMode == ShadeModeFlat)
  457. && (m_blendMode == BlendModeSource)
  458. )
  459. )
  460. ) {
  461. m_pfnDrawLines = DrawLinesRasterizer;
  462. } else {
  463. m_pfnDrawLines = DrawLinesWithPolygons;
  464. }
  465. }
  466. }
  467. //////////////////////////////////////////////////////////////////////////////
  468. //
  469. // Get State
  470. //
  471. //////////////////////////////////////////////////////////////////////////////
  472. bool GetClipping()
  473. {
  474. return m_bClip;
  475. }
  476. const Matrix& GetMatrix()
  477. {
  478. return m_mat;
  479. }
  480. const Matrix& GetInverseModelMatrix()
  481. {
  482. if (m_bUpdateInverse) {
  483. m_bUpdateInverse = false;
  484. m_matInverse.SetInverse(m_mat);
  485. }
  486. return m_matInverse;
  487. }
  488. //////////////////////////////////////////////////////////////////////////////
  489. //
  490. // Set State
  491. //
  492. //////////////////////////////////////////////////////////////////////////////
  493. void SetMatrix(const Matrix& mat)
  494. {
  495. m_mat = mat;
  496. m_bUpdateMatFull = true;
  497. m_bUpdateLighting = true;
  498. m_bUpdateInverse = true;
  499. }
  500. void SetPerspectiveMatrix(const Matrix& mat)
  501. {
  502. m_matPerspective = mat;
  503. m_bUpdateMatFull = true;
  504. }
  505. void SetClipping(bool bClip)
  506. {
  507. m_bClip = bClip;
  508. m_bUpdateMatFull = true;
  509. m_bUpdatePointers = true;
  510. }
  511. void RemoveClipPlane(int indexRemove)
  512. {
  513. ZAssert(indexRemove >= 0 && indexRemove + 6 < m_countPlanes);
  514. for(int index = m_countPlanes - indexRemove - 1; index < m_countPlanes - 1; index++) {
  515. m_pplane[index] = m_pplane[index + 1];
  516. }
  517. m_countPlanes--;
  518. }
  519. void AddClipPlane(const Plane& plane)
  520. {
  521. ZAssert(m_countPlanes < g_maxCountPlanes);
  522. //
  523. // transform the plane into eye coordinates
  524. //
  525. const Matrix& mat = GetFullMatrix();
  526. Matrix mati;
  527. mati.SetInverse(mat);
  528. mati.Transpose();
  529. HVector p = plane.GetHVector();
  530. HVector pp = mati.Transform(p);
  531. m_pplane[m_countPlanes] = Plane(pp);
  532. m_countPlanes++;
  533. }
  534. void SetShadeMode(ShadeMode shadeMode)
  535. {
  536. m_shadeMode = shadeMode;
  537. m_bUpdatePointers = true;
  538. m_prasterizer->SetShadeMode(shadeMode);
  539. }
  540. void SetMaterial(Material* pmaterial)
  541. {
  542. m_pmaterial = pmaterial;
  543. m_bUpdatePointers = true;
  544. }
  545. void SetBlendMode(BlendMode blendMode)
  546. {
  547. m_blendMode = blendMode;
  548. m_bUpdatePointers = true;
  549. m_prasterizer->SetBlendMode(blendMode);
  550. }
  551. void SetTexture(Surface* psurfaceTexture)
  552. {
  553. m_prasterizer->SetTexture(psurfaceTexture);
  554. }
  555. void SetWrapMode(WrapMode wrapMode)
  556. {
  557. m_prasterizer->SetWrapMode(wrapMode);
  558. }
  559. void SetCullMode(CullMode cullMode)
  560. {
  561. m_prasterizer->SetCullMode(cullMode);
  562. }
  563. void SetZTest(bool bZTest)
  564. {
  565. m_bZTest = bZTest;
  566. m_bUpdatePointers = true;
  567. m_prasterizer->SetZTest(bZTest);
  568. }
  569. void SetZWrite(bool bZWrite)
  570. {
  571. m_bZWrite = bZWrite;
  572. m_bUpdatePointers = true;
  573. m_prasterizer->SetZWrite(bZWrite);
  574. }
  575. void SetLinearFilter(bool bLinearFilter)
  576. {
  577. m_prasterizer->SetLinearFilter(bLinearFilter);
  578. }
  579. void SetPerspectiveCorrection(bool bPerspectiveCorrection)
  580. {
  581. m_prasterizer->SetPerspectiveCorrection(bPerspectiveCorrection);
  582. }
  583. void SetDither(bool bDither)
  584. {
  585. m_prasterizer->SetDither(bDither);
  586. }
  587. void SetColorKey(bool bColorKey)
  588. {
  589. m_prasterizer->SetColorKey(bColorKey);
  590. }
  591. void SetLineWidth(float width)
  592. {
  593. m_lineWidth = 0.5f * width;
  594. }
  595. void SetDeformation(Deformation* pdeform)
  596. {
  597. m_pdeform = pdeform;
  598. m_bUpdatePointers = true;
  599. }
  600. //////////////////////////////////////////////////////////////////////////////
  601. //
  602. // Buffers
  603. //
  604. //////////////////////////////////////////////////////////////////////////////
  605. //
  606. // , may want to grow to more than count
  607. //
  608. void SizeVertexLBuffer(int count)
  609. {
  610. if (m_countVertexLBuffer < count) {
  611. m_countVertexLBuffer = count;
  612. m_pvertexLBuffer = (VertexL*)realloc(m_pvertexLBuffer, sizeof(VertexL) * count);
  613. }
  614. }
  615. void SizeVertexTLBuffer(int count)
  616. {
  617. if (m_countVertexTLBuffer < count) {
  618. m_countVertexTLBuffer = count;
  619. m_pvertexTLBuffer = (VertexTL*)realloc(m_pvertexTLBuffer, sizeof(VertexTL) * count);
  620. }
  621. }
  622. void SizeVertexScreenBuffer(int count)
  623. {
  624. if (m_countVertexScreenBuffer < count) {
  625. m_pvertexScreenBuffer = (VertexScreen*)realloc(m_pvertexScreenBuffer, sizeof(VertexScreen) * count);
  626. for (int index = m_countVertexScreenBuffer; index < count; index++) {
  627. m_pvertexScreenBuffer[index].specular = 0;
  628. }
  629. m_countVertexScreenBuffer = count;
  630. }
  631. }
  632. void SizeIndexBuffer(int count)
  633. {
  634. if (m_countIndexBuffer < count) {
  635. m_countIndexBuffer = count;
  636. m_pindexBuffer = (MeshIndex*)realloc(m_pindexBuffer, sizeof(MeshIndex) * count);
  637. }
  638. }
  639. //////////////////////////////////////////////////////////////////////////////
  640. //
  641. // Vertex Buffers
  642. //
  643. //////////////////////////////////////////////////////////////////////////////
  644. VertexL* GetVertexLBuffer(int count)
  645. {
  646. SizeVertexLBuffer(count);
  647. return m_pvertexLBuffer;
  648. }
  649. VertexScreen* GetVertexScreenBuffer(int count)
  650. {
  651. SizeVertexScreenBuffer(count);
  652. return m_pvertexScreenBuffer;
  653. }
  654. //////////////////////////////////////////////////////////////////////////////
  655. //
  656. //
  657. //
  658. //////////////////////////////////////////////////////////////////////////////
  659. void StoreTriangle(MeshIndex index1, MeshIndex index2, MeshIndex index3)
  660. {
  661. SizeIndexBuffer(m_indexIndexBuffer + 3);
  662. m_pindexBuffer[m_indexIndexBuffer ] = index1;
  663. m_pindexBuffer[m_indexIndexBuffer + 1] = index2;
  664. m_pindexBuffer[m_indexIndexBuffer + 2] = index3;
  665. m_indexIndexBuffer += 3;
  666. }
  667. void StoreLine(MeshIndex index1, MeshIndex index2)
  668. {
  669. SizeIndexBuffer(m_indexIndexBuffer + 2);
  670. m_pindexBuffer[m_indexIndexBuffer ] = index1;
  671. m_pindexBuffer[m_indexIndexBuffer + 1] = index2;
  672. m_indexIndexBuffer += 2;
  673. }
  674. //////////////////////////////////////////////////////////////////////////////
  675. //
  676. //
  677. //
  678. //////////////////////////////////////////////////////////////////////////////
  679. void ClampVertex(VertexScreen& vertex)
  680. {
  681. if (vertex.x < m_rectClipScreen.XMin()) {
  682. vertex.x = m_rectClipScreen.XMin();
  683. } else if (vertex.x > m_rectClipScreen.XMax()) {
  684. vertex.x = m_rectClipScreen.XMax();
  685. }
  686. if (vertex.y < m_rectClipScreen.YMin()) {
  687. vertex.y = m_rectClipScreen.YMin();
  688. } else if (vertex.y > m_rectClipScreen.YMax()) {
  689. vertex.y = m_rectClipScreen.YMax();
  690. }
  691. if (vertex.z < 0) {
  692. vertex.z = 0;
  693. } else if (vertex.z > 1) {
  694. vertex.z = 1;
  695. }
  696. }
  697. //////////////////////////////////////////////////////////////////////////////
  698. //
  699. //
  700. //
  701. //////////////////////////////////////////////////////////////////////////////
  702. MeshIndex ConvertVertex(VertexTL& vertex)
  703. {
  704. SizeVertexScreenBuffer(m_indexVertexScreenBuffer + 1);
  705. vertex.m_index = m_indexVertexScreenBuffer;
  706. VertexScreen* pvertex = m_pvertexScreenBuffer + m_indexVertexScreenBuffer;
  707. float rhw = 1.0f / vertex.m_pos.w;
  708. pvertex->x = m_scalex * rhw * vertex.m_pos.x + m_xoffset;
  709. pvertex->y = m_scaley * rhw * vertex.m_pos.y + m_yoffset;
  710. pvertex->z = rhw * vertex.m_pos.z;
  711. pvertex->qw = rhw;
  712. pvertex->u = vertex.m_pointTexture.X();
  713. pvertex->v = vertex.m_pointTexture.Y();
  714. pvertex->color = MakeD3DCOLOR(vertex.m_color);
  715. pvertex->specular = 0;
  716. ClampVertex(*pvertex);
  717. m_indexVertexScreenBuffer++;
  718. return vertex.m_index;
  719. }
  720. //////////////////////////////////////////////////////////////////////////////
  721. //
  722. //
  723. //
  724. //////////////////////////////////////////////////////////////////////////////
  725. MeshIndex TranslateIndex(VertexTL& vertex)
  726. {
  727. if (vertex.m_index == 0xffff) {
  728. return ConvertVertex(vertex);
  729. }
  730. return vertex.m_index;
  731. }
  732. //////////////////////////////////////////////////////////////////////////////
  733. //
  734. //
  735. //
  736. //////////////////////////////////////////////////////////////////////////////
  737. int TranslateIntersection(
  738. const Plane& plane,
  739. const VertexTL& vertex0,
  740. const VertexTL& vertex1
  741. ) {
  742. VertexTL vertex;
  743. CalculateIntersection(plane, vertex0, vertex1, vertex);
  744. return ConvertVertex(vertex);
  745. }
  746. //////////////////////////////////////////////////////////////////////////////
  747. //
  748. // Plane
  749. //
  750. //////////////////////////////////////////////////////////////////////////////
  751. void CalculateIntersection(
  752. const Plane& plane,
  753. const VertexTL& vertex0,
  754. const VertexTL& vertex1,
  755. VertexTL& vertexOut
  756. ) {
  757. float alpha = plane.Intersect(vertex0.m_pos, vertex1.m_pos);
  758. vertexOut.Interpolate(vertex0, vertex1, alpha);
  759. vertexOut.m_index = 0xffff;
  760. }
  761. //////////////////////////////////////////////////////////////////////////////
  762. //
  763. // Clip a polygon to a plane
  764. //
  765. //////////////////////////////////////////////////////////////////////////////
  766. int ClipPolygonToPlane(
  767. const Plane& plane,
  768. Code bit,
  769. VertexTL* pvertexIn,
  770. int vcountIn,
  771. VertexTL* pvertexOut
  772. ) {
  773. int vcount = 0;
  774. int vindexPrevious = vcountIn - 1;
  775. Code codePrevious = pvertexIn[vindexPrevious].m_code & bit;
  776. for (int vindex = 0; vindex < vcountIn; vindex++) {
  777. Code code = pvertexIn[vindex].m_code & bit;
  778. if ((code ^ codePrevious) != 0) {
  779. CalculateIntersection(
  780. plane,
  781. pvertexIn[vindexPrevious],
  782. pvertexIn[vindex],
  783. pvertexOut[vcount]
  784. );
  785. pvertexOut[vcount].UpdateClipCode();
  786. if (m_countPlanes > 6) {
  787. Code code = ClipPlane;
  788. for (int index = 6; index < m_countPlanes; index++, code <<= 1) {
  789. pvertexOut[vcount].UpdateClipCode(m_pplane[index], code);
  790. }
  791. }
  792. vcount++;
  793. }
  794. if (code == 0) {
  795. pvertexOut[vcount] = pvertexIn[vindex];
  796. vcount++;
  797. }
  798. ZAssert(vcount <= 8);
  799. codePrevious = code;
  800. vindexPrevious = vindex;
  801. }
  802. return vcount;
  803. }
  804. //////////////////////////////////////////////////////////////////////////////
  805. //
  806. // Clip a polygon to a set of planess
  807. //
  808. //////////////////////////////////////////////////////////////////////////////
  809. void ClipPolygonToPlanes(
  810. const Plane* pplane,
  811. int pcount,
  812. Code codeOr,
  813. const VertexTL& vertex0,
  814. const VertexTL& vertex1,
  815. const VertexTL& vertex2
  816. ) {
  817. VertexTL pverticesIn[3] =
  818. {
  819. vertex0,
  820. vertex1,
  821. vertex2
  822. };
  823. VertexTL pverticesOut0[8];
  824. VertexTL pverticesOut1[8];
  825. VertexTL* pvertexIn = pverticesIn;
  826. VertexTL* pvertexOut = pverticesOut0;
  827. VertexTL* pvertexOther = pverticesOut1;
  828. int vcount = 3;
  829. Code bit = 1;
  830. int pindex = 0;
  831. while (pindex < pcount) {
  832. if ((codeOr & bit) != 0) {
  833. vcount = ClipPolygonToPlane(pplane[pindex], bit, pvertexIn, vcount, pvertexOut);
  834. pvertexIn = pvertexOut;
  835. pvertexOut = pvertexOther;
  836. pvertexOther = pvertexIn;
  837. }
  838. bit *= 2;
  839. pindex++;
  840. }
  841. //
  842. // Translate the vertices to screen coordinates
  843. //
  844. MeshIndex aindex[7];
  845. int index;
  846. for(index = 0; index < vcount; index++) {
  847. aindex[index] = TranslateIndex(pvertexIn[index]);
  848. }
  849. //
  850. // Form all of the triangle fans
  851. //
  852. for(index = 1; index < vcount - 1; index++) {
  853. StoreTriangle(
  854. aindex[0],
  855. aindex[index],
  856. aindex[index + 1]
  857. );
  858. }
  859. }
  860. //////////////////////////////////////////////////////////////////////////////
  861. //
  862. //
  863. //
  864. //////////////////////////////////////////////////////////////////////////////
  865. void ClipPolygonToPlane(
  866. const Plane& plane,
  867. Code code0,
  868. Code code1,
  869. Code code2,
  870. VertexTL& vertex0,
  871. VertexTL& vertex1,
  872. VertexTL& vertex2
  873. ) {
  874. if (code0 != 0) {
  875. if (code1 != 0) {
  876. // p0 and p1 outside
  877. StoreTriangle(
  878. TranslateIntersection(plane, vertex2, vertex0),
  879. TranslateIntersection(plane, vertex1, vertex2),
  880. TranslateIndex(vertex2)
  881. );
  882. } else if (code2 != 0) {
  883. // p0 and p2 outside
  884. StoreTriangle(
  885. TranslateIntersection(plane, vertex0, vertex1),
  886. TranslateIndex(vertex1),
  887. TranslateIntersection(plane, vertex2, vertex1)
  888. );
  889. } else {
  890. // p0 outside
  891. int index0 = TranslateIntersection(plane, vertex0, vertex1);
  892. int index2 = TranslateIndex(vertex2);
  893. StoreTriangle(
  894. index0,
  895. TranslateIndex(vertex1),
  896. index2
  897. );
  898. StoreTriangle(
  899. index0,
  900. index2,
  901. TranslateIntersection(plane, vertex0, vertex2)
  902. );
  903. }
  904. } else {
  905. if (code1 != 0) {
  906. if (code2 != 0) {
  907. // p1 and p2 outside
  908. StoreTriangle(
  909. TranslateIndex(vertex0),
  910. TranslateIntersection(plane, vertex0, vertex1),
  911. TranslateIntersection(plane, vertex2, vertex0)
  912. );
  913. } else {
  914. // p1 outside
  915. int index0 = TranslateIndex(vertex0);
  916. int index2 = TranslateIntersection(plane, vertex1, vertex2);
  917. StoreTriangle(
  918. index0,
  919. TranslateIntersection(plane, vertex0, vertex1),
  920. index2
  921. );
  922. StoreTriangle(
  923. index0,
  924. index2,
  925. TranslateIndex(vertex2)
  926. );
  927. }
  928. } else {
  929. // p2 outside
  930. int index0 = TranslateIndex(vertex0);
  931. int index2 = TranslateIntersection(plane, vertex1, vertex2);
  932. StoreTriangle(
  933. index0,
  934. TranslateIndex(vertex1),
  935. index2
  936. );
  937. StoreTriangle(
  938. index0,
  939. index2,
  940. TranslateIntersection(plane, vertex2, vertex0)
  941. );
  942. }
  943. }
  944. }
  945. //////////////////////////////////////////////////////////////////////////////
  946. //
  947. // Clip Triangles
  948. //
  949. //////////////////////////////////////////////////////////////////////////////
  950. void ClipTriangles(VertexTL* pvertex, int vcountIn, const MeshIndex* pindex, int icountIn)
  951. {
  952. //
  953. // Clip each triangle
  954. //
  955. for(int index = 0; index < icountIn; index += 3) {
  956. int index0 = pindex[index + 0];
  957. int index1 = pindex[index + 1];
  958. int index2 = pindex[index + 2];
  959. Code code0 = pvertex[index0].m_code;
  960. Code code1 = pvertex[index1].m_code;
  961. Code code2 = pvertex[index2].m_code;
  962. Code codeAnd = code0 & code1 & code2;
  963. if (codeAnd == 0) {
  964. Code codeOr = code0 | code1 | code2;
  965. if (codeOr == 0) {
  966. //
  967. // Not clipped
  968. //
  969. StoreTriangle(
  970. TranslateIndex(pvertex[index0]),
  971. TranslateIndex(pvertex[index1]),
  972. TranslateIndex(pvertex[index2])
  973. );
  974. } else {
  975. //
  976. // Partially clipped
  977. //
  978. Code bit = 1;
  979. int pindex = 0;
  980. while (
  981. (pindex < m_countPlanes)
  982. && (codeOr != bit)
  983. ) {
  984. pindex++;
  985. bit *= 2;
  986. }
  987. if (pindex < m_countPlanes) {
  988. //
  989. // Clipped by a single plane
  990. //
  991. ClipPolygonToPlane(
  992. m_pplane[pindex],
  993. code0,
  994. code1,
  995. code2,
  996. pvertex[index0],
  997. pvertex[index1],
  998. pvertex[index2]
  999. );
  1000. } else {
  1001. //
  1002. // Clipped by multiple planes
  1003. //
  1004. ClipPolygonToPlanes(
  1005. m_pplane,
  1006. m_countPlanes,
  1007. codeOr,
  1008. pvertex[index0],
  1009. pvertex[index1],
  1010. pvertex[index2]
  1011. );
  1012. }
  1013. }
  1014. } else {
  1015. //
  1016. // Completely clipped
  1017. //
  1018. int i = 0;
  1019. }
  1020. }
  1021. }
  1022. //////////////////////////////////////////////////////////////////////////////
  1023. //
  1024. // Clip a line to a set of planess
  1025. //
  1026. //////////////////////////////////////////////////////////////////////////////
  1027. void ClipLineToPlanes(
  1028. const Plane* pplane,
  1029. int pcount,
  1030. Code codeOr,
  1031. const VertexTL& vertex0,
  1032. const VertexTL& vertex1
  1033. ) {
  1034. float t0 = 0;
  1035. float t1 = 1;
  1036. int vcount = 3;
  1037. Code bit = 1;
  1038. int pindex = 0;
  1039. while (pindex < pcount) {
  1040. if ((codeOr & bit) != 0) {
  1041. float t = pplane[pindex].Intersect(vertex0.m_pos, vertex1.m_pos);
  1042. if ((vertex0.m_code & bit) != 0) {
  1043. if (t > t0) {
  1044. t0 = t;
  1045. }
  1046. } else {
  1047. if (t < t1) {
  1048. t1 = t;
  1049. }
  1050. }
  1051. }
  1052. bit *= 2;
  1053. pindex++;
  1054. }
  1055. if (t0 < t1) {
  1056. VertexTL vertexT0; vertexT0.Interpolate(vertex0, vertex1, t0);
  1057. VertexTL vertexT1; vertexT1.Interpolate(vertex0, vertex1, t1);
  1058. StoreLine(
  1059. ConvertVertex(vertexT0),
  1060. ConvertVertex(vertexT1)
  1061. );
  1062. }
  1063. }
  1064. //////////////////////////////////////////////////////////////////////////////
  1065. //
  1066. // Clip Lines
  1067. //
  1068. //////////////////////////////////////////////////////////////////////////////
  1069. void ClipLines(VertexTL* pvertex, int vcount, const MeshIndex* pindex, int icount)
  1070. {
  1071. for (int index = 0; index < icount; index += 2) {
  1072. int index0 = pindex[index + 0];
  1073. int index1 = pindex[index + 1];
  1074. Code code0 = pvertex[index0].m_code;
  1075. Code code1 = pvertex[index1].m_code;
  1076. Code codeAnd = code0 & code1;
  1077. if (codeAnd == 0) {
  1078. Code codeOr = code0 | code1;
  1079. if (codeOr == 0) {
  1080. //
  1081. // Not clipped
  1082. //
  1083. StoreLine(
  1084. TranslateIndex(pvertex[index0]),
  1085. TranslateIndex(pvertex[index1])
  1086. );
  1087. } else {
  1088. //
  1089. // Clipped
  1090. //
  1091. ClipLineToPlanes(
  1092. m_pplane,
  1093. m_countPlanes,
  1094. codeOr,
  1095. pvertex[index0],
  1096. pvertex[index1]
  1097. );
  1098. }
  1099. } else {
  1100. //
  1101. // Completely clipped
  1102. //
  1103. }
  1104. }
  1105. }
  1106. //////////////////////////////////////////////////////////////////////////////
  1107. //
  1108. // Clip Points
  1109. //
  1110. //////////////////////////////////////////////////////////////////////////////
  1111. void ClipPoints(VertexTL* pvertex, int vcount, const MeshIndex* pindex, int icount)
  1112. {
  1113. for(int index = 0; index < vcount; index++) {
  1114. if (pvertex[index].m_code == 0) {
  1115. ConvertVertex(pvertex[index]);
  1116. }
  1117. }
  1118. }
  1119. //////////////////////////////////////////////////////////////////////////////
  1120. //
  1121. // Transform with deformation and clipping
  1122. //
  1123. //////////////////////////////////////////////////////////////////////////////
  1124. void TransformDeformClip(const VertexL* pvertex, int vcount, const MeshIndex* pindex, int icount, PFNClip pfnClip, PFNDraw pfnDraw)
  1125. {
  1126. SizeVertexTLBuffer(vcount);
  1127. Matrix mat = m_mat;
  1128. m_mat.SetIdentity();
  1129. m_bUpdateMatFull = true;
  1130. const Matrix& matFull = GetFullMatrix();
  1131. for (int index = 0; index < vcount; index++) {
  1132. Vector vecLocal = Vector(pvertex[index].x, pvertex[index].y, pvertex[index].z);
  1133. HVector hvec(
  1134. m_pdeform->Deform(
  1135. mat.Transform(
  1136. vecLocal
  1137. )
  1138. )
  1139. );
  1140. m_pvertexTLBuffer[index].m_pos = matFull.Transform(hvec);
  1141. m_pvertexTLBuffer[index].m_pointTexture = Point(pvertex[index].u, pvertex[index].v);
  1142. m_pvertexTLBuffer[index].m_color =
  1143. Color(
  1144. pvertex[index].r,
  1145. pvertex[index].g,
  1146. pvertex[index].b,
  1147. pvertex[index].a
  1148. );
  1149. m_pvertexTLBuffer[index].m_index = 0xffff;
  1150. m_pvertexTLBuffer[index].UpdateClipCode();
  1151. }
  1152. if (m_countPlanes > 6) {
  1153. for (int index = 0; index < vcount; index++) {
  1154. Code code = ClipPlane;
  1155. for (int iplane = 6; iplane < m_countPlanes; iplane++, code <<= 1) {
  1156. m_pvertexTLBuffer[index].UpdateClipCode(m_pplane[iplane], code);
  1157. }
  1158. }
  1159. }
  1160. m_indexVertexScreenBuffer = 0;
  1161. m_indexIndexBuffer = 0;
  1162. (this->*pfnClip)(m_pvertexTLBuffer, vcount, pindex, icount);
  1163. if (m_indexVertexScreenBuffer != 0) {
  1164. (this->*pfnDraw)(
  1165. m_pvertexScreenBuffer,
  1166. m_indexVertexScreenBuffer,
  1167. m_pindexBuffer,
  1168. m_indexIndexBuffer
  1169. );
  1170. }
  1171. m_mat = mat;
  1172. }
  1173. //////////////////////////////////////////////////////////////////////////////
  1174. //
  1175. // Transform with clipping
  1176. //
  1177. //////////////////////////////////////////////////////////////////////////////
  1178. void TransformClip(const VertexL* pvertex, int vcount, const MeshIndex* pindex, int icount, PFNClip pfnClip, PFNDraw pfnDraw)
  1179. {
  1180. SizeVertexTLBuffer(vcount);
  1181. const Matrix& mat = GetFullMatrix();
  1182. for (int index = 0; index < vcount; index++) {
  1183. HVector hvec(
  1184. pvertex[index].x,
  1185. pvertex[index].y,
  1186. pvertex[index].z,
  1187. 1
  1188. );
  1189. m_pvertexTLBuffer[index].m_pos = mat.Transform(hvec);
  1190. m_pvertexTLBuffer[index].m_pointTexture = Point(pvertex[index].u, pvertex[index].v);
  1191. m_pvertexTLBuffer[index].m_color =
  1192. Color(
  1193. pvertex[index].r,
  1194. pvertex[index].g,
  1195. pvertex[index].b,
  1196. pvertex[index].a
  1197. );
  1198. m_pvertexTLBuffer[index].m_index = 0xffff;
  1199. m_pvertexTLBuffer[index].UpdateClipCode();
  1200. }
  1201. if (m_countPlanes > 6) {
  1202. for (int index = 0; index < vcount; index++) {
  1203. Code code = ClipPlane;
  1204. for (int iplane = 6; iplane < m_countPlanes; iplane++, code <<= 1) {
  1205. m_pvertexTLBuffer[index].UpdateClipCode(m_pplane[iplane], code);
  1206. }
  1207. }
  1208. }
  1209. m_indexVertexScreenBuffer = 0;
  1210. m_indexIndexBuffer = 0;
  1211. (this->*pfnClip)(m_pvertexTLBuffer, vcount, pindex, icount);
  1212. if (m_indexVertexScreenBuffer != 0) {
  1213. (this->*pfnDraw)(
  1214. m_pvertexScreenBuffer,
  1215. m_indexVertexScreenBuffer,
  1216. m_pindexBuffer,
  1217. m_indexIndexBuffer
  1218. );
  1219. }
  1220. }
  1221. //////////////////////////////////////////////////////////////////////////////
  1222. //
  1223. // Special case Transform and light without clipping
  1224. //
  1225. //////////////////////////////////////////////////////////////////////////////
  1226. #ifndef USEASM
  1227. void TransformAndLightNoClip(
  1228. const Vertex* pvertex,
  1229. int vcount,
  1230. const MeshIndex* pindex,
  1231. int icount,
  1232. PFNClip pfnClip,
  1233. PFNDraw pfnDraw
  1234. ) {
  1235. SizeVertexScreenBuffer(vcount);
  1236. UpdateLighting();
  1237. const Matrix& mat = GetFullMatrix();
  1238. for (int index = 0; index < vcount; index++) {
  1239. const float x = pvertex[index].x;
  1240. const float y = pvertex[index].y;
  1241. const float z = pvertex[index].z;
  1242. const float rhw = 1.0f / (mat[3][0] * x + mat[3][1] * y + mat[3][2] * z + mat[3][3]);
  1243. m_pvertexScreenBuffer[index].x = rhw * (mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3]);
  1244. m_pvertexScreenBuffer[index].y = rhw * (mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3]);
  1245. m_pvertexScreenBuffer[index].z = rhw * (mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3]);
  1246. m_pvertexScreenBuffer[index].qw = rhw;
  1247. m_pvertexScreenBuffer[index].u = pvertex[index].u;
  1248. m_pvertexScreenBuffer[index].v = pvertex[index].v;
  1249. {
  1250. float fbright =
  1251. 255.0f * (
  1252. pvertex[index].nx * m_vecLight.X()
  1253. + pvertex[index].ny * m_vecLight.Y()
  1254. + pvertex[index].nz * m_vecLight.Z()
  1255. + m_brightAmbient
  1256. );
  1257. int bright = MakeInt(fbrigth);
  1258. if (bright > 255) {
  1259. bright = 255;
  1260. } else if (bright < 0) {
  1261. bright = 0;
  1262. }
  1263. m_pvertexScreenBuffer[index].color = 0xff000000 | bright | (bright << 8) | (bright << 16);
  1264. }
  1265. }
  1266. (this->*pfnDraw)(m_pvertexScreenBuffer, vcount, pindex, icount);
  1267. }
  1268. #else
  1269. void TransformAndLightNoClip(
  1270. const Vertex* pvertex,
  1271. int vcount,
  1272. const MeshIndex* pindex,
  1273. int icount,
  1274. PFNClip pfnClip,
  1275. PFNDraw pfnDraw
  1276. ) {
  1277. UpdateLighting();
  1278. SizeVertexScreenBuffer(vcount);
  1279. const Matrix mat = GetFullMatrix();
  1280. const Vector vecLight = m_vecLight;
  1281. const float brightAmbient = m_brightAmbient;
  1282. const float mult = 255.0f;
  1283. const float one = 1.0f;
  1284. int bright;
  1285. _asm {
  1286. mov ebx, 255
  1287. mov ecx, this
  1288. mov esi, pvertex
  1289. mov edi, [ecx].m_pvertexScreenBuffer
  1290. mov ecx, vcount
  1291. loopTop:
  1292. // int bright = (int)(255.0f * (pvertex[index].GetNormal() * m_vecLight + m_brightAmbient));
  1293. // const float rhw = 1.0f / (mat[3][0] * x + mat[3][1] * y + mat[3][2] * z + mat[3][3]);
  1294. // m_pvertexScreenBuffer[index].SetX(rhw * (mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3]);
  1295. // m_pvertexScreenBuffer[index].SetY(rhw * (mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3]);
  1296. // m_pvertexScreenBuffer[index].SetZ(rhw * (mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3]));
  1297. // m_pvertexScreenBuffer[index].SetTextureCoordinate(pvertex[index].GetTextureCoordinate());
  1298. fld [vecLight].x //
  1299. fmul [esi]Vertex.nx // lx
  1300. fld [vecLight].y //
  1301. fmul [esi]Vertex.ny // ly, lx
  1302. fld [vecLight].z //
  1303. fmul [esi]Vertex.nz // lz, ly, lx
  1304. fxch st(2) // lx, ly, lz
  1305. faddp st(1), st(0) // lx + ly, lz
  1306. fld one // 1, lx + ly, lz
  1307. fld [mat + 48 + 0] //
  1308. fmul [esi]Vertex.x // wx, 1, lx + ly, lz
  1309. fxch st(3) // lz, 1, lx + ly, wx
  1310. fadd [brightAmbient] // lz + dl, 1, lx + ly, wx
  1311. fld [mat + 48 + 4] //
  1312. fmul [esi]Vertex.y // wy, lz + dl, 1, lx + ly, wx
  1313. fxch st(1) // lz + dl, wy, 1, lx + ly, wx
  1314. faddp st(3), st(0) // wy, 1, l, wx
  1315. fld [mat + 48 + 8] //
  1316. fmul [esi]Vertex.z // wz, wy, 1, l, wx
  1317. fxch st(1) // wy, wz, 1, l, wx
  1318. faddp st(4), st(0) // wz, 1, l, wx + wy
  1319. fxch st(2) // l, 1, wz, wx + wy
  1320. fmul mult // 256 * l, 1, wz, wx + wy
  1321. fld [mat + 0 + 0] //
  1322. fmul [esi]Vertex.x // xx, 255 * l, 1, wz, wx + wy
  1323. fxch st(3) // wz, 255 * l, 1, xx, wx + wy
  1324. fadd DWORD PTR [mat + 48 + 12] // wz + dw, 255 * l, 1, xx, wx + wy
  1325. fxch st(1) // 255 * l, wz + dw, 1, xx, wx + wy
  1326. fistp bright // wz + dw, 1, xx, wx + wy
  1327. fld [mat + 0 + 4] //
  1328. fmul [esi]Vertex.y // xy, wz + dw, 1, xx, wx + wy
  1329. fxch st(1) // wz + dw, xy, 1, xx, wx + wy
  1330. faddp st(4), st(0) // xy, 1, xx, w
  1331. fld [mat + 0 + 8] //
  1332. fmul [esi]Vertex.z // xz, xy, 1, xx, w
  1333. fxch st(1) // xy, xz, 1, xx, w
  1334. faddp st(3), st(0) // xz, 1, xx + xy, w
  1335. fxch st(3) // w, 1, xx + xy, xz
  1336. fdivp st(1), st(0) // rhw, xx + xy, xz
  1337. fxch st(2) // xz, xx + xy, rhw
  1338. // if (bright > 255) {
  1339. // bright = 255;
  1340. // } else if (bright < 0) {
  1341. // bright = 0;
  1342. // }
  1343. mov eax,bright
  1344. cmp eax,ebx
  1345. jle label1
  1346. mov eax,ebx
  1347. jmp label2
  1348. label1:
  1349. test eax,eax
  1350. jge label2
  1351. xor eax,eax
  1352. // m_pvertexScreenBuffer[index].color = 0xff000000 | bright | (bright << 8) | (bright << 16);
  1353. label2:
  1354. mov edx,eax
  1355. shl edx,8
  1356. or edx,eax
  1357. shl edx,8
  1358. or edx,eax
  1359. or edx, 0xff000000
  1360. mov [edi]VertexScreen.color, edx
  1361. mov eax, [esi]Vertex.u
  1362. mov edx, [esi]Vertex.v
  1363. mov [edi]VertexScreen.u, eax
  1364. mov [edi]VertexScreen.v, edx
  1365. // continue with floating point stuff
  1366. // xz, xx + xy, rhw
  1367. fadd DWORD PTR [mat + 0 + 12] // xz + dx, xx + xy, rhw
  1368. fld [mat + 16 + 0] //
  1369. fmul [esi]Vertex.x // yx, xz + dx, xx + xy, rhw
  1370. fld [mat + 16 + 4] //
  1371. fmul [esi]Vertex.y // yy, yx, xz + dx, xx + xy, rhw
  1372. fld [mat + 16 + 8] //
  1373. fmul [esi]Vertex.z // yz, yy, yx, xz + dx, xx + xy, rhw
  1374. fxch st(1) // yy, yz, yx, xz + dx, xx + xy, rhw
  1375. faddp st(2), st(0) // yz, yx + yy, xz + dx, xx + xy, rhw
  1376. fld [mat + 32 + 0] //
  1377. fmul [esi]Vertex.x // zx, yz, yx + yy, xz + dx, xx + xy, rhw
  1378. fld [mat + 32 + 4] //
  1379. fmul [esi]Vertex.y // zy, zx, yz, yx + yy, xz + dx, xx + xy, rhw
  1380. fld [mat + 32 + 8] //
  1381. fmul [esi]Vertex.z // zz, zy, zx, yz, yx + yy, xz + dx, xx + xy, rhw
  1382. fxch st(3) // yz, zy, zx, zz, yx + yy, xz + dx, xx + xy, rhw
  1383. fadd DWORD PTR [mat + 16 + 12] // yz + dy, zy, zx, zz, yx + yy, xz + dx, xx + xy, rhw
  1384. fxch st(1) // zy, yz + dy, zx, zz, yx + yy, xz + dx, xx + xy, rhw
  1385. faddp st(2), st(0) // yz + dy, zx + zy, zz, yx + yy, xz + dx, xx + xy, rhw
  1386. fxch st(2) // zz, zx + zy, yz + dy, yx + yy, xz + dx, xx + xy, rhw
  1387. fadd DWORD PTR [mat + 32 + 12] // zz + dz, zx + zy, yz + dy, yx + yy, xz + dx, xx + xy, rhw
  1388. fxch st(4) // xz + dx, zx + zy, yz + dy, yx + yy, zz + dz, xx + xy, rhw
  1389. faddp st(5), st(0) // zx + zy, yz + dy, yx + yy, zz + dz, x, rhw
  1390. fxch st(1) // yz + dy, zx + zy, yx + yy, zz + dz, x, rhw
  1391. faddp st(2), st(0) // zx + zy, y, zz + dz, x, rhw
  1392. faddp st(2), st(0) // y, z, x, rhw
  1393. fxch st(2) // x, z, y, rhw
  1394. fmul st(0), st(3) // rhw*x, z, y, rhw
  1395. fxch st(2) // y, z, rhw*x, rhw
  1396. fmul st(0), st(3) // rhw*y, z, rhw*x, rhw
  1397. fxch st(1) // z, rhw*y, rhw*x, rhw
  1398. fmul st(0), st(3) // rhw*z, rhw*y, rhw*x, rhw
  1399. fxch st(3) // rhw, rhw*y, rhw*x, rhw*z
  1400. fstp [edi]VertexScreen.qw // rhw*y, rhw*x, rhw*z
  1401. fxch st(1) // rhw*x, rhw*y, rhw*z
  1402. fstp [edi]VertexScreen.x // rhw*y, rhw*z
  1403. fstp [edi]VertexScreen.y // rhw*z
  1404. fstp [edi]VertexScreen.z //
  1405. // loop
  1406. add edi, SIZE VertexScreen
  1407. add esi, SIZE Vertex
  1408. dec ecx
  1409. jne loopTop
  1410. }
  1411. (this->*pfnDraw)(m_pvertexScreenBuffer, vcount, pindex, icount);
  1412. }
  1413. #endif
  1414. //////////////////////////////////////////////////////////////////////////////
  1415. //
  1416. // Tranform without clipping
  1417. //
  1418. //////////////////////////////////////////////////////////////////////////////
  1419. void TransformNoClip(const VertexL* pvertex, int vcount, const MeshIndex* pindex, int icount, PFNClip pfnClip, PFNDraw pfnDraw)
  1420. {
  1421. SizeVertexScreenBuffer(vcount);
  1422. const Matrix& mat = GetFullMatrix();
  1423. for (int index = 0; index < vcount; index++) {
  1424. const float x = pvertex[index].x;
  1425. const float y = pvertex[index].y;
  1426. const float z = pvertex[index].z;
  1427. const float rhw = 1.0f / (mat[3][0] * x + mat[3][1] * y + mat[3][2] * z + mat[3][3]);
  1428. m_pvertexScreenBuffer[index].x = rhw * (mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3]);
  1429. m_pvertexScreenBuffer[index].y = rhw * (mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3]);
  1430. m_pvertexScreenBuffer[index].z = rhw * (mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3]);
  1431. m_pvertexScreenBuffer[index].qw = rhw;
  1432. m_pvertexScreenBuffer[index].u = pvertex[index].u;
  1433. m_pvertexScreenBuffer[index].v = pvertex[index].v;
  1434. m_pvertexScreenBuffer[index].color =
  1435. MakeD3DCOLOR(
  1436. Color(
  1437. pvertex[index].r,
  1438. pvertex[index].g,
  1439. pvertex[index].b,
  1440. pvertex[index].a
  1441. )
  1442. );
  1443. }
  1444. (this->*pfnDraw)(m_pvertexScreenBuffer, vcount, pindex, icount);
  1445. }
  1446. //////////////////////////////////////////////////////////////////////////////
  1447. //
  1448. // Tranform without clipping or lighting
  1449. //
  1450. //////////////////////////////////////////////////////////////////////////////
  1451. void TransformNoClipNoLight(const Vertex* pvertex, int vcount, const MeshIndex* pindex, int icount, PFNClip pfnClip, PFNDraw pfnDraw)
  1452. {
  1453. SizeVertexScreenBuffer(vcount);
  1454. const Matrix& mat = GetFullMatrix();
  1455. for (int index = 0; index < vcount; index++) {
  1456. const float x = pvertex[index].x;
  1457. const float y = pvertex[index].y;
  1458. const float z = pvertex[index].z;
  1459. const float rhw = 1.0f / (mat[3][0] * x + mat[3][1] * y + mat[3][2] * z + mat[3][3]);
  1460. m_pvertexScreenBuffer[index].x = rhw * (mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3]);
  1461. m_pvertexScreenBuffer[index].y = rhw * (mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3]);
  1462. m_pvertexScreenBuffer[index].z = rhw * (mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3]);
  1463. m_pvertexScreenBuffer[index].qw = rhw;
  1464. m_pvertexScreenBuffer[index].u = pvertex[index].u;
  1465. m_pvertexScreenBuffer[index].v = pvertex[index].v;
  1466. }
  1467. (this->*pfnDraw)(m_pvertexScreenBuffer, vcount, pindex, icount);
  1468. }
  1469. //////////////////////////////////////////////////////////////////////////////
  1470. //
  1471. // Copy Lighting
  1472. //
  1473. //////////////////////////////////////////////////////////////////////////////
  1474. void LightVertexCopy(const Vertex* pvertex, int vcount, const MeshIndex* pindex, int icount, PFNClip pfnClip, PFNDraw pfnDraw)
  1475. {
  1476. SizeVertexLBuffer(vcount);
  1477. for (int index = 0; index < vcount; index++) {
  1478. m_pvertexLBuffer[index].x = pvertex[index].x;
  1479. m_pvertexLBuffer[index].y = pvertex[index].y;
  1480. m_pvertexLBuffer[index].z = pvertex[index].z;
  1481. m_pvertexLBuffer[index].u = pvertex[index].u;
  1482. m_pvertexLBuffer[index].v = pvertex[index].v;
  1483. m_pvertexLBuffer[index].r = 1;
  1484. m_pvertexLBuffer[index].g = 1;
  1485. m_pvertexLBuffer[index].b = 1;
  1486. m_pvertexLBuffer[index].a = 1;
  1487. }
  1488. (this->*m_pfnTransform)(m_pvertexLBuffer, vcount, pindex, icount, pfnClip, pfnDraw);
  1489. }
  1490. //////////////////////////////////////////////////////////////////////////////
  1491. //
  1492. // Copy Lighting
  1493. //
  1494. //////////////////////////////////////////////////////////////////////////////
  1495. void LightVertexGlobalColor(const Vertex* pvertex, int vcount, const MeshIndex* pindex, int icount, PFNClip pfnClip, PFNDraw pfnDraw)
  1496. {
  1497. SizeVertexLBuffer(vcount);
  1498. float r = m_colorGlobal.R();
  1499. float g = m_colorGlobal.G();
  1500. float b = m_colorGlobal.B();
  1501. float a = m_colorGlobal.A();
  1502. for (int index = 0; index < vcount; index++) {
  1503. m_pvertexLBuffer[index].x = pvertex[index].x;
  1504. m_pvertexLBuffer[index].y = pvertex[index].y;
  1505. m_pvertexLBuffer[index].z = pvertex[index].z;
  1506. m_pvertexLBuffer[index].u = pvertex[index].u;
  1507. m_pvertexLBuffer[index].v = pvertex[index].v;
  1508. m_pvertexLBuffer[index].r = r;
  1509. m_pvertexLBuffer[index].g = g;
  1510. m_pvertexLBuffer[index].b = b;
  1511. m_pvertexLBuffer[index].a = a;
  1512. }
  1513. (this->*m_pfnTransform)(m_pvertexLBuffer, vcount, pindex, icount, pfnClip, pfnDraw);
  1514. }
  1515. //////////////////////////////////////////////////////////////////////////////
  1516. //
  1517. // Bi-Directional Lighting
  1518. //
  1519. //////////////////////////////////////////////////////////////////////////////
  1520. float Saturate(float value)
  1521. {
  1522. if (value > 1) {
  1523. return 1;
  1524. } else if (value < 0) {
  1525. return 0;
  1526. }
  1527. return value;
  1528. }
  1529. void BidirectionalLightVertex(const Vertex* pvertex, int vcount, const MeshIndex* pindex, int icount, PFNClip pfnClip, PFNDraw pfnDraw)
  1530. {
  1531. UpdateLighting();
  1532. SizeVertexLBuffer(vcount);
  1533. for (int index = 0; index < vcount; index++) {
  1534. m_pvertexLBuffer[index].x = pvertex[index].x;
  1535. m_pvertexLBuffer[index].y = pvertex[index].y;
  1536. m_pvertexLBuffer[index].z = pvertex[index].z;
  1537. m_pvertexLBuffer[index].u = pvertex[index].u;
  1538. m_pvertexLBuffer[index].v = pvertex[index].v;
  1539. float bright =
  1540. pvertex[index].nx * m_vecLight.X()
  1541. + pvertex[index].ny * m_vecLight.Y()
  1542. + pvertex[index].nz * m_vecLight.Z();
  1543. if (bright >= 0) {
  1544. //bright += m_brightAmbient;
  1545. /*
  1546. bright = Saturate(bright);
  1547. m_pvertexLBuffer[index].r = bright * m_color.R();
  1548. m_pvertexLBuffer[index].g = bright * m_color.G();
  1549. m_pvertexLBuffer[index].b = bright * m_color.B();
  1550. */
  1551. m_pvertexLBuffer[index].r = Saturate(bright * m_color.R() + m_brightAmbient);
  1552. m_pvertexLBuffer[index].g = Saturate(bright * m_color.G() + m_brightAmbient);
  1553. m_pvertexLBuffer[index].b = Saturate(bright * m_color.B() + m_brightAmbient);
  1554. } else {
  1555. bright = /*m_brightAmbient*/ - bright;
  1556. /*
  1557. bright = Saturate(bright);
  1558. m_pvertexLBuffer[index].r = bright * m_colorAlt.R();
  1559. m_pvertexLBuffer[index].g = bright * m_colorAlt.G();
  1560. m_pvertexLBuffer[index].b = bright * m_colorAlt.B();
  1561. */
  1562. m_pvertexLBuffer[index].r = Saturate(bright * m_colorAlt.R() + m_brightAmbient);
  1563. m_pvertexLBuffer[index].g = Saturate(bright * m_colorAlt.G() + m_brightAmbient);
  1564. m_pvertexLBuffer[index].b = Saturate(bright * m_colorAlt.B() + m_brightAmbient);
  1565. }
  1566. m_pvertexLBuffer[index].a = 1;
  1567. }
  1568. (this->*m_pfnTransform)(m_pvertexLBuffer, vcount, pindex, icount, pfnClip, pfnDraw);
  1569. }
  1570. //////////////////////////////////////////////////////////////////////////////
  1571. //
  1572. // Directional Lighting
  1573. //
  1574. //////////////////////////////////////////////////////////////////////////////
  1575. void LightVertex(const Vertex* pvertex, int vcount, const MeshIndex* pindex, int icount, PFNClip pfnClip, PFNDraw pfnDraw)
  1576. {
  1577. UpdateLighting();
  1578. SizeVertexLBuffer(vcount);
  1579. for (int index = 0; index < vcount; index++) {
  1580. m_pvertexLBuffer[index].x = pvertex[index].x;
  1581. m_pvertexLBuffer[index].y = pvertex[index].y;
  1582. m_pvertexLBuffer[index].z = pvertex[index].z;
  1583. m_pvertexLBuffer[index].u = pvertex[index].u;
  1584. m_pvertexLBuffer[index].v = pvertex[index].v;
  1585. float bright =
  1586. pvertex[index].nx * m_vecLight.X()
  1587. + pvertex[index].ny * m_vecLight.Y()
  1588. + pvertex[index].nz * m_vecLight.Z()
  1589. + m_brightAmbient;
  1590. if (bright > 1) {
  1591. bright = 1;
  1592. } else if (bright < 0) {
  1593. bright = 0;
  1594. }
  1595. m_pvertexLBuffer[index].r = bright;
  1596. m_pvertexLBuffer[index].g = bright;
  1597. m_pvertexLBuffer[index].b = bright;
  1598. m_pvertexLBuffer[index].a = 1;
  1599. }
  1600. (this->*m_pfnTransform)(m_pvertexLBuffer, vcount, pindex, icount, pfnClip, pfnDraw);
  1601. }
  1602. //////////////////////////////////////////////////////////////////////////////
  1603. //
  1604. // Directional Lighting
  1605. //
  1606. //////////////////////////////////////////////////////////////////////////////
  1607. void MaterialLightVertex(const Vertex* pvertex, int vcount, const MeshIndex* pindex, int icount, PFNClip pfnClip, PFNDraw pfnDraw)
  1608. {
  1609. UpdateLighting();
  1610. SizeVertexLBuffer(vcount);
  1611. float r = m_pmaterial->GetDiffuse().GetRed();
  1612. float g = m_pmaterial->GetDiffuse().GetGreen();
  1613. float b = m_pmaterial->GetDiffuse().GetBlue();
  1614. float a = m_pmaterial->GetDiffuse().GetAlpha();
  1615. for (int index = 0; index < vcount; index++) {
  1616. m_pvertexLBuffer[index].x = pvertex[index].x;
  1617. m_pvertexLBuffer[index].y = pvertex[index].y;
  1618. m_pvertexLBuffer[index].z = pvertex[index].z;
  1619. m_pvertexLBuffer[index].u = pvertex[index].u;
  1620. m_pvertexLBuffer[index].v = pvertex[index].v;
  1621. float bright =
  1622. pvertex[index].nx * m_vecLight.X()
  1623. + pvertex[index].ny * m_vecLight.Y()
  1624. + pvertex[index].nz * m_vecLight.Z()
  1625. + m_brightAmbient;
  1626. if (bright > 1) {
  1627. bright = 1;
  1628. } else if (bright < 0) {
  1629. bright = 0;
  1630. }
  1631. m_pvertexLBuffer[index].r = r * bright;
  1632. m_pvertexLBuffer[index].g = g * bright;
  1633. m_pvertexLBuffer[index].b = b * bright;
  1634. m_pvertexLBuffer[index].a = a;
  1635. }
  1636. (this->*m_pfnTransform)(m_pvertexLBuffer, vcount, pindex, icount, pfnClip, pfnDraw);
  1637. }
  1638. //////////////////////////////////////////////////////////////////////////////
  1639. //
  1640. // Draw lines using triangles
  1641. //
  1642. //////////////////////////////////////////////////////////////////////////////
  1643. void StoreVertex(
  1644. VertexScreen& pvertex,
  1645. float x,
  1646. float y,
  1647. float z,
  1648. float qw,
  1649. D3DCOLOR color,
  1650. float u,
  1651. float v
  1652. ) {
  1653. pvertex.x = x;
  1654. pvertex.y = y;
  1655. pvertex.z = z;
  1656. pvertex.qw = qw;
  1657. pvertex.color = color;
  1658. pvertex.specular = 0;
  1659. pvertex.u = u;
  1660. pvertex.v = v;
  1661. }
  1662. void DrawLinesWithPolygons(const VertexScreen* pvertexInArg, int vcount, const MeshIndex* pindexInArg, int icount)
  1663. {
  1664. bool bUsingVertexBuffer = (pvertexInArg == m_pvertexScreenBuffer);
  1665. bool bUsingIndexBuffer = (pindexInArg == m_pindexBuffer );
  1666. //
  1667. // Allocate space for the triangles
  1668. //
  1669. SizeIndexBuffer(icount + icount * 3);
  1670. VertexScreen* pvertexOut = GetVertexScreenBuffer(vcount + icount * 2) + vcount;
  1671. MeshIndex* pindexOut = m_pindexBuffer + icount;
  1672. //
  1673. // Figure out which source index point to use
  1674. //
  1675. const VertexScreen* pvertexIn = bUsingVertexBuffer ? m_pvertexScreenBuffer : pvertexInArg;
  1676. const MeshIndex* pindexIn = bUsingIndexBuffer ? m_pindexBuffer : pindexInArg ;
  1677. //
  1678. // Build all of the triangles
  1679. //
  1680. Vector vecUp(0, 0, 1);
  1681. VertexScreen* pvertex = pvertexOut;
  1682. MeshIndex* pindex = pindexOut;
  1683. int indexOut = 0;
  1684. for (int index = 0; index < icount; index += 2) {
  1685. const VertexScreen& vertex1 = pvertexIn[pindexIn[index ]];
  1686. const VertexScreen& vertex2 = pvertexIn[pindexIn[index + 1]];
  1687. if (
  1688. vertex1.x != vertex2.x
  1689. || vertex1.y != vertex2.y
  1690. ) {
  1691. Vector vecForward(vertex2.x - vertex1.x, vertex2.y - vertex1.y, 0);
  1692. Vector vecLeft = CrossProduct(vecUp, vecForward);
  1693. vecLeft = vecLeft.Normalize() * m_lineWidth;
  1694. pvertex[0] = vertex1;
  1695. pvertex[0].x = vertex1.x + vecLeft.X();// * vertex1.qw;
  1696. pvertex[0].y = vertex1.y + vecLeft.Y();// * vertex1.qw;
  1697. pvertex[0].z = vertex1.z;
  1698. pvertex[0].qw = vertex1.qw;
  1699. pvertex[0].u = vertex1.u;
  1700. pvertex[0].v = 0;
  1701. pvertex[0].color = vertex1.color;
  1702. pvertex[0].specular = vertex1.specular;
  1703. pvertex[1] = vertex1;
  1704. pvertex[1].x = vertex1.x - vecLeft.X();// * vertex1.qw;
  1705. pvertex[1].y = vertex1.y - vecLeft.Y();// * vertex1.qw;
  1706. pvertex[1].z = vertex1.z;
  1707. pvertex[1].qw = vertex1.qw;
  1708. pvertex[1].u = vertex1.u;
  1709. pvertex[1].v = 1;
  1710. pvertex[1].color = vertex1.color;
  1711. pvertex[1].specular = vertex1.specular;
  1712. pvertex[2] = vertex2;
  1713. pvertex[2].x = vertex2.x + vecLeft.X();// * vertex2.qw;
  1714. pvertex[2].y = vertex2.y + vecLeft.Y();// * vertex2.qw;
  1715. pvertex[2].z = vertex2.z;
  1716. pvertex[2].qw = vertex2.qw;
  1717. pvertex[2].u = vertex2.u;
  1718. pvertex[2].v = 0;
  1719. pvertex[2].color = vertex2.color;
  1720. pvertex[2].specular = vertex2.specular;
  1721. pvertex[3] = vertex2;
  1722. pvertex[3].x = vertex2.x - vecLeft.X();// * vertex2.qw;
  1723. pvertex[3].y = vertex2.y - vecLeft.Y();// * vertex2.qw;
  1724. pvertex[3].z = vertex2.z;
  1725. pvertex[3].qw = vertex2.qw;
  1726. pvertex[3].u = vertex2.u;
  1727. pvertex[3].v = 1;
  1728. pvertex[3].color = vertex2.color;
  1729. pvertex[3].specular = vertex2.specular;
  1730. pvertex += 4;
  1731. pindex[0] = indexOut + 0;
  1732. pindex[1] = indexOut + 1;
  1733. pindex[2] = indexOut + 2;
  1734. pindex[3] = indexOut + 1;
  1735. pindex[4] = indexOut + 3;
  1736. pindex[5] = indexOut + 2;
  1737. pindex += 6;
  1738. indexOut += 4;
  1739. }
  1740. }
  1741. //
  1742. // Update the performance counter
  1743. //
  1744. #ifdef EnablePerformanceCounters
  1745. m_countTriangles += icount;
  1746. #endif
  1747. //
  1748. // Render them
  1749. //
  1750. m_prasterizer->DrawTriangles(pvertexOut, pvertex - pvertexOut, pindexOut, pindex - pindexOut);
  1751. }
  1752. //////////////////////////////////////////////////////////////////////////////
  1753. //
  1754. // Screen Vertices
  1755. //
  1756. //////////////////////////////////////////////////////////////////////////////
  1757. void DrawLinesRasterizer(const VertexScreen* pvertex, int vcount, const MeshIndex* pindex, int icount)
  1758. {
  1759. m_prasterizer->DrawLines(pvertex, vcount, pindex, icount);
  1760. }
  1761. //////////////////////////////////////////////////////////////////////////////
  1762. //
  1763. // Screen Vertices
  1764. //
  1765. //////////////////////////////////////////////////////////////////////////////
  1766. void DrawTriangles(const VertexScreen* pvertex, int vcount, const MeshIndex* pindex, int icount)
  1767. {
  1768. m_prasterizer->DrawTriangles(pvertex, vcount, pindex, icount);
  1769. }
  1770. void DrawLines(const VertexScreen* pvertex, int vcount, const MeshIndex* pindex, int icount)
  1771. {
  1772. UpdatePointers();
  1773. (this->*m_pfnDrawLines)(pvertex, vcount, pindex, icount);
  1774. }
  1775. void DrawPoints(const VertexScreen* pvertex, int vcount, const MeshIndex* pindex, int icount)
  1776. {
  1777. m_prasterizer->DrawPoints(pvertex, vcount);
  1778. }
  1779. void DrawPoints(const VertexScreen* pvertex, int vcount)
  1780. {
  1781. m_prasterizer->DrawPoints(pvertex, vcount);
  1782. }
  1783. void DrawTriangles(const D3DVertex* pvertex, int vcount, const MeshIndex* pindex, int icount)
  1784. {
  1785. ZAssert(false);
  1786. }
  1787. void DrawLines(const D3DVertex* pvertex, int vcount, const MeshIndex* pindex, int icount)
  1788. {
  1789. ZAssert(false);
  1790. }
  1791. void DrawPoints(const D3DVertex* pvertex, int vcount, const MeshIndex* pindex, int icount)
  1792. {
  1793. ZAssert(false);
  1794. }
  1795. void DrawPoints(const D3DVertex* pvertex, int vcount)
  1796. {
  1797. ZAssert(false);
  1798. }
  1799. //////////////////////////////////////////////////////////////////////////////
  1800. //
  1801. //
  1802. //
  1803. //////////////////////////////////////////////////////////////////////////////
  1804. void DrawTriangles(const Vertex* pvertex, int vcount, const MeshIndex* pindex, int icount)
  1805. {
  1806. #ifdef EnablePerformanceCounters
  1807. m_countTriangles += icount / 3;
  1808. #endif
  1809. UpdatePointers();
  1810. (this->*m_pfnLightVertex)(pvertex, vcount, pindex, icount, ClipTriangles, DrawTriangles);
  1811. }
  1812. //////////////////////////////////////////////////////////////////////////////
  1813. //
  1814. //
  1815. //
  1816. //////////////////////////////////////////////////////////////////////////////
  1817. void DrawLines(const Vertex* pvertex, int vcount, const MeshIndex* pindex, int icount)
  1818. {
  1819. #ifdef EnablePerformanceCounters
  1820. m_countLines += icount - 1;
  1821. #endif
  1822. UpdatePointers();
  1823. (this->*m_pfnLightVertex)(pvertex, vcount, pindex, icount, ClipLines, m_pfnDrawLines);
  1824. }
  1825. //////////////////////////////////////////////////////////////////////////////
  1826. //
  1827. //
  1828. //
  1829. //////////////////////////////////////////////////////////////////////////////
  1830. void DrawPoints(const Vertex* pvertex, int vcount)
  1831. {
  1832. #ifdef EnablePerformanceCounters
  1833. m_countPoints += vcount;
  1834. #endif
  1835. UpdatePointers();
  1836. (this->*m_pfnLightVertex)(pvertex, vcount, NULL, 0, ClipPoints, DrawPoints);
  1837. }
  1838. //////////////////////////////////////////////////////////////////////////////
  1839. //
  1840. // Draw Colored Triangles
  1841. //
  1842. //////////////////////////////////////////////////////////////////////////////
  1843. void DrawTriangles(const VertexL* pvertex, int vcount, const MeshIndex* pindex, int icount)
  1844. {
  1845. #ifdef EnablePerformanceCounters
  1846. m_countTriangles += icount / 3;
  1847. #endif
  1848. UpdatePointers();
  1849. (this->*m_pfnLightVertexL)(pvertex, vcount, pindex, icount, ClipTriangles, DrawTriangles);
  1850. }
  1851. //////////////////////////////////////////////////////////////////////////////
  1852. //
  1853. // Draw Colored Lines
  1854. //
  1855. //////////////////////////////////////////////////////////////////////////////
  1856. void DrawLines(const VertexL* pvertex, int vcount, const MeshIndex* pindex, int icount)
  1857. {
  1858. #ifdef EnablePerformanceCounters
  1859. m_countLines += icount - 1;
  1860. #endif
  1861. UpdatePointers();
  1862. (this->*m_pfnLightVertexL)(pvertex, vcount, pindex, icount, ClipLines, m_pfnDrawLines);
  1863. }
  1864. //////////////////////////////////////////////////////////////////////////////
  1865. //
  1866. // Draw Colored Points
  1867. //
  1868. //////////////////////////////////////////////////////////////////////////////
  1869. void DrawPoints(const VertexL* pvertex, int vcount)
  1870. {
  1871. #ifdef EnablePerformanceCounters
  1872. m_countPoints += vcount;
  1873. #endif
  1874. UpdatePointers();
  1875. (this->*m_pfnLightVertexL)(pvertex, vcount, NULL, 0, ClipPoints, DrawPoints);
  1876. }
  1877. };
  1878. TRef<IDevice3D> CreateDevice3D(Rasterizer* prasterizer)
  1879. {
  1880. return new Device3D(prasterizer);
  1881. }