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.

189 lines
5.6 KiB

  1. /*
  2. ** Copyright 1991, 1992, 1993, 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. #include "precomp.h"
  18. #pragma hdrstop
  19. /* - Fetch converts GLubyte alpha value to float and puts in __GLcolor
  20. - Likewise, Store does the reverse
  21. - All input coords are viewport biased
  22. */
  23. static void FASTCALL
  24. Store(__GLalphaBuffer *afb, GLint x, GLint y, const __GLcolor *color)
  25. {
  26. GLubyte *pAlpha;
  27. pAlpha = __GL_FB_ADDRESS(afb, (GLubyte*), x, y);
  28. *pAlpha = (GLubyte) FTOL( color->a );
  29. }
  30. static void FASTCALL
  31. StoreSpan(__GLalphaBuffer *afb)
  32. {
  33. GLint w;
  34. GLubyte *pAlpha;
  35. __GLcolor *cp;
  36. __GLcontext *gc = afb->buf.gc;
  37. w = gc->polygon.shader.length;
  38. cp = gc->polygon.shader.colors;
  39. pAlpha = __GL_FB_ADDRESS(afb, (GLubyte*), gc->polygon.shader.frag.x,
  40. gc->polygon.shader.frag.y);
  41. for( ; w ; w--, cp++, pAlpha++ )
  42. *pAlpha = (GLubyte) FTOL( cp->a );
  43. }
  44. // Generic version of StoreSpan
  45. static void FASTCALL
  46. StoreSpan2( __GLalphaBuffer *afb, GLint x, GLint y, GLint w, __GLcolor *cp )
  47. {
  48. GLubyte *pAlpha;
  49. __GLcontext *gc = afb->buf.gc;
  50. pAlpha = __GL_FB_ADDRESS(afb, (GLubyte*), x, y);
  51. for( ; w ; w--, cp++, pAlpha++ )
  52. *pAlpha = (GLubyte) FTOL( cp->a );
  53. }
  54. static void FASTCALL
  55. Fetch(__GLalphaBuffer *afb, GLint x, GLint y, __GLcolor *result)
  56. {
  57. GLubyte *pAlpha;
  58. pAlpha = __GL_FB_ADDRESS(afb, (GLubyte*), x, y);
  59. result->a = (__GLfloat) *pAlpha;
  60. }
  61. static void FASTCALL
  62. ReadSpan(__GLalphaBuffer *afb, GLint x, GLint y, GLint w, __GLcolor *results)
  63. {
  64. GLubyte *pAlpha;
  65. pAlpha = __GL_FB_ADDRESS(afb, (GLubyte*), x, y);
  66. for( ; w ; w--, results++, pAlpha++ )
  67. results->a = (__GLfloat) *pAlpha;
  68. }
  69. static void FASTCALL Clear(__GLalphaBuffer *afb)
  70. {
  71. __GLcontext *gc = afb->buf.gc;
  72. __GLcolor *clear;
  73. BYTE alphaClear;
  74. GLint x0, x1, y0, y1;
  75. int width, height, i;
  76. GLubyte *puj;
  77. // Check if alpha is masked
  78. if( ! gc->state.raster.aMask )
  79. return;
  80. // Get the alpha clear value
  81. clear = &gc->state.raster.clear;
  82. alphaClear = (BYTE) (clear->a*gc->frontBuffer.alphaScale);
  83. // Get area to clear
  84. x0 = __GL_UNBIAS_X(gc, gc->transform.clipX0);
  85. x1 = __GL_UNBIAS_X(gc, gc->transform.clipX1);
  86. y0 = __GL_UNBIAS_Y(gc, gc->transform.clipY0);
  87. y1 = __GL_UNBIAS_Y(gc, gc->transform.clipY1);
  88. width = x1 - x0;
  89. height = y1 - y0;
  90. if( (width <= 0) || (height <= 0) )
  91. return;
  92. puj = (GLubyte *)((ULONG_PTR)afb->buf.base + (y0*afb->buf.outerWidth) + x0 );
  93. if (width == afb->buf.outerWidth) {
  94. // Clearing contiguous buffer
  95. RtlFillMemory( (PVOID) puj, width * height, alphaClear);
  96. return;
  97. }
  98. // Clearing sub-rectangle of buffer
  99. for( i = height; i; i--, puj += afb->buf.outerWidth )
  100. RtlFillMemory( (PVOID) puj, width, alphaClear );
  101. }
  102. void FASTCALL __glInitAlpha(__GLcontext *gc, __GLcolorBuffer *cfb)
  103. {
  104. __GLalphaBuffer *afb = &cfb->alphaBuf;
  105. // The software alpha buffer is 8-bit.
  106. afb->buf.elementSize = sizeof(GLubyte);
  107. afb->store = Store;
  108. afb->storeSpan = StoreSpan;
  109. afb->storeSpan2 = StoreSpan2;
  110. afb->fetch = Fetch;
  111. afb->readSpan = ReadSpan;
  112. afb->clear = Clear;
  113. afb->buf.gc = gc;
  114. afb->alphaScale = cfb->alphaScale;
  115. }
  116. /*
  117. ** Initialize a lookup table that is indexed by the iterated alpha value.
  118. ** The table indicates whether the alpha test passed or failed, based on
  119. ** the current alpha function and the alpha reference value.
  120. **
  121. ** NOTE: The alpha span routines will never be called if the alpha test
  122. ** is GL_ALWAYS (its useless) or if the alpha test is GL_NEVER. This
  123. ** is accomplished in the __glGenericPickSpanProcs procedure.
  124. */
  125. void FASTCALL __glValidateAlphaTest(__GLcontext *gc)
  126. {
  127. GLubyte *atft;
  128. GLint i, limit;
  129. GLint ref;
  130. GLenum alphaTestFunc = gc->state.raster.alphaFunction;
  131. limit = gc->constants.alphaTestSize;
  132. ref = (GLint)
  133. ((gc->state.raster.alphaReference * gc->frontBuffer.alphaScale) *
  134. gc->constants.alphaTableConv);
  135. /*
  136. ** Allocate alpha test function table the first time. It needs
  137. ** to have at most one entry for each possible alpha value.
  138. */
  139. atft = gc->alphaTestFuncTable;
  140. if (!atft) {
  141. atft = (GLubyte*) GCALLOC(gc, (limit) * sizeof(GLubyte));
  142. gc->alphaTestFuncTable = atft;
  143. }
  144. /*
  145. ** Build up alpha test lookup table. The computed alpha value is
  146. ** used as an index into this table to determine if the alpha
  147. ** test passed or failed.
  148. */
  149. for (i = 0; i < limit; i++) {
  150. switch (alphaTestFunc) {
  151. case GL_NEVER: *atft++ = GL_FALSE; break;
  152. case GL_LESS: *atft++ = (GLubyte) (i < ref); break;
  153. case GL_EQUAL: *atft++ = (GLubyte) (i == ref); break;
  154. case GL_LEQUAL: *atft++ = (GLubyte) (i <= ref); break;
  155. case GL_GREATER: *atft++ = (GLubyte) (i > ref); break;
  156. case GL_NOTEQUAL: *atft++ = (GLubyte) (i != ref); break;
  157. case GL_GEQUAL: *atft++ = (GLubyte) (i >= ref); break;
  158. case GL_ALWAYS: *atft++ = GL_TRUE; break;
  159. }
  160. }
  161. }