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.

430 lines
12 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. ** $Revision: 1.21 $
  18. ** $Date: 1993/09/23 16:37:59 $
  19. */
  20. #include "precomp.h"
  21. #pragma hdrstop
  22. void APIPRIVATE __glim_FeedbackBuffer(GLsizei bufferLength, GLenum type, GLfloat buffer[])
  23. {
  24. __GL_SETUP_NOT_IN_BEGIN();
  25. if ((type < GL_2D) || (type > GL_4D_COLOR_TEXTURE)) {
  26. __glSetError(GL_INVALID_ENUM);
  27. return;
  28. }
  29. if (bufferLength < 0) {
  30. __glSetError(GL_INVALID_VALUE);
  31. return;
  32. }
  33. if (gc->renderMode == GL_FEEDBACK) {
  34. __glSetError(GL_INVALID_OPERATION);
  35. return;
  36. }
  37. gc->feedback.resultBase = buffer;
  38. gc->feedback.result = buffer;
  39. gc->feedback.resultLength = bufferLength;
  40. gc->feedback.overFlowed = GL_FALSE;
  41. gc->feedback.type = type;
  42. }
  43. void APIPRIVATE __glim_PassThrough(GLfloat element)
  44. {
  45. __GL_SETUP_NOT_IN_BEGIN();
  46. if (gc->renderMode == GL_FEEDBACK) {
  47. __glFeedbackTag(gc, GL_PASS_THROUGH_TOKEN);
  48. __glFeedbackTag(gc, element);
  49. }
  50. }
  51. /************************************************************************/
  52. void __glFeedbackTag(__GLcontext *gc, GLfloat f)
  53. {
  54. if (!gc->feedback.overFlowed) {
  55. if (gc->feedback.result >=
  56. gc->feedback.resultBase + gc->feedback.resultLength) {
  57. gc->feedback.overFlowed = GL_TRUE;
  58. } else {
  59. gc->feedback.result[0] = f;
  60. gc->feedback.result = gc->feedback.result + 1;
  61. }
  62. }
  63. }
  64. static void FASTCALL feedback(__GLcontext *gc, __GLvertex *v)
  65. {
  66. GLenum type = gc->feedback.type;
  67. #ifdef NT
  68. // Do coordinates
  69. __glFeedbackTag(gc, v->window.x - gc->constants.fviewportXAdjust);
  70. if (gc->constants.yInverted)
  71. __glFeedbackTag(gc, (gc->constants.height -
  72. (v->window.y - gc->constants.fviewportYAdjust)));
  73. else
  74. __glFeedbackTag(gc, v->window.y - gc->constants.fviewportYAdjust);
  75. if (type != GL_2D)
  76. __glFeedbackTag(gc, v->window.z / gc->depthBuffer.scale);
  77. /*
  78. ** NOTE: return clip.w, as window.w has no spec defined meaning.
  79. ** It is true that this implementation uses window.w, but thats
  80. ** something different.
  81. */
  82. if (type == GL_4D_COLOR_TEXTURE)
  83. __glFeedbackTag(gc, v->clip.w);
  84. #else
  85. switch (type) {
  86. case GL_2D:
  87. __glFeedbackTag(gc, v->window.x - gc->constants.fviewportXAdjust);
  88. if (gc->constants.yInverted) {
  89. __glFeedbackTag(gc, (gc->constants.height -
  90. (v->window.y - gc->constants.fviewportYAdjust)) -
  91. gc->constants.viewportEpsilon);
  92. } else {
  93. __glFeedbackTag(gc, v->window.y - gc->constants.fviewportYAdjust);
  94. }
  95. break;
  96. case GL_3D:
  97. case GL_3D_COLOR:
  98. case GL_3D_COLOR_TEXTURE:
  99. __glFeedbackTag(gc, v->window.x - gc->constants.fviewportXAdjust);
  100. if (gc->constants.yInverted) {
  101. __glFeedbackTag(gc, (gc->constants.height -
  102. (v->window.y - gc->constants.fviewportYAdjust)) -
  103. gc->constants.viewportEpsilon);
  104. } else {
  105. __glFeedbackTag(gc, v->window.y - gc->constants.fviewportYAdjust);
  106. }
  107. __glFeedbackTag(gc, v->window.z / gc->depthBuffer.scale);
  108. break;
  109. case GL_4D_COLOR_TEXTURE:
  110. __glFeedbackTag(gc, v->window.x - gc->constants.fviewportXAdjust);
  111. if (gc->constants.yInverted) {
  112. __glFeedbackTag(gc, (gc->constants.height -
  113. (v->window.y - gc->constants.fviewportYAdjust)) -
  114. gc->constants.viewportEpsilon);
  115. } else {
  116. __glFeedbackTag(gc, v->window.y - gc->constants.fviewportYAdjust);
  117. }
  118. __glFeedbackTag(gc, v->window.z / gc->depthBuffer.scale);
  119. /*
  120. ** NOTE: return clip.w, as window.w has no spec defined meaning.
  121. ** It is true that this implementation uses window.w, but thats
  122. ** something different.
  123. */
  124. __glFeedbackTag(gc, v->clip.w);
  125. break;
  126. }
  127. #endif
  128. switch (type) {
  129. case GL_3D_COLOR:
  130. case GL_3D_COLOR_TEXTURE:
  131. case GL_4D_COLOR_TEXTURE:
  132. {
  133. __GLcolor *c = v->color;
  134. if (gc->modes.rgbMode) {
  135. __glFeedbackTag(gc, c->r * gc->oneOverRedVertexScale);
  136. __glFeedbackTag(gc, c->g * gc->oneOverGreenVertexScale);
  137. __glFeedbackTag(gc, c->b * gc->oneOverBlueVertexScale);
  138. __glFeedbackTag(gc, c->a * gc->oneOverAlphaVertexScale);
  139. } else {
  140. __glFeedbackTag(gc, c->r);
  141. }
  142. }
  143. break;
  144. case GL_2D:
  145. case GL_3D:
  146. break;
  147. }
  148. switch (type) {
  149. case GL_3D_COLOR_TEXTURE:
  150. case GL_4D_COLOR_TEXTURE:
  151. __glFeedbackTag(gc, v->texture.x);
  152. __glFeedbackTag(gc, v->texture.y);
  153. __glFeedbackTag(gc, v->texture.z);
  154. __glFeedbackTag(gc, v->texture.w);
  155. break;
  156. case GL_2D:
  157. case GL_3D:
  158. case GL_3D_COLOR:
  159. break;
  160. }
  161. }
  162. void FASTCALL __glFeedbackCopyPixels(__GLcontext *gc, __GLvertex *vx)
  163. {
  164. __glFeedbackTag(gc, GL_COPY_PIXEL_TOKEN);
  165. feedback(gc, vx);
  166. }
  167. void FASTCALL __glFeedbackDrawPixels(__GLcontext *gc, __GLvertex *vx)
  168. {
  169. __glFeedbackTag(gc, GL_DRAW_PIXEL_TOKEN);
  170. feedback(gc, vx);
  171. }
  172. void FASTCALL __glFeedbackBitmap(__GLcontext *gc, __GLvertex *vx)
  173. {
  174. __glFeedbackTag(gc, GL_BITMAP_TOKEN);
  175. feedback(gc, vx);
  176. }
  177. /* feedback version of renderPoint proc */
  178. void FASTCALL __glFeedbackPoint(__GLcontext *gc, __GLvertex *vx)
  179. {
  180. __glFeedbackTag(gc, GL_POINT_TOKEN);
  181. feedback(gc, vx);
  182. }
  183. /* feedback version of renderLine proc */
  184. void FASTCALL __glFeedbackLine(__GLcontext *gc, __GLvertex *a, __GLvertex *b,
  185. GLuint flags)
  186. {
  187. GLuint modeFlags = gc->polygon.shader.modeFlags;
  188. __GLcolor *oacp;
  189. oacp = a->color;
  190. if (!(modeFlags & __GL_SHADE_SMOOTH_LIGHT)
  191. #ifdef GL_WIN_phong_shading
  192. && !(modeFlags & __GL_SHADE_PHONG)
  193. #endif //GL_WIN_phong_shading
  194. ) {
  195. a->color = b->color;
  196. }
  197. if (gc->line.notResetStipple) {
  198. __glFeedbackTag(gc, GL_LINE_TOKEN);
  199. } else {
  200. gc->line.notResetStipple = GL_TRUE;
  201. __glFeedbackTag(gc, GL_LINE_RESET_TOKEN);
  202. }
  203. feedback(gc, a);
  204. feedback(gc, b);
  205. a->color = oacp;
  206. }
  207. /* feedback version of renderTriangle proc */
  208. void FASTCALL __glFeedbackTriangle(__GLcontext *gc, __GLvertex *a, __GLvertex *b,
  209. __GLvertex *c)
  210. {
  211. __GLfloat dxAC, dxBC, dyAC, dyBC, area;
  212. GLboolean ccw;
  213. GLint face;
  214. GLuint modeFlags;
  215. #ifdef SGI
  216. // not used
  217. GLboolean first;
  218. __GLfloat x, y, z, wInv;
  219. __GLfloat vpXScale, vpYScale, vpZScale;
  220. __GLfloat vpXCenter, vpYCenter, vpZCenter;
  221. __GLviewport *vp;
  222. /* Compute window coordinates first, if not already done */
  223. vp = &gc->state.viewport;
  224. vpXCenter = vp->xCenter;
  225. vpYCenter = vp->yCenter;
  226. vpZCenter = vp->zCenter;
  227. vpXScale = vp->xScale;
  228. vpYScale = vp->yScale;
  229. vpZScale = vp->zScale;
  230. #endif
  231. /* Compute signed area of the triangle */
  232. dxAC = a->window.x - c->window.x;
  233. dxBC = b->window.x - c->window.x;
  234. dyAC = a->window.y - c->window.y;
  235. dyBC = b->window.y - c->window.y;
  236. area = dxAC * dyBC - dxBC * dyAC;
  237. ccw = area >= __glZero;
  238. /*
  239. ** Figure out if face is culled or not. The face check needs to be
  240. ** based on the vertex winding before sorting. This code uses the
  241. ** reversed flag to invert the sense of ccw - an xor accomplishes
  242. ** this conversion without an if test.
  243. **
  244. ** ccw reversed xor
  245. ** --- -------- ---
  246. ** 0 0 0 (remain !ccw)
  247. ** 1 0 1 (remain ccw)
  248. ** 0 1 1 (become ccw)
  249. ** 1 1 0 (become cw)
  250. */
  251. face = gc->polygon.face[ccw];
  252. if (face == gc->polygon.cullFace) {
  253. /* Culled */
  254. return;
  255. }
  256. #ifdef NT
  257. /*
  258. ** Pick face to use for coloring
  259. */
  260. modeFlags = gc->polygon.shader.modeFlags;
  261. if (modeFlags & __GL_SHADE_SMOOTH_LIGHT)
  262. { /* Smooth shading */
  263. if (modeFlags & __GL_SHADE_TWOSIDED && face == __GL_BACKFACE)
  264. {
  265. a->color++;
  266. b->color++;
  267. c->color++;
  268. }
  269. }
  270. else
  271. { /* Flat shading */
  272. __GLvertex *pv = gc->vertex.provoking;
  273. if (modeFlags & __GL_SHADE_TWOSIDED && face == __GL_BACKFACE)
  274. pv->color++;
  275. a->color = pv->color;
  276. b->color = pv->color;
  277. c->color = pv->color;
  278. }
  279. #else
  280. /*
  281. ** Pick face to use for coloring
  282. */
  283. modeFlags = gc->polygon.shader.modeFlags;
  284. needs = gc->vertex.needs;
  285. if (gc->state.light.shadingModel == GL_FLAT) {
  286. __GLvertex *pv = gc->vertex.provoking;
  287. GLuint pvneeds;
  288. GLuint faceNeeds;
  289. GLint colorFace;
  290. if (modeFlags & __GL_SHADE_TWOSIDED) {
  291. colorFace = face;
  292. faceNeeds = gc->vertex.faceNeeds[face];
  293. } else {
  294. colorFace = __GL_FRONTFACE;
  295. faceNeeds = gc->vertex.faceNeeds[__GL_FRONTFACE];
  296. }
  297. pv->color = &pv->colors[colorFace];
  298. a->color = pv->color;
  299. b->color = pv->color;
  300. c->color = pv->color;
  301. pvneeds = faceNeeds & (__GL_HAS_LIGHTING |
  302. __GL_HAS_FRONT_COLOR | __GL_HAS_BACK_COLOR);
  303. if (~pv->has & pvneeds) {
  304. (*pv->validate)(gc, pv, pvneeds);
  305. }
  306. } else {
  307. GLuint faceNeeds;
  308. GLint colorFace;
  309. if (modeFlags & __GL_SHADE_TWOSIDED) {
  310. colorFace = face;
  311. needs |= gc->vertex.faceNeeds[face];
  312. } else {
  313. colorFace = __GL_FRONTFACE;
  314. needs |= gc->vertex.faceNeeds[__GL_FRONTFACE];
  315. }
  316. a->color = &a->colors[colorFace];
  317. b->color = &b->colors[colorFace];
  318. c->color = &c->colors[colorFace];
  319. }
  320. if (~a->has & needs) (*a->validate)(gc, a, needs);
  321. if (~b->has & needs) (*b->validate)(gc, b, needs);
  322. if (~c->has & needs) (*c->validate)(gc, c, needs);
  323. #endif
  324. /* Deal with polygon face modes */
  325. switch (gc->polygon.mode[face]) {
  326. case __GL_POLYGON_MODE_POINT:
  327. #ifdef NT
  328. if (a->has & __GL_HAS_EDGEFLAG_BOUNDARY) __glFeedbackPoint(gc, a);
  329. if (b->has & __GL_HAS_EDGEFLAG_BOUNDARY) __glFeedbackPoint(gc, b);
  330. if (c->has & __GL_HAS_EDGEFLAG_BOUNDARY) __glFeedbackPoint(gc, c);
  331. break;
  332. #else
  333. if (a->boundaryEdge) {
  334. __glFeedbackTag(gc, GL_POINT_TOKEN);
  335. feedback(gc, a);
  336. }
  337. if (b->boundaryEdge) {
  338. __glFeedbackTag(gc, GL_POINT_TOKEN);
  339. feedback(gc, b);
  340. }
  341. if (c->boundaryEdge) {
  342. __glFeedbackTag(gc, GL_POINT_TOKEN);
  343. feedback(gc, c);
  344. }
  345. break;
  346. #endif
  347. case __GL_POLYGON_MODE_LINE:
  348. #ifdef NT
  349. if (a->has & __GL_HAS_EDGEFLAG_BOUNDARY) __glFeedbackLine(gc, a, b, 0);
  350. if (b->has & __GL_HAS_EDGEFLAG_BOUNDARY) __glFeedbackLine(gc, b, c, 0);
  351. if (c->has & __GL_HAS_EDGEFLAG_BOUNDARY) __glFeedbackLine(gc, c, a, 0);
  352. break;
  353. #else
  354. if (a->boundaryEdge) {
  355. if (!gc->line.notResetStipple) {
  356. gc->line.notResetStipple = GL_TRUE;
  357. __glFeedbackTag(gc, GL_LINE_RESET_TOKEN);
  358. } else {
  359. __glFeedbackTag(gc, GL_LINE_TOKEN);
  360. }
  361. feedback(gc, a);
  362. feedback(gc, b);
  363. }
  364. if (b->boundaryEdge) {
  365. if (!gc->line.notResetStipple) {
  366. gc->line.notResetStipple = GL_TRUE;
  367. __glFeedbackTag(gc, GL_LINE_RESET_TOKEN);
  368. } else {
  369. __glFeedbackTag(gc, GL_LINE_TOKEN);
  370. }
  371. feedback(gc, b);
  372. feedback(gc, c);
  373. }
  374. if (c->boundaryEdge) {
  375. if (!gc->line.notResetStipple) {
  376. gc->line.notResetStipple = GL_TRUE;
  377. __glFeedbackTag(gc, GL_LINE_RESET_TOKEN);
  378. } else {
  379. __glFeedbackTag(gc, GL_LINE_TOKEN);
  380. }
  381. feedback(gc, c);
  382. feedback(gc, a);
  383. }
  384. break;
  385. #endif
  386. case __GL_POLYGON_MODE_FILL:
  387. __glFeedbackTag(gc, GL_POLYGON_TOKEN);
  388. __glFeedbackTag(gc, 3);
  389. feedback(gc, a);
  390. feedback(gc, b);
  391. feedback(gc, c);
  392. break;
  393. }
  394. /* Restore color pointers */
  395. a->color = &a->colors[__GL_FRONTFACE];
  396. b->color = &b->colors[__GL_FRONTFACE];
  397. c->color = &c->colors[__GL_FRONTFACE];
  398. if (gc->state.light.shadingModel == GL_FLAT) {
  399. __GLvertex *pv = gc->vertex.provoking;
  400. pv->color = &pv->colors[__GL_FRONTFACE];
  401. }
  402. }