ReactOS  0.4.14-dev-50-g13bb5e2
span.c
Go to the documentation of this file.
1 /* $Id: span.c,v 1.12 1997/08/14 01:12:37 brianp Exp $ */
2 
3 /*
4  * Mesa 3-D graphics library
5  * Version: 2.4
6  * Copyright (C) 1995-1997 Brian Paul
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22 
23 
24 /*
25  * $Log: span.c,v $
26  * Revision 1.12 1997/08/14 01:12:37 brianp
27  * replaced a few for loops with MEMSET calls
28  *
29  * Revision 1.11 1997/07/24 01:21:56 brianp
30  * changed precompiled header symbol from PCH to PC_HEADER
31  *
32  * Revision 1.10 1997/05/28 03:26:29 brianp
33  * added precompiled header (PCH) support
34  *
35  * Revision 1.9 1997/05/03 00:51:30 brianp
36  * new texturing function call: gl_texture_pixels()
37  *
38  * Revision 1.8 1997/04/16 23:54:11 brianp
39  * do per-pixel fog if texturing is enabled
40  *
41  * Revision 1.7 1997/02/09 19:53:43 brianp
42  * now use TEXTURE_xD enable constants
43  *
44  * Revision 1.6 1997/02/09 18:43:34 brianp
45  * added GL_EXT_texture3D support
46  *
47  * Revision 1.5 1997/01/28 22:17:44 brianp
48  * new RGBA mode logic op support
49  *
50  * Revision 1.4 1996/09/25 03:22:05 brianp
51  * added NO_DRAW_BIT support
52  *
53  * Revision 1.3 1996/09/15 14:18:55 brianp
54  * now use GLframebuffer and GLvisual
55  *
56  * Revision 1.2 1996/09/15 01:48:58 brianp
57  * removed #define NULL 0
58  *
59  * Revision 1.1 1996/09/13 01:38:16 brianp
60  * Initial revision
61  *
62  */
63 
64 
65 /*
66  * pixel span rasterization:
67  * These functions simulate the rasterization pipeline.
68  */
69 
70 
71 #ifdef PC_HEADER
72 #include "all.h"
73 #else
74 #include <string.h>
75 #include "alpha.h"
76 #include "alphabuf.h"
77 #include "blend.h"
78 #include "depth.h"
79 #include "fog.h"
80 #include "logic.h"
81 #include "macros.h"
82 #include "masking.h"
83 #include "scissor.h"
84 #include "span.h"
85 #include "stencil.h"
86 #include "texture.h"
87 #include "types.h"
88 #endif
89 
90 
91 
92 
93 /*
94  * Apply the current polygon stipple pattern to a span of pixels.
95  */
96 static void stipple_polygon_span( GLcontext *ctx,
97  GLuint n, GLint x, GLint y, GLubyte mask[] )
98 {
99  register GLuint i, m, stipple, highbit=0x80000000;
100 
101  stipple = ctx->PolygonStipple[y % 32];
102  m = highbit >> (GLuint) (x % 32);
103 
104  for (i=0;i<n;i++) {
105  if ((m & stipple)==0) {
106  mask[i] = 0;
107  }
108  m = m >> 1;
109  if (m==0) {
110  m = 0x80000000;
111  }
112  }
113 }
114 
115 
116 
117 /*
118  * Clip a pixel span to the current buffer/window boundaries.
119  * Return: 0 = all pixels clipped
120  * 1 = at least one pixel is visible
121  */
123  GLint n, GLint x, GLint y, GLubyte mask[] )
124 {
125  GLint i;
126 
127  /* Clip to top and bottom */
128  if (y<0 || y>=ctx->Buffer->Height) {
129  return 0;
130  }
131 
132  /* Clip to left and right */
133  if (x>=0 && x+n<=ctx->Buffer->Width) {
134  /* no clipping needed */
135  return 1;
136  }
137  else if (x+n<=0) {
138  /* completely off left side */
139  return 0;
140  }
141  else if (x>=ctx->Buffer->Width) {
142  /* completely off right side */
143  return 0;
144  }
145  else {
146  /* clip-test each pixel, this could be done better */
147  for (i=0;i<n;i++) {
148  if (x+i<0 || x+i>=ctx->Buffer->Width) {
149  mask[i] = 0;
150  }
151  }
152  return 1;
153  }
154 }
155 
156 
157 
158 /*
159  * Write a horizontal span of color index pixels to the frame buffer.
160  * Stenciling, Depth-testing, etc. are done as needed.
161  * Input: n - number of pixels in the span
162  * x, y - location of leftmost pixel in the span
163  * z - array of [n] z-values
164  * index - array of [n] color indexes
165  * primitive - either GL_POINT, GL_LINE, GL_POLYGON, or GL_BITMAP
166  */
168  GLuint n, GLint x, GLint y, GLdepth z[],
169  GLuint index[], GLenum primitive )
170 {
172  GLuint index_save[MAX_WIDTH];
173 
174  /* init mask to 1's (all pixels are to be written) */
175  MEMSET(mask, 1, n);
176 
177  if ((ctx->RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
178  if (clip_span(ctx,n,x,y,mask)==0) {
179  return;
180  }
181  }
182 
183  /* Per-pixel fog */
184  if (ctx->Fog.Enabled
185  && (ctx->Hint.Fog==GL_NICEST || primitive==GL_BITMAP)) {
186  gl_fog_index_pixels( ctx, n, z, index );
187  }
188 
189  /* Do the scissor test */
190  if (ctx->Scissor.Enabled) {
191  if (gl_scissor_span( ctx, n, x, y, mask )==0) {
192  return;
193  }
194  }
195 
196  /* Polygon Stippling */
197  if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) {
198  stipple_polygon_span( ctx, n, x, y, mask );
199  }
200 
201  if (ctx->Stencil.Enabled) {
202  /* first stencil test */
203  if (gl_stencil_span( ctx, n, x, y, mask )==0) {
204  return;
205  }
206  /* depth buffering w/ stencil */
207  gl_depth_stencil_span( ctx, n, x, y, z, mask );
208  }
209  else if (ctx->Depth.Test) {
210  /* regular depth testing */
211  if ((*ctx->Driver.DepthTestSpan)( ctx, n, x, y, z, mask )==0) return;
212  }
213 
214  if (ctx->RasterMask & NO_DRAW_BIT) {
215  /* write no pixels */
216  return;
217  }
218 
219  if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
220  /* Save a copy of the indexes since LogicOp and IndexMask
221  * may change them
222  */
223  MEMCPY( index_save, index, n * sizeof(GLuint) );
224  }
225 
226  if (ctx->Color.SWLogicOpEnabled) {
227  gl_logicop_ci_span( ctx, n, x, y, index, mask );
228  }
229  if (ctx->Color.SWmasking) {
230  gl_mask_index_span( ctx, n, x, y, index );
231  }
232 
233  /* write pixels */
234  (*ctx->Driver.WriteIndexSpan)( ctx, n, x, y, index, mask );
235 
236 
237  if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
238  /*** Also draw to back buffer ***/
239  (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
240  MEMCPY( index, index_save, n * sizeof(GLuint) );
241  if (ctx->Color.SWLogicOpEnabled) {
242  gl_logicop_ci_span( ctx, n, x, y, index, mask );
243  }
244  if (ctx->Color.SWmasking) {
245  gl_mask_index_span( ctx, n, x, y, index );
246  }
247  (*ctx->Driver.WriteIndexSpan)( ctx, n, x, y, index, mask );
248  (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
249  }
250 }
251 
252 
253 
254 
256  GLuint n, GLint x, GLint y, GLdepth z[],
257  GLuint index, GLenum primitive )
258 {
259  GLuint i;
261  GLuint index_save[MAX_WIDTH];
262 
263  /* init mask to 1's (all pixels are to be written) */
264  MEMSET(mask, 1, n);
265 
266  if ((ctx->RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP)
267  {
268  if (clip_span( ctx,n,x,y,mask)==0) {
269  return;
270  }
271  }
272 
273  /* Do the scissor test */
274  if (ctx->Scissor.Enabled)
275  {
276  if (gl_scissor_span( ctx, n, x, y, mask )==0) {
277  return;
278  }
279  }
280 
281  /* Polygon Stippling */
282  if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON)
283  {
284  stipple_polygon_span( ctx, n, x, y, mask );
285  }
286 
287  if (ctx->Stencil.Enabled)
288  {
289  /* first stencil test */
290  if (gl_stencil_span( ctx, n, x, y, mask )==0)
291  {
292  return;
293  }
294  /* depth buffering w/ stencil */
295  gl_depth_stencil_span( ctx, n, x, y, z, mask );
296  }
297  else if (ctx->Depth.Test)
298  {
299  /* regular depth testing */
300  if ((*ctx->Driver.DepthTestSpan)( ctx, n, x, y, z, mask )==0)
301  return;
302  }
303 
304  if (ctx->RasterMask & NO_DRAW_BIT)
305  {
306  /* write no pixels */
307  return;
308  }
309 
310  if ((ctx->Fog.Enabled && (ctx->Hint.Fog==GL_NICEST || primitive==GL_BITMAP))
311  || ctx->Color.SWLogicOpEnabled || ctx->Color.SWmasking)
312  {
313  GLuint ispan[MAX_WIDTH];
314  /* index may change, replicate single index into an array */
315  for (i=0;i<n;i++)
316  {
317  ispan[i] = index;
318  }
319 
320  if (ctx->Fog.Enabled
321  && (ctx->Hint.Fog==GL_NICEST || primitive==GL_BITMAP))
322  {
323  gl_fog_index_pixels( ctx, n, z, ispan );
324  }
325 
326  if (ctx->RasterMask & FRONT_AND_BACK_BIT)
327  {
328  MEMCPY( index_save, ispan, n * sizeof(GLuint) );
329  }
330 
331  if (ctx->Color.SWLogicOpEnabled)
332  {
333  gl_logicop_ci_span( ctx, n, x, y, ispan, mask );
334  }
335 
336  if (ctx->Color.SWmasking)
337  {
338  gl_mask_index_span( ctx, n, x, y, ispan );
339  }
340 
341  (*ctx->Driver.WriteIndexSpan)( ctx, n, x, y, ispan, mask );
342 
343  if (ctx->RasterMask & FRONT_AND_BACK_BIT)
344  {
345  /*** Also draw to back buffer ***/
346  (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
347  for (i=0;i<n;i++)
348  {
349  ispan[i] = index;
350  }
351 
352  if (ctx->Color.SWLogicOpEnabled) {
353  gl_logicop_ci_span( ctx, n, x, y, ispan, mask );
354  }
355  if (ctx->Color.SWmasking) {
356  gl_mask_index_span( ctx, n, x, y, ispan );
357  }
358  (*ctx->Driver.WriteIndexSpan)( ctx, n, x, y, ispan, mask );
359  (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
360  }
361  }
362  else
363  {
364  (*ctx->Driver.WriteMonoindexSpan)( ctx, n, x, y, mask );
365 
366  if (ctx->RasterMask & FRONT_AND_BACK_BIT)
367  {
368  /*** Also draw to back buffer ***/
369  (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
370  (*ctx->Driver.WriteMonoindexSpan)( ctx, n, x, y, mask );
371  (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
372  }
373  }
374 }
375 
376 
377 
379  GLuint n, GLint x, GLint y, GLdepth z[],
380  GLubyte r[], GLubyte g[],
381  GLubyte b[], GLubyte a[],
382  GLenum primitive )
383 {
385  GLboolean write_all = GL_TRUE;
386  GLubyte rtmp[MAX_WIDTH], gtmp[MAX_WIDTH], btmp[MAX_WIDTH], atmp[MAX_WIDTH];
387  GLubyte *red, *green, *blue, *alpha;
388 
389  /* init mask to 1's (all pixels are to be written) */
390  MEMSET(mask, 1, n);
391 
392  if ((ctx->RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
393  if (clip_span( ctx,n,x,y,mask)==0) {
394  return;
395  }
396  write_all = GL_FALSE;
397  }
398 
399  if ((primitive==GL_BITMAP && ctx->MutablePixels)
400  || (ctx->RasterMask & FRONT_AND_BACK_BIT)) {
401  /* must make a copy of the colors since they may be modified */
402  MEMCPY( rtmp, r, n * sizeof(GLubyte) );
403  MEMCPY( gtmp, g, n * sizeof(GLubyte) );
404  MEMCPY( btmp, b, n * sizeof(GLubyte) );
405  MEMCPY( atmp, a, n * sizeof(GLubyte) );
406  red = rtmp;
407  green = gtmp;
408  blue = btmp;
409  alpha = atmp;
410  }
411  else {
412  red = r;
413  green = g;
414  blue = b;
415  alpha = a;
416  }
417 
418  /* Per-pixel fog */
419  if (ctx->Fog.Enabled && (ctx->Hint.Fog==GL_NICEST || primitive==GL_BITMAP
420  || ctx->Texture.Enabled)) {
421  gl_fog_color_pixels( ctx, n, z, red, green, blue, alpha );
422  }
423 
424  /* Do the scissor test */
425  if (ctx->Scissor.Enabled) {
426  if (gl_scissor_span( ctx, n, x, y, mask )==0) {
427  return;
428  }
429  write_all = GL_FALSE;
430  }
431 
432  /* Polygon Stippling */
433  if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) {
434  stipple_polygon_span( ctx, n, x, y, mask );
435  write_all = GL_FALSE;
436  }
437 
438  /* Do the alpha test */
439  if (ctx->Color.AlphaEnabled) {
440  if (gl_alpha_test( ctx, n, alpha, mask )==0) {
441  return;
442  }
443  write_all = GL_FALSE;
444  }
445 
446  if (ctx->Stencil.Enabled) {
447  /* first stencil test */
448  if (gl_stencil_span( ctx, n, x, y, mask )==0) {
449  return;
450  }
451  /* depth buffering w/ stencil */
452  gl_depth_stencil_span( ctx, n, x, y, z, mask );
453  write_all = GL_FALSE;
454  }
455  else if (ctx->Depth.Test) {
456  /* regular depth testing */
457  GLuint m = (*ctx->Driver.DepthTestSpan)( ctx, n, x, y, z, mask );
458  if (m==0) {
459  return;
460  }
461  if (m<n) {
462  write_all = GL_FALSE;
463  }
464  }
465 
466  if (ctx->RasterMask & NO_DRAW_BIT) {
467  /* write no pixels */
468  return;
469  }
470 
471  /* logic op or blending */
472  if (ctx->Color.SWLogicOpEnabled) {
473  gl_logicop_rgba_span( ctx, n, x, y, red, green, blue, alpha, mask );
474  }
475  else if (ctx->Color.BlendEnabled) {
476  gl_blend_span( ctx, n, x, y, red, green, blue, alpha, mask );
477  }
478 
479  /* Color component masking */
480  if (ctx->Color.SWmasking) {
481  gl_mask_color_span( ctx, n, x, y, red, green, blue, alpha );
482  }
483 
484  /* write pixels */
485  (*ctx->Driver.WriteColorSpan)( ctx, n, x, y, red, green, blue, alpha,
486  write_all ? NULL : mask );
487  if (ctx->RasterMask & ALPHABUF_BIT) {
488  gl_write_alpha_span( ctx, n, x, y, alpha, write_all ? NULL : mask );
489  }
490 
491  if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
492  /*** Also render to back buffer ***/
493  MEMCPY( rtmp, r, n * sizeof(GLubyte) );
494  MEMCPY( gtmp, g, n * sizeof(GLubyte) );
495  MEMCPY( btmp, b, n * sizeof(GLubyte) );
496  MEMCPY( atmp, a, n * sizeof(GLubyte) );
497  (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
498  if (ctx->Color.SWLogicOpEnabled) {
499  gl_logicop_rgba_span( ctx, n, x, y, red, green, blue, alpha, mask );
500  }
501  else if (ctx->Color.BlendEnabled) {
502  gl_blend_span( ctx, n, x, y, red, green, blue, alpha, mask );
503  }
504  if (ctx->Color.SWmasking) {
505  gl_mask_color_span( ctx, n, x, y, red, green, blue, alpha );
506  }
507  (*ctx->Driver.WriteColorSpan)( ctx, n, x, y, red, green, blue, alpha,
508  write_all ? NULL : mask );
509  if (ctx->RasterMask & ALPHABUF_BIT) {
510  ctx->Buffer->Alpha = ctx->Buffer->BackAlpha;
511  gl_write_alpha_span( ctx, n, x, y, alpha, write_all ? NULL : mask );
512  ctx->Buffer->Alpha = ctx->Buffer->FrontAlpha;
513  }
514  (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
515  }
516 
517 }
518 
519 
520 
521 /*
522  * Write a horizontal span of color pixels to the frame buffer.
523  * The color is initially constant for the whole span.
524  * Alpha-testing, stenciling, depth-testing, and blending are done as needed.
525  * Input: n - number of pixels in the span
526  * x, y - location of leftmost pixel in the span
527  * z - array of [n] z-values
528  * r, g, b, a - the color of the pixels
529  * primitive - either GL_POINT, GL_LINE, GL_POLYGON or GL_BITMAP.
530  */
532  GLuint n, GLint x, GLint y, GLdepth z[],
533  GLint r, GLint g, GLint b, GLint a,
534  GLenum primitive )
535 {
536  GLuint i;
538  GLboolean write_all = GL_TRUE;
540 
541  /* init mask to 1's (all pixels are to be written) */
542  MEMSET(mask, 1, n);
543 
544  if ((ctx->RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
545  if (clip_span( ctx,n,x,y,mask)==0) {
546  return;
547  }
548  write_all = GL_FALSE;
549  }
550 
551  /* Do the scissor test */
552  if (ctx->Scissor.Enabled) {
553  if (gl_scissor_span( ctx, n, x, y, mask )==0) {
554  return;
555  }
556  write_all = GL_FALSE;
557  }
558 
559  /* Polygon Stippling */
560  if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) {
561  stipple_polygon_span( ctx, n, x, y, mask );
562  write_all = GL_FALSE;
563  }
564 
565  /* Do the alpha test */
566  if (ctx->Color.AlphaEnabled) {
568  for (i=0;i<n;i++) {
569  alpha[i] = a;
570  }
571  if (gl_alpha_test( ctx, n, alpha, mask )==0) {
572  return;
573  }
574  write_all = GL_FALSE;
575  }
576 
577  if (ctx->Stencil.Enabled) {
578  /* first stencil test */
579  if (gl_stencil_span( ctx, n, x, y, mask )==0) {
580  return;
581  }
582  /* depth buffering w/ stencil */
583  gl_depth_stencil_span( ctx, n, x, y, z, mask );
584  write_all = GL_FALSE;
585  }
586  else if (ctx->Depth.Test) {
587  /* regular depth testing */
588  GLuint m = (*ctx->Driver.DepthTestSpan)( ctx, n, x, y, z, mask );
589  if (m==0) {
590  return;
591  }
592  if (m<n) {
593  write_all = GL_FALSE;
594  }
595  }
596 
597  if (ctx->RasterMask & NO_DRAW_BIT) {
598  /* write no pixels */
599  return;
600  }
601 
602  if (ctx->Color.BlendEnabled || ctx->Color.SWLogicOpEnabled
603  || ctx->Color.SWmasking) {
604  /* assign same color to each pixel */
605  for (i=0;i<n;i++) {
606  if (mask[i]) {
607  red[i] = r;
608  green[i] = g;
609  blue[i] = b;
610  alpha[i] = a;
611  }
612  }
613 
614  if (ctx->Color.SWLogicOpEnabled) {
615  gl_logicop_rgba_span( ctx, n, x, y, red, green, blue, alpha, mask );
616  }
617  else if (ctx->Color.BlendEnabled) {
618  gl_blend_span( ctx, n, x, y, red, green, blue, alpha, mask );
619  }
620 
621  /* Color component masking */
622  if (ctx->Color.SWmasking) {
623  gl_mask_color_span( ctx, n, x, y, red, green, blue, alpha );
624  }
625 
626  /* write pixels */
627  (*ctx->Driver.WriteColorSpan)( ctx, n, x, y, red, green, blue, alpha,
628  write_all ? NULL : mask );
629  if (ctx->RasterMask & ALPHABUF_BIT) {
630  gl_write_alpha_span( ctx, n, x, y, alpha, write_all ? NULL : mask );
631  }
632 
633  if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
634  /*** Also draw to back buffer ***/
635  for (i=0;i<n;i++) {
636  if (mask[i]) {
637  red[i] = r;
638  green[i] = g;
639  blue[i] = b;
640  alpha[i] = a;
641  }
642  }
643  (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
644  if (ctx->Color.SWLogicOpEnabled) {
645  gl_logicop_rgba_span( ctx, n, x, y, red, green, blue, alpha, mask);
646  }
647  else if (ctx->Color.BlendEnabled) {
648  gl_blend_span( ctx, n, x, y, red, green, blue, alpha, mask );
649  }
650  if (ctx->Color.SWmasking) {
651  gl_mask_color_span( ctx, n, x, y, red, green, blue, alpha );
652  }
653  (*ctx->Driver.WriteColorSpan)( ctx, n, x, y, red, green, blue, alpha,
654  write_all ? NULL : mask );
655  (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
656  if (ctx->RasterMask & ALPHABUF_BIT) {
657  ctx->Buffer->Alpha = ctx->Buffer->BackAlpha;
658  gl_write_alpha_span( ctx, n, x, y, alpha,
659  write_all ? NULL : mask );
660  ctx->Buffer->Alpha = ctx->Buffer->FrontAlpha;
661  }
662  }
663  }
664  else {
665  (*ctx->Driver.WriteMonocolorSpan)( ctx, n, x, y, mask );
666  if (ctx->RasterMask & ALPHABUF_BIT) {
667  gl_write_mono_alpha_span( ctx, n, x, y, a, write_all ? NULL : mask );
668  }
669  if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
670  /* Also draw to back buffer */
671  (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
672  (*ctx->Driver.WriteMonocolorSpan)( ctx, n, x, y, mask );
673  (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
674  if (ctx->RasterMask & ALPHABUF_BIT) {
675  ctx->Buffer->Alpha = ctx->Buffer->BackAlpha;
676  gl_write_mono_alpha_span( ctx, n, x, y, a,
677  write_all ? NULL : mask );
678  ctx->Buffer->Alpha = ctx->Buffer->FrontAlpha;
679  }
680  }
681  }
682 }
683 
684 
685 
686 /*
687  * Write a horizontal span of textured pixels to the frame buffer.
688  * The color of each pixel is different.
689  * Alpha-testing, stenciling, depth-testing, and blending are done
690  * as needed.
691  * Input: n - number of pixels in the span
692  * x, y - location of leftmost pixel in the span
693  * z - array of [n] z-values
694  * s, t - array of (s,t) texture coordinates for each pixel
695  * lambda - array of texture lambda values
696  * red, green, blue, alpha - array of [n] color components
697  * primitive - either GL_POINT, GL_LINE, GL_POLYGON or GL_BITMAP.
698  */
700  GLuint n, GLint x, GLint y, GLdepth z[],
701  GLfloat s[], GLfloat t[], GLfloat u[],
702  GLfloat lambda[],
703  GLubyte r[], GLubyte g[],
704  GLubyte b[], GLubyte a[],
705  GLenum primitive )
706 {
708  GLboolean write_all = GL_TRUE;
709  GLubyte rtmp[MAX_WIDTH], gtmp[MAX_WIDTH], btmp[MAX_WIDTH], atmp[MAX_WIDTH];
710  GLubyte *red, *green, *blue, *alpha;
711 
712  /* init mask to 1's (all pixels are to be written) */
713  MEMSET(mask, 1, n);
714 
715  if ((ctx->RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
716  if (clip_span( ctx,n,x,y,mask)==0) {
717  return;
718  }
719  write_all = GL_FALSE;
720  }
721 
722 
723  if (primitive==GL_BITMAP || (ctx->RasterMask & FRONT_AND_BACK_BIT)) {
724  /* must make a copy of the colors since they may be modified */
725  MEMCPY( rtmp, r, n * sizeof(GLubyte) );
726  MEMCPY( gtmp, g, n * sizeof(GLubyte) );
727  MEMCPY( btmp, b, n * sizeof(GLubyte) );
728  MEMCPY( atmp, a, n * sizeof(GLubyte) );
729  red = rtmp;
730  green = gtmp;
731  blue = btmp;
732  alpha = atmp;
733  }
734  else {
735  red = r;
736  green = g;
737  blue = b;
738  alpha = a;
739  }
740 
741  /* Texture */
742  ASSERT(ctx->Texture.Enabled);
743  gl_texture_pixels( ctx, n, s, t, u, lambda, red, green, blue, alpha );
744 
745  /* Per-pixel fog */
746  if (ctx->Fog.Enabled && (ctx->Hint.Fog==GL_NICEST || primitive==GL_BITMAP
747  || ctx->Texture.Enabled)) {
748  gl_fog_color_pixels( ctx, n, z, red, green, blue, alpha );
749  }
750 
751  /* Do the scissor test */
752  if (ctx->Scissor.Enabled) {
753  if (gl_scissor_span( ctx, n, x, y, mask )==0) {
754  return;
755  }
756  write_all = GL_FALSE;
757  }
758 
759  /* Polygon Stippling */
760  if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) {
761  stipple_polygon_span( ctx, n, x, y, mask );
762  write_all = GL_FALSE;
763  }
764 
765  /* Do the alpha test */
766  if (ctx->Color.AlphaEnabled) {
767  if (gl_alpha_test( ctx, n, alpha, mask )==0) {
768  return;
769  }
770  write_all = GL_FALSE;
771  }
772 
773  if (ctx->Stencil.Enabled) {
774  /* first stencil test */
775  if (gl_stencil_span( ctx, n, x, y, mask )==0) {
776  return;
777  }
778  /* depth buffering w/ stencil */
779  gl_depth_stencil_span( ctx, n, x, y, z, mask );
780  write_all = GL_FALSE;
781  }
782  else if (ctx->Depth.Test) {
783  /* regular depth testing */
784  GLuint m = (*ctx->Driver.DepthTestSpan)( ctx, n, x, y, z, mask );
785  if (m==0) {
786  return;
787  }
788  if (m<n) {
789  write_all = GL_FALSE;
790  }
791  }
792 
793  if (ctx->RasterMask & NO_DRAW_BIT) {
794  /* write no pixels */
795  return;
796  }
797 
798  /* blending */
799  if (ctx->Color.SWLogicOpEnabled) {
800  gl_logicop_rgba_span( ctx, n, x, y, red, green, blue, alpha, mask );
801  }
802  else if (ctx->Color.BlendEnabled) {
803  gl_blend_span( ctx, n, x, y, red, green, blue, alpha, mask );
804  }
805 
806  if (ctx->Color.SWmasking) {
807  gl_mask_color_span( ctx, n, x, y, red, green, blue, alpha );
808  }
809 
810  /* write pixels */
811  (*ctx->Driver.WriteColorSpan)( ctx, n, x, y, red, green, blue, alpha,
812  write_all ? NULL : mask );
813  if (ctx->RasterMask & ALPHABUF_BIT) {
814  gl_write_alpha_span( ctx, n, x, y, alpha, write_all ? NULL : mask );
815  }
816 
817  if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
818  /* Also draw to back buffer */
819  MEMCPY( rtmp, r, n * sizeof(GLubyte) );
820  MEMCPY( gtmp, g, n * sizeof(GLubyte) );
821  MEMCPY( btmp, b, n * sizeof(GLubyte) );
822  MEMCPY( atmp, a, n * sizeof(GLubyte) );
823  (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
824  if (ctx->Color.SWLogicOpEnabled) {
825  gl_logicop_rgba_span( ctx, n, x, y, red, green, blue, alpha, mask );
826  }
827  else if (ctx->Color.BlendEnabled) {
828  gl_blend_span( ctx, n, x, y, red, green, blue, alpha, mask );
829  }
830  if (ctx->Color.SWmasking) {
831  gl_mask_color_span( ctx, n, x, y, red, green, blue, alpha );
832  }
833  (*ctx->Driver.WriteColorSpan)( ctx, n, x, y, red, green, blue, alpha,
834  write_all ? NULL : mask );
835  (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
836  if (ctx->RasterMask & ALPHABUF_BIT) {
837  ctx->Buffer->Alpha = ctx->Buffer->BackAlpha;
838  gl_write_alpha_span( ctx, n, x, y, alpha, write_all ? NULL : mask );
839  ctx->Buffer->Alpha = ctx->Buffer->FrontAlpha;
840  }
841  }
842 }
843 
844 
845 
846 /*
847  * Read RGBA pixels from frame buffer. Clipping will be done to prevent
848  * reading ouside the buffer's boundaries.
849  */
851  GLuint n, GLint x, GLint y,
852  GLubyte red[], GLubyte green[],
853  GLubyte blue[], GLubyte alpha[] )
854 {
855  register GLuint i;
856 
857  if (y<0 || y>=ctx->Buffer->Height || x>=ctx->Buffer->Width) {
858  /* completely above, below, or right */
859  for (i=0;i<n;i++) {
860  red[i] = green[i] = blue[i] = alpha[i] = 0;
861  }
862  }
863  else {
864  if (x>=0 && x+n<=ctx->Buffer->Width) {
865  /* OK */
866  (*ctx->Driver.ReadColorSpan)( ctx, n, x, y, red, green, blue, alpha );
867  if (ctx->RasterMask & ALPHABUF_BIT) {
868  gl_read_alpha_span( ctx, n, x, y, alpha );
869  }
870  }
871  else {
872  i = 0;
873  if (x<0) {
874  while (x<0 && n>0) {
875  red[i] = green[i] = blue[i] = alpha[i] = 0;
876  x++;
877  n--;
878  i++;
879  }
880  }
881  n = MIN2( n, ctx->Buffer->Width - x );
882  (*ctx->Driver.ReadColorSpan)( ctx, n, x, y, red+i, green+i, blue+i, alpha+i);
883  if (ctx->RasterMask & ALPHABUF_BIT) {
884  gl_read_alpha_span( ctx, n, x, y, alpha+i );
885  }
886  }
887  }
888 }
889 
890 
891 
892 
893 /*
894  * Read CI pixels from frame buffer. Clipping will be done to prevent
895  * reading ouside the buffer's boundaries.
896  */
898  GLuint n, GLint x, GLint y, GLuint indx[] )
899 {
900  register GLuint i;
901 
902  if (y<0 || y>=ctx->Buffer->Height || x>=ctx->Buffer->Width) {
903  /* completely above, below, or right */
904  for (i=0;i<n;i++) {
905  indx[i] = 0;
906  }
907  }
908  else {
909  if (x>=0 && x+n<=ctx->Buffer->Width) {
910  /* OK */
911  (*ctx->Driver.ReadIndexSpan)( ctx, n, x, y, indx );
912  }
913  else {
914  i = 0;
915  if (x<0) {
916  while (x<0 && n>0) {
917  indx[i] = 0;
918  x++;
919  n--;
920  i++;
921  }
922  }
923  n = MIN2( n, ctx->Buffer->Width - x );
924  (*ctx->Driver.ReadIndexSpan)( ctx, n, x, y, indx+i );
925  }
926  }
927 }
928 
929 
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
GLint gl_alpha_test(GLcontext *ctx, GLuint n, const GLubyte alpha[], GLubyte mask[])
Definition: alpha.c:92
#define GL_BACK
Definition: gl.h:271
#define MEMSET(DST, VAL, N)
Definition: macros.h:241
#define GL_BITMAP
Definition: gl.h:497
GLframebuffer * Buffer
Definition: types.h:1273
void gl_blend_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[], GLubyte mask[])
Definition: blend.c:507
void gl_mask_color_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[])
Definition: masking.c:93
unsigned char GLubyte
Definition: gl.h:157
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define GL_FALSE
Definition: gl.h:173
struct gl_polygon_attrib Polygon
Definition: types.h:1330
GLdouble n
Definition: glext.h:7729
void gl_fog_color_pixels(GLcontext *ctx, GLuint n, const GLdepth z[], GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[])
Definition: fog.c:252
GLdouble GLdouble t
Definition: gl.h:2047
static void stipple_polygon_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLubyte mask[])
Definition: span.c:96
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
void gl_logicop_rgba_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[], GLubyte mask[])
Definition: logic.c:364
void gl_read_alpha_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLubyte alpha[])
Definition: alphabuf.c:246
GLint Height
Definition: types.h:1179
const GLfloat * m
Definition: glext.h:10848
GLuint RasterMask
Definition: types.h:1361
struct dd_function_table Driver
Definition: types.h:1276
#define WINCLIP_BIT
Definition: types.h:1224
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLenum GLint GLuint mask
Definition: glext.h:6028
#define a
Definition: ke_i.h:78
#define GL_FRONT
Definition: gl.h:270
unsigned char GLboolean
Definition: gl.h:151
GLdouble GLdouble z
Definition: glext.h:5874
#define NO_DRAW_BIT
Definition: types.h:1226
GLint gl_scissor_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLubyte mask[])
Definition: scissor.c:87
smooth NULL
Definition: ftsmooth.c:416
void gl_read_index_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLuint indx[])
Definition: span.c:897
void gl_read_color_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[])
Definition: span.c:850
static GLuint clip_span(GLcontext *ctx, GLint n, GLint x, GLint y, GLubyte mask[])
Definition: span.c:122
Definition: bufpool.h:45
GLuint index
Definition: glext.h:6031
void gl_write_index_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLdepth z[], GLuint index[], GLenum primitive)
Definition: span.c:167
struct gl_colorbuffer_attrib Color
Definition: types.h:1319
GLclampf GLclampf blue
Definition: gl.h:1740
void gl_write_color_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLdepth z[], GLubyte r[], GLubyte g[], GLubyte b[], GLubyte a[], GLenum primitive)
Definition: span.c:378
#define b
Definition: ke_i.h:79
void gl_fog_index_pixels(GLcontext *ctx, GLuint n, const GLdepth z[], GLuint index[])
Definition: fog.c:333
struct gl_fog_attrib Fog
Definition: types.h:1323
struct gl_scissor_attrib Scissor
Definition: types.h:1332
struct gl_texture_attrib Texture
Definition: types.h:1334
GLboolean GLboolean g
Definition: glext.h:6204
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLint GLdepth
Definition: types.h:218
#define ALPHABUF_BIT
Definition: types.h:1223
#define MAX_WIDTH
Definition: config.h:130
#define MEMCPY(DST, SRC, BYTES)
Definition: macros.h:231
GLint gl_stencil_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLubyte mask[])
Definition: stencil.c:339
GLclampf green
Definition: gl.h:1740
#define red
Definition: linetest.c:67
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define index(s, c)
Definition: various.h:29
void gl_write_alpha_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLubyte alpha[], GLubyte mask[])
Definition: alphabuf.c:155
#define GL_NICEST
Definition: gl.h:585
GLdouble s
Definition: gl.h:2039
GLubyte * Alpha
Definition: types.h:1192
unsigned int GLenum
Definition: gl.h:150
void gl_write_texture_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLdepth z[], GLfloat s[], GLfloat t[], GLfloat u[], GLfloat lambda[], GLubyte r[], GLubyte g[], GLubyte b[], GLubyte a[], GLenum primitive)
Definition: span.c:699
GLubyte * BackAlpha
Definition: types.h:1191
GLuint PolygonStipple[32]
Definition: types.h:1331
struct gl_hint_attrib Hint
Definition: types.h:1324
struct gl_depthbuffer_attrib Depth
Definition: types.h:1321
unsigned int GLuint
Definition: gl.h:159
#define GL_TRUE
Definition: gl.h:174
struct gl_stencil_attrib Stencil
Definition: types.h:1333
void gl_logicop_ci_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLuint index[], GLubyte mask[])
Definition: logic.c:105
void gl_depth_stencil_span(GLcontext *ctx, GLuint n, GLint x, GLint y, const GLdepth z[], GLubyte mask[])
Definition: stencil.c:514
void gl_write_monocolor_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLdepth z[], GLint r, GLint g, GLint b, GLint a, GLenum primitive)
Definition: span.c:531
void gl_write_mono_alpha_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLubyte alpha, GLubyte mask[])
Definition: alphabuf.c:177
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint Width
Definition: types.h:1178
#define GL_POLYGON
Definition: gl.h:199
float GLfloat
Definition: gl.h:161
void gl_texture_pixels(GLcontext *ctx, GLuint n, const GLfloat s[], const GLfloat t[], const GLfloat r[], const GLfloat lambda[], GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[])
Definition: texture.c:1678
GLclampf GLclampf GLclampf alpha
Definition: gl.h:1740
#define MIN2(A, B)
Definition: macros.h:159
int GLint
Definition: gl.h:156
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLubyte * FrontAlpha
Definition: types.h:1190
#define FRONT_AND_BACK_BIT
Definition: types.h:1225
void gl_write_monoindex_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLdepth z[], GLuint index, GLenum primitive)
Definition: span.c:255
void gl_mask_index_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLuint index[])
Definition: masking.c:161
GLboolean MutablePixels
Definition: types.h:1369