Source code of Windows XP (NT5)
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.

889 lines
26 KiB

  1. /*
  2. ** Copyright 1991, Silicon Graphics, Inc.
  3. ** All Rights Reserved.
  4. **
  5. ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6. ** the contents of this file may not be disclosed to third parties, copied or
  7. ** duplicated in any form, in whole or in part, without the prior written
  8. ** permission of Silicon Graphics, Inc.
  9. **
  10. ** RESTRICTED RIGHTS LEGEND:
  11. ** Use, duplication or disclosure by the Government is subject to restrictions
  12. ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13. ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14. ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15. ** rights reserved under the Copyright Laws of the United States.
  16. **
  17. */
  18. #include "precomp.h"
  19. #pragma hdrstop
  20. #include "phong.h"
  21. #define __TWO_31 ((__GLfloat) 2147483648.0)
  22. /*
  23. ** Most line functions will start off by computing the information
  24. ** computed by this routine.
  25. **
  26. ** The excessive number of labels in this routine is partly due
  27. ** to the fact that it is used as a model for writing an assembly
  28. ** equivalent.
  29. */
  30. #ifndef NT
  31. void FASTCALL __glInitLineData(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  32. {
  33. GLint start, end;
  34. __GLfloat x0,y0,x1,y1;
  35. __GLfloat minorStart;
  36. GLint intMinorStart;
  37. __GLfloat dx, dy;
  38. __GLfloat offset;
  39. __GLfloat slope;
  40. __GLlineState *ls = &gc->state.line;
  41. __GLfloat halfWidth;
  42. __GLfloat x0frac, x1frac, y0frac, y1frac, half, totDist;
  43. gc->line.options.v0 = v0;
  44. gc->line.options.v1 = v1;
  45. gc->line.options.width = gc->state.line.aliasedWidth;
  46. x0=v0->window.x;
  47. y0=v0->window.y;
  48. x1=v1->window.x;
  49. y1=v1->window.y;
  50. dx=x1-x0;
  51. dy=y1-y0;
  52. halfWidth = (ls->aliasedWidth - 1) * __glHalf;
  53. /* Ugh. This is slow. Bummer. */
  54. x0frac = x0 - ((GLint) x0);
  55. x1frac = x1 - ((GLint) x1);
  56. y0frac = y0 - ((GLint) y0);
  57. y1frac = y1 - ((GLint) y1);
  58. half = __glHalf;
  59. if (dx > __glZero) {
  60. if (dy > __glZero) {
  61. if (dx > dy) { /* dx > dy > 0 */
  62. gc->line.options.yBig = 1;
  63. posxmajor: /* dx > |dy| >= 0 */
  64. gc->line.options.yLittle = 0;
  65. gc->line.options.xBig = 1;
  66. gc->line.options.xLittle = 1;
  67. slope = dy/dx;
  68. start = (GLint) (x0);
  69. end = (GLint) (x1);
  70. y0frac -= half;
  71. if (y0frac < 0) y0frac = -y0frac;
  72. totDist = y0frac + x0frac - half;
  73. if (totDist > half) start++;
  74. y1frac -= half;
  75. if (y1frac < 0) y1frac = -y1frac;
  76. totDist = y1frac + x1frac - half;
  77. if (totDist > half) end++;
  78. offset = start + half - x0;
  79. gc->line.options.length = dx;
  80. gc->line.options.numPixels = end - start;
  81. xmajorfinish:
  82. gc->line.options.axis = __GL_X_MAJOR;
  83. gc->line.options.xStart = start;
  84. gc->line.options.offset = offset;
  85. minorStart = y0 + offset*slope - halfWidth;
  86. intMinorStart = (GLint) minorStart;
  87. minorStart -= intMinorStart;
  88. gc->line.options.yStart = intMinorStart;
  89. gc->line.options.dfraction = (GLint)(slope * __TWO_31);
  90. gc->line.options.fraction = (GLint)(minorStart * __TWO_31);
  91. } else { /* dy >= dx > 0 */
  92. gc->line.options.xBig = 1;
  93. posymajor: /* dy >= |dx| >= 0, dy != 0 */
  94. gc->line.options.xLittle = 0;
  95. gc->line.options.yBig = 1;
  96. gc->line.options.yLittle = 1;
  97. slope = dx/dy;
  98. start = (GLint) (y0);
  99. end = (GLint) (y1);
  100. x0frac -= half;
  101. if (x0frac < 0) x0frac = -x0frac;
  102. totDist = y0frac + x0frac - half;
  103. if (totDist > half) start++;
  104. x1frac -= half;
  105. if (x1frac < 0) x1frac = -x1frac;
  106. totDist = y1frac + x1frac - half;
  107. if (totDist > half) end++;
  108. offset = start + half - y0;
  109. gc->line.options.length = dy;
  110. gc->line.options.numPixels = end - start;
  111. ymajorfinish:
  112. gc->line.options.axis = __GL_Y_MAJOR;
  113. gc->line.options.yStart = start;
  114. gc->line.options.offset = offset;
  115. minorStart = x0 + offset*slope - halfWidth;
  116. intMinorStart = (GLint) minorStart;
  117. minorStart -= intMinorStart;
  118. gc->line.options.xStart = intMinorStart;
  119. gc->line.options.dfraction = (GLint)(slope * __TWO_31);
  120. gc->line.options.fraction = (GLint)(minorStart * __TWO_31);
  121. }
  122. } else {
  123. if (dx > -dy) { /* dx > -dy >= 0 */
  124. gc->line.options.yBig = -1;
  125. goto posxmajor;
  126. } else { /* -dy >= dx >= 0, dy != 0 */
  127. gc->line.options.xBig = 1;
  128. negymajor: /* -dy >= |dx| >= 0, dy != 0 */
  129. gc->line.options.xLittle = 0;
  130. gc->line.options.yBig = -1;
  131. gc->line.options.yLittle = -1;
  132. slope = dx/-dy;
  133. start = (GLint) (y0);
  134. end = (GLint) (y1);
  135. x0frac -= half;
  136. if (x0frac < 0) x0frac = -x0frac;
  137. totDist = x0frac + half - y0frac;
  138. if (totDist > half) start--;
  139. x1frac -= half;
  140. if (x1frac < 0) x1frac = -x1frac;
  141. totDist = x1frac + half - y1frac;
  142. if (totDist > half) end--;
  143. offset = y0 - (start + half);
  144. gc->line.options.length = -dy;
  145. gc->line.options.numPixels = start - end;
  146. goto ymajorfinish;
  147. }
  148. }
  149. } else {
  150. if (dy > __glZero) {
  151. if (-dx > dy) { /* -dx > dy > 0 */
  152. gc->line.options.yBig = 1;
  153. negxmajor: /* -dx > |dy| >= 0 */
  154. gc->line.options.yLittle = 0;
  155. gc->line.options.xBig = -1;
  156. gc->line.options.xLittle = -1;
  157. slope = dy/-dx;
  158. start = (GLint) (x0);
  159. end = (GLint) (x1);
  160. y0frac -= half;
  161. if (y0frac < 0) y0frac = -y0frac;
  162. totDist = y0frac + half - x0frac;
  163. if (totDist > half) start--;
  164. y1frac -= half;
  165. if (y1frac < 0) y1frac = -y1frac;
  166. totDist = y1frac + half - x1frac;
  167. if (totDist > half) end--;
  168. offset = x0 - (start + half);
  169. gc->line.options.length = -dx;
  170. gc->line.options.numPixels = start - end;
  171. goto xmajorfinish;
  172. } else { /* dy >= -dx >= 0, dy != 0 */
  173. gc->line.options.xBig = -1;
  174. goto posymajor;
  175. }
  176. } else {
  177. if (dx < dy) { /* -dx > -dy >= 0 */
  178. gc->line.options.yBig = -1;
  179. goto negxmajor;
  180. } else { /* -dy >= -dx >= 0 */
  181. #ifdef NT
  182. if (dx == dy && dy == 0) {
  183. gc->line.options.numPixels = 0;
  184. return;
  185. }
  186. #else
  187. if (dx == dy && dy == 0) return;
  188. #endif
  189. gc->line.options.xBig = -1;
  190. goto negymajor;
  191. }
  192. }
  193. }
  194. }
  195. #endif
  196. #ifdef NT
  197. void FASTCALL __glRenderAliasLine(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1, GLuint flags)
  198. #else
  199. void FASTCALL __glRenderAliasLine(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  200. #endif
  201. {
  202. __GLlineState *ls = &gc->state.line;
  203. __GLfloat invDelta;
  204. __GLfloat winv, r;
  205. __GLcolor *cp;
  206. __GLfloat offset;
  207. GLuint modeFlags = gc->polygon.shader.modeFlags;
  208. #ifndef NT
  209. __glInitLineData(gc, v0, v1);
  210. if (gc->line.options.numPixels == 0) return;
  211. #else
  212. GLboolean init;
  213. CHOP_ROUND_ON();
  214. init = (GLboolean)__glInitLineData(gc, v0, v1);
  215. CHOP_ROUND_OFF();
  216. if (!init)
  217. {
  218. return;
  219. }
  220. invDelta = gc->line.options.oneOverLength;
  221. #endif
  222. offset = gc->line.options.offset;
  223. /*
  224. ** Set up increments for any enabled line options.
  225. */
  226. #ifndef NT
  227. invDelta = __glOne / gc->line.options.length;
  228. #endif
  229. if (modeFlags & __GL_SHADE_DEPTH_ITER) {
  230. __GLfloat dzdx;
  231. /*
  232. ** Calculate window z coordinate increment and starting position.
  233. */
  234. dzdx = (v1->window.z - v0->window.z) * invDelta;
  235. #ifdef NT
  236. if(( gc->modes.depthBits == 16 ) &&
  237. ( gc->depthBuffer.scale <= (GLuint)0xffff )) {
  238. gc->polygon.shader.frag.z =
  239. (__GLzValue)(Z16_SCALE *(v0->window.z + dzdx * offset));
  240. gc->polygon.shader.dzdx = (GLint)(Z16_SCALE * dzdx);
  241. }
  242. else {
  243. gc->polygon.shader.frag.z =
  244. (__GLzValue)(v0->window.z + dzdx * offset);
  245. gc->polygon.shader.dzdx = (GLint)dzdx;
  246. }
  247. #else
  248. gc->polygon.shader.frag.z = (__GLzValue)(v0->window.z + dzdx * offset);
  249. gc->polygon.shader.dzdx = (GLint)dzdx;
  250. #endif
  251. }
  252. if (modeFlags & __GL_SHADE_LINE_STIPPLE) {
  253. if (!gc->line.notResetStipple) {
  254. gc->line.stipplePosition = 0;
  255. gc->line.repeat = 0;
  256. gc->line.notResetStipple = GL_TRUE;
  257. }
  258. }
  259. if (modeFlags & __GL_SHADE_COMPUTE_FOG)
  260. {
  261. __GLfloat f1, f0;
  262. __GLfloat dfdx;
  263. gc->line.options.f0 = f0 = v0->eyeZ;
  264. gc->polygon.shader.dfdx = dfdx =
  265. (v1->eyeZ - v0->eyeZ) * invDelta;
  266. gc->polygon.shader.frag.f = f0 + dfdx * offset;
  267. }
  268. else if (modeFlags & __GL_SHADE_INTERP_FOG)
  269. {
  270. __GLfloat f1, f0;
  271. __GLfloat dfdx;
  272. f0 = v0->fog;
  273. f1 = v1->fog;
  274. gc->line.options.f0 = f0;
  275. gc->polygon.shader.dfdx = dfdx = (f1 - f0) * invDelta;
  276. gc->polygon.shader.frag.f = f0 + dfdx * offset;
  277. }
  278. if (modeFlags & __GL_SHADE_TEXTURE) {
  279. __GLfloat v0QW, v1QW;
  280. __GLfloat dS, dT, dQWdX;
  281. winv = v0->window.w;
  282. /*
  283. ** Calculate texture s and t value increments.
  284. */
  285. v0QW = v0->texture.w * winv;
  286. v1QW = v1->texture.w * v1->window.w;
  287. dS = (v1->texture.x * v1QW - v0->texture.x * v0QW) * invDelta;
  288. dT = (v1->texture.y * v1QW - v0->texture.y * v0QW) * invDelta;
  289. gc->polygon.shader.dsdx = dS;
  290. gc->polygon.shader.dtdx = dT;
  291. gc->polygon.shader.dqwdx = dQWdX = (v1QW - v0QW) * invDelta;
  292. gc->polygon.shader.frag.s = v0->texture.x * winv + dS * offset;
  293. gc->polygon.shader.frag.t = v0->texture.y * winv + dT * offset;
  294. gc->polygon.shader.frag.qw = v0->texture.w * winv + dQWdX * offset;
  295. }
  296. #ifdef GL_WIN_phong_shading
  297. if (modeFlags & __GL_SHADE_PHONG)
  298. (*gc->procs.phong.InitLineParams) (gc, v0, v1, invDelta);
  299. #endif //GL_WIN_phong_shading
  300. if ((modeFlags & __GL_SHADE_SMOOTH)
  301. #ifdef GL_WIN_phong_shading
  302. || ((modeFlags & __GL_SHADE_PHONG) &&
  303. (gc->polygon.shader.phong.flags & __GL_PHONG_NEED_COLOR_XPOLATE))
  304. #endif //GL_WIN_phong_shading
  305. ) {
  306. __GLcolor *c0 = v0->color;
  307. __GLcolor *c1 = v1->color;
  308. __GLfloat drdx, dgdx, dbdx, dadx;
  309. /*
  310. ** Calculate red, green, blue and alpha value increments.
  311. */
  312. drdx = (c1->r - c0->r) * invDelta;
  313. if (gc->modes.rgbMode) {
  314. dgdx = (c1->g - c0->g) * invDelta;
  315. dbdx = (c1->b - c0->b) * invDelta;
  316. dadx = (c1->a - c0->a) * invDelta;
  317. gc->polygon.shader.dgdx = dgdx;
  318. gc->polygon.shader.dbdx = dbdx;
  319. gc->polygon.shader.dadx = dadx;
  320. }
  321. gc->polygon.shader.drdx = drdx;
  322. cp = v0->color;
  323. } else {
  324. cp = v1->color;
  325. // Initialize these values to zero even for the flat case
  326. // because there is an optimization in so_prim which will
  327. // turn off smooth shading without repicking, so these need
  328. // to be valid
  329. gc->polygon.shader.drdx = __glZero;
  330. gc->polygon.shader.dgdx = __glZero;
  331. gc->polygon.shader.dbdx = __glZero;
  332. gc->polygon.shader.dadx = __glZero;
  333. }
  334. r = cp->r;
  335. if (modeFlags & __GL_SHADE_RGB) {
  336. __GLfloat g,b,a;
  337. g = cp->g;
  338. b = cp->b;
  339. a = cp->a;
  340. gc->polygon.shader.frag.color.g = g;
  341. gc->polygon.shader.frag.color.b = b;
  342. gc->polygon.shader.frag.color.a = a;
  343. }
  344. gc->polygon.shader.frag.color.r = r;
  345. gc->polygon.shader.length = gc->line.options.numPixels;
  346. (*gc->procs.line.processLine)(gc);
  347. }
  348. #ifdef NT
  349. void FASTCALL __glRenderFlatFogLine(__GLcontext *gc, __GLvertex *v0,
  350. __GLvertex *v1, GLuint flags)
  351. #else
  352. void FASTCALL __glRenderFlatFogLine(__GLcontext *gc, __GLvertex *v0,
  353. __GLvertex *v1)
  354. #endif
  355. {
  356. __GLcolor v0col, v1col;
  357. __GLcolor *v0ocp, *v1ocp;
  358. (*gc->procs.fogColor)(gc, &v0col, v1->color, v0->fog);
  359. (*gc->procs.fogColor)(gc, &v1col, v1->color, v1->fog);
  360. v0ocp = v0->color;
  361. v1ocp = v1->color;
  362. v0->color = &v0col;
  363. v1->color = &v1col;
  364. #ifdef NT
  365. (*gc->procs.renderLine2)(gc, v0, v1, flags);
  366. #else
  367. (*gc->procs.renderLine2)(gc, v0, v1);
  368. #endif
  369. v0->color = v0ocp;
  370. v1->color = v1ocp;
  371. }
  372. /************************************************************************/
  373. /*
  374. ** Most line functions will start off by computing the information
  375. ** computed by this routine.
  376. **
  377. ** The excessive number of labels in this routine is partly due
  378. ** to the fact that it is used as a model for writing an assembly
  379. ** equivalent.
  380. */
  381. void FASTCALL __glInitAALineData(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  382. {
  383. GLint start;
  384. __GLfloat width;
  385. __GLfloat x0,y0,x1,y1;
  386. __GLfloat minorStart;
  387. GLint intMinorStart;
  388. __GLfloat dx, dy;
  389. __GLfloat offset;
  390. __GLfloat slope;
  391. __GLlineState *ls = &gc->state.line;
  392. __GLfloat halfWidth;
  393. __GLfloat realLength, oneOverRealLength;
  394. __GLfloat dldx, dldy;
  395. __GLfloat dddx, dddy;
  396. gc->line.options.v0 = v0;
  397. gc->line.options.v1 = v1;
  398. x0=v0->window.x;
  399. y0=v0->window.y;
  400. x1=v1->window.x;
  401. y1=v1->window.y;
  402. dx=x1-x0;
  403. dy=y1-y0;
  404. realLength = __GL_SQRTF(dx*dx+dy*dy);
  405. oneOverRealLength = realLength == __glZero ? __glZero : __glOne/realLength;
  406. gc->line.options.realLength = realLength;
  407. gc->line.options.dldx = dldx = dx * oneOverRealLength;
  408. gc->line.options.dldy = dldy = dy * oneOverRealLength;
  409. gc->line.options.dddx = dddx = -dldy;
  410. gc->line.options.dddy = dddy = dldx;
  411. if (dx > __glZero) {
  412. if (dy > __glZero) { /* dx > 0, dy > 0 */
  413. gc->line.options.dlBig = dldx + dldy;
  414. gc->line.options.ddBig = dddx + dddy;
  415. if (dx > dy) { /* dx > dy > 0 */
  416. gc->line.options.yBig = 1;
  417. posxmajor: /* dx > |dy| >= 0 */
  418. gc->line.options.yLittle = 0;
  419. gc->line.options.xBig = 1;
  420. gc->line.options.xLittle = 1;
  421. gc->line.options.dlLittle = dldx;
  422. gc->line.options.ddLittle = dddx;
  423. slope = dy/dx;
  424. start = (GLint) x0;
  425. offset = start + __glHalf - x0;
  426. gc->line.options.length = dx;
  427. gc->line.options.numPixels = (GLint)__GL_FAST_CEILF(x1 - x0) + 1;
  428. width = __GL_FAST_CEILF(gc->state.line.smoothWidth *
  429. realLength / dx);
  430. xmajorfinish:
  431. gc->line.options.width = (GLint)width + 1;
  432. halfWidth = width * __glHalf;
  433. gc->line.options.axis = __GL_X_MAJOR;
  434. gc->line.options.xStart = start;
  435. gc->line.options.offset = offset;
  436. minorStart = y0 + offset*slope - halfWidth;
  437. intMinorStart = (GLint) minorStart;
  438. minorStart -= intMinorStart;
  439. gc->line.options.yStart = intMinorStart;
  440. gc->line.options.dfraction = (GLint)(slope * __TWO_31);
  441. gc->line.options.fraction = (GLint)(minorStart * __TWO_31);
  442. } else { /* dy >= dx > 0 */
  443. gc->line.options.xBig = 1;
  444. posymajor: /* dy >= |dx| >= 0, dy != 0 */
  445. gc->line.options.xLittle = 0;
  446. gc->line.options.yBig = 1;
  447. gc->line.options.yLittle = 1;
  448. gc->line.options.dlLittle = dldy;
  449. gc->line.options.ddLittle = dddy;
  450. slope = dx/dy;
  451. start = (GLint) y0;
  452. offset = start + __glHalf - y0;
  453. gc->line.options.length = dy;
  454. gc->line.options.numPixels = (GLint)__GL_FAST_CEILF(y1 - y0) + 1;
  455. width = __GL_FAST_CEILF(gc->state.line.smoothWidth *
  456. realLength / dy);
  457. ymajorfinish:
  458. gc->line.options.width = (GLint)width + 1;
  459. halfWidth = width * __glHalf;
  460. gc->line.options.axis = __GL_Y_MAJOR;
  461. gc->line.options.yStart = start;
  462. gc->line.options.offset = offset;
  463. minorStart = x0 + offset*slope - halfWidth;
  464. intMinorStart = (GLint) minorStart;
  465. minorStart -= intMinorStart;
  466. gc->line.options.xStart = intMinorStart;
  467. gc->line.options.dfraction = (GLint)(slope * __TWO_31);
  468. gc->line.options.fraction = (GLint)(minorStart * __TWO_31);
  469. }
  470. } else { /* dx > 0, dy <= 0 */
  471. gc->line.options.dlBig = dldx - dldy;
  472. gc->line.options.ddBig = dddx - dddy;
  473. if (dx > -dy) { /* dx > -dy >= 0 */
  474. gc->line.options.yBig = -1;
  475. goto posxmajor;
  476. } else { /* -dy >= dx >= 0, dy != 0 */
  477. gc->line.options.xBig = 1;
  478. negymajor: /* -dy >= |dx| >= 0, dy != 0 */
  479. gc->line.options.xLittle = 0;
  480. gc->line.options.yBig = -1;
  481. gc->line.options.yLittle = -1;
  482. gc->line.options.dlLittle = -dldy;
  483. gc->line.options.ddLittle = -dddy;
  484. slope = dx/-dy;
  485. start = (GLint) y0;
  486. offset = y0 - (start + __glHalf);
  487. gc->line.options.length = -dy;
  488. gc->line.options.numPixels = (GLint)__GL_FAST_CEILF(y0 - y1) + 1;
  489. width = __GL_FAST_CEILF(-gc->state.line.smoothWidth *
  490. realLength / dy);
  491. goto ymajorfinish;
  492. }
  493. }
  494. } else {
  495. if (dy > __glZero) { /* dx <= 0, dy > 0 */
  496. gc->line.options.dlBig = dldy - dldx;
  497. gc->line.options.ddBig = dddy - dddx;
  498. if (-dx > dy) { /* -dx > dy > 0 */
  499. gc->line.options.yBig = 1;
  500. negxmajor: /* -dx > |dy| >= 0 */
  501. gc->line.options.yLittle = 0;
  502. gc->line.options.xBig = -1;
  503. gc->line.options.xLittle = -1;
  504. gc->line.options.dlLittle = -dldx;
  505. gc->line.options.ddLittle = -dddx;
  506. slope = dy/-dx;
  507. start = (GLint) x0;
  508. offset = x0 - (start + __glHalf);
  509. gc->line.options.length = -dx;
  510. gc->line.options.numPixels = (GLint)__GL_FAST_CEILF(x0 - x1) + 1;
  511. width = __GL_FAST_CEILF(-gc->state.line.smoothWidth *
  512. realLength / dx);
  513. goto xmajorfinish;
  514. } else { /* dy >= -dx >= 0, dy != 0 */
  515. gc->line.options.xBig = -1;
  516. goto posymajor;
  517. }
  518. } else { /* dx <= 0, dy <= 0 */
  519. gc->line.options.dlBig = -dldx - dldy;
  520. gc->line.options.ddBig = -dddx - dddy;
  521. if (dx < dy) { /* -dx > -dy >= 0 */
  522. gc->line.options.yBig = -1;
  523. goto negxmajor;
  524. } else { /* -dy >= -dx >= 0 */
  525. if (dx == dy && dy == 0) {
  526. gc->line.options.length = 0;
  527. return;
  528. }
  529. gc->line.options.xBig = -1;
  530. goto negymajor;
  531. }
  532. }
  533. }
  534. }
  535. #ifdef NT
  536. void FASTCALL __glRenderAntiAliasLine(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1, GLuint flags)
  537. #else
  538. void FASTCALL __glRenderAntiAliasLine(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  539. #endif
  540. {
  541. __GLlineState *ls = &gc->state.line;
  542. __GLfloat invDelta;
  543. __GLfloat winv;
  544. __GLcolor *cp;
  545. __GLfloat offset;
  546. GLint lineRep;
  547. GLint x, y, xBig, xLittle, yBig, yLittle;
  548. GLint fraction, dfraction;
  549. __GLfloat dlLittle, dlBig;
  550. __GLfloat ddLittle, ddBig;
  551. __GLfloat length, width;
  552. __GLfloat lineLength;
  553. __GLfloat dx, dy;
  554. GLuint modeFlags = gc->polygon.shader.modeFlags;
  555. __glInitAALineData(gc, v0, v1);
  556. if (gc->line.options.length == 0) return;
  557. offset = gc->line.options.offset;
  558. /*
  559. ** Set up increments for any enabled line options.
  560. */
  561. invDelta = __glOne / gc->line.options.length;
  562. if (modeFlags & __GL_SHADE_DEPTH_ITER) {
  563. /*
  564. ** Calculate window z coordinate increment and starting position.
  565. */
  566. #ifdef NT
  567. if(( gc->modes.depthBits == 16 ) &&
  568. ( gc->depthBuffer.scale <= (GLuint)0xffff )) {
  569. gc->polygon.shader.dzdx = (GLint)((v1->window.z - v0->window.z) *
  570. invDelta * Z16_SCALE);
  571. gc->polygon.shader.frag.z = (GLint)(Z16_SCALE*v0->window.z +
  572. gc->polygon.shader.dzdx * offset);
  573. }
  574. else {
  575. gc->polygon.shader.dzdx = (GLint)((v1->window.z - v0->window.z) *
  576. invDelta);
  577. gc->polygon.shader.frag.z = (GLint)(v0->window.z +
  578. gc->polygon.shader.dzdx * offset);
  579. }
  580. #else
  581. gc->polygon.shader.dzdx = (GLint)((v1->window.z - v0->window.z) *
  582. invDelta);
  583. gc->polygon.shader.frag.z = (GLint)(v0->window.z +
  584. gc->polygon.shader.dzdx * offset);
  585. #endif
  586. }
  587. if (modeFlags & __GL_SHADE_LINE_STIPPLE) {
  588. if (!gc->line.notResetStipple) {
  589. gc->line.stipplePosition = 0;
  590. gc->line.repeat = 0;
  591. gc->line.notResetStipple = GL_TRUE;
  592. }
  593. }
  594. if (modeFlags & __GL_SHADE_COMPUTE_FOG)
  595. {
  596. __GLfloat f1, f0;
  597. __GLfloat dfdx;
  598. f0 = v0->eyeZ;
  599. f1 = v1->eyeZ;
  600. gc->line.options.f0 = f0;
  601. gc->polygon.shader.dfdx = dfdx = (f1 - f0) * invDelta;
  602. gc->polygon.shader.frag.f = f0 + dfdx * offset;
  603. }
  604. else if (modeFlags & __GL_SHADE_INTERP_FOG)
  605. {
  606. __GLfloat f1, f0;
  607. __GLfloat dfdx;
  608. f0 = v0->fog;
  609. f1 = v1->fog;
  610. gc->line.options.f0 = f0;
  611. gc->polygon.shader.dfdx = dfdx = (f1 - f0) * invDelta;
  612. gc->polygon.shader.frag.f = f0 + dfdx * offset;
  613. }
  614. if ((modeFlags & __GL_SHADE_SMOOTH)
  615. #ifdef GL_WIN_phong_shading
  616. || ((modeFlags & __GL_SHADE_PHONG) &&
  617. (gc->polygon.shader.phong.flags & __GL_PHONG_NEED_COLOR_XPOLATE))
  618. #endif //GL_WIN_phong_shading
  619. )
  620. {
  621. __GLcolor *c0 = v0->color;
  622. __GLcolor *c1 = v1->color;
  623. /*
  624. ** Calculate red, green, blue and alpha value increments.
  625. */
  626. gc->polygon.shader.drdx = (c1->r - c0->r) * invDelta;
  627. if (gc->modes.rgbMode) {
  628. gc->polygon.shader.dgdx = (c1->g - c0->g) * invDelta;
  629. gc->polygon.shader.dbdx = (c1->b - c0->b) * invDelta;
  630. gc->polygon.shader.dadx = (c1->a - c0->a) * invDelta;
  631. }
  632. cp = v0->color;
  633. } else {
  634. cp = v1->color;
  635. // Initialize these values to zero even for the flat case
  636. // because there is an optimization in so_prim which will
  637. // turn off smooth shading without repicking, so these need
  638. // to be valid
  639. gc->polygon.shader.drdx = __glZero;
  640. gc->polygon.shader.dgdx = __glZero;
  641. gc->polygon.shader.dbdx = __glZero;
  642. gc->polygon.shader.dadx = __glZero;
  643. }
  644. gc->polygon.shader.frag.color.r = cp->r;
  645. if (gc->modes.rgbMode) {
  646. gc->polygon.shader.frag.color.g = cp->g;
  647. gc->polygon.shader.frag.color.b = cp->b;
  648. gc->polygon.shader.frag.color.a = cp->a;
  649. }
  650. if (gc->texture.textureEnabled) {
  651. __GLfloat v0QW, v1QW;
  652. __GLfloat dS, dT;
  653. /*
  654. ** Calculate texture s and t value increments.
  655. */
  656. v0QW = v0->texture.w * v0->window.w;
  657. v1QW = v1->texture.w * v1->window.w;
  658. dS = (v1->texture.x * v1QW - v0->texture.x * v0QW) * invDelta;
  659. dT = (v1->texture.y * v1QW - v0->texture.y * v0QW) * invDelta;
  660. gc->polygon.shader.dsdx = dS;
  661. gc->polygon.shader.dtdx = dT;
  662. gc->polygon.shader.dqwdx = (v1QW - v0QW) * invDelta;
  663. winv = v0->window.w;
  664. gc->polygon.shader.frag.s = v0->texture.x * winv +
  665. gc->polygon.shader.dsdx * offset;
  666. gc->polygon.shader.frag.t = v0->texture.y * winv +
  667. gc->polygon.shader.dtdx * offset;
  668. gc->polygon.shader.frag.qw = v0->texture.w * winv +
  669. gc->polygon.shader.dqwdx * offset;
  670. }
  671. lineRep = gc->line.options.width;
  672. fraction = gc->line.options.fraction;
  673. dfraction = gc->line.options.dfraction;
  674. x = gc->line.options.xStart;
  675. y = gc->line.options.yStart;
  676. xBig = gc->line.options.xBig;
  677. yBig = gc->line.options.yBig;
  678. xLittle = gc->line.options.xLittle;
  679. yLittle = gc->line.options.yLittle;
  680. dlLittle = gc->line.options.dlLittle;
  681. dlBig = gc->line.options.dlBig;
  682. ddLittle = gc->line.options.ddLittle;
  683. ddBig = gc->line.options.ddBig;
  684. dx = x + __glHalf - v0->window.x;
  685. dy = y + __glHalf - v0->window.y;
  686. length = dx * gc->line.options.dldx +
  687. dy * gc->line.options.dldy;
  688. width = dx * gc->line.options.dddx +
  689. dy * gc->line.options.dddy;
  690. lineLength = gc->line.options.realLength + __glHalf;
  691. if (modeFlags & __GL_SHADE_LINE_STIPPLE) {
  692. gc->line.options.stippleOffset =
  693. gc->line.stipplePosition * gc->state.line.stippleRepeat +
  694. gc->line.repeat - __glHalf;
  695. /* XXX Move to a validation routine? */
  696. gc->line.options.oneOverStippleRepeat =
  697. __glOne / gc->state.line.stippleRepeat;
  698. }
  699. while (--lineRep >= 0) {
  700. /* Trace the line backwards as needed */
  701. while (length > -__glHalf) {
  702. fraction -= dfraction;
  703. if (fraction < 0) {
  704. fraction &= ~0x80000000;
  705. length -= dlBig;
  706. width -= ddBig;
  707. x -= xBig;
  708. y -= yBig;
  709. } else {
  710. length -= dlLittle;
  711. width -= ddLittle;
  712. x -= xLittle;
  713. y -= yLittle;
  714. }
  715. }
  716. /* Trace line forwards to correct */
  717. while (length <= -__glHalf) {
  718. fraction += dfraction;
  719. if (fraction < 0) {
  720. fraction &= ~0x80000000;
  721. length += dlBig;
  722. width += ddBig;
  723. x += xBig;
  724. y += yBig;
  725. } else {
  726. length += dlLittle;
  727. width += ddLittle;
  728. x += xLittle;
  729. y += yLittle;
  730. }
  731. }
  732. #ifdef GL_WIN_phong_shading
  733. if (modeFlags & __GL_SHADE_PHONG)
  734. (*gc->procs.phong.InitLineParams) (gc, v0, v1, invDelta);
  735. #endif //GL_WIN_phong_shading
  736. /* Save new fraction/dfraction */
  737. gc->line.options.plength = length;
  738. gc->line.options.pwidth = width;
  739. gc->line.options.fraction = fraction;
  740. gc->line.options.dfraction = dfraction;
  741. gc->line.options.xStart = x;
  742. gc->line.options.yStart = y;
  743. gc->polygon.shader.length = gc->line.options.numPixels;
  744. (*gc->procs.line.processLine)(gc);
  745. if (gc->line.options.axis == __GL_X_MAJOR) {
  746. y++;
  747. length += gc->line.options.dldy;
  748. width += gc->line.options.dddy;
  749. } else {
  750. x++;
  751. length += gc->line.options.dldx;
  752. width += gc->line.options.dddx;
  753. }
  754. }
  755. if (modeFlags & __GL_SHADE_LINE_STIPPLE) {
  756. /* Update stipple. Ugh. */
  757. int increase;
  758. int posInc;
  759. /* Shift stipple by 'increase' bits */
  760. increase = (GLint)__GL_FAST_CEILF(gc->line.options.realLength);
  761. posInc = increase / gc->state.line.stippleRepeat;
  762. gc->line.stipplePosition = (gc->line.stipplePosition + posInc) & 0xf;
  763. gc->line.repeat = (gc->line.repeat + increase) % gc->state.line.stippleRepeat;
  764. }
  765. }
  766. #ifdef NT
  767. void FASTCALL __glNopLineBegin(__GLcontext *gc)
  768. {
  769. }
  770. void FASTCALL __glNopLineEnd(__GLcontext *gc)
  771. {
  772. }
  773. #endif // NT