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.

880 lines
24 KiB

  1. /*
  2. ** Copyright 1991,1992, 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 <namesint.h>
  21. #include <math.h>
  22. /*
  23. ** Some math routines that are optimized in assembly
  24. */
  25. #define __GL_FRAC(f) ((f) - __GL_FAST_FLOORF(f))
  26. /************************************************************************/
  27. // Repeats the given float value in float [0, scale) and converts to
  28. // int. The repeat count is an integer which is a power of two
  29. #define REPEAT_SCALED_VAL(val, scale, repeat) \
  30. (__GL_FLOAT_GEZ(val) ? (FTOL((val) * (scale)) & ((repeat)-1)) : \
  31. ((repeat)-1)-(FTOL(-(val) * (scale)) & ((repeat)-1)))
  32. // Clamps the given float value to float [0, scale) and converts to int
  33. #define CLAMP_SCALED_VAL(val, scale) \
  34. (__GL_FLOAT_LEZ(val) ? 0 : \
  35. __GL_FLOAT_COMPARE_PONE(val, >=) ? (FTOL(scale)-1) : \
  36. FTOL((val) * (scale)))
  37. /*
  38. ** Return texel nearest the s coordinate. s is converted to u
  39. ** implicitly during this step.
  40. */
  41. void FASTCALL __glNearestFilter1(__GLcontext *gc, __GLtexture *tex,
  42. __GLmipMapLevel *lp, __GLcolor *color,
  43. __GLfloat s, __GLfloat t, __GLtexel *result)
  44. {
  45. GLint col;
  46. __GLfloat w2f;
  47. CHOP_ROUND_ON();
  48. #ifdef __GL_LINT
  49. gc = gc;
  50. color = color;
  51. t = t;
  52. #endif
  53. /* Find texel index */
  54. w2f = lp->width2f;
  55. if (tex->params.sWrapMode == GL_REPEAT) {
  56. col = REPEAT_SCALED_VAL(s, w2f, lp->width2);
  57. } else {
  58. col = CLAMP_SCALED_VAL(s, w2f);
  59. }
  60. CHOP_ROUND_OFF();
  61. /* Lookup texel */
  62. (*lp->extract)(lp, tex, 0, col, result);
  63. }
  64. /*
  65. ** Return texel nearest the s&t coordinates. s&t are converted to u&v
  66. ** implicitly during this step.
  67. */
  68. void FASTCALL __glNearestFilter2(__GLcontext *gc, __GLtexture *tex,
  69. __GLmipMapLevel *lp, __GLcolor *color,
  70. __GLfloat s, __GLfloat t, __GLtexel *result)
  71. {
  72. GLint row, col;
  73. __GLfloat w2f, h2f;
  74. CHOP_ROUND_ON();
  75. #ifdef __GL_LINT
  76. gc = gc;
  77. color = color;
  78. #endif
  79. /* Find texel column address */
  80. w2f = lp->width2f;
  81. if (tex->params.sWrapMode == GL_REPEAT) {
  82. col = REPEAT_SCALED_VAL(s, w2f, lp->width2);
  83. } else {
  84. col = CLAMP_SCALED_VAL(s, w2f);
  85. }
  86. /* Find texel row address */
  87. h2f = lp->height2f;
  88. if (tex->params.tWrapMode == GL_REPEAT) {
  89. row = REPEAT_SCALED_VAL(t, h2f, lp->height2);
  90. } else {
  91. row = CLAMP_SCALED_VAL(t, h2f);
  92. }
  93. CHOP_ROUND_OFF();
  94. /* Lookup texel */
  95. (*lp->extract)(lp, tex, row, col, result);
  96. }
  97. /*
  98. ** Return texel which is a linear combination of texels near s.
  99. */
  100. void FASTCALL __glLinearFilter1(__GLcontext *gc, __GLtexture *tex,
  101. __GLmipMapLevel *lp, __GLcolor *color,
  102. __GLfloat s, __GLfloat t, __GLtexel *result)
  103. {
  104. __GLfloat u, alpha, omalpha, w2f;
  105. GLint col0, col1;
  106. __GLtexel t0, t1;
  107. #ifdef __GL_LINT
  108. color = color;
  109. t = t;
  110. #endif
  111. /* Find col0 and col1 */
  112. w2f = lp->width2f;
  113. u = s * w2f;
  114. if (tex->params.sWrapMode == GL_REPEAT) {
  115. GLint w2mask = lp->width2 - 1;
  116. u -= __glHalf;
  117. col0 = __GL_FAST_FLOORF_I(u);
  118. alpha = u - (__GLfloat) col0; // Get fractional part
  119. col0 &= w2mask;
  120. col1 = (col0 + 1) & w2mask;
  121. } else {
  122. if (u < __glZero) u = __glZero;
  123. else if (u > w2f) u = w2f;
  124. u -= __glHalf;
  125. col0 = __GL_FAST_FLOORF_I(u);
  126. alpha = u - (__GLfloat) col0; // Get fractional part
  127. col1 = col0 + 1;
  128. }
  129. /* Calculate the final texel value as a combination of the two texels */
  130. (*lp->extract)(lp, tex, 0, col0, &t0);
  131. (*lp->extract)(lp, tex, 0, col1, &t1);
  132. omalpha = __glOne - alpha;
  133. switch (lp->baseFormat) {
  134. case GL_LUMINANCE_ALPHA:
  135. result->alpha = omalpha * t0.alpha + alpha * t1.alpha;
  136. /* FALLTHROUGH */
  137. case GL_LUMINANCE:
  138. result->luminance = omalpha * t0.luminance + alpha * t1.luminance;
  139. break;
  140. case GL_RGBA:
  141. result->alpha = omalpha * t0.alpha + alpha * t1.alpha;
  142. /* FALLTHROUGH */
  143. case GL_RGB:
  144. result->r = omalpha * t0.r + alpha * t1.r;
  145. result->g = omalpha * t0.g + alpha * t1.g;
  146. result->b = omalpha * t0.b + alpha * t1.b;
  147. break;
  148. case GL_ALPHA:
  149. result->alpha = omalpha * t0.alpha + alpha * t1.alpha;
  150. break;
  151. case GL_INTENSITY:
  152. result->intensity = omalpha * t0.intensity + alpha * t1.intensity;
  153. break;
  154. }
  155. }
  156. /*
  157. ** Return texel which is a linear combination of texels near s&t.
  158. */
  159. void FASTCALL __glLinearFilter2(__GLcontext *gc, __GLtexture *tex,
  160. __GLmipMapLevel *lp, __GLcolor *color,
  161. __GLfloat s, __GLfloat t, __GLtexel *result)
  162. {
  163. __GLfloat u, v, alpha, beta, half, w2f, h2f;
  164. GLint col0, row0, col1, row1;
  165. __GLtexel t00, t01, t10, t11;
  166. __GLfloat omalpha, ombeta, m00, m01, m10, m11;
  167. #ifdef __GL_LINT
  168. color = color;
  169. #endif
  170. /* Find col0, col1 */
  171. w2f = lp->width2f;
  172. u = s * w2f;
  173. half = __glHalf;
  174. if (tex->params.sWrapMode == GL_REPEAT) {
  175. GLint w2mask = lp->width2 - 1;
  176. u -= half;
  177. col0 = __GL_FAST_FLOORF_I(u);
  178. alpha = u - (__GLfloat) col0; // Get fractional part
  179. col0 &= w2mask;
  180. col1 = (col0 + 1) & w2mask;
  181. } else {
  182. if (u < __glZero) u = __glZero;
  183. else if (u > w2f) u = w2f;
  184. u -= half;
  185. col0 = __GL_FAST_FLOORF_I(u);
  186. alpha = u - (__GLfloat) col0; // Get fractional part
  187. col1 = col0 + 1;
  188. }
  189. /* Find row0, row1 */
  190. h2f = lp->height2f;
  191. v = t * h2f;
  192. if (tex->params.tWrapMode == GL_REPEAT) {
  193. GLint h2mask = lp->height2 - 1;
  194. v -= half;
  195. row0 = (__GL_FAST_FLOORF_I(v));
  196. beta = v - (__GLfloat) row0; // Get fractional part
  197. row0 &= h2mask;
  198. row1 = (row0 + 1) & h2mask;
  199. } else {
  200. if (v < __glZero) v = __glZero;
  201. else if (v > h2f) v = h2f;
  202. v -= half;
  203. row0 = __GL_FAST_FLOORF_I(v);
  204. beta = v - (__GLfloat) row0; // Get fractional part
  205. row1 = row0 + 1;
  206. }
  207. /* Calculate the final texel value as a combination of the square chosen */
  208. (*lp->extract)(lp, tex, row0, col0, &t00);
  209. (*lp->extract)(lp, tex, row0, col1, &t10);
  210. (*lp->extract)(lp, tex, row1, col0, &t01);
  211. (*lp->extract)(lp, tex, row1, col1, &t11);
  212. omalpha = __glOne - alpha;
  213. ombeta = __glOne - beta;
  214. m00 = omalpha * ombeta;
  215. m10 = alpha * ombeta;
  216. m01 = omalpha * beta;
  217. m11 = alpha * beta;
  218. switch (lp->baseFormat) {
  219. case GL_LUMINANCE_ALPHA:
  220. /* FALLTHROUGH */
  221. result->alpha = m00*t00.alpha + m10*t10.alpha + m01*t01.alpha
  222. + m11*t11.alpha;
  223. case GL_LUMINANCE:
  224. result->luminance = m00*t00.luminance + m10*t10.luminance
  225. + m01*t01.luminance + m11*t11.luminance;
  226. break;
  227. case GL_RGBA:
  228. /* FALLTHROUGH */
  229. result->alpha = m00*t00.alpha + m10*t10.alpha + m01*t01.alpha
  230. + m11*t11.alpha;
  231. case GL_RGB:
  232. result->r = m00*t00.r + m10*t10.r + m01*t01.r + m11*t11.r;
  233. result->g = m00*t00.g + m10*t10.g + m01*t01.g + m11*t11.g;
  234. result->b = m00*t00.b + m10*t10.b + m01*t01.b + m11*t11.b;
  235. break;
  236. case GL_ALPHA:
  237. result->alpha = m00*t00.alpha + m10*t10.alpha + m01*t01.alpha
  238. + m11*t11.alpha;
  239. break;
  240. case GL_INTENSITY:
  241. result->intensity = m00*t00.intensity + m10*t10.intensity
  242. + m01*t01.intensity + m11*t11.intensity;
  243. break;
  244. }
  245. }
  246. // Macros to convert unsigned byte rgb{a} to float
  247. #define __glBGRByteToFloat( fdst, bsrc ) \
  248. (fdst)->b = __GL_UB_TO_FLOAT( *(bsrc)++ ); \
  249. (fdst)->g = __GL_UB_TO_FLOAT( *(bsrc)++ ); \
  250. (fdst)->r = __GL_UB_TO_FLOAT( *(bsrc)++ ); \
  251. (bsrc)++;
  252. #define __glBGRAByteToFloat( fdst, bsrc ) \
  253. (fdst)->b = __GL_UB_TO_FLOAT( *(bsrc)++ ); \
  254. (fdst)->g = __GL_UB_TO_FLOAT( *(bsrc)++ ); \
  255. (fdst)->r = __GL_UB_TO_FLOAT( *(bsrc)++ ); \
  256. (fdst)->a = __GL_UB_TO_FLOAT( *(bsrc)++ );
  257. void FASTCALL __glLinearFilter2_BGR8Repeat(__GLcontext *gc, __GLtexture *tex,
  258. __GLmipMapLevel *lp, __GLcolor *color,
  259. __GLfloat s, __GLfloat t, __GLtexel *result)
  260. {
  261. __GLfloat u, v, alpha, beta, half;
  262. GLint col, row, rowLen;
  263. __GLcolor t00, t01, t10, t11;
  264. __GLfloat omalpha, ombeta, m00, m01, m10, m11;
  265. GLint width2m1, height2m1;
  266. GLubyte *image, *pData;
  267. #ifdef __GL_LINT
  268. color = color;
  269. #endif
  270. half = __glHalf;
  271. width2m1 = lp->width2 - 1;
  272. height2m1 = lp->height2 - 1;
  273. /* Find col, compute alpha */
  274. u = (s * lp->width2f) - half;
  275. col = __GL_FAST_FLOORF_I(u);
  276. alpha = u - (__GLfloat) col; // Get fractional part
  277. col &= width2m1;
  278. /* Find row, compute beta */
  279. v = (t * lp->height2f) - half;
  280. row = __GL_FAST_FLOORF_I(v);
  281. beta = v - (__GLfloat) row; // Get fractional part
  282. row &= height2m1;
  283. // Extract first texel at row, col
  284. pData = image =
  285. (GLubyte *)lp->buffer + (((row << lp->widthLog2) + col) << 2);
  286. __glBGRByteToFloat( &t00, pData );
  287. // Extract remaining texels
  288. rowLen = lp->width2 << 2; // row length in bytes
  289. if( (row < height2m1) &&
  290. (col < width2m1) )
  291. {
  292. // Most common case - the texels are a compact block of 4
  293. // Next texel along row
  294. __glBGRByteToFloat( &t10, pData );
  295. // Up to next row...
  296. pData += (rowLen-8);
  297. __glBGRByteToFloat( &t01, pData );
  298. __glBGRByteToFloat( &t11, pData );
  299. } else {
  300. // Exceptional case : one or both of row, col are on edge
  301. GLint rowInc, colInc; // increments in bytes
  302. // Calc increments to next texel along row/col
  303. if( col < width2m1 )
  304. rowInc = 4;
  305. else
  306. // increment to left edge
  307. rowInc = -(rowLen - 4);
  308. if( row < height2m1 )
  309. // increment by row length
  310. colInc = rowLen;
  311. else
  312. // increment to lower edge
  313. colInc = - height2m1 * rowLen;
  314. // Next texel along row
  315. pData = image + rowInc;
  316. __glBGRByteToFloat( &t10, pData );
  317. // Second row, first texel
  318. pData = image + colInc;
  319. __glBGRByteToFloat( &t01, pData );
  320. // Next texel along row
  321. pData += (rowInc - 4);
  322. __glBGRByteToFloat( &t11, pData );
  323. }
  324. omalpha = __glOne - alpha;
  325. ombeta = __glOne - beta;
  326. m00 = omalpha * ombeta;
  327. m10 = alpha * ombeta;
  328. m01 = omalpha * beta;
  329. m11 = alpha * beta;
  330. result->r = m00*t00.r + m10*t10.r + m01*t01.r + m11*t11.r;
  331. result->g = m00*t00.g + m10*t10.g + m01*t01.g + m11*t11.g;
  332. result->b = m00*t00.b + m10*t10.b + m01*t01.b + m11*t11.b;
  333. }
  334. void FASTCALL __glLinearFilter2_BGRA8Repeat(__GLcontext *gc, __GLtexture *tex,
  335. __GLmipMapLevel *lp, __GLcolor *color,
  336. __GLfloat s, __GLfloat t, __GLtexel *result)
  337. {
  338. __GLfloat u, v, alpha, beta, half;
  339. GLint col, row, rowLen;
  340. __GLcolor t00, t01, t10, t11;
  341. __GLfloat omalpha, ombeta, m00, m01, m10, m11;
  342. GLint width2m1, height2m1;
  343. GLubyte *image, *pData;
  344. #ifdef __GL_LINT
  345. color = color;
  346. #endif
  347. half = __glHalf;
  348. width2m1 = lp->width2 - 1;
  349. height2m1 = lp->height2 - 1;
  350. /* Find col, compute alpha */
  351. u = (s * lp->width2f) - half;
  352. col = __GL_FAST_FLOORF_I(u);
  353. alpha = u - (__GLfloat) col; // Get fractional part
  354. col &= width2m1;
  355. /* Find row, compute beta */
  356. v = (t * lp->height2f) - half;
  357. row = __GL_FAST_FLOORF_I(v);
  358. beta = v - (__GLfloat) row; // Get fractional part
  359. row &= height2m1;
  360. // Extract first texel
  361. pData = image =
  362. (GLubyte *)lp->buffer + (((row << lp->widthLog2) + col) << 2);
  363. // Extract the first texel at row, col
  364. __glBGRAByteToFloat( &t00, pData );
  365. // Extract remaining texels
  366. rowLen = lp->width2 << 2; // row length in bytes
  367. if( (row < height2m1) &&
  368. (col < width2m1) )
  369. {
  370. // Most common case - the texels are a compact block of 4
  371. // Next texel along row...
  372. __glBGRAByteToFloat( &t10, pData );
  373. // Up to next row...
  374. pData += (rowLen-8);
  375. __glBGRAByteToFloat( &t01, pData );
  376. __glBGRAByteToFloat( &t11, pData );
  377. } else {
  378. // Exceptional case : one or both of row, col are on edge
  379. GLint rowInc, colInc; // increments in bytes
  380. // Calc increments to next texel along row/col
  381. if( col < width2m1 )
  382. rowInc = 4;
  383. else
  384. // increment to left edge
  385. rowInc = -(rowLen - 4);
  386. if( row < height2m1 )
  387. // increment by row length
  388. colInc = rowLen;
  389. else
  390. // increment to lower edge
  391. colInc = - height2m1 * rowLen;
  392. // Next texel along row
  393. pData = image + rowInc;
  394. __glBGRAByteToFloat( &t10, pData );
  395. // Second row, first texel
  396. pData = image + colInc;
  397. __glBGRAByteToFloat( &t01, pData );
  398. // Next texel along row
  399. pData += (rowInc - 4);
  400. __glBGRAByteToFloat( &t11, pData );
  401. }
  402. omalpha = __glOne - alpha;
  403. ombeta = __glOne - beta;
  404. m00 = omalpha * ombeta;
  405. m10 = alpha * ombeta;
  406. m01 = omalpha * beta;
  407. m11 = alpha * beta;
  408. result->r = m00*t00.r + m10*t10.r + m01*t01.r + m11*t11.r;
  409. result->g = m00*t00.g + m10*t10.g + m01*t01.g + m11*t11.g;
  410. result->b = m00*t00.b + m10*t10.b + m01*t01.b + m11*t11.b;
  411. result->alpha = m00*t00.a + m10*t10.a + m01*t01.a + m11*t11.a;
  412. }
  413. /*
  414. ** Linear min/mag filter
  415. */
  416. void FASTCALL __glLinearFilter(__GLcontext *gc, __GLtexture *tex, __GLfloat lod,
  417. __GLcolor *color, __GLfloat s, __GLfloat t,
  418. __GLtexel *result)
  419. {
  420. #ifdef __GL_LINT
  421. lod = lod;
  422. #endif
  423. (*tex->linear)(gc, tex, &tex->level[0], color, s, t, result);
  424. }
  425. /*
  426. ** Nearest min/mag filter
  427. */
  428. void FASTCALL __glNearestFilter(__GLcontext *gc, __GLtexture *tex, __GLfloat lod,
  429. __GLcolor *color, __GLfloat s, __GLfloat t,
  430. __GLtexel *result)
  431. {
  432. #ifdef __GL_LINT
  433. lod = lod;
  434. #endif
  435. (*tex->nearest)(gc, tex, &tex->level[0], color, s, t, result);
  436. }
  437. /*
  438. ** Apply minification rules to find the texel value.
  439. */
  440. void FASTCALL __glNMNFilter(__GLcontext *gc, __GLtexture *tex, __GLfloat lod,
  441. __GLcolor *color, __GLfloat s, __GLfloat t,
  442. __GLtexel *result)
  443. {
  444. __GLmipMapLevel *lp;
  445. GLint p, d;
  446. if (lod <= ((__GLfloat)0.5)) {
  447. d = 0;
  448. } else {
  449. p = tex->p;
  450. d = FTOL(lod + ((__GLfloat)0.49995)); /* NOTE: .5 minus epsilon */
  451. if (d > p) {
  452. d = p;
  453. }
  454. }
  455. lp = &tex->level[d];
  456. (*tex->nearest)(gc, tex, lp, color, s, t, result);
  457. }
  458. /*
  459. ** Apply minification rules to find the texel value.
  460. */
  461. void FASTCALL __glLMNFilter(__GLcontext *gc, __GLtexture *tex, __GLfloat lod,
  462. __GLcolor *color, __GLfloat s, __GLfloat t,
  463. __GLtexel *result)
  464. {
  465. __GLmipMapLevel *lp;
  466. GLint p, d;
  467. if (lod <= ((__GLfloat) 0.5)) {
  468. d = 0;
  469. } else {
  470. p = tex->p;
  471. d = FTOL(lod + ((__GLfloat) 0.49995)); /* NOTE: .5 minus epsilon */
  472. if (d > p) {
  473. d = p;
  474. }
  475. }
  476. lp = &tex->level[d];
  477. (*tex->linear)(gc, tex, lp, color, s, t, result);
  478. }
  479. /*
  480. ** Apply minification rules to find the texel value.
  481. */
  482. void FASTCALL __glNMLFilter(__GLcontext *gc, __GLtexture *tex, __GLfloat lod,
  483. __GLcolor *color, __GLfloat s, __GLfloat t,
  484. __GLtexel *result)
  485. {
  486. __GLmipMapLevel *lp;
  487. GLint p, d;
  488. __GLtexel td, td1;
  489. __GLfloat f, omf;
  490. p = tex->p;
  491. d = (FTOL(lod)) + 1;
  492. if (d > p || d < 0) {
  493. /* Clamp d to last available mipmap */
  494. lp = &tex->level[p];
  495. (*tex->nearest)(gc, tex, lp, color, s, t, result);
  496. } else {
  497. (*tex->nearest)(gc, tex, &tex->level[d], color, s, t, &td);
  498. (*tex->nearest)(gc, tex, &tex->level[d-1], color, s, t, &td1);
  499. f = __GL_FRAC(lod);
  500. omf = __glOne - f;
  501. switch (tex->level[0].baseFormat) {
  502. case GL_LUMINANCE_ALPHA:
  503. result->alpha = omf * td1.alpha + f * td.alpha;
  504. /* FALLTHROUGH */
  505. case GL_LUMINANCE:
  506. result->luminance = omf * td1.luminance + f * td.luminance;
  507. break;
  508. case GL_RGBA:
  509. result->alpha = omf * td1.alpha + f * td.alpha;
  510. /* FALLTHROUGH */
  511. case GL_RGB:
  512. result->r = omf * td1.r + f * td.r;
  513. result->g = omf * td1.g + f * td.g;
  514. result->b = omf * td1.b + f * td.b;
  515. break;
  516. case GL_ALPHA:
  517. result->alpha = omf * td1.alpha + f * td.alpha;
  518. break;
  519. case GL_INTENSITY:
  520. result->intensity = omf * td1.intensity + f * td.intensity;
  521. break;
  522. }
  523. }
  524. }
  525. /*
  526. ** Apply minification rules to find the texel value.
  527. */
  528. void FASTCALL __glLMLFilter(__GLcontext *gc, __GLtexture *tex, __GLfloat lod,
  529. __GLcolor *color, __GLfloat s, __GLfloat t,
  530. __GLtexel *result)
  531. {
  532. __GLmipMapLevel *lp;
  533. GLint p, d;
  534. __GLtexel td, td1;
  535. __GLfloat f, omf;
  536. p = tex->p;
  537. d = (FTOL(lod)) + 1;
  538. if (d > p || d < 0) {
  539. /* Clamp d to last available mipmap */
  540. lp = &tex->level[p];
  541. (*tex->linear)(gc, tex, lp, color, s, t, result);
  542. } else {
  543. (*tex->linear)(gc, tex, &tex->level[d], color, s, t, &td);
  544. (*tex->linear)(gc, tex, &tex->level[d-1], color, s, t, &td1);
  545. f = __GL_FRAC(lod);
  546. omf = __glOne - f;
  547. switch (tex->level[0].baseFormat) {
  548. case GL_LUMINANCE_ALPHA:
  549. result->alpha = omf * td1.alpha + f * td.alpha;
  550. /* FALLTHROUGH */
  551. case GL_LUMINANCE:
  552. result->luminance = omf * td1.luminance + f * td.luminance;
  553. break;
  554. case GL_RGBA:
  555. result->alpha = omf * td1.alpha + f * td.alpha;
  556. /* FALLTHROUGH */
  557. case GL_RGB:
  558. result->r = omf * td1.r + f * td.r;
  559. result->g = omf * td1.g + f * td.g;
  560. result->b = omf * td1.b + f * td.b;
  561. break;
  562. case GL_ALPHA:
  563. result->alpha = omf * td1.alpha + f * td.alpha;
  564. break;
  565. case GL_INTENSITY:
  566. result->intensity = omf * td1.intensity + f * td.intensity;
  567. break;
  568. }
  569. }
  570. }
  571. /************************************************************************/
  572. __GLfloat __glNopPolygonRho(__GLcontext *gc, const __GLshade *sh,
  573. __GLfloat s, __GLfloat t, __GLfloat winv)
  574. {
  575. #ifdef __GL_LINT
  576. gc = gc;
  577. sh = sh;
  578. s = s;
  579. t = t;
  580. winv = winv;
  581. #endif
  582. return __glZero;
  583. }
  584. /*
  585. ** Compute the "rho" (level of detail) parameter used by the texturing code.
  586. ** Instead of fully computing the derivatives compute nearby texture coordinates
  587. ** and discover the derivative. The incoming s & t arguments have not
  588. ** been divided by winv yet.
  589. */
  590. __GLfloat __glComputePolygonRho(__GLcontext *gc, const __GLshade *sh,
  591. __GLfloat s, __GLfloat t, __GLfloat qw)
  592. {
  593. __GLfloat w0, w1, p0, p1;
  594. __GLfloat pupx, pupy, pvpx, pvpy;
  595. __GLfloat px, py, one;
  596. __GLtexture *tex = gc->texture.currentTexture;
  597. if( qw == (__GLfloat) 0.0 ) {
  598. return (__GLfloat) 0.0;
  599. }
  600. /* Compute partial of u with respect to x */
  601. one = __glOne;
  602. w0 = one / (qw - sh->dqwdx);
  603. w1 = one / (qw + sh->dqwdx);
  604. p0 = (s - sh->dsdx) * w0;
  605. p1 = (s + sh->dsdx) * w1;
  606. pupx = (p1 - p0) * tex->level[0].width2f;
  607. /* Compute partial of v with repsect to y */
  608. p0 = (t - sh->dtdx) * w0;
  609. p1 = (t + sh->dtdx) * w1;
  610. pvpx = (p1 - p0) * tex->level[0].height2f;
  611. /* Compute partial of u with respect to y */
  612. w0 = one / (qw - sh->dqwdy);
  613. w1 = one / (qw + sh->dqwdy);
  614. p0 = (s - sh->dsdy) * w0;
  615. p1 = (s + sh->dsdy) * w1;
  616. pupy = (p1 - p0) * tex->level[0].width2f;
  617. /* Figure partial of u&v with repsect to y */
  618. p0 = (t - sh->dtdy) * w0;
  619. p1 = (t + sh->dtdy) * w1;
  620. pvpy = (p1 - p0) * tex->level[0].height2f;
  621. /* Finally, figure sum of squares */
  622. px = pupx * pupx + pvpx * pvpx;
  623. py = pupy * pupy + pvpy * pvpy;
  624. /* Return largest value as the level of detail */
  625. if (px > py) {
  626. return px * ((__GLfloat) 0.25);
  627. } else {
  628. return py * ((__GLfloat) 0.25);
  629. }
  630. }
  631. __GLfloat __glNopLineRho(__GLcontext *gc, __GLfloat s, __GLfloat t,
  632. __GLfloat wInv)
  633. {
  634. #ifdef __GL_LINT
  635. gc = gc;
  636. s = s;
  637. t = t;
  638. wInv = wInv;
  639. #endif
  640. return __glZero;
  641. }
  642. __GLfloat __glComputeLineRho(__GLcontext *gc, __GLfloat s, __GLfloat t,
  643. __GLfloat wInv)
  644. {
  645. __GLfloat pspx, pspy, ptpx, ptpy;
  646. __GLfloat pupx, pupy, pvpx, pvpy;
  647. __GLfloat temp, pu, pv;
  648. __GLfloat magnitude, invMag, invMag2;
  649. __GLfloat dx, dy;
  650. __GLfloat s0w0, s1w1, t0w0, t1w1, w1Inv, w0Inv;
  651. const __GLvertex *v0 = gc->line.options.v0;
  652. const __GLvertex *v1 = gc->line.options.v1;
  653. /* Compute the length of the line (its magnitude) */
  654. dx = v1->window.x - v0->window.x;
  655. dy = v1->window.y - v0->window.y;
  656. magnitude = __GL_SQRTF(dx*dx + dy*dy);
  657. invMag = __glOne / magnitude;
  658. invMag2 = invMag * invMag;
  659. w0Inv = v0->window.w;
  660. w1Inv = v1->window.w;
  661. s0w0 = v0->texture.x * w0Inv;
  662. t0w0 = v0->texture.y * w0Inv;
  663. s1w1 = v1->texture.x * w1Inv;
  664. t1w1 = v1->texture.y * w1Inv;
  665. /* Compute s partials */
  666. temp = ((s1w1 - s0w0) - s * (w1Inv - w0Inv)) / wInv;
  667. pspx = temp * dx * invMag2;
  668. pspy = temp * dy * invMag2;
  669. /* Compute t partials */
  670. temp = ((t1w1 - t0w0) - t * (w1Inv - w0Inv)) / wInv;
  671. ptpx = temp * dx * invMag2;
  672. ptpy = temp * dy * invMag2;
  673. pupx = pspx * gc->texture.currentTexture->level[0].width2;
  674. pupy = pspy * gc->texture.currentTexture->level[0].width2;
  675. pvpx = ptpx * gc->texture.currentTexture->level[0].height2;
  676. pvpy = ptpy * gc->texture.currentTexture->level[0].height2;
  677. /* Now compute rho */
  678. pu = pupx * dx + pupy * dy;
  679. pu = pu * pu;
  680. pv = pvpx * dx + pvpy * dy;
  681. pv = pv * pv;
  682. return (pu + pv) * invMag2;
  683. }
  684. /************************************************************************/
  685. /*
  686. ** Fast texture a fragment assumes that rho is noise - this is true
  687. ** when no mipmapping is being done and the min and mag filters are
  688. ** the same.
  689. */
  690. void __glFastTextureFragment(__GLcontext *gc, __GLcolor *color,
  691. __GLfloat s, __GLfloat t, __GLfloat rho)
  692. {
  693. __GLtexture *tex = gc->texture.currentTexture;
  694. __GLtexel texel;
  695. #ifdef __GL_LINT
  696. rho = rho;
  697. #endif
  698. (*tex->magnify)(gc, tex, __glZero, color, s, t, &texel);
  699. (*tex->env)(gc, color, &texel);
  700. }
  701. /*
  702. ** Non-mipmapping texturing function.
  703. */
  704. void __glTextureFragment(__GLcontext *gc, __GLcolor *color,
  705. __GLfloat s, __GLfloat t, __GLfloat rho)
  706. {
  707. __GLtexture *tex = gc->texture.currentTexture;
  708. __GLtexel texel;
  709. if (rho <= tex->c) {
  710. (*tex->magnify)(gc, tex, __glZero, color, s, t, &texel);
  711. } else {
  712. (*tex->minnify)(gc, tex, __glZero, color, s, t, &texel);
  713. }
  714. /* Now apply texture environment to get final color */
  715. (*tex->env)(gc, color, &texel);
  716. }
  717. void __glMipMapFragment(__GLcontext *gc, __GLcolor *color,
  718. __GLfloat s, __GLfloat t, __GLfloat rho)
  719. {
  720. __GLtexture *tex = gc->texture.currentTexture;
  721. __GLtexel texel;
  722. /* In the spec c is given in terms of lambda.
  723. ** Here c is compared to rho (really rho^2) and adjusted accordingly.
  724. */
  725. if (rho <= tex->c) {
  726. /* NOTE: rho is ignored by magnify proc */
  727. (*tex->magnify)(gc, tex, rho, color, s, t, &texel);
  728. } else {
  729. if (rho) {
  730. /* Convert rho to lambda */
  731. /* This is an approximation of log base 2 */
  732. // Note that these approximations are inaccurate for rho < 1.0, but
  733. // rho is less than tex->c to get here. Since currently tex->c is
  734. // a constant 1.0, this is not a problem.
  735. // This method directly manipulates the floating point binary
  736. // representation.
  737. #define __GL_FLOAT_EXPONENT_ZERO \
  738. (__GL_FLOAT_EXPONENT_BIAS << __GL_FLOAT_EXPONENT_SHIFT)
  739. unsigned int lrho;
  740. LONG exponent;
  741. ASSERTOPENGL( rho >= 1.0f, "Log base 2 approximation not accurate");
  742. // Extract exponent
  743. lrho = CASTFIX(rho);
  744. exponent = ( (lrho & __GL_FLOAT_EXPONENT_MASK)
  745. >> __GL_FLOAT_EXPONENT_SHIFT )
  746. - __GL_FLOAT_EXPONENT_BIAS;
  747. // Extract fractional part of the floating point number
  748. lrho &= ~__GL_FLOAT_EXPONENT_MASK; // dump current exponent
  749. lrho |= __GL_FLOAT_EXPONENT_ZERO; // zap in zero exponent
  750. // Convert back to float, subtract implicit mantissa 1.0, and
  751. // add the exponent value to yield the approximation.
  752. rho = (CASTFLOAT(lrho) - 1.0f + (__GLfloat) exponent) * 0.5f;
  753. } else {
  754. rho = __glZero;
  755. }
  756. (*tex->minnify)(gc, tex, rho, color, s, t, &texel);
  757. }
  758. /* Now apply texture environment to get final color */
  759. (*tex->env)(gc, color, &texel);
  760. }