Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1955 lines
53 KiB

  1. ;---------------------------Module-Header------------------------------;
  2. ; Module Name: so_prim.asm
  3. ;
  4. ; xform routines.
  5. ;
  6. ; Created: 10/14/1996
  7. ; Author: Otto Berkes [ottob]
  8. ;
  9. ; Copyright (c) 1996 Microsoft Corporation
  10. ;----------------------------------------------------------------------;
  11. .386
  12. .model small,pascal
  13. assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT
  14. assume fs:nothing,gs:nothing
  15. .xlist
  16. include gli386.inc
  17. .list
  18. PROFILE = 0
  19. include profile.inc
  20. .data
  21. extrn ___glClipCodes :DWORD
  22. extrn ___glOne:DWORD
  23. extrn ___glHalf:DWORD
  24. extrn ___glZero:DWORD
  25. ;------------------------------------------------------------------------------------------
  26. ; Internal definitions:
  27. ;
  28. _R_ = 0
  29. _G_ = 4
  30. _B_ = 8
  31. _A_ = 12
  32. _X_ = 0
  33. _Y_ = 4
  34. _Z_ = 8
  35. _W_ = 12
  36. ;------------------------------------------------------------------------------------------
  37. ; pdLast is passed as parameter
  38. ;
  39. pdLast equ [ebp+8]
  40. ;
  41. ; Temporary data
  42. ;
  43. gc equ -4[ebp]
  44. pa equ -8[ebp]
  45. .code
  46. extrn @__glNormalize@8:NEAR
  47. ;------------------------------------------------------------------------------------------
  48. ; Makes clip code for frustum clip planes
  49. ; General case
  50. ;
  51. ; Input:
  52. ; edx = pointer to POLYARRAY
  53. ; ecx = pointer to graphics context
  54. ; pdLast = pointer to the last vertex
  55. ; pa = pointer to POLYARRAY
  56. ; gc = pointer to graphics context
  57. ; ReuseClipCode if set to 1, new clip code is combined using OR with existing one
  58. ;
  59. ; Returns:
  60. ; eax = andClipCodes for POLYARRAY
  61. ;
  62. PAClipCheckFrustum MACRO ReuseClipCode
  63. mov edx, DWORD PTR [edx+PA_pd0]
  64. vertexLoop:
  65. mov esi, DWORD PTR [edx+PD_clip+_W_] ; esi = clipW
  66. or esi, esi ; if (clipW == 0) go to special case
  67. jz @WEqZero
  68. fld ___glOne
  69. fdiv DWORD PTR [edx+PD_clip+_W_] ; start division
  70. ; edi will accumulate index to clip table
  71. ; bit 6 - 1 if clipW < 0
  72. ; bit 5 - 1 if clipX < 0
  73. ; bit 4 - 1 if abs(clipX) < abs(clipW)
  74. ; bit 3 - 1 if clipY < 0
  75. ; bit 2 - 1 if abs(clipY) < abs(clipW)
  76. ; bit 1 - 1 if clipZ < 0
  77. ; bit 0 - 1 if abs(clipZ) < abs(clipW)
  78. xor edi, edi
  79. add esi, esi ; esi = abs(clipW) shifted left 1 bit
  80. mov ebx, [edx+PD_clip+_X_] ; ebx = clipX
  81. adc edi, edi ; edi = sign clipW
  82. add esi, 1 ; X-W bit should be set when X-W <= 0 !!!
  83. add ebx, ebx ; ebx = abs(clipX) shifted left 1 bit
  84. adc edi, edi ; edi = edi << 1 + sign(clipX)
  85. sub ebx, esi
  86. adc edi, edi ; edi = edi << 1 + sign(abs(clipX) - abs(clipW))
  87. mov ebx, [edx+PD_clip+_Y_]
  88. mov ecx, pa
  89. add ebx, ebx
  90. adc edi, edi ; edi = edi << 1 + sign(clipY)
  91. sub ebx, esi
  92. adc edi, edi ; edi = edi << 1 + sign(abs(clipY) - abs(clipW))
  93. mov ebx, [edx+PD_clip+_Z_]
  94. add edx, sizeof_POLYDATA ; advance vertex ptr
  95. add ebx, ebx ; edi = edi << 1 + sign(clipZ)
  96. adc edi, edi
  97. sub ebx, esi
  98. adc edi, edi ; edi = edi << 1 + sign(abs(clipZ) - abs(clipW))
  99. mov esi, [ecx+PA_orClipCodes] ; get prim OR code
  100. mov ebx, [ecx+PA_andClipCodes] ; get prim AND code
  101. mov ecx, ___glClipCodes[edi*4] ; ecx = clip code
  102. mov edi, pa
  103. if ReuseClipCode eq 1
  104. or ecx, [edx+PD_clipCode-sizeof_POLYDATA] ; update vertex clip code
  105. endif
  106. mov [edx+PD_clipCode-sizeof_POLYDATA], ecx ; store vertex clip code
  107. or esi, ecx ; compute prim OR
  108. and ebx, ecx ; " " AND
  109. mov [edi+PA_orClipCodes], esi ; store prim OR
  110. mov [edi+PA_andClipCodes], ebx ; store prim AND
  111. mov ebx, gc
  112. mov edi, pdLast
  113. ;; Save invW in window.w:
  114. fstp DWORD PTR [edx+PD_window+_W_ - sizeof_POLYDATA]
  115. or ecx, ecx
  116. jnz @Done
  117. fld DWORD PTR [edx+PD_clip+_X_ - sizeof_POLYDATA]
  118. fmul DWORD PTR [ebx+GC_VIEWPORT_xScale]
  119. fld DWORD PTR [edx+PD_clip+_Y_ - sizeof_POLYDATA]
  120. fmul DWORD PTR [ebx+GC_VIEWPORT_yScale]
  121. fld DWORD PTR [edx+PD_clip+_Z_ - sizeof_POLYDATA]
  122. fmul DWORD PTR [ebx+GC_VIEWPORT_zScale] ; z y x
  123. fxch st(2) ; x y z
  124. fmul DWORD PTR [edx+PD_window+_W_ - sizeof_POLYDATA] ; X y z
  125. fxch st(1) ; y X z
  126. fmul DWORD PTR [edx+PD_window+_W_ - sizeof_POLYDATA] ; Y X z
  127. fxch st(2) ; z X Y
  128. fmul DWORD PTR [edx+PD_window+_W_ - sizeof_POLYDATA] ; Z X Y
  129. fxch st(1) ; X Z Y
  130. fadd DWORD PTR [ebx+GC_VIEWPORT_xCenter] ; x Z Y
  131. fxch st(2) ; Y Z x
  132. fadd DWORD PTR [ebx+GC_VIEWPORT_yCenter] ; y Z x
  133. fxch st(1) ; Z y x
  134. fadd DWORD PTR [ebx+GC_VIEWPORT_zCenter] ; z y x
  135. fxch st(2) ; x y z
  136. fstp DWORD PTR [edx+PD_window+_X_ - sizeof_POLYDATA]
  137. fstp DWORD PTR [edx+PD_window+_Y_ - sizeof_POLYDATA]
  138. fstp DWORD PTR [edx+PD_window+_Z_ - sizeof_POLYDATA]
  139. @Done:
  140. cmp edx, edi ; pd > pdLast?
  141. jbe vertexLoop ; yes -> process next vertex
  142. @Exit:
  143. mov edx, pa
  144. pop edi
  145. pop esi
  146. pop ebx
  147. mov esp, ebp
  148. pop ebp
  149. mov eax, [edx + PA_andClipCodes] ; return value
  150. ret 4
  151. ;
  152. ; W == 0
  153. ;
  154. @WEqZero:
  155. xor edi, edi
  156. mov ebx, [edx+PD_clip+_X_] ; ebx = clipX
  157. add ebx, ebx ; ebx = abs(clipX) shifted left 1 bit
  158. adc edi, edi ; edi = edi << 1 + sign(clipX)
  159. add edi, edi ; edi = edi << 1
  160. mov ebx, [edx+PD_clip+_Y_]
  161. mov ecx, pa
  162. add ebx, ebx
  163. adc edi, edi ; edi = edi << 1 + sign(clipY)
  164. add edi, edi ; edi = edi << 1
  165. mov ebx, [edx+PD_clip+_Z_]
  166. add edx, sizeof_POLYDATA ; advance vertex ptr
  167. add ebx, ebx ; edi = edi << 1 + sign(clipZ)
  168. adc edi, edi
  169. add edi, edi ; edi = edi << 1
  170. mov esi, [ecx+PA_orClipCodes] ; get prim OR code
  171. mov ebx, [ecx+PA_andClipCodes] ; get prim AND code
  172. mov ecx, ___glClipCodes[edi*4] ; ecx = clip code
  173. mov edi, pa
  174. if ReuseClipCode eq 1
  175. or ecx, [edx+PD_clipCode-sizeof_POLYDATA] ; update vertex clip code
  176. endif
  177. mov [edx+PD_clipCode-sizeof_POLYDATA], ecx ; store vertex clip code
  178. or esi, ecx ; compute prim OR
  179. and ebx, ecx ; " " AND
  180. mov [edi+PA_orClipCodes], esi ; store prim OR
  181. mov [edi+PA_andClipCodes], ebx ; store prim AND
  182. mov ebx, gc
  183. mov edi, pdLast
  184. ;; Save invW in window.w:
  185. mov DWORD PTR [edx+PD_window+_W_ - sizeof_POLYDATA], 0
  186. or ecx, ecx
  187. jnz @Done
  188. mov ecx, DWORD PTR [ebx+GC_VIEWPORT_xCenter]
  189. mov ebx, DWORD PTR [ebx+GC_VIEWPORT_yCenter]
  190. mov DWORD PTR [edx+PD_window+_X_ - sizeof_POLYDATA], ecx
  191. mov ecx, DWORD PTR [ebx+GC_VIEWPORT_zCenter]
  192. mov DWORD PTR [edx+PD_window+_Y_ - sizeof_POLYDATA], ebx
  193. mov DWORD PTR [edx+PD_window+_Z_ - sizeof_POLYDATA], ecx
  194. jmp @Done
  195. ENDM
  196. ;------------------------------------------------------------------------------------------
  197. ; Make clip code for frustum clip planes
  198. ; General case
  199. ;
  200. ; Prototype:
  201. ; GLuint FASTCALL PAClipCheckFrustum(__GLcontext *gc, POLYARRAY *pa,
  202. ; POLYDATA *pdLast);
  203. ; Input:
  204. ; edx = pa pointer to POLYARRAY
  205. ; ecx = gc pointer to graphics context
  206. ; [esp+4] = pointer to the last vertex
  207. ; andClipCodes for POLYARRAY is set to -1
  208. ; orClipCodes for POLYARRAY is set to 0
  209. ;
  210. ; Returns:
  211. ; andClipCodes for POLYARRAY
  212. ;
  213. @PAClipCheckFrustum@12 PROC NEAR
  214. push ebp
  215. mov ebp, esp
  216. sub esp, 12
  217. mov DWORD PTR pa, edx
  218. mov DWORD PTR gc, ecx
  219. push ebx
  220. push esi
  221. push edi
  222. PAClipCheckFrustum 0
  223. @PAClipCheckFrustum@12 ENDP
  224. ;------------------------------------------------------------------------------------------
  225. ; Makes clip code for frustum clip planes
  226. ; Case when vertices have W == 1.0
  227. ;
  228. ; Input:
  229. ; edx = pa pointer to POLYARRAY
  230. ; ecx = gc pointer to graphics context
  231. ; pa = pointer to POLYARRAY
  232. ; gc = pointer to graphics context
  233. ; pdLast = pointer to the last vertex
  234. ; ReuseClipCode if set to 1, new clip code is combined using OR with existing one
  235. ;
  236. ; Returns:
  237. ; eax = andClipCodes for POLYARRAY
  238. ;
  239. PAClipCheckFrustumWOne MACRO ReuseClipCode
  240. mov edx, DWORD PTR [edx+PA_pd0]
  241. vertexLoop:
  242. ; edi will accumulate index to clip table
  243. ; bit 6 - 1 if clipW < 0 --- always 0 for this case
  244. ; bit 5 - 1 if clipX < 0
  245. ; bit 4 - 1 if abs(clipX) < abs(clipW)
  246. ; bit 3 - 1 if clipY < 0
  247. ; bit 2 - 1 if abs(clipY) < abs(clipW)
  248. ; bit 1 - 1 if clipZ < 0
  249. ; bit 0 - 1 if abs(clipZ) < abs(clipW)
  250. xor edi, edi
  251. mov ebx, [edx+PD_clip+_X_] ; ebx = clipX
  252. mov esi, (__FLOAT_ONE*2) + 1
  253. add ebx, ebx ; ebx = abs(clipX) shifted left 1 bit
  254. adc edi, edi ; edi = edi << 1 + sign(clipX)
  255. sub ebx, esi
  256. adc edi, edi ; edi = edi << 1 + sign(abs(clipX) - abs(clipW))
  257. mov ebx, [edx+PD_clip+_Y_]
  258. mov ecx, pa
  259. add ebx, ebx
  260. adc edi, edi ; edi = edi << 1 + sign(clipY)
  261. sub ebx, esi
  262. adc edi, edi ; edi = edi << 1 + sign(abs(clipY) - abs(clipW))
  263. mov ebx, [edx+PD_clip+_Z_]
  264. add edx, sizeof_POLYDATA ; advance vertex ptr
  265. add ebx, ebx ; edi = edi << 1 + sign(clipZ)
  266. adc edi, edi
  267. sub ebx, esi
  268. adc edi, edi ; edi = edi << 1 + sign(abs(clipZ) - abs(clipW))
  269. mov esi, [ecx+PA_orClipCodes] ; get prim OR code
  270. mov ebx, [ecx+PA_andClipCodes] ; get prim AND code
  271. mov ecx, ___glClipCodes[edi*4] ; ecx = clip code
  272. mov edi, pa
  273. if ReuseClipCode eq 1
  274. or ecx, [edx+PD_clipCode-sizeof_POLYDATA] ; update vertex clip code
  275. endif
  276. mov [edx+PD_clipCode-sizeof_POLYDATA], ecx ; store vertex clip code
  277. or esi, ecx ; compute prim OR
  278. and ebx, ecx ; " " AND
  279. mov [edi+PA_orClipCodes], esi ; store prim OR
  280. mov [edi+PA_andClipCodes], ebx ; store prim AND
  281. mov ebx, gc
  282. mov edi, pdLast
  283. ;; Save invW in window.w:
  284. mov DWORD PTR [edx+PD_window+_W_ - sizeof_POLYDATA], __FLOAT_ONE
  285. or ecx, ecx
  286. jnz @Done
  287. fld DWORD PTR [edx+PD_clip+_X_ - sizeof_POLYDATA]
  288. fmul DWORD PTR [ebx+GC_VIEWPORT_xScale]
  289. fld DWORD PTR [edx+PD_clip+_Y_ - sizeof_POLYDATA]
  290. fmul DWORD PTR [ebx+GC_VIEWPORT_yScale]
  291. fld DWORD PTR [edx+PD_clip+_Z_ - sizeof_POLYDATA]
  292. fmul DWORD PTR [ebx+GC_VIEWPORT_zScale] ; z y x
  293. fxch st(2) ; x y z
  294. fadd DWORD PTR [ebx+GC_VIEWPORT_xCenter] ; x y z
  295. fxch st(1) ; y x z
  296. fadd DWORD PTR [ebx+GC_VIEWPORT_yCenter] ; y x z
  297. fxch st(2) ; z x y
  298. fadd DWORD PTR [ebx+GC_VIEWPORT_zCenter] ; z x y
  299. fxch st(1) ; x z y
  300. fstp DWORD PTR [edx+PD_window+_X_ - sizeof_POLYDATA]
  301. fstp DWORD PTR [edx+PD_window+_Z_ - sizeof_POLYDATA]
  302. fstp DWORD PTR [edx+PD_window+_Y_ - sizeof_POLYDATA]
  303. @Done:
  304. cmp edx, edi ; pd > pdLast?
  305. jbe vertexLoop ; yes -> process next vertex
  306. @Exit:
  307. mov edx, pa
  308. pop edi
  309. pop esi
  310. pop ebx
  311. mov esp, ebp
  312. pop ebp
  313. mov eax, [edx + PA_andClipCodes] ; return value
  314. ret 4
  315. ENDM
  316. ;------------------------------------------------------------------------------------------
  317. ; Makes clip code for frustum clip planes
  318. ; Case when vertices have W == 1.0
  319. ;
  320. ; Prototype:
  321. ; GLuint FASTCALL PAClipCheckFrustumWOne(__GLcontext *gc, POLYARRAY *pa,
  322. ; POLYDATA *pdLast);
  323. ; Input:
  324. ; edx = pa pointer to POLYARRAY
  325. ; ecx = gc pointer to graphics context
  326. ; [esp+4] = pointer to the last vertex
  327. ; andClipCodes for POLYARRAY is set to -1
  328. ; orClipCodes for POLYARRAY is set to 0
  329. ;
  330. ; Returns:
  331. ; eax = andClipCodes for POLYARRAY
  332. ;
  333. @PAClipCheckFrustumWOne@12 PROC NEAR
  334. push ebp
  335. mov ebp, esp
  336. sub esp, 12
  337. mov DWORD PTR pa, edx
  338. mov DWORD PTR gc, ecx
  339. push ebx
  340. push esi
  341. push edi
  342. PAClipCheckFrustumWOne 0
  343. @PAClipCheckFrustumWOne@12 ENDP
  344. ;------------------------------------------------------------------------------------------
  345. ; Makes clip code for frustum clip planes
  346. ; Case when vertices have W == 1.0 and Z == 0.0
  347. ;
  348. ; Input:
  349. ; edx = pa pointer to POLYARRAY
  350. ; ecx = gc pointer to graphics context
  351. ; pa = pointer to POLYARRAY
  352. ; gc = pointer to graphics context
  353. ; pdLast = pointer to the last vertex
  354. ; ReuseClipCode if set to 1, new clip code is combined using OR with existing one
  355. ;
  356. ; Returns:
  357. ; eax = andClipCodes for POLYARRAY
  358. ;
  359. PAClipCheckFrustum2D MACRO ReuseClipCode
  360. mov edx, DWORD PTR [edx+PA_pd0]
  361. vertexLoop:
  362. ; edi will accumulate index to clip table
  363. ; bit 6 - 1 if clipW < 0 --- always 0 for this case
  364. ; bit 5 - 1 if clipX < 0
  365. ; bit 4 - 1 if abs(clipX) < abs(clipW)
  366. ; bit 3 - 1 if clipY < 0
  367. ; bit 2 - 1 if abs(clipY) < abs(clipW)
  368. ; bit 1 - 1 if clipZ < 0
  369. ; bit 0 - 1 if abs(clipZ) < abs(clipW)
  370. xor edi, edi
  371. mov ebx, [edx+PD_clip+_X_] ; ebx = clipX
  372. mov esi, (__FLOAT_ONE*2) + 1
  373. add ebx, ebx ; ebx = abs(clipX) shifted left 1 bit
  374. adc edi, edi ; edi = edi << 1 + sign(clipX)
  375. sub ebx, esi
  376. adc edi, edi ; edi = edi << 1 + sign(abs(clipX) - abs(clipW))
  377. mov ebx, [edx+PD_clip+_Y_]
  378. mov ecx, pa
  379. add ebx, ebx
  380. adc edi, edi ; edi = edi << 1 + sign(clipY)
  381. sub ebx, esi
  382. adc edi, edi ; edi = edi << 1 + sign(abs(clipY) - abs(clipW))
  383. add edx, sizeof_POLYDATA ; advance vertex ptr
  384. add edi, edi ; sign(clipZ) = 0
  385. lea edi, [edi+edi+1] ; sign(abs(clipZ) - abs(clipW)) = 0
  386. mov esi, [ecx+PA_orClipCodes] ; get prim OR code
  387. mov ebx, [ecx+PA_andClipCodes] ; get prim AND code
  388. mov ecx, ___glClipCodes[edi*4] ; ecx = clip code
  389. mov edi, pa
  390. if ReuseClipCode eq 1
  391. or ecx, [edx+PD_clipCode-sizeof_POLYDATA] ; update vertex clip code
  392. endif
  393. mov [edx+PD_clipCode-sizeof_POLYDATA], ecx ; store vertex clip code
  394. or esi, ecx ; compute prim OR
  395. and ebx, ecx ; " " AND
  396. mov [edi+PA_orClipCodes], esi ; store prim OR
  397. mov [edi+PA_andClipCodes], ebx ; store prim AND
  398. mov ebx, gc
  399. mov edi, pdLast
  400. ;; Save invW in window.w:
  401. mov DWORD PTR [edx+PD_window+_W_ - sizeof_POLYDATA], __FLOAT_ONE
  402. or ecx, ecx
  403. jnz @Done
  404. fld DWORD PTR [edx+PD_clip+_X_ - sizeof_POLYDATA]
  405. fmul DWORD PTR [ebx+GC_VIEWPORT_xScale]
  406. fld DWORD PTR [edx+PD_clip+_Y_ - sizeof_POLYDATA]
  407. fmul DWORD PTR [ebx+GC_VIEWPORT_yScale]
  408. fxch st(1) ; x y
  409. fadd DWORD PTR [ebx+GC_VIEWPORT_xCenter] ; x y
  410. fxch st(1) ; y x
  411. fadd DWORD PTR [ebx+GC_VIEWPORT_yCenter] ; y x
  412. fxch st(1) ; x y
  413. mov ecx, DWORD PTR [ebx+GC_VIEWPORT_zCenter]
  414. mov DWORD PTR [edx+PD_window+_Z_ - sizeof_POLYDATA], ecx
  415. fstp DWORD PTR [edx+PD_window+_X_ - sizeof_POLYDATA]
  416. fstp DWORD PTR [edx+PD_window+_Y_ - sizeof_POLYDATA]
  417. @Done:
  418. cmp edx, edi ; pd > pdLast?
  419. jbe vertexLoop ; yes -> process next vertex
  420. @Exit:
  421. mov edx, pa
  422. pop edi
  423. pop esi
  424. pop ebx
  425. mov esp, ebp
  426. pop ebp
  427. mov eax, [edx + PA_andClipCodes] ; return value
  428. ret 4
  429. ENDM
  430. ;------------------------------------------------------------------------------------------
  431. ; Makes clip code for frustum clip planes
  432. ; Case when vertices have W == 1.0
  433. ;
  434. ; Prototype:
  435. ; GLuint FASTCALL PAClipCheckFrustum2D(__GLcontext *gc, POLYARRAY *pa,
  436. ; POLYDATA *pdLast);
  437. ; Input:
  438. ; edx = pa pointer to POLYARRAY
  439. ; ecx = gc pointer to graphics context
  440. ; [esp+4] = pointer to the last vertex
  441. ; andClipCodes for POLYARRAY is set to -1
  442. ; orClipCodes for POLYARRAY is set to 0
  443. ;
  444. ; Returns:
  445. ; eax = andClipCodes for POLYARRAY
  446. ;
  447. @PAClipCheckFrustum2D@12 PROC NEAR
  448. push ebp
  449. mov ebp, esp
  450. sub esp, 12
  451. xor eax, eax
  452. mov pa, edx
  453. mov [edx+PA_orClipCodes], eax ; PA orClipCodes = 0
  454. dec eax
  455. push ebx
  456. mov [edx+PA_andClipCodes], eax ; PA andClipCodes = -1
  457. push esi
  458. mov DWORD PTR gc, ecx
  459. push edi
  460. PAClipCheckFrustum2D 0
  461. @PAClipCheckFrustum2D@12 ENDP
  462. ;------------------------------------------------------------------------------------------
  463. ; Makes clip code for user planes
  464. ;
  465. ; Input:
  466. ; edx = pa
  467. ; ecx = gc
  468. ; pdLast = pointer to the last vertex
  469. ; ReuseClipCode if set to 1, new clip code is combined using OR with existing one
  470. ;
  471. PAClipCheckUser MACRO ReuseClipCode
  472. result equ -16[ebp]
  473. cwSave equ -20[ebp]
  474. cwTemp equ -24[ebp]
  475. clipPlaneMask equ -28[ebp]
  476. firstPlane equ -32[ebp]
  477. ;; We have to turn on rounding with double precision. There is
  478. ;; too much error in the dot product otherwise (test with tlogo).
  479. fnstcw WORD PTR cwSave
  480. mov edi, DWORD PTR cwSave
  481. and edi, 0f0ffh
  482. or edi, 00200h
  483. mov cwTemp, edi
  484. fldcw WORD PTR cwTemp
  485. mov edi, pdLast ; edi will store POLYARRAY pointer
  486. mov edx, DWORD PTR [edx+PA_pd0]
  487. mov esi, DWORD PTR [ecx+GC_STATE_enablesClipPlanes] ; esi = clipPlaneMask
  488. mov ebx, [ecx+GC_STATE_clipPlanes0] ; ebx points to the current user plane
  489. or esi, esi
  490. jz @Exit1 ; No user planes
  491. mov clipPlaneMask, esi ; save clipPlaneMask
  492. mov firstPlane, ebx ; save pointer to the first clip plane
  493. @vertexLoop:
  494. mov esi, clipPlaneMask ; reload clipPlaneMask
  495. xor eax, eax ; prepare clip code
  496. mov ecx, __GL_CLIP_USER0 ; ecx stores __GL_CLIP_USER bits
  497. mov ebx, firstPlane ; reload pointer to the first clip plane
  498. @doAnotherPlane:
  499. test esi, 1 ; if (clipPlanesMask & 1 == 0) skip the plane
  500. je SHORT @noClipTest
  501. ;
  502. ; Dot the vertex clip coordinate against the clip plane and see
  503. ; if the sign is negative. If so, then the point is out.
  504. ;
  505. ; if (x * plane->x + y * plane->y + z * plane->z + w * plane->w <
  506. ; __glZero)
  507. ;
  508. fld DWORD PTR [ebx+_X_]
  509. fmul DWORD PTR [edx+PD_eye+_X_]
  510. fld DWORD PTR [ebx+_Y_]
  511. fmul DWORD PTR [edx+PD_eye+_Y_]
  512. fld DWORD PTR [ebx+_Z_]
  513. fmul DWORD PTR [edx+PD_eye+_Z_] ; z y x
  514. fxch ST(2) ; x y z
  515. faddp ST(1), ST(0) ; xy z
  516. fld DWORD PTR [ebx+_W_] ; w xy z
  517. fmul DWORD PTR [edx+PD_eye+_W_]
  518. fxch ST(2) ; z xy w
  519. faddp ST(1), ST(0) ; zxy w
  520. faddp ST(1), ST(0) ; zxyw
  521. fstp DWORD PTR result
  522. cmp result, 0
  523. jge @noClipTest
  524. or eax, ecx ; code |= bit;
  525. @noClipTest:
  526. add ecx, ecx ; bit <<= 1;
  527. add ebx, 16 ; plane++;
  528. shr esi, 1 ; clipPlanesMask >>= 1;
  529. jne SHORT @doAnotherPlane
  530. if ReuseClipCode eq 1
  531. or [edx+PD_clipCode], eax ; store vertex clip code
  532. else
  533. mov [edx+PD_clipCode], eax ; store vertex clip code
  534. endif
  535. add edx, sizeof_POLYDATA ; advance vertex ptr
  536. cmp edx, edi
  537. jbe @vertexLoop ; process next vertex
  538. ;; restore FP state:
  539. fldcw WORD PTR cwSave
  540. @Exit1:
  541. ENDM
  542. ;-------------------------------------------------------------------------------------------
  543. ; Make clip code when user clip planes are present
  544. ;
  545. ; Prototype:
  546. ; GLuint FASTCALL PAClipCheckFrustumAll(__GLcontext *gc, POLYARRAY *pa,
  547. ; POLYDATA *pdLast);
  548. ; Input:
  549. ; edx = pa pointer to POLYARRAY
  550. ; ecx = gc pointer to graphics context
  551. ; [esp+4] = pointer to the last vertex
  552. ; andClipCodes for POLYARRAY is set to -1
  553. ; orClipCodes for POLYARRAY is set to 0
  554. ;
  555. ; Returns:
  556. ; eax = andClipCodes for POLYARRAY
  557. ;
  558. @PAClipCheckAll@12 PROC NEAR
  559. push ebp
  560. mov ebp, esp
  561. sub esp, 32
  562. mov DWORD PTR pa, edx
  563. mov DWORD PTR gc, ecx
  564. push ebx
  565. push esi
  566. push edi
  567. PAClipCheckUser 0 ; Check user clip planes first
  568. mov edx, pa
  569. PAClipCheckFrustum 1 ; Check frustum clip planes. We have to use OR when
  570. ; updating vertex clip code
  571. @PAClipCheckAll@12 ENDP
  572. ;--------------------------------------------------------------------------------------------
  573. pd equ -4[ebp]
  574. pdLast equ -8[ebp]
  575. @PolyArrayPropagateSameColor@8 PROC NEAR
  576. push ebp
  577. mov eax, DWORD PTR [edx+PA_pdNextVertex]
  578. mov ebp, esp
  579. sub eax, sizeof_POLYDATA
  580. sub esp, 8
  581. mov DWORD PTR pdLast, eax
  582. push ebx
  583. push esi
  584. mov ebx, DWORD PTR [edx+PA_pd0]
  585. push edi
  586. ; EAX = pdLast = pa->pdNextVertex-1;
  587. ; EBX = pd = pa->pd0;
  588. mov DWORD PTR pd, ebx
  589. ; if (pd > pdLast)
  590. cmp eax, ebx
  591. jb @Done
  592. mov eax, [edx+PA_flags]
  593. lea edi, DWORD PTR [ebx+PD_colors0]
  594. ; if (pa->flags & POLYARRAY_CLAMP_COLOR) {
  595. test eax, POLYARRAY_CLAMP_COLOR
  596. je @ClampDone
  597. mov eax, [edi+_R_]
  598. mov ebx, [ecx+GC_redVertexScale]
  599. sub ebx, eax
  600. mov [ecx+GC_redClampTable], eax
  601. shr eax, 31
  602. add ebx, ebx
  603. mov edx, [edi+_G_]
  604. adc eax, eax
  605. mov ebx, [ecx+GC_greenVertexScale]
  606. sub ebx, edx
  607. mov eax, [4*eax+ecx+GC_redClampTable]
  608. mov [ecx+GC_greenClampTable], edx
  609. shr edx, 31
  610. add ebx, ebx
  611. mov [edi+_R_], eax
  612. adc edx, edx
  613. mov eax, [edi+_B_]
  614. mov ebx, [ecx+GC_blueVertexScale]
  615. sub ebx, eax
  616. mov edx, [4*edx+ecx+GC_greenClampTable]
  617. mov [ecx+GC_blueClampTable], eax
  618. shr eax, 31
  619. add ebx, ebx
  620. mov [edi+_G_], edx
  621. adc eax, eax
  622. mov edx, [edi+_A_]
  623. mov ebx, [ecx+GC_alphaVertexScale]
  624. sub ebx, edx
  625. mov eax, [4*eax+ecx+GC_blueClampTable]
  626. mov [ecx+GC_alphaClampTable], edx
  627. shr edx, 31
  628. add ebx, ebx
  629. adc edx, edx
  630. mov [edi+_B_], eax
  631. mov edx, [4*edx+ecx+GC_alphaClampTable]
  632. mov [edi+_A_], edx
  633. @ClampDone:
  634. ;; Register usage.
  635. ;; EAX: r, EBX: g, ECX: b, EDX: a
  636. ;; ESI: &pdLast->colors[0]
  637. ;; EDI: &pd->colors[0]
  638. mov edi, pd
  639. mov esi, pdLast
  640. lea edi, [edi+PD_colors0+sizeof_POLYDATA]
  641. lea esi, [esi+PD_colors0]
  642. mov eax, [edi+_R_-sizeof_POLYDATA]
  643. cmp edi, esi
  644. ja @Done
  645. mov ebx, [edi+_G_-sizeof_POLYDATA]
  646. mov ecx, [edi+_B_-sizeof_POLYDATA]
  647. mov edx, [edi+_A_-sizeof_POLYDATA]
  648. @DoLoop:
  649. mov [edi+_R_], eax
  650. mov [edi+_G_], ebx
  651. mov [edi+_B_], ecx
  652. mov [edi+_A_], edx
  653. add edi, sizeof_POLYDATA
  654. cmp edi, esi
  655. jbe @DoLoop
  656. @Done:
  657. pop edi
  658. pop esi
  659. pop ebx
  660. mov esp, ebp
  661. pop ebp
  662. ret 0
  663. @PolyArrayPropagateSameColor@8 ENDP
  664. ;------------------------------------------------------------------------
  665. ; Copy cached non lit color from GC to a polydata
  666. ;
  667. ; Input:
  668. ; PDreg - register with POLYDATA address
  669. ; GCreg - register with GC address
  670. ; GC_LIGHT_value - front or back light (0 or 1)
  671. ; face - 0 for front face, 1 for back face
  672. ; tmpreg1,
  673. ; tmpreg2 - temporary registers
  674. ;
  675. COPY_CACHED_NON_LIT MACRO PDreg, GCreg, GC_LIGHT_value, face, tmpreg1, tmpreg2
  676. mov eax, [ebx+GC_LIGHT_value+MATERIAL_cachedNonLit+_R_]
  677. mov ecx, [ebx+GC_LIGHT_value+MATERIAL_cachedNonLit+_G_]
  678. mov [esi+PD_colors0+(face*16)+_R_], eax
  679. mov [esi+PD_colors0+(face*16)+_G_], ecx
  680. mov eax, [ebx+GC_LIGHT_value+MATERIAL_cachedNonLit+_B_]
  681. mov ecx, [ebx+GC_LIGHT_value+MATERIAL_alpha]
  682. mov [esi+PD_colors0+(face*16)+_B_], eax
  683. mov [esi+PD_colors0+(face*16)+_A_], ecx
  684. ENDM
  685. ;------------------------------------------------------------------------
  686. ; No lights case
  687. ;
  688. POLYARRAYZIPPYCALCRGBCOLOR0 MACRO GC_LIGHT_value, face
  689. push ebp
  690. mov ebp, esp
  691. sub esp, 56
  692. push ebx
  693. push esi
  694. push edi
  695. mov esi, pdFirst
  696. mov edi, pdLast
  697. mov ebx, ecx ; ebx = gc
  698. ;
  699. ; for (pd = pdFirst; pd <= pdLast; pd++)
  700. ;
  701. @lightVertexLoop:
  702. COPY_CACHED_NON_LIT <esi>, <ebx>, GC_LIGHT_value, face, <eax>, <ecx>
  703. add esi, sizeof_POLYDATA
  704. cmp edi, esi
  705. jae @lightVertexLoop
  706. pop edi
  707. pop esi
  708. pop ebx
  709. mov esp, ebp
  710. pop ebp
  711. ret 12
  712. ENDM
  713. ;------------------------------------------------------------------------
  714. ; Parameters:
  715. ;
  716. ; ecx - GC
  717. ; NUMBER_OF_LIGHTS - 1 for one light, 2 for more than one light
  718. ;
  719. pdFirst equ 12[ebp]
  720. pdLast equ 16[ebp]
  721. pd equ pdFirst
  722. face equ -4[ebp]
  723. nonBack equ -4[ebp]
  724. nxi equ DWORD PTR -8[ebp]
  725. nyi equ DWORD PTR -12[ebp]
  726. nzi equ DWORD PTR -16[ebp]
  727. n1 equ DWORD PTR -20[ebp]
  728. n2 equ DWORD PTR -24[ebp]
  729. ifx equ -28[ebp]
  730. msm equ -32[ebp]
  731. baseEmissiveAmbientR equ DWORD PTR -36[ebp]
  732. baseEmissiveAmbientG equ DWORD PTR -40[ebp]
  733. baseEmissiveAmbientB equ DWORD PTR -44[ebp]
  734. rsi equ DWORD PTR -48[ebp]
  735. gsi equ DWORD PTR -52[ebp]
  736. bsi equ DWORD PTR -56[ebp]
  737. ;;
  738. ;; We will handle infinite lights with special cases for front and
  739. ;; back faces.
  740. ;;
  741. POLYARRAYZIPPYCALCRGBCOLOR MACRO GC_LIGHT_value, LIGHTSOURCE_value, face, NUMBER_OF_LIGHTS
  742. ;; GL_LIGHT_value = GL_LIGHT_front or GC_LIGHT_back
  743. ;; LIGHTSOURCE_value = LIGHTSOURCE_front or LIGHTSOURCE_back
  744. ;; face = __GL_FRONTFACE or __GL_BACKFACE
  745. push ebp
  746. mov ebp, esp
  747. sub esp, 56
  748. if NUMBER_OF_LIGHTS eq 2
  749. xor eax, eax
  750. endif
  751. push ebx
  752. push esi
  753. push edi
  754. ;; NOTE: esi, ebx held constant in this routine.
  755. ;; esi = pd
  756. ;; ebx = gc
  757. mov esi, pdFirst
  758. mov ebx, ecx
  759. ;; Start the vertex-processing loop
  760. ;;
  761. ;; for (pd = pdFirst; pd <= pdLast; pd++)
  762. @lightVertexLoop:
  763. ;; If normal has not changed for this vertex, use the previously computed color.
  764. ;; if (!(pd->flags & POLYDATA_NORMAL_VALID))
  765. mov edx, [esi+PD_flags]
  766. test edx, POLYDATA_NORMAL_VALID
  767. jne @normalIsValid
  768. mov eax, [(face*16) + esi + (PD_colors0 - sizeof_POLYDATA)+_R_]
  769. mov ecx, [(face*16) + esi + (PD_colors0 - sizeof_POLYDATA)+_G_]
  770. mov [(face*16) + esi + PD_colors0+_R_], eax
  771. mov [(face*16) + esi + PD_colors0+_G_], ecx
  772. mov eax, [(face*16) + esi + (PD_colors0 - sizeof_POLYDATA)+_B_]
  773. mov ecx, [(face*16) + esi + (PD_colors0 - sizeof_POLYDATA)+_A_]
  774. mov [(face*16) + esi + PD_colors0+_B_], eax
  775. mov [(face*16) + esi + PD_colors0+_A_], ecx
  776. ;; loop to next pd
  777. mov edi, pdLast
  778. add esi, sizeof_POLYDATA
  779. if NUMBER_OF_LIGHTS eq 2
  780. xor eax, eax
  781. endif
  782. cmp edi, esi
  783. jae @lightVertexLoop
  784. jmp @lightsDone
  785. @normalIsValid:
  786. if NUMBER_OF_LIGHTS eq 2
  787. mov nonBack, eax
  788. endif
  789. mov edi, [ebx+GC_LIGHT_sources]
  790. if face eq __GL_FRONTFACE
  791. else
  792. mov eax, [esi+PD_normal+_X_]
  793. mov ecx, [esi+PD_normal+_Y_]
  794. mov edx, [esi+PD_normal+_Z_]
  795. xor eax, 80000000h
  796. xor ecx, 80000000h
  797. xor edx, 80000000h
  798. mov nxi, eax
  799. mov nyi, ecx
  800. mov nzi, edx
  801. endif
  802. if NUMBER_OF_LIGHTS eq 2
  803. test edi, edi
  804. je @lightSourcesDone
  805. @lightSourcesLoop:
  806. endif
  807. ;; for (lsm = gc->light.sources; lsm; lsm = lsm->next)
  808. ;; edi = lsm (light source pointer)
  809. ;; n1 = nxi * lsm->unitVPpli.x + nyi * lsm->unitVPpli.y +
  810. ;; nzi * lsm->unitVPpli.z;
  811. if face eq __GL_FRONTFACE
  812. fld DWORD PTR [esi+PD_normal+_X_]
  813. fmul DWORD PTR [edi+LIGHTSOURCE_unitVPpli+_X_]
  814. fld DWORD PTR [esi+PD_normal+_Y_]
  815. fmul DWORD PTR [edi+LIGHTSOURCE_unitVPpli+_Y_]
  816. fld DWORD PTR [esi+PD_normal+_Z_]
  817. fmul DWORD PTR [edi+LIGHTSOURCE_unitVPpli+_Z_]
  818. else
  819. fld nxi
  820. fmul DWORD PTR [edi+LIGHTSOURCE_unitVPpli+_X_]
  821. fld nyi
  822. fmul DWORD PTR [edi+LIGHTSOURCE_unitVPpli+_Y_]
  823. fld nzi
  824. fmul DWORD PTR [edi+LIGHTSOURCE_unitVPpli+_Z_]
  825. endif
  826. fxch ST(2)
  827. faddp ST(1), ST
  828. faddp ST(1), ST
  829. fstp n1
  830. ;; if (__GL_FLOAT_GTZ(n1))
  831. if NUMBER_OF_LIGHTS eq 2
  832. mov ecx, nonBack
  833. endif
  834. cmp n1, 0
  835. jg @f
  836. if NUMBER_OF_LIGHTS eq 2
  837. mov edi, [edi+LIGHTSOURCE_next]
  838. test edi, edi
  839. je @lightSourcesDone
  840. jmp @lightSourcesLoop
  841. else
  842. COPY_CACHED_NON_LIT <esi>, <ebx>, GC_LIGHT_value, face, <eax>, <ecx>
  843. ;; loop to next pd
  844. mov edi, pdLast
  845. add esi, sizeof_POLYDATA
  846. cmp edi, esi
  847. jae @lightVertexLoop
  848. jmp @lightsDone
  849. endif
  850. @@:
  851. if NUMBER_OF_LIGHTS eq 2
  852. test ecx, ecx ; Has lighting been computed
  853. jne @f
  854. endif
  855. fld DWORD PTR [ebx+GC_LIGHT_value+MATERIAL_cachedEmissiveAmbient+_B_]
  856. if NUMBER_OF_LIGHTS eq 2
  857. inc ecx
  858. endif
  859. fld DWORD PTR [ebx+GC_LIGHT_value+MATERIAL_cachedEmissiveAmbient+_G_]
  860. if NUMBER_OF_LIGHTS eq 2
  861. mov nonBack, ecx
  862. endif
  863. fld DWORD PTR [ebx+GC_LIGHT_value+MATERIAL_cachedEmissiveAmbient+_R_]
  864. @@:
  865. ;; n2 = (nxi * lsm->hHat.x + nyi * lsm->hHat.y + nzi * lsm->hHat.z)
  866. ;; - msm_threshold;
  867. if face eq __GL_FRONTFACE
  868. fld DWORD PTR [esi+PD_normal+_X_]
  869. fmul DWORD PTR [edi+LIGHTSOURCE_hHat+_X_]
  870. fld DWORD PTR [esi+PD_normal+_Y_]
  871. fmul DWORD PTR [edi+LIGHTSOURCE_hHat+_Y_]
  872. fxch ST(1)
  873. fsub DWORD PTR [ebx+GC_LIGHT_value+MATERIAL_threshold]
  874. fld DWORD PTR [esi+PD_normal+_Z_]
  875. fmul DWORD PTR [edi+LIGHTSOURCE_hHat+_Z_]
  876. else
  877. fld nxi
  878. fmul DWORD PTR [edi+LIGHTSOURCE_hHat+_X_]
  879. fld nyi
  880. fmul DWORD PTR [edi+LIGHTSOURCE_hHat+_Y_]
  881. fxch ST(1)
  882. fsub DWORD PTR [ebx+GC_LIGHT_value+MATERIAL_threshold]
  883. fld nzi
  884. fmul DWORD PTR [edi+LIGHTSOURCE_hHat+_Z_]
  885. endif
  886. fxch ST(2)
  887. faddp ST(1), ST
  888. faddp ST(1), ST
  889. fstp n2
  890. ;; if (__GL_FLOAT_GEZ(n2))
  891. mov eax, n2
  892. or eax, eax
  893. js @noSpecularEffect
  894. ;; ifx = (GLint)(n2 * msm_scale + __glHalf);
  895. fld n2
  896. fmul DWORD PTR [ebx+GC_LIGHT_value+MATERIAL_scale]
  897. mov edx, __FLOAT_ONE
  898. ;; Note: we don't have to do this add since we can assume that rounding
  899. ;; enabled:
  900. ;; fadd ___glHalf
  901. mov ecx, [ebx+GC_LIGHT_value+MATERIAL_specTable]
  902. fistp DWORD PTR ifx
  903. ;; if (ifx < __GL_SPEC_LOOKUP_TABLE_SIZE )
  904. mov eax, ifx
  905. cmp eax, __GL_SPEC_LOOKUP_TABLE_SIZE
  906. jge @specularSaturate
  907. ;; n2 = msm_specTable[ifx];
  908. mov edx, DWORD PTR [ecx+eax*4]
  909. @specularSaturate:
  910. mov n2, edx
  911. fld n2
  912. fmul DWORD PTR [edi+LIGHTSOURCE_value+LIGHTSOURCEPERMATERIAL_specular+_R_]
  913. fld n2
  914. fmul DWORD PTR [edi+LIGHTSOURCE_value+LIGHTSOURCEPERMATERIAL_specular+_G_]
  915. fld n2
  916. fmul DWORD PTR [edi+LIGHTSOURCE_value+LIGHTSOURCEPERMATERIAL_specular+_B_]
  917. fxch ST(2) ; r g b R G B
  918. faddp ST(3), ST ; g b R G B
  919. faddp ST(3), ST ; b R G B
  920. faddp ST(3), ST ; R G B
  921. @noSpecularEffect:
  922. ;; now handle diffuse affect:
  923. fld n1
  924. fmul DWORD PTR [edi+LIGHTSOURCE_value+LIGHTSOURCEPERMATERIAL_diffuse+_R_]
  925. fld n1
  926. fmul DWORD PTR [edi+LIGHTSOURCE_value+LIGHTSOURCEPERMATERIAL_diffuse+_G_]
  927. fld n1
  928. fmul DWORD PTR [edi+LIGHTSOURCE_value+LIGHTSOURCEPERMATERIAL_diffuse+_B_]
  929. fxch ST(2) ; r g b R G B
  930. faddp ST(3), ST ; g b R G B
  931. if NUMBER_OF_LIGHTS eq 2
  932. mov edi, [edi+LIGHTSOURCE_next]
  933. endif
  934. faddp ST(3), ST ; b R G B
  935. if NUMBER_OF_LIGHTS eq 2
  936. test edi, edi
  937. endif
  938. faddp ST(3), ST ; R G B
  939. if NUMBER_OF_LIGHTS eq 2
  940. jne @lightSourcesLoop
  941. @lightSourcesDone:
  942. mov eax, nonBack
  943. test eax,eax
  944. jne @f
  945. COPY_CACHED_NON_LIT <esi>, <ebx>, GC_LIGHT_value, face, <eax>, <ecx>
  946. ;; loop to next pd
  947. mov edi, pdLast
  948. add esi, sizeof_POLYDATA
  949. xor eax, eax
  950. cmp edi, esi
  951. jae @lightVertexLoop
  952. jmp @lightsDone
  953. @@:
  954. endif ; NUMBER_OF_LIGHTS eq 2
  955. ;; OK, we had some lighting for this vertex. Now, handle clamping:
  956. fstp rsi
  957. mov eax, [ebx+GC_redVertexScale]
  958. fstp gsi
  959. mov edx, rsi
  960. fstp bsi
  961. mov ecx, [ebx+GC_greenVertexScale]
  962. mov edi, gsi
  963. sub eax, edx
  964. sub ecx, edi
  965. or eax, edx
  966. or ecx, edi
  967. mov edx, [ebx+GC_blueVertexScale]
  968. or eax, ecx
  969. mov edi, bsi
  970. or eax, edi
  971. sub edx, edi
  972. or eax, edx
  973. jns @noClamp
  974. mov eax, rsi
  975. mov ecx, [ebx+GC_redVertexScale]
  976. sub ecx, eax
  977. mov [ebx+GC_redClampTable], eax
  978. shr eax, 31
  979. add ecx, ecx
  980. mov edx, gsi
  981. adc eax, eax
  982. mov ecx, [ebx+GC_greenVertexScale]
  983. sub ecx, edx
  984. mov eax, [4*eax+ebx+GC_redClampTable]
  985. mov [ebx+GC_greenClampTable], edx
  986. shr edx, 31
  987. add ecx, ecx
  988. mov rsi, eax
  989. adc edx, edx
  990. mov eax, bsi
  991. mov ecx, [ebx+GC_blueVertexScale]
  992. sub ecx, eax
  993. mov edx, [4*edx+ebx+GC_greenClampTable]
  994. mov [ebx+GC_blueClampTable], eax
  995. shr eax, 31
  996. add ecx, ecx
  997. mov gsi, edx
  998. adc eax, eax
  999. mov eax, [4*eax+ebx+GC_blueClampTable]
  1000. mov bsi, eax
  1001. @noClamp:
  1002. ;; store colors
  1003. mov eax, [ebx+GC_LIGHT_value+MATERIAL_alpha]
  1004. mov ecx, rsi
  1005. mov edx, gsi
  1006. mov edi, bsi
  1007. mov [esi+PD_colors0+(face*16)+_A_], eax
  1008. mov [esi+PD_colors0+(face*16)+_R_], ecx
  1009. mov [esi+PD_colors0+(face*16)+_G_], edx
  1010. mov [esi+PD_colors0+(face*16)+_B_], edi
  1011. ;; loop to next pd
  1012. mov edi, pdLast
  1013. add esi, sizeof_POLYDATA
  1014. xor eax, eax
  1015. cmp edi, esi
  1016. jae @lightVertexLoop
  1017. @lightsDone:
  1018. pop edi
  1019. pop esi
  1020. pop ebx
  1021. mov esp, ebp
  1022. pop ebp
  1023. ret 12
  1024. ENDM
  1025. ;--------------------------------------------------------------------------------
  1026. @PolyArrayZippyCalcRGBColorFront@20 PROC NEAR
  1027. POLYARRAYZIPPYCALCRGBCOLOR GC_LIGHT_front, LIGHTSOURCE_front, __GL_FRONTFACE, 2
  1028. @PolyArrayZippyCalcRGBColorFront@20 ENDP
  1029. @PolyArrayZippyCalcRGBColorBack@20 PROC NEAR
  1030. POLYARRAYZIPPYCALCRGBCOLOR GC_LIGHT_back, LIGHTSOURCE_back, __GL_BACKFACE, 2
  1031. @PolyArrayZippyCalcRGBColorBack@20 ENDP
  1032. ;
  1033. ; Functions for the one light source
  1034. ;
  1035. @PolyArrayZippyCalcRGBColorFront1@20 PROC NEAR
  1036. POLYARRAYZIPPYCALCRGBCOLOR GC_LIGHT_front, LIGHTSOURCE_front, __GL_FRONTFACE, 1
  1037. @PolyArrayZippyCalcRGBColorFront1@20 ENDP
  1038. @PolyArrayZippyCalcRGBColorBack1@20 PROC NEAR
  1039. POLYARRAYZIPPYCALCRGBCOLOR GC_LIGHT_back, LIGHTSOURCE_back, __GL_BACKFACE, 1
  1040. @PolyArrayZippyCalcRGBColorBack1@20 ENDP
  1041. ;
  1042. ; Functions for the no light sources
  1043. ;
  1044. @PolyArrayZippyCalcRGBColorFront0@20 PROC NEAR
  1045. POLYARRAYZIPPYCALCRGBCOLOR0 GC_LIGHT_front, __GL_FRONTFACE
  1046. @PolyArrayZippyCalcRGBColorFront0@20 ENDP
  1047. @PolyArrayZippyCalcRGBColorBack0@20 PROC NEAR
  1048. POLYARRAYZIPPYCALCRGBCOLOR0 GC_LIGHT_back, __GL_BACKFACE
  1049. @PolyArrayZippyCalcRGBColorBack0@20 ENDP
  1050. ;--------------------------------------------------------------------------------
  1051. ; void FASTCALL PolyArrayZippyCalcRGBColor(__GLcontext* gc, int face, POLYARRAY* pa,
  1052. ; POLYDATA* pdFirst, POLYDATA* pdLast)
  1053. ;
  1054. ; Input:
  1055. ; ecx = gc
  1056. ; edx = face (0 - front, 1 - back)
  1057. ; [esp+4] = pa
  1058. ; [esp+8] = pdFirst
  1059. ; [esp+12] = pdLast
  1060. ;
  1061. @PolyArrayZippyCalcRGBColor@20 PROC NEAR
  1062. push edi
  1063. mov edi, [ecx+GC_LIGHT_sources]
  1064. or edi, edi
  1065. jz @noLights
  1066. cmp [edi+LIGHTSOURCE_next], 0
  1067. jne @multipleLights
  1068. ;
  1069. ; one lignt case
  1070. ;
  1071. pop edi
  1072. test edx, edx
  1073. je @PolyArrayZippyCalcRGBColorFront1@20
  1074. jmp @PolyArrayZippyCalcRGBColorBack1@20
  1075. @noLights:
  1076. pop edi
  1077. test edx, edx
  1078. je @PolyArrayZippyCalcRGBColorFront0@20
  1079. jmp @PolyArrayZippyCalcRGBColorBack0@20
  1080. @multipleLights:
  1081. pop edi
  1082. test edx, edx
  1083. je @PolyArrayZippyCalcRGBColorFront@20
  1084. jmp @PolyArrayZippyCalcRGBColorBack@20
  1085. @PolyArrayZippyCalcRGBColor@20 ENDP
  1086. ;--------------------------------------------------------------------------------
  1087. ; void FASTCALL PolyArrayZippyCalcRGBColor(__GLcontext* gc, int face, POLYARRAY* pa,
  1088. ; POLYDATA* pdFirst, POLYDATA* pdLast)
  1089. ;
  1090. ; Input:
  1091. ; ecx = gc
  1092. ; edx = face (0 - front, 1 - back)
  1093. ; [esp+4] = pa
  1094. ; [esp+8] = pdFirst
  1095. ; [esp+12] = pdLast
  1096. ;
  1097. emissiveAmbientR equ DWORD PTR -60[ebp]
  1098. emissiveAmbientG equ DWORD PTR -64[ebp]
  1099. emissiveAmbientB equ DWORD PTR -68[ebp]
  1100. colorMaterialChange equ -72[ebp]
  1101. alpha equ DWORD PTR -76[ebp]
  1102. ri equ DWORD PTR -80[ebp]
  1103. gi equ DWORD PTR -84[ebp]
  1104. bi equ DWORD PTR -88[ebp]
  1105. diffuseSpecularR equ DWORD PTR -92[ebp]
  1106. diffuseSpecularG equ DWORD PTR -96[ebp]
  1107. diffuseSpecularB equ DWORD PTR -100[ebp]
  1108. @PolyArrayFastCalcRGBColor@20 PROC NEAR
  1109. mov eax, [ecx+GC_LIGHT_front+MATERIAL_colorMaterialChange]
  1110. test edx, edx
  1111. je @f
  1112. mov eax, [ecx+GC_LIGHT_back+MATERIAL_colorMaterialChange]
  1113. @@:
  1114. test eax, eax
  1115. je @PolyArrayZippyCalcRGBColor@20
  1116. push ebp
  1117. mov ebp, esp
  1118. sub esp, 100
  1119. test edx, edx
  1120. push ebx
  1121. mov ebx, ecx
  1122. push esi
  1123. ;; if (face == __GL_FRONTFACE)
  1124. ;; msm = &gc->light.front;
  1125. ;; else
  1126. ;; msm = &gc->light.back;
  1127. lea ecx, DWORD PTR [ebx+GC_LIGHT_front]
  1128. je short @f
  1129. lea ecx, DWORD PTR [ebx+GC_LIGHT_back]
  1130. @@:
  1131. push edi
  1132. mov DWORD PTR face, edx
  1133. mov msm, ecx
  1134. mov eax, [ecx+MATERIAL_colorMaterialChange]
  1135. mov colorMaterialChange, eax
  1136. test eax, __GL_MATERIAL_AMBIENT
  1137. jne @baseEmissiveSimple
  1138. mov eax, [ecx+MATERIAL_cachedEmissiveAmbient+_R_]
  1139. mov edx, [ecx+MATERIAL_cachedEmissiveAmbient+_G_]
  1140. mov baseEmissiveAmbientR, eax
  1141. mov emissiveAmbientR, eax
  1142. mov baseEmissiveAmbientG, edx
  1143. mov emissiveAmbientG, edx
  1144. mov eax, [ecx+MATERIAL_cachedEmissiveAmbient+_B_]
  1145. mov esi, pdFirst
  1146. mov edi, pdLast
  1147. mov baseEmissiveAmbientB, eax
  1148. cmp edi, esi
  1149. mov emissiveAmbientB, eax
  1150. jb @lightsDone
  1151. jmp @baseEmissiveDone
  1152. @baseEmissiveSimple:
  1153. mov eax, [ecx+MATERIAL_paSceneColor+_R_]
  1154. mov edx, [ecx+MATERIAL_paSceneColor+_G_]
  1155. mov baseEmissiveAmbientR, eax
  1156. mov emissiveAmbientR, eax
  1157. mov baseEmissiveAmbientG, edx
  1158. mov emissiveAmbientG, edx
  1159. mov eax, [ecx+MATERIAL_paSceneColor+_B_]
  1160. mov esi, pdFirst
  1161. mov edi, pdLast
  1162. mov baseEmissiveAmbientB, eax
  1163. cmp edi, esi
  1164. mov emissiveAmbientB, eax
  1165. jb @lightsDone
  1166. @baseEmissiveDone:
  1167. ; If there is no emissive or ambient color material change, this
  1168. ; will be the emissive and ambient components.
  1169. ;
  1170. ; emissiveAmbientI.r = baseEmissiveAmbient.r;
  1171. ; emissiveAmbientI.g = baseEmissiveAmbient.g;
  1172. ; emissiveAmbientI.b = baseEmissiveAmbient.b;
  1173. ;;
  1174. ;;
  1175. ;; Vertex loop follows:
  1176. ;;
  1177. ;;
  1178. ;; for (pd = pdFirst; pd <= pdLast; pd++)
  1179. @lightVertexLoop:
  1180. ;; If normal has not changed for this vertex, use the previously
  1181. ;; computed color.
  1182. ;; [if !(pd->flags & (POLYDATA_NORMAL_VALID | POLYDATA_COLOR_VALID))]
  1183. mov edx, [esi+PD_flags]
  1184. test edx, POLYDATA_NORMAL_VALID OR POLYDATA_COLOR_VALID
  1185. jne @normalOrColorIsValid
  1186. mov eax, face
  1187. shl eax, 4
  1188. lea edi, [eax + esi + PD_colors0]
  1189. lea esi, [eax + esi + (PD_colors0 - sizeof_POLYDATA)]
  1190. movsd
  1191. movsd
  1192. movsd
  1193. movsd
  1194. mov esi, pd
  1195. mov edi, pdLast
  1196. add esi, sizeof_POLYDATA
  1197. cmp edi, esi
  1198. mov pd, esi
  1199. jae @lightVertexLoop
  1200. jmp @lightsDone
  1201. @normalOrColorIsValid:
  1202. ;; if (pd->flags & POLYDATA_COLOR_VALID)
  1203. ;; ri = pd->colors[0].r * gc->oneOverRedVertexScale;
  1204. ;; gi = pd->colors[0].g * gc->oneOverGreenVertexScale;
  1205. ;; bi = pd->colors[0].b * gc->oneOverBlueVertexScale;
  1206. ;; alpha = pd->colors[0].a;
  1207. test edx, POLYDATA_COLOR_VALID
  1208. je @usePreviousColors
  1209. mov eax, [esi+PD_colors0+_A_]
  1210. mov alpha, eax
  1211. mov eax, colorMaterialChange
  1212. fld DWORD PTR [esi+PD_colors0+_R_]
  1213. fmul DWORD PTR [ebx+GC_oneOverRedVertexScale]
  1214. fld DWORD PTr [esi+PD_colors0+_G_]
  1215. fmul DWORD PTR [ebx+GC_oneOverGreenVertexScale]
  1216. fld DWORD PTR [esi+PD_colors0+_B_]
  1217. fmul DWORD PTR [ebx+GC_oneOverBlueVertexScale] ;; b g r
  1218. fxch ST(2) ;; r g b
  1219. fstp ri
  1220. fstp gi
  1221. fstp bi ;; FPU stack empty
  1222. test eax, __GL_MATERIAL_AMBIENT
  1223. je @noMaterialAmbient
  1224. ;;
  1225. ;; Handle ambient color changes:
  1226. ;;
  1227. ;; if (msm_colorMaterialChange & __GL_MATERIAL_AMBIENT) {
  1228. ;; emissiveAmbient.r = baseEmissiveAmbient.r + ri * lm_ambient.r;
  1229. ;; emissiveAmbient.g = baseEmissiveAmbient.g + gi * lm_ambient.g;
  1230. ;; emissiveAmbient.b = baseEmissiveAmbient.b + bi * lm_ambient.b;
  1231. ;; }
  1232. fld ri
  1233. fmul DWORD PTR [ebx+GC_STATE_lightModelAmbient+_R_]
  1234. fld gi
  1235. mov edi, [ebx+GC_LIGHT_sources]
  1236. fmul DWORD PTR [ebx+GC_STATE_lightModelAmbient+_G_]
  1237. fld bi
  1238. test edi, edi
  1239. fmul DWORD PTR [ebx+GC_STATE_lightModelAmbient+_B_] ; b g r
  1240. fxch ST(1) ; g b r
  1241. fadd baseEmissiveAmbientG ; G b r
  1242. fxch ST(1) ; b G r
  1243. fadd baseEmissiveAmbientB ; B G r
  1244. fxch ST(2) ; r G B
  1245. fadd baseEmissiveAmbientR ; R G B
  1246. jne @ambientLoop
  1247. fstp emissiveAmbientR ;; If we don't have to process
  1248. fstp emissiveAmbientG ;; the lights, pop the FPU stack
  1249. fstp emissiveAmbientB ;; and continue
  1250. jmp @emissiveAmbientDone
  1251. @ambientLoop:
  1252. ;; Add per-light per-material ambient values.
  1253. ;; We will start with the current basEmissiveAmbient values
  1254. ;; already on the stack.
  1255. ;; for (lsm = gc->light.sources; lsm; lsm = lsm->next) {
  1256. ;; emissiveAmbientI.r += ri * lsm->state.ambient.r;
  1257. ;; emissiveAmbientI.g += gi * lsm->stats.ambient.g;
  1258. ;; emissiveAmbientI.b += bi * lsm->state.ambient.b;
  1259. ;; }
  1260. mov edx, [edi+LIGHTSOURCE_state] ; lss
  1261. fld ri
  1262. fmul DWORD PTR [edx+LIGHTSOURCESTATE_ambient+_R_]
  1263. fld gi
  1264. fmul DWORD PTR [edx+LIGHTSOURCESTATE_ambient+_G_]
  1265. fld bi
  1266. fmul DWORD PTR [edx+LIGHTSOURCESTATE_ambient+_B_] ;; b g r R G B
  1267. fxch ST(2) ;; r g b R G B
  1268. faddp ST(3), ST(0)
  1269. mov edi, [edi+LIGHTSOURCE_next]
  1270. faddp ST(3), ST(0)
  1271. test edi, edi
  1272. faddp ST(3), ST(0)
  1273. jne @ambientLoop
  1274. ;; There are no lights, so pop the emissive result at this point
  1275. ;; and continue:
  1276. fstp emissiveAmbientR
  1277. fstp emissiveAmbientG
  1278. fstp emissiveAmbientB
  1279. jmp @emissiveAmbientDone
  1280. @noMaterialAmbient:
  1281. ;;
  1282. ;; Handle emissive material changes if needed:
  1283. ;;
  1284. test eax, __GL_MATERIAL_EMISSIVE
  1285. je @emissiveAmbientDone
  1286. ;; emissiveAmbientR = baseEmissiveAmbientR + pd->colors[0].r;
  1287. ;; emissiveAmbientG = baseEmissiveAmbientG + pd->colors[0].g;
  1288. ;; emissiveAmbientB = baseEmissiveAmbientB + pd->colors[0].b;
  1289. fld baseEmissiveAmbientR
  1290. fadd DWORD PTR [esi+PD_colors0+_R_]
  1291. fld baseEmissiveAmbientG
  1292. fadd DWORD PTR [esi+PD_colors0+_G_]
  1293. fld baseEmissiveAmbientB
  1294. fadd DWORD PTR [esi+PD_colors0+_B_] ; b g r
  1295. fxch ST(2) ; r g b
  1296. fstp emissiveAmbientR
  1297. fstp emissiveAmbientG
  1298. fstp emissiveAmbientB
  1299. @emissiveAmbientDone:
  1300. @usePreviousColors:
  1301. ;;
  1302. ;; OK, we're done handling emissive and diffuse color changes, or
  1303. ;; we're simply using the previous values. Now, handle portion of
  1304. ;; lighting which depends on the vertex normals (diffuse + specular):
  1305. ;;
  1306. ;; if (pd->flags & POLYDATA_NORMAL_VALID)
  1307. mov edx, [esi+PD_flags]
  1308. test edx, POLYDATA_NORMAL_VALID
  1309. je @normalNotValid
  1310. mov eax, face
  1311. ;; if (face == __GL_FRONTFACE)
  1312. mov ecx, [esi+PD_normal+_X_]
  1313. mov edx, [esi+PD_normal+_Y_]
  1314. mov esi, [esi+PD_normal+_Z_]
  1315. test eax, eax
  1316. je @notBackFace
  1317. ;; negate the floating-point normal values
  1318. xor ecx, 80000000h
  1319. xor edx, 80000000h
  1320. xor esi, 80000000h
  1321. @notBackFace:
  1322. mov nxi, ecx
  1323. mov nyi, edx
  1324. mov nzi, esi
  1325. jmp @calcColor
  1326. @normalNotValid:
  1327. ;; if (!(msm_colorMaterialChange & (__GL_MATERIAL_SPECULAR | __GL_MATERIAL_DIFFUSE)))
  1328. ;; goto store_color;
  1329. test eax, __GL_MATERIAL_SPECULAR OR __GL_MATERIAL_DIFFUSE
  1330. je @storeColor
  1331. @calcColor:
  1332. fld ___glZero
  1333. mov esi, [ebx+GC_LIGHT_sources]
  1334. fld ___glZero
  1335. test esi, esi
  1336. fld ___glZero
  1337. je @lightSourcesDone
  1338. @lightSourcesLoop:
  1339. ;; for (lsm = gc->light.sources; lsm; lsm = lsm->next)
  1340. mov eax, face
  1341. ;; lspmm = &lsm->front + face;
  1342. lea ecx, [esi+LIGHTSOURCE_front]
  1343. test eax, eax
  1344. je @f
  1345. lea ecx, [esi+LIGHTSOURCE_back]
  1346. @@:
  1347. ;; esi = lsm
  1348. ;; ecx = lspmm
  1349. ;; n1 = nxi * lsm->unitVPpli.x + nyi * lsm->unitVPpli.y +
  1350. ;; nzi * lsm->unitVPpli.z;
  1351. fld nxi
  1352. mov edi, msm
  1353. fmul DWORD PTR [esi+LIGHTSOURCE_unitVPpli+_X_]
  1354. fld nyi
  1355. fmul DWORD PTR [esi+LIGHTSOURCE_unitVPpli+_Y_]
  1356. fld nzi
  1357. fmul DWORD PTR [esi+LIGHTSOURCE_unitVPpli+_Z_]
  1358. fxch ST(2)
  1359. faddp ST(1), ST
  1360. faddp ST(1), ST
  1361. fstp n1
  1362. ;; if (__GL_FLOAT_GTZ(n1))
  1363. mov eax, n1
  1364. cmp eax, 0
  1365. jg @f
  1366. mov esi, [esi+LIGHTSOURCE_next]
  1367. test esi, esi
  1368. jne @lightSourcesLoop
  1369. jmp @lightSourcesDone
  1370. @@:
  1371. ;; n2 = (nxi * lsm->hHat.x + nyi * lsm->hHat.y + nzi * lsm->hHat.z)
  1372. ;; - msm_threshold;
  1373. fld nxi
  1374. fmul DWORD PTR [esi+LIGHTSOURCE_hHat+_X_]
  1375. fld nyi
  1376. fmul DWORD PTR [esi+LIGHTSOURCE_hHat+_Y_]
  1377. fxch ST(1)
  1378. fsub DWORD PTR [edi+MATERIAL_threshold]
  1379. fld nzi
  1380. fmul DWORD PTR [esi+LIGHTSOURCE_hHat+_Z_]
  1381. fxch ST(2)
  1382. faddp ST(1), ST
  1383. faddp ST(1), ST
  1384. fstp n2
  1385. ;; if (__GL_FLOAT_GEZ(n2))
  1386. mov eax, n2
  1387. or eax, eax
  1388. js @noSpecularEffect
  1389. ;; ifx = (GLint)(n2 * msm_scale + __glHalf);
  1390. fld n2
  1391. fmul DWORD PTR [edi+MATERIAL_scale]
  1392. mov edx, __FLOAT_ONE
  1393. ;; Note: we don't have to do this add since we can assume that rounding
  1394. ;; enabled:
  1395. ;; fadd ___glHalf
  1396. mov edi, [edi+MATERIAL_specTable]
  1397. fistp DWORD PTR ifx
  1398. ;; if (ifx < __GL_SPEC_LOOKUP_TABLE_SIZE )
  1399. mov eax, ifx
  1400. cmp eax, __GL_SPEC_LOOKUP_TABLE_SIZE
  1401. jge @specularSaturate
  1402. ;; n2 = msm_specTable[ifx];
  1403. mov edx, DWORD PTR [edi+eax*4]
  1404. @specularSaturate:
  1405. mov eax, colorMaterialChange
  1406. mov n2, edx
  1407. test eax, __GL_MATERIAL_SPECULAR
  1408. je @noSpecularMaterialChange
  1409. fld n2
  1410. mov edx, [esi+LIGHTSOURCE_state]
  1411. fmul ri
  1412. fld n2
  1413. fmul gi
  1414. fld n2
  1415. fmul bi ; b g r
  1416. fxch ST(2) ; r g b
  1417. fmul DWORD PTR [edx+LIGHTSOURCESTATE_specular+_R_]
  1418. fxch ST(1) ; g r b
  1419. fmul DWORD PTR [edx+LIGHTSOURCESTATE_specular+_G_]
  1420. fxch ST(2) ; b r g
  1421. fmul DWORD PTR [edx+LIGHTSOURCESTATE_specular+_B_]
  1422. fxch ST(1) ; r b g R G B
  1423. faddp ST(3), ST(0) ; b g R G B
  1424. fxch ST(1) ; g b R G B
  1425. faddp ST(3), ST(0) ; b R G B
  1426. faddp ST(3), ST(0) ; R G B
  1427. jmp short @noSpecularEffect
  1428. @noSpecularMaterialChange:
  1429. fld n2
  1430. fmul DWORD PTR [ecx+LIGHTSOURCEPERMATERIAL_specular+_R_]
  1431. fld n2
  1432. fmul DWORD PTR [ecx+LIGHTSOURCEPERMATERIAL_specular+_G_]
  1433. fld n2
  1434. fmul DWORD PTR [ecx+LIGHTSOURCEPERMATERIAL_specular+_B_]
  1435. fxch ST(2) ; r g b R G B
  1436. faddp ST(3), ST ; g b R G B
  1437. faddp ST(3), ST ; b R G B
  1438. faddp ST(3), ST ; R G B
  1439. @noSpecularEffect:
  1440. ;; now handle diffuse affect:
  1441. mov eax, colorMaterialChange
  1442. test eax, __GL_MATERIAL_DIFFUSE
  1443. je @noDiffuseMaterialChange
  1444. fld n1
  1445. mov edx, [esi+LIGHTSOURCE_state]
  1446. fmul ri
  1447. fld n1
  1448. fmul gi
  1449. fld n1
  1450. fmul bi ; b g r
  1451. fxch ST(2) ; r g b
  1452. fmul DWORD PTR [edx+LIGHTSOURCESTATE_diffuse+_R_]
  1453. fxch ST(1) ; g r b
  1454. fmul DWORD PTR [edx+LIGHTSOURCESTATE_diffuse+_G_]
  1455. fxch ST(2) ; b r g
  1456. fmul DWORD PTR [edx+LIGHTSOURCESTATE_diffuse+_B_]
  1457. fxch ST(1) ; r b g R G B
  1458. faddp ST(3), ST(0) ; b g R G B
  1459. fxch ST(1) ; g b R G B
  1460. faddp ST(3), ST(0) ; b R G B
  1461. faddp ST(3), ST(0) ; R G B
  1462. jmp short @lightSourcesDone
  1463. @noDiffuseMaterialChange:
  1464. fld n1
  1465. fmul DWORD PTR [ecx+LIGHTSOURCEPERMATERIAL_diffuse+_R_]
  1466. fld n1
  1467. fmul DWORD PTR [ecx+LIGHTSOURCEPERMATERIAL_diffuse+_G_]
  1468. fld n1
  1469. fmul DWORD PTR [ecx+LIGHTSOURCEPERMATERIAL_diffuse+_B_]
  1470. fxch ST(2) ; r g b R G B
  1471. faddp ST(3), ST ; g b R G B
  1472. mov esi, [esi+LIGHTSOURCE_next]
  1473. faddp ST(3), ST ; b R G B
  1474. test esi, esi
  1475. faddp ST(3), ST ; R G B
  1476. jne @lightSourcesLoop
  1477. @lightSourcesDone:
  1478. fst diffuseSpecularR
  1479. fadd emissiveAmbientR ; R g b
  1480. fxch ST(1) ; g R b
  1481. fst diffuseSpecularG
  1482. fadd emissiveAmbientG ; G R b
  1483. fxch ST(2) ; b R G
  1484. fst diffuseSpecularB
  1485. fadd emissiveAmbientB ; B R G
  1486. fxch ST(1) ; R B G
  1487. fstp rsi
  1488. mov eax, [ebx+GC_redVertexScale]
  1489. fstp bsi
  1490. mov ecx, [ebx+GC_greenVertexScale]
  1491. fstp gsi
  1492. mov edx, rsi
  1493. jmp short @handleClamp
  1494. @storeColor:
  1495. ;; Now add emissiveAmbient (on FP stack) and diffuseSpecular.
  1496. ;; Interleave with start of clamping:
  1497. fld emissiveAmbientR
  1498. mov eax, [ebx+GC_redVertexScale]
  1499. fadd diffuseSpecularR
  1500. mov ecx, [ebx+GC_greenVertexScale]
  1501. fld emissiveAmbientG
  1502. fadd diffuseSpecularG
  1503. fld emissiveAmbientB
  1504. fadd diffuseSpecularB
  1505. fxch ST(2) ; r g b
  1506. fstp rsi
  1507. fstp gsi
  1508. mov edx, rsi
  1509. fstp bsi
  1510. @handleClamp:
  1511. ;; handle clamping:
  1512. mov edi, gsi
  1513. sub eax, edx
  1514. sub ecx, edi
  1515. or eax, edx
  1516. or ecx, edi
  1517. mov edx, [ebx+GC_blueVertexScale]
  1518. or eax, ecx
  1519. mov edi, bsi
  1520. or eax, edi
  1521. sub edx, edi
  1522. or eax, edx
  1523. jns @noClamp
  1524. mov eax, rsi
  1525. mov ecx, [ebx+GC_redVertexScale]
  1526. sub ecx, eax
  1527. mov [ebx+GC_redClampTable], eax
  1528. shr eax, 31
  1529. add ecx, ecx
  1530. mov edx, gsi
  1531. adc eax, eax
  1532. mov ecx, [ebx+GC_greenVertexScale]
  1533. sub ecx, edx
  1534. mov eax, [4*eax+ebx+GC_redClampTable]
  1535. mov [ebx+GC_greenClampTable], edx
  1536. shr edx, 31
  1537. add ecx, ecx
  1538. mov rsi, eax
  1539. adc edx, edx
  1540. mov eax, bsi
  1541. mov ecx, [ebx+GC_blueVertexScale]
  1542. sub ecx, eax
  1543. mov edx, [4*edx+ebx+GC_greenClampTable]
  1544. mov [ebx+GC_blueClampTable], eax
  1545. shr eax, 31
  1546. add ecx, ecx
  1547. mov gsi, edx
  1548. adc eax, eax
  1549. mov eax, [4*eax+ebx+GC_blueClampTable]
  1550. mov bsi, eax
  1551. @noClamp:
  1552. ;; ecx = pd->colors[face]
  1553. mov edx, msm
  1554. mov eax, face
  1555. mov esi, pd
  1556. shl eax, 4
  1557. lea ecx, [esi+PD_colors0]
  1558. mov edi, colorMaterialChange
  1559. add ecx, eax
  1560. test edi, __GL_MATERIAL_DIFFUSE
  1561. je @noAlphaChange
  1562. mov edx, alpha
  1563. mov eax, [ebx+GC_alphaVertexScale]
  1564. test edx, edx
  1565. jns @f
  1566. xor edx, edx
  1567. @@:
  1568. sub eax, edx
  1569. jge @alphaDone
  1570. mov edx, [ebx+GC_alphaVertexScale]
  1571. jmp short @alphaDone
  1572. @noAlphaChange:
  1573. mov edx, [edx+MATERIAL_alpha]
  1574. @alphaDone:
  1575. mov edi, pdLast
  1576. add esi, sizeof_POLYDATA
  1577. ;; store colors
  1578. mov [ecx+_A_], edx
  1579. mov eax, rsi
  1580. mov edx, gsi
  1581. mov [ecx+_R_], eax
  1582. mov pd, esi
  1583. mov eax, bsi
  1584. mov [ecx+_G_], edx
  1585. mov [ecx+_B_], eax
  1586. ;; loop to next pd
  1587. cmp edi, esi
  1588. jae @lightVertexLoop
  1589. @lightsDone:
  1590. pop edi
  1591. pop esi
  1592. pop ebx
  1593. mov esp, ebp
  1594. pop ebp
  1595. ret 12
  1596. @PolyArrayFastCalcRGBColor@20 ENDP
  1597. END