1 /* $Id: depth.c,v 1.11 1997/07/24 01:24:45 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: depth.c,v $ 26 * Revision 1.11 1997/07/24 01:24:45 brianp 27 * changed precompiled header symbol from PCH to PC_HEADER 28 * 29 * Revision 1.10 1997/05/28 03:24:22 brianp 30 * added precompiled header (PCH) support 31 * 32 * Revision 1.9 1997/04/20 19:54:15 brianp 33 * replaced abort() with gl_problem() 34 * 35 * Revision 1.8 1997/02/27 19:58:52 brianp 36 * don't try to clear depth buffer if there isn't one 37 * 38 * Revision 1.7 1997/01/31 23:33:08 brianp 39 * replaced calloc with malloc in gl_alloc_depth_buffer() 40 * 41 * Revision 1.6 1996/11/04 01:42:07 brianp 42 * multiply Viewport.Sz and .Tz by DEPTH_SCALE 43 * 44 * Revision 1.5 1996/10/09 03:07:25 brianp 45 * replaced malloc with calloc in gl_alloc_depth_buffer() 46 * 47 * Revision 1.4 1996/09/27 01:24:58 brianp 48 * added missing default cases to switches 49 * 50 * Revision 1.3 1996/09/19 00:54:05 brianp 51 * added missing returns after some gl_error() calls 52 * 53 * Revision 1.2 1996/09/15 14:19:16 brianp 54 * now use GLframebuffer and GLvisual 55 * 56 * Revision 1.1 1996/09/13 01:38:16 brianp 57 * Initial revision 58 * 59 */ 60 61 62 /* 63 * Depth buffer functions 64 */ 65 66 67 #ifdef PC_HEADER 68 #include "all.h" 69 #else 70 #include <stdlib.h> 71 #include <string.h> 72 #include "context.h" 73 #include "depth.h" 74 #include "dlist.h" 75 #include "macros.h" 76 #include "types.h" 77 #endif 78 79 80 81 /**********************************************************************/ 82 /***** API Functions *****/ 83 /**********************************************************************/ 84 85 86 87 void gl_ClearDepth( GLcontext* ctx, GLclampd depth ) 88 { 89 if (INSIDE_BEGIN_END(ctx)) { 90 gl_error( ctx, GL_INVALID_OPERATION, "glClearDepth" ); 91 return; 92 } 93 ctx->Depth.Clear = (GLfloat) CLAMP( depth, 0.0, 1.0 ); 94 } 95 96 97 98 void gl_DepthFunc( GLcontext* ctx, GLenum func ) 99 { 100 if (INSIDE_BEGIN_END(ctx)) { 101 gl_error( ctx, GL_INVALID_OPERATION, "glDepthFunc" ); 102 return; 103 } 104 105 switch (func) { 106 case GL_NEVER: 107 case GL_LESS: /* (default) pass if incoming z < stored z */ 108 case GL_GEQUAL: 109 case GL_LEQUAL: 110 case GL_GREATER: 111 case GL_NOTEQUAL: 112 case GL_EQUAL: 113 case GL_ALWAYS: 114 ctx->Depth.Func = func; 115 ctx->NewState |= NEW_RASTER_OPS; 116 break; 117 default: 118 gl_error( ctx, GL_INVALID_ENUM, "glDepth.Func" ); 119 } 120 } 121 122 123 124 void gl_DepthMask( GLcontext* ctx, GLboolean flag ) 125 { 126 if (INSIDE_BEGIN_END(ctx)) { 127 gl_error( ctx, GL_INVALID_OPERATION, "glDepthMask" ); 128 return; 129 } 130 131 /* 132 * GL_TRUE indicates depth buffer writing is enabled (default) 133 * GL_FALSE indicates depth buffer writing is disabled 134 */ 135 ctx->Depth.Mask = flag; 136 ctx->NewState |= NEW_RASTER_OPS; 137 } 138 139 140 141 void gl_DepthRange( GLcontext* ctx, GLclampd nearval, GLclampd farval ) 142 { 143 /* 144 * nearval - specifies mapping of the near clipping plane to window 145 * coordinates, default is 0 146 * farval - specifies mapping of the far clipping plane to window 147 * coordinates, default is 1 148 * 149 * After clipping and div by w, z coords are in -1.0 to 1.0, 150 * corresponding to near and far clipping planes. glDepthRange 151 * specifies a linear mapping of the normalized z coords in 152 * this range to window z coords. 153 */ 154 155 GLfloat n, f; 156 157 if (INSIDE_BEGIN_END(ctx)) { 158 gl_error( ctx, GL_INVALID_OPERATION, "glDepthRange" ); 159 return; 160 } 161 162 n = (GLfloat) CLAMP( nearval, 0.0, 1.0 ); 163 f = (GLfloat) CLAMP( farval, 0.0, 1.0 ); 164 165 ctx->Viewport.Near = n; 166 ctx->Viewport.Far = f; 167 ctx->Viewport.Sz = DEPTH_SCALE * ((f - n) / 2.0); 168 ctx->Viewport.Tz = DEPTH_SCALE * ((f - n) / 2.0 + n); 169 } 170 171 172 173 /**********************************************************************/ 174 /***** Depth Testing Functions *****/ 175 /**********************************************************************/ 176 177 178 /* 179 * Depth test horizontal spans of fragments. These functions are called 180 * via ctx->Driver.depth_test_span only. 181 * 182 * Input: n - number of pixels in the span 183 * x, y - location of leftmost pixel in span in window coords 184 * z - array [n] of integer depth values 185 * In/Out: mask - array [n] of flags (1=draw pixel, 0=don't draw) 186 * Return: number of pixels which passed depth test 187 */ 188 189 190 /* 191 * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ). 192 */ 193 GLuint gl_depth_test_span_generic( GLcontext* ctx, 194 GLuint n, GLint x, GLint y, 195 const GLdepth z[], 196 GLubyte mask[] ) 197 { 198 GLdepth *zptr = Z_ADDRESS( ctx, x, y ); 199 GLubyte *m = mask; 200 GLuint i; 201 GLuint passed = 0; 202 203 /* switch cases ordered from most frequent to less frequent */ 204 switch (ctx->Depth.Func) { 205 case GL_LESS: 206 if (ctx->Depth.Mask) { 207 /* Update Z buffer */ 208 for (i=0; i<n; i++,zptr++,m++) { 209 if (*m) { 210 if (z[i] < *zptr) { 211 /* pass */ 212 *zptr = z[i]; 213 passed++; 214 } 215 else { 216 /* fail */ 217 *m = 0; 218 } 219 } 220 } 221 } 222 else { 223 /* Don't update Z buffer */ 224 for (i=0; i<n; i++,zptr++,m++) { 225 if (*m) { 226 if (z[i] < *zptr) { 227 /* pass */ 228 passed++; 229 } 230 else { 231 *m = 0; 232 } 233 } 234 } 235 } 236 break; 237 case GL_LEQUAL: 238 if (ctx->Depth.Mask) { 239 /* Update Z buffer */ 240 for (i=0;i<n;i++,zptr++,m++) { 241 if (*m) { 242 if (z[i] <= *zptr) { 243 *zptr = z[i]; 244 passed++; 245 } 246 else { 247 *m = 0; 248 } 249 } 250 } 251 } 252 else { 253 /* Don't update Z buffer */ 254 for (i=0;i<n;i++,zptr++,m++) { 255 if (*m) { 256 if (z[i] <= *zptr) { 257 /* pass */ 258 passed++; 259 } 260 else { 261 *m = 0; 262 } 263 } 264 } 265 } 266 break; 267 case GL_GEQUAL: 268 if (ctx->Depth.Mask) { 269 /* Update Z buffer */ 270 for (i=0;i<n;i++,zptr++,m++) { 271 if (*m) { 272 if (z[i] >= *zptr) { 273 *zptr = z[i]; 274 passed++; 275 } 276 else { 277 *m = 0; 278 } 279 } 280 } 281 } 282 else { 283 /* Don't update Z buffer */ 284 for (i=0;i<n;i++,zptr++,m++) { 285 if (*m) { 286 if (z[i] >= *zptr) { 287 /* pass */ 288 passed++; 289 } 290 else { 291 *m = 0; 292 } 293 } 294 } 295 } 296 break; 297 case GL_GREATER: 298 if (ctx->Depth.Mask) { 299 /* Update Z buffer */ 300 for (i=0;i<n;i++,zptr++,m++) { 301 if (*m) { 302 if (z[i] > *zptr) { 303 *zptr = z[i]; 304 passed++; 305 } 306 else { 307 *m = 0; 308 } 309 } 310 } 311 } 312 else { 313 /* Don't update Z buffer */ 314 for (i=0;i<n;i++,zptr++,m++) { 315 if (*m) { 316 if (z[i] > *zptr) { 317 /* pass */ 318 passed++; 319 } 320 else { 321 *m = 0; 322 } 323 } 324 } 325 } 326 break; 327 case GL_NOTEQUAL: 328 if (ctx->Depth.Mask) { 329 /* Update Z buffer */ 330 for (i=0;i<n;i++,zptr++,m++) { 331 if (*m) { 332 if (z[i] != *zptr) { 333 *zptr = z[i]; 334 passed++; 335 } 336 else { 337 *m = 0; 338 } 339 } 340 } 341 } 342 else { 343 /* Don't update Z buffer */ 344 for (i=0;i<n;i++,zptr++,m++) { 345 if (*m) { 346 if (z[i] != *zptr) { 347 /* pass */ 348 passed++; 349 } 350 else { 351 *m = 0; 352 } 353 } 354 } 355 } 356 break; 357 case GL_EQUAL: 358 if (ctx->Depth.Mask) { 359 /* Update Z buffer */ 360 for (i=0;i<n;i++,zptr++,m++) { 361 if (*m) { 362 if (z[i] == *zptr) { 363 *zptr = z[i]; 364 passed++; 365 } 366 else { 367 *m =0; 368 } 369 } 370 } 371 } 372 else { 373 /* Don't update Z buffer */ 374 for (i=0;i<n;i++,zptr++,m++) { 375 if (*m) { 376 if (z[i] == *zptr) { 377 /* pass */ 378 passed++; 379 } 380 else { 381 *m =0; 382 } 383 } 384 } 385 } 386 break; 387 case GL_ALWAYS: 388 if (ctx->Depth.Mask) { 389 /* Update Z buffer */ 390 for (i=0;i<n;i++,zptr++,m++) { 391 if (*m) { 392 *zptr = z[i]; 393 passed++; 394 } 395 } 396 } 397 else { 398 /* Don't update Z buffer or mask */ 399 passed = n; 400 } 401 break; 402 case GL_NEVER: 403 for (i=0;i<n;i++) { 404 mask[i] = 0; 405 } 406 break; 407 default: 408 gl_problem(ctx, "Bad depth func in gl_depth_test_span_generic"); 409 } /*switch*/ 410 411 return passed; 412 } 413 414 415 416 /* 417 * glDepthFunc(GL_LESS) and glDepthMask(GL_TRUE). 418 */ 419 GLuint gl_depth_test_span_less( GLcontext* ctx, 420 GLuint n, GLint x, GLint y, const GLdepth z[], 421 GLubyte mask[] ) 422 { 423 GLdepth *zptr = Z_ADDRESS( ctx, x, y ); 424 GLuint i; 425 GLuint passed = 0; 426 427 for (i=0; i<n; i++) { 428 if (mask[i]) { 429 if (z[i] < zptr[i]) { 430 /* pass */ 431 zptr[i] = z[i]; 432 passed++; 433 } 434 else { 435 /* fail */ 436 mask[i] = 0; 437 } 438 } 439 } 440 return passed; 441 } 442 443 444 /* 445 * glDepthFunc(GL_GREATER) and glDepthMask(GL_TRUE). 446 */ 447 GLuint gl_depth_test_span_greater( GLcontext* ctx, 448 GLuint n, GLint x, GLint y, 449 const GLdepth z[], 450 GLubyte mask[] ) 451 { 452 GLdepth *zptr = Z_ADDRESS( ctx, x, y ); 453 GLuint i; 454 GLuint passed = 0; 455 456 for (i=0; i<n; i++) { 457 if (mask[i]) { 458 if (z[i] > zptr[i]) { 459 /* pass */ 460 zptr[i] = z[i]; 461 passed++; 462 } 463 else { 464 /* fail */ 465 mask[i] = 0; 466 } 467 } 468 } 469 return passed; 470 } 471 472 473 474 /* 475 * Depth test an array of randomly positioned fragments. 476 */ 477 478 479 #define ZADDR_SETUP GLdepth *depthbuffer = ctx->Buffer->Depth; \ 480 GLint width = ctx->Buffer->Width; 481 482 #define ZADDR( X, Y ) (depthbuffer + (Y) * width + (X) ) 483 484 485 486 /* 487 * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ). 488 */ 489 void gl_depth_test_pixels_generic( GLcontext* ctx, 490 GLuint n, const GLint x[], const GLint y[], 491 const GLdepth z[], GLubyte mask[] ) 492 { 493 register GLdepth *zptr; 494 register GLuint i; 495 496 /* switch cases ordered from most frequent to less frequent */ 497 switch (ctx->Depth.Func) { 498 case GL_LESS: 499 if (ctx->Depth.Mask) { 500 /* Update Z buffer */ 501 for (i=0; i<n; i++) { 502 if (mask[i]) { 503 zptr = Z_ADDRESS(ctx,x[i],y[i]); 504 if (z[i] < *zptr) { 505 /* pass */ 506 *zptr = z[i]; 507 } 508 else { 509 /* fail */ 510 mask[i] = 0; 511 } 512 } 513 } 514 } 515 else { 516 /* Don't update Z buffer */ 517 for (i=0; i<n; i++) { 518 if (mask[i]) { 519 zptr = Z_ADDRESS(ctx,x[i],y[i]); 520 if (z[i] < *zptr) { 521 /* pass */ 522 } 523 else { 524 /* fail */ 525 mask[i] = 0; 526 } 527 } 528 } 529 } 530 break; 531 case GL_LEQUAL: 532 if (ctx->Depth.Mask) { 533 /* Update Z buffer */ 534 for (i=0; i<n; i++) { 535 if (mask[i]) { 536 zptr = Z_ADDRESS(ctx,x[i],y[i]); 537 if (z[i] <= *zptr) { 538 /* pass */ 539 *zptr = z[i]; 540 } 541 else { 542 /* fail */ 543 mask[i] = 0; 544 } 545 } 546 } 547 } 548 else { 549 /* Don't update Z buffer */ 550 for (i=0; i<n; i++) { 551 if (mask[i]) { 552 zptr = Z_ADDRESS(ctx,x[i],y[i]); 553 if (z[i] <= *zptr) { 554 /* pass */ 555 } 556 else { 557 /* fail */ 558 mask[i] = 0; 559 } 560 } 561 } 562 } 563 break; 564 case GL_GEQUAL: 565 if (ctx->Depth.Mask) { 566 /* Update Z buffer */ 567 for (i=0; i<n; i++) { 568 if (mask[i]) { 569 zptr = Z_ADDRESS(ctx,x[i],y[i]); 570 if (z[i] >= *zptr) { 571 /* pass */ 572 *zptr = z[i]; 573 } 574 else { 575 /* fail */ 576 mask[i] = 0; 577 } 578 } 579 } 580 } 581 else { 582 /* Don't update Z buffer */ 583 for (i=0; i<n; i++) { 584 if (mask[i]) { 585 zptr = Z_ADDRESS(ctx,x[i],y[i]); 586 if (z[i] >= *zptr) { 587 /* pass */ 588 } 589 else { 590 /* fail */ 591 mask[i] = 0; 592 } 593 } 594 } 595 } 596 break; 597 case GL_GREATER: 598 if (ctx->Depth.Mask) { 599 /* Update Z buffer */ 600 for (i=0; i<n; i++) { 601 if (mask[i]) { 602 zptr = Z_ADDRESS(ctx,x[i],y[i]); 603 if (z[i] > *zptr) { 604 /* pass */ 605 *zptr = z[i]; 606 } 607 else { 608 /* fail */ 609 mask[i] = 0; 610 } 611 } 612 } 613 } 614 else { 615 /* Don't update Z buffer */ 616 for (i=0; i<n; i++) { 617 if (mask[i]) { 618 zptr = Z_ADDRESS(ctx,x[i],y[i]); 619 if (z[i] > *zptr) { 620 /* pass */ 621 } 622 else { 623 /* fail */ 624 mask[i] = 0; 625 } 626 } 627 } 628 } 629 break; 630 case GL_NOTEQUAL: 631 if (ctx->Depth.Mask) { 632 /* Update Z buffer */ 633 for (i=0; i<n; i++) { 634 if (mask[i]) { 635 zptr = Z_ADDRESS(ctx,x[i],y[i]); 636 if (z[i] != *zptr) { 637 /* pass */ 638 *zptr = z[i]; 639 } 640 else { 641 /* fail */ 642 mask[i] = 0; 643 } 644 } 645 } 646 } 647 else { 648 /* Don't update Z buffer */ 649 for (i=0; i<n; i++) { 650 if (mask[i]) { 651 zptr = Z_ADDRESS(ctx,x[i],y[i]); 652 if (z[i] != *zptr) { 653 /* pass */ 654 } 655 else { 656 /* fail */ 657 mask[i] = 0; 658 } 659 } 660 } 661 } 662 break; 663 case GL_EQUAL: 664 if (ctx->Depth.Mask) { 665 /* Update Z buffer */ 666 for (i=0; i<n; i++) { 667 if (mask[i]) { 668 zptr = Z_ADDRESS(ctx,x[i],y[i]); 669 if (z[i] == *zptr) { 670 /* pass */ 671 *zptr = z[i]; 672 } 673 else { 674 /* fail */ 675 mask[i] = 0; 676 } 677 } 678 } 679 } 680 else { 681 /* Don't update Z buffer */ 682 for (i=0; i<n; i++) { 683 if (mask[i]) { 684 zptr = Z_ADDRESS(ctx,x[i],y[i]); 685 if (z[i] == *zptr) { 686 /* pass */ 687 } 688 else { 689 /* fail */ 690 mask[i] = 0; 691 } 692 } 693 } 694 } 695 break; 696 case GL_ALWAYS: 697 if (ctx->Depth.Mask) { 698 /* Update Z buffer */ 699 for (i=0; i<n; i++) { 700 if (mask[i]) { 701 zptr = Z_ADDRESS(ctx,x[i],y[i]); 702 *zptr = z[i]; 703 } 704 } 705 } 706 else { 707 /* Don't update Z buffer or mask */ 708 } 709 break; 710 case GL_NEVER: 711 /* depth test never passes */ 712 for (i=0;i<n;i++) { 713 mask[i] = 0; 714 } 715 break; 716 default: 717 gl_problem(ctx, "Bad depth func in gl_depth_test_pixels_generic"); 718 } /*switch*/ 719 } 720 721 722 723 /* 724 * glDepthFunc( GL_LESS ) and glDepthMask( GL_TRUE ). 725 */ 726 void gl_depth_test_pixels_less( GLcontext* ctx, 727 GLuint n, const GLint x[], const GLint y[], 728 const GLdepth z[], GLubyte mask[] ) 729 { 730 GLdepth *zptr; 731 GLuint i; 732 733 for (i=0; i<n; i++) { 734 if (mask[i]) { 735 zptr = Z_ADDRESS(ctx,x[i],y[i]); 736 if (z[i] < *zptr) { 737 /* pass */ 738 *zptr = z[i]; 739 } 740 else { 741 /* fail */ 742 mask[i] = 0; 743 } 744 } 745 } 746 } 747 748 749 /* 750 * glDepthFunc( GL_GREATER ) and glDepthMask( GL_TRUE ). 751 */ 752 void gl_depth_test_pixels_greater( GLcontext* ctx, 753 GLuint n, const GLint x[], const GLint y[], 754 const GLdepth z[], GLubyte mask[] ) 755 { 756 GLdepth *zptr; 757 GLuint i; 758 759 for (i=0; i<n; i++) { 760 if (mask[i]) { 761 zptr = Z_ADDRESS(ctx,x[i],y[i]); 762 if (z[i] > *zptr) { 763 /* pass */ 764 *zptr = z[i]; 765 } 766 else { 767 /* fail */ 768 mask[i] = 0; 769 } 770 } 771 } 772 } 773 774 775 776 777 /**********************************************************************/ 778 /***** Read Depth Buffer *****/ 779 /**********************************************************************/ 780 781 782 /* 783 * Return a span of depth values from the depth buffer as floats in [0,1]. 784 * This function is only called through Driver.read_depth_span_float() 785 * Input: n - how many pixels 786 * x,y - location of first pixel 787 * Output: depth - the array of depth values 788 */ 789 void gl_read_depth_span_float( GLcontext* ctx, 790 GLuint n, GLint x, GLint y, GLfloat depth[] ) 791 { 792 GLdepth *zptr; 793 GLfloat scale; 794 GLuint i; 795 796 scale = 1.0F / DEPTH_SCALE; 797 798 if (ctx->Buffer->Depth) { 799 zptr = Z_ADDRESS( ctx, x, y ); 800 for (i=0;i<n;i++) { 801 depth[i] = (GLfloat) zptr[i] * scale; 802 } 803 } 804 else { 805 for (i=0;i<n;i++) { 806 depth[i] = 0.0F; 807 } 808 } 809 } 810 811 812 /* 813 * Return a span of depth values from the depth buffer as integers in 814 * [0,MAX_DEPTH]. 815 * This function is only called through Driver.read_depth_span_int() 816 * Input: n - how many pixels 817 * x,y - location of first pixel 818 * Output: depth - the array of depth values 819 */ 820 void gl_read_depth_span_int( GLcontext* ctx, 821 GLuint n, GLint x, GLint y, GLdepth depth[] ) 822 { 823 if (ctx->Buffer->Depth) { 824 GLdepth *zptr = Z_ADDRESS( ctx, x, y ); 825 MEMCPY( depth, zptr, n * sizeof(GLdepth) ); 826 } 827 else { 828 GLuint i; 829 for (i=0;i<n;i++) { 830 depth[i] = 0.0; 831 } 832 } 833 } 834 835 836 837 /**********************************************************************/ 838 /***** Allocate and Clear Depth Buffer *****/ 839 /**********************************************************************/ 840 841 842 843 /* 844 * Allocate a new depth buffer. If there's already a depth buffer allocated 845 * it will be free()'d. The new depth buffer will be uniniitalized. 846 * This function is only called through Driver.alloc_depth_buffer. 847 */ 848 void gl_alloc_depth_buffer( GLcontext* ctx ) 849 { 850 /* deallocate current depth buffer if present */ 851 if (ctx->Buffer->Depth) { 852 free(ctx->Buffer->Depth); 853 ctx->Buffer->Depth = NULL; 854 } 855 856 /* allocate new depth buffer, but don't initialize it */ 857 ctx->Buffer->Depth = (GLdepth *) malloc( ctx->Buffer->Width 858 * ctx->Buffer->Height 859 * sizeof(GLdepth) ); 860 if (!ctx->Buffer->Depth) { 861 /* out of memory */ 862 ctx->Depth.Test = GL_FALSE; 863 gl_error( ctx, GL_OUT_OF_MEMORY, "Couldn't allocate depth buffer" ); 864 } 865 } 866 867 868 869 870 /* 871 * Clear the depth buffer. If the depth buffer doesn't exist yet we'll 872 * allocate it now. 873 * This function is only called through Driver.clear_depth_buffer. 874 */ 875 void gl_clear_depth_buffer( GLcontext* ctx ) 876 { 877 GLdepth clear_value = (GLdepth) (ctx->Depth.Clear * DEPTH_SCALE); 878 879 if (ctx->Visual->DepthBits==0 || !ctx->Buffer->Depth) { 880 /* no depth buffer */ 881 return; 882 } 883 884 /* The loops in this function have been written so the IRIX 5.3 885 * C compiler can unroll them. Hopefully other compilers can too! 886 */ 887 888 if (ctx->Scissor.Enabled) { 889 /* only clear scissor region */ 890 GLint y; 891 for (y=ctx->Buffer->Ymin; y<=ctx->Buffer->Ymax; y++) { 892 GLdepth *d = Z_ADDRESS( ctx, ctx->Buffer->Xmin, y ); 893 GLint n = ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1; 894 do { 895 *d++ = clear_value; 896 n--; 897 } while (n); 898 } 899 } 900 else { 901 /* clear whole buffer */ 902 GLdepth *d = ctx->Buffer->Depth; 903 GLint n = ctx->Buffer->Width * ctx->Buffer->Height; 904 while (n>=16) { 905 d[0] = clear_value; d[1] = clear_value; 906 d[2] = clear_value; d[3] = clear_value; 907 d[4] = clear_value; d[5] = clear_value; 908 d[6] = clear_value; d[7] = clear_value; 909 d[8] = clear_value; d[9] = clear_value; 910 d[10] = clear_value; d[11] = clear_value; 911 d[12] = clear_value; d[13] = clear_value; 912 d[14] = clear_value; d[15] = clear_value; 913 d += 16; 914 n -= 16; 915 } 916 while (n>0) { 917 *d++ = clear_value; 918 n--; 919 } 920 } 921 } 922 923 924 925