GOSVertex.hpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. //===========================================================================//
  2. // Copyright (C) Microsoft Corporation. All rights reserved. //
  3. //===========================================================================//
  4. #pragma once
  5. #define MLR_GOSVERTEX_HPP
  6. #include <MLR\MLR.hpp>
  7. #include <Stuff\Scalar.hpp>
  8. #include <GameOS.hpp>
  9. namespace MidLevelRenderer {
  10. //##########################################################################
  11. //#################### GOSVertex ##############################
  12. //##########################################################################
  13. class GOSVertex :
  14. public gos_VERTEX
  15. {
  16. public:
  17. GOSVertex();
  18. static Stuff::Scalar
  19. farClipReciprocal;
  20. inline GOSVertex&
  21. operator=(const GOSVertex& V)
  22. {
  23. Check_Pointer(this);
  24. x = V.x;
  25. y = V.y;
  26. z = V.z;
  27. rhw = V.rhw;
  28. argb = V.argb;
  29. frgb = V.frgb;
  30. u = V.u;
  31. v = V.v;
  32. return *this;
  33. };
  34. inline GOSVertex&
  35. operator=(const Stuff::Vector4D& v)
  36. {
  37. Check_Pointer(this);
  38. Verify(!Stuff::Small_Enough(v.w));
  39. // Tell_Value(v);
  40. rhw = 1.0f / v.w;
  41. x = v.x * rhw;
  42. Verify(x>=0.0f && x<=1.0f);
  43. y = v.y * rhw;
  44. Verify(y>=0.0f && y<=1.0f);
  45. z = v.z * rhw;
  46. Verify(z>=0.0f && z<1.0f);
  47. return *this;
  48. }
  49. inline GOSVertex&
  50. operator=(const Stuff::RGBAColor& c)
  51. {
  52. Check_Pointer(this);
  53. // DEBUG_STREAM << "c = <" << c.alpha << ", " << c.red << ", ";
  54. // DEBUG_STREAM << c.green << ", " << c.blue << ">" << endl;
  55. float f;
  56. f = c.alpha * 255.99f;
  57. Clamp(f, 0.0f, 255.f);
  58. argb = Stuff::Round_Float_To_Byte (f);
  59. f = c.red * 255.99f;
  60. Clamp(f, 0.0f, 255.f);
  61. argb = (argb << 8) | Stuff::Round_Float_To_Byte (f);
  62. f = c.green * 255.99f;
  63. Clamp(f, 0.0f, 255.f);
  64. argb = (argb << 8) | Stuff::Round_Float_To_Byte (f);
  65. f = c.blue * 255.99f;
  66. Clamp(f, 0.0f, 255.f);
  67. argb = (argb << 8) | Stuff::Round_Float_To_Byte (f);
  68. // DEBUG_STREAM << "0x" << hex << argb << dec << endl;
  69. return *this;
  70. }
  71. inline GOSVertex&
  72. operator=(const DWORD c)
  73. {
  74. Check_Pointer(this);
  75. argb = c;
  76. return *this;
  77. }
  78. inline GOSVertex&
  79. operator=(const Stuff::Vector2DOf<Stuff::Scalar>& uv)
  80. {
  81. Check_Pointer(this);
  82. u = uv[0];
  83. v = uv[1];
  84. return *this;
  85. }
  86. inline void
  87. GOSTransformNoClip(
  88. const Stuff::Point3D &v,
  89. const Stuff::Matrix4D &m,
  90. Stuff::Scalar *uv
  91. #if FOG_HACK
  92. , int foggy
  93. #endif
  94. );
  95. #if FOG_HACK
  96. static BYTE GOSVertex::fogTable[Limits::Max_Number_Of_FogStates][1024];
  97. static void
  98. SetFogTableEntry(int entry, Stuff::Scalar fogNearClip, Stuff::Scalar fogFarClip, Stuff::Scalar fogDensity);
  99. #endif
  100. protected:
  101. };
  102. struct ViewportScalars
  103. {
  104. static Stuff::Scalar MulX;
  105. static Stuff::Scalar MulY;
  106. static Stuff::Scalar AddX;
  107. static Stuff::Scalar AddY;
  108. };
  109. typedef Stuff::Vector2DOf<Stuff::Scalar> Vector2DScalar;
  110. const float float_cheat = 12582912.0f/256.0f;
  111. const float One_Over_256 = 1.0f/256.0f;
  112. #pragma warning (disable : 4725)
  113. void
  114. GOSVertex::GOSTransformNoClip(
  115. const Stuff::Point3D &_v,
  116. const Stuff::Matrix4D &m,
  117. Stuff::Scalar *uv
  118. #if FOG_HACK
  119. , int foggy
  120. #endif
  121. )
  122. {
  123. Check_Pointer(this);
  124. Check_Object(&_v);
  125. Check_Object(&m);
  126. #if USE_ASSEMBLER_CODE
  127. Stuff::Scalar *f = &x;
  128. _asm {
  129. mov edx, m
  130. mov eax, _v
  131. fld dword ptr [eax] // v.x
  132. fld dword ptr [eax+4] // v.y
  133. fld dword ptr [eax+8] // v.z
  134. mov eax, f
  135. fld dword ptr [edx+34h] // m[1][3]
  136. fmul st, st(2) // v.y
  137. fld dword ptr [edx+38h] // m[2][3]
  138. fmul st, st(2) // v.z
  139. fxch st(1)
  140. fadd dword ptr [edx+3Ch] // m[3][3]
  141. fld dword ptr [edx+30h] // m[0][3]
  142. fmul st, st(5) // v.x
  143. fxch st(2)
  144. faddp st(1),st
  145. fld dword ptr [edx+14h] // m[1][1]
  146. fmul st, st(4) // v.y
  147. fxch st(2)
  148. faddp st(1),st
  149. fld dword ptr [edx+18h] // m[2][1]
  150. fmul st, st(3) // v.z
  151. fxch st(1)
  152. fstp dword ptr [eax+0Ch] // w
  153. fadd dword ptr [edx+1Ch] // m[3][1]
  154. fld dword ptr [edx+10h] // m[0][1]
  155. fmul st, st(5) // v.x
  156. fxch st(2)
  157. faddp st(1),st
  158. fld dword ptr [edx+24h] // m[1][2]
  159. fmul st, st(4) // v.y
  160. fxch st(2)
  161. faddp st(1),st
  162. fld dword ptr [edx+28h] // m[2][2]
  163. fmul st, st(3) // v.z
  164. fxch st(1)
  165. fstp dword ptr [eax+4] // y
  166. fadd dword ptr [edx+2Ch] // m[3][2]
  167. fld dword ptr [edx+20h] // m[0][2]
  168. fmul st, st(5) // v.x
  169. fxch st(2)
  170. faddp st(1),st
  171. fld dword ptr [edx+4] // m[1][0]
  172. fmul st, st(4) // v.y
  173. fxch st(2)
  174. faddp st(1),st
  175. fld dword ptr [edx+8] // m[2][0]
  176. fmul st, st(3) // v.z
  177. fxch st(1)
  178. fstp dword ptr [eax+8] // z
  179. fadd dword ptr [edx+0Ch] // m[3][0]
  180. fld dword ptr [edx] // m[0][0]
  181. fmul st, st(5) // v.x
  182. fxch st(2)
  183. faddp st(1),st
  184. faddp st(1),st
  185. // fld1
  186. // fdivrp st(1),st
  187. // get rid of x, y, z
  188. fstp st(1)
  189. fstp st(1)
  190. fstp st(1)
  191. fstp dword ptr [eax] // x
  192. }
  193. #else
  194. x = v.x*m(0,0) + v.y*m(1,0) + v.z*m(2,0) + m(3,0);
  195. y = v.x*m(0,1) + v.y*m(1,1) + v.z*m(2,1) + m(3,1);
  196. z = v.x*m(0,2) + v.y*m(1,2) + v.z*m(2,2) + m(3,2);
  197. rhw = v.x*m(0,3) + v.y*m(1,3) + v.z*m(2,3) + m(3,3);
  198. #endif
  199. #if 0 //USE_ASSEMBLER_CODE
  200. _asm {
  201. ; gos_vertices[0].w = 1.0f/coords[offset].w;
  202. mov ecx, f
  203. fld1
  204. fdiv dword ptr [ecx+0Ch]
  205. fst dword ptr [ecx+0Ch]
  206. ; gos_vertices[0].x = coords[offset].x * gos_vertices[0].w;
  207. fld st(0)
  208. fmul dword ptr [ecx]
  209. fstp dword ptr [ecx]
  210. ; gos_vertices[0].y = coords[offset].y * gos_vertices[0].w;
  211. fld dword ptr [ecx+4]
  212. fmul st,st(1)
  213. fstp dword ptr [ecx+4]
  214. ; gos_vertices[0].z = coords[offset].z * gos_vertices[0].w;
  215. ; fld dword ptr [ecx+8]
  216. fmul dword ptr [ecx+8]
  217. fstp dword ptr [ecx+8]
  218. ; fstp st(0)
  219. }
  220. #else
  221. #if FOG_HACK
  222. if(foggy)
  223. {
  224. *((BYTE *)&frgb + 3) =
  225. fogTable[foggy-1][Stuff::Truncate_Float_To_Word(rhw)];
  226. }
  227. else
  228. {
  229. *((BYTE *)&frgb + 3) = 0xff;
  230. }
  231. #endif
  232. rhw = 1.0f/rhw;
  233. Verify( MLRState::GetHasMaxUVs() ? (uv[0]<MLRState::GetMaxUV() && uv[0]>-MLRState::GetMaxUV()) : 1 );
  234. Verify( MLRState::GetHasMaxUVs() ? (uv[1]<MLRState::GetMaxUV() && uv[1]>-MLRState::GetMaxUV()) : 1 );
  235. u = uv[0];
  236. v = uv[1];
  237. x = x * rhw;
  238. y = y * rhw;
  239. z = z * rhw;
  240. #endif
  241. Verify(rhw > Stuff::SMALL);
  242. Verify(x >= 0.0f);
  243. Verify(y >= 0.0f);
  244. Verify(z >= 0.0f);
  245. Verify(x <= 1.0f);
  246. Verify(y <= 1.0f);
  247. Verify(z < 1.0f);
  248. x = x*ViewportScalars::MulX + ViewportScalars::AddX;
  249. y = y*ViewportScalars::MulY + ViewportScalars::AddY;
  250. }
  251. // create a dword color out of 4 rgba floats
  252. inline DWORD
  253. GOSCopyColor( const Stuff::RGBAColor *color )
  254. {
  255. Stuff::Scalar f;
  256. #if USE_ASSEMBLER_CODE
  257. DWORD argb;
  258. _asm {
  259. fld float_cheat
  260. mov esi, dword ptr [color]
  261. fld dword ptr [esi + 0Ch]
  262. mov ecx, dword ptr [esi + 0Ch]
  263. fadd st, st(1)
  264. rcl ecx, 1
  265. sbb eax, eax
  266. xor eax, -1
  267. fstp f
  268. xor ecx, ecx
  269. mov ebx, f
  270. and ebx, eax
  271. test ebx, 0000ff00h
  272. seta cl
  273. xor eax, eax
  274. sub eax, ecx
  275. or ebx, eax
  276. and ebx, 000000ffh
  277. mov argb, ebx
  278. fld dword ptr [esi]
  279. mov ecx, dword ptr [esi]
  280. fadd st, st(1)
  281. rcl ecx, 1
  282. sbb eax, eax
  283. xor eax, -1
  284. fstp f
  285. xor ecx, ecx
  286. mov ebx, f
  287. and ebx, eax
  288. test ebx, 0000ff00h
  289. seta cl
  290. xor eax, eax
  291. sub eax, ecx
  292. or ebx, eax
  293. and ebx, 000000ffh
  294. mov ecx, argb
  295. shl ecx, 8
  296. or ecx, ebx
  297. mov argb, ecx
  298. fld dword ptr [esi+4]
  299. mov ecx, dword ptr [esi+4]
  300. fadd st, st(1)
  301. rcl ecx, 1
  302. sbb eax, eax
  303. xor eax, -1
  304. fstp f
  305. xor ecx, ecx
  306. mov ebx, f
  307. and ebx, eax
  308. test ebx, 0000ff00h
  309. seta cl
  310. xor eax, eax
  311. sub eax, ecx
  312. or ebx, eax
  313. and ebx, 000000ffh
  314. mov ecx, argb
  315. shl ecx, 8
  316. or ecx, ebx
  317. mov argb, ecx
  318. ; fld dword ptr [esi+8]
  319. mov ecx, dword ptr [esi+8]
  320. fadd dword ptr [esi+8]
  321. rcl ecx, 1
  322. sbb eax, eax
  323. xor eax, -1
  324. fstp f
  325. xor ecx, ecx
  326. mov ebx, f
  327. and ebx, eax
  328. test ebx, 0000ff00h
  329. seta cl
  330. xor eax, eax
  331. sub eax, ecx
  332. or ebx, eax
  333. and ebx, 000000ffh
  334. mov ecx, argb
  335. shl ecx, 8
  336. or ecx, ebx
  337. mov argb, ecx
  338. }
  339. #else
  340. f = color->alpha * 255.99f;
  341. Clamp(f, 0.0f, 255.f);
  342. argb = Stuff::Positive_Float_To_Byte (f);
  343. f = colors->red * 255.99f;
  344. Clamp(f, 0.0f, 255.f);
  345. argb = (gos_vertices[0].argb << 8) | Stuff::Positive_Float_To_Byte (f);
  346. f = colors->green * 255.99f;
  347. Clamp(f, 0.0f, 255.f);
  348. argb = (gos_vertices[0].argb << 8) | Stuff::Positive_Float_To_Byte (f);
  349. f = colors->blue * 255.99f;
  350. Clamp(f, 0.0f, 255.f);
  351. argb = (gos_vertices[0].argb << 8) | Stuff::Positive_Float_To_Byte (f);
  352. #endif
  353. return argb;
  354. }
  355. inline DWORD
  356. Color_DWORD_Lerp (
  357. DWORD _from,
  358. DWORD _to,
  359. Stuff::Scalar _lerp
  360. )
  361. {
  362. Stuff::RGBAColor from, to, lerp;
  363. from.blue = (_from & 0xff) * One_Over_256;
  364. _from = _from>>8;
  365. from.green = (_from & 0xff) * One_Over_256;
  366. _from = _from>>8;
  367. from.red = (_from & 0xff) * One_Over_256;
  368. _from = _from>>8;
  369. from.alpha = (_from & 0xff) * One_Over_256;
  370. // ====
  371. to.blue = (_to & 0xff) * One_Over_256;
  372. _to = _to>>8;
  373. to.green = (_to & 0xff) * One_Over_256;
  374. _to = _to>>8;
  375. to.red = (_to & 0xff) * One_Over_256;
  376. _to = _to>>8;
  377. to.alpha = (_to & 0xff) * One_Over_256;
  378. lerp.Lerp(from, to, _lerp);
  379. return GOSCopyColor(&lerp);
  380. }
  381. //######################################################################################################################
  382. // the lines below will produce following functions:
  383. //
  384. // bool GOSCopyData(GOSVertex*, const Stuff::Vector4D*, int);
  385. // bool GOSCopyData(GOSVertex*, const Stuff::Vector4D*, const DWORD*, int);
  386. // bool GOSCopyData(GOSVertex*, const Stuff::Vector4D*, const RGBAColor*, int);
  387. // bool GOSCopyData(GOSVertex*, const Stuff::Vector4D*, const Vector2DScalar*, int);
  388. // bool GOSCopyData(GOSVertex*, const Stuff::Vector4D*, const DWORD*, const Vector2DScalar*, int);
  389. // bool GOSCopyData(GOSVertex*, const Stuff::Vector4D*, const RGBAColor*, const Vector2DScalar*, int);
  390. //
  391. // bool GOSCopyTriangleData(GOSVertex*, const Stuff::Vector4D*, int, int, int);
  392. // bool GOSCopyTriangleData(GOSVertex*, const Stuff::Vector4D*, const DWORD*, int, int, int);
  393. // bool GOSCopyTriangleData(GOSVertex*, const Stuff::Vector4D*, const RGBAColor*, int, int, int);
  394. // bool GOSCopyTriangleData(GOSVertex*, const Stuff::Vector4D*, const Vector2DScalar*, int, int, int);
  395. // bool GOSCopyTriangleData(GOSVertex*, const Stuff::Vector4D*, const DWORD*, const Vector2DScalar*, int, int, int);
  396. // bool GOSCopyTriangleData(GOSVertex*, const Stuff::Vector4D*, const RGBAColor*, const Vector2DScalar*, int, int, int);
  397. //#######################################################################################################################
  398. #define I_SAY_YES_TO_COLOR
  399. #define I_SAY_YES_TO_TEXTURE
  400. #define I_SAY_YES_TO_DWORD_COLOR
  401. #include <MLR\GOSVertexManipulation.hpp>
  402. #undef I_SAY_YES_TO_DWORD_COLOR
  403. #include <MLR\GOSVertexManipulation.hpp>
  404. #undef I_SAY_YES_TO_COLOR
  405. #include <MLR\GOSVertexManipulation.hpp>
  406. #define I_SAY_YES_TO_COLOR
  407. #undef I_SAY_YES_TO_TEXTURE
  408. #include <MLR\GOSVertexManipulation.hpp>
  409. #define I_SAY_YES_TO_DWORD_COLOR
  410. #include <MLR\GOSVertexManipulation.hpp>
  411. #undef I_SAY_YES_TO_COLOR
  412. #include <MLR\GOSVertexManipulation.hpp>
  413. #define MLR_GOSVERTEXMANIPULATION_HPP
  414. }