head 3.16; access; symbols merge-1:3.13.2.3 autoconf:3.13.0.4 experimental-1:3.13.0.2 mesa-3-1-with-kw3:3.1; locks; strict; comment @ * @; 3.16 date 99.07.12.12.05.25; author keithw; state Exp; branches; next 3.15; 3.15 date 99.07.03.19.09.40; author miklos; state Exp; branches; next 3.14; 3.14 date 99.06.14.11.53.20; author keithw; state Exp; branches; next 3.13; 3.13 date 99.05.16.17.09.59; author keithw; state Exp; branches 3.13.2.1; next 3.12; 3.12 date 99.05.11.17.43.00; author keithw; state Exp; branches; next 3.11; 3.11 date 99.05.01.18.46.15; author keithw; state Exp; branches; next 3.10; 3.10 date 99.04.29.14.43.16; author keithw; state Exp; branches; next 3.9; 3.9 date 99.04.07.22.19.04; author brianp; state Exp; branches; next 3.8; 3.8 date 99.03.31.20.18.41; author keithw; state Exp; branches; next 3.7; 3.7 date 99.03.23.13.09.21; author keithw; state Exp; branches; next 3.6; 3.6 date 99.03.20.18.59.12; author brianp; state Exp; branches; next 3.5; 3.5 date 99.03.17.16.51.17; author keithw; state Exp; branches; next 3.4; 3.4 date 99.03.17.12.08.22; author keithw; state Exp; branches; next 3.3; 3.3 date 99.02.27.17.17.14; author brianp; state Exp; branches; next 3.2; 3.2 date 99.02.26.03.37.25; author brianp; state Exp; branches; next 3.1; 3.1 date 99.02.25.14.12.32; author keithw; state Exp; branches; next ; 3.13.2.1 date 99.05.21.21.29.28; author keithw; state Exp; branches; next 3.13.2.2; 3.13.2.2 date 99.05.22.09.44.26; author keithw; state Exp; branches; next 3.13.2.3; 3.13.2.3 date 99.06.19.15.04.15; author keithw; state Exp; branches; next ; desc @@ 3.16 log @merge from experimental branch upto merge-1 tag @ text @/* $Id: vbcull.c,v 3.15 1999/07/03 19:09:40 miklos Exp $ */ /* * Mesa 3-D graphics library * Version: 3.1 * * Copyright (C) 1999 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * New (3.1) transformation code written by Keith Whitwell. */ #ifdef PC_HEADER #include "all.h" #else #include #include "context.h" #include "macros.h" #include "types.h" #include "vb.h" #include "vbcull.h" #include "vbrender.h" #include "xform.h" #endif /* Culling for vertices and primitives. * (C) Keith Whitwell, December 1998. * * These functions build bitmasks which can be used to shortcircuit * lighting, fogging and texture calculations, and to convert * two-sided lighting into one-sided on a per-vertex basis. * * Each of these functions returns a value 'cullcount'. The meaning * of this value just has to satisfy the requirements: * * cullcount == VB->Count implies the entire vb has been culled and * can be discarded. * * cullcount == 0 implies that every vertex in the buffer is required * and that the cullmask can be ignored for transformation * and lighting. * */ const char *gl_prim_name[GL_POLYGON+2] = { "GL_POINTS", "GL_LINES", "GL_LINE_LOOP", "GL_LINE_STRIP", "GL_TRIANGLES", "GL_TRIANGLE_STRIP", "GL_TRIANGLE_FAN", "GL_QUADS", "GL_QUAD_STRIP", "GL_POLYGON", "culled primitive" }; static GLuint gl_cull_points( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint parity, CONST GLfloat (*proj)[4]) { const GLubyte *clipmask = VB->ClipMask; GLubyte *cullmask = VB->CullMask; GLuint i, cullcount = 0; (void) parity; (void) proj; /* This is pretty pointless. (arf arf) */ for (i=start+1;iCullMask+start, unculled_prim, (count-start)*sizeof(GLubyte)); return 0; } #define CULL_LINE( i1, i, nr ) \ do { \ GLubyte ClipOr = VB->ClipMask[i1] | VB->ClipMask[i]; \ \ if (ClipOr) { \ if (VB->ClipMask[i1] & VB->ClipMask[i] & CLIP_ALL_BITS) { \ cullcount+=nr; \ } \ else { \ cullmask[i1] |= VERT_FACE_FRONT; \ cullmask[i] |= VERT_FACE_FRONT | PRIM_FACE_FRONT | PRIM_CLIPPED; \ } \ } else { \ cullmask[i1] |= VERT_FACE_FRONT; \ cullmask[i] |= VERT_FACE_FRONT | PRIM_FACE_FRONT; \ } \ } while (0) static GLuint gl_cull_lines( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint parity, CONST GLfloat (*proj)[4]) { GLubyte *cullmask = VB->CullMask; GLuint cullcount = 0; GLuint i; GLuint last = count - 1; (void) parity; (void) proj; for (i = start; i < last ; i += 2) { CULL_LINE(i, i+1, 2); } if (i != last) cullcount++; return cullcount; } static GLuint gl_cull_line_strip( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint parity, CONST GLfloat (*proj)[4]) { GLubyte *cullmask = VB->CullMask; GLuint cullcount = 0; GLuint i; GLuint last = count - 1; GLuint nr = 2; (void) parity; (void) proj; for (i = start; i < last ; i++, nr = 1) { CULL_LINE(i, i+1, nr); } if (i != last) cullcount++; return cullcount; } static GLuint gl_cull_line_loop( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint parity, CONST GLfloat (*proj)[4]) { GLuint cullcount = 0; GLubyte *cullmask = VB->CullMask; GLuint i, last = count - 1; (void) parity; (void) proj; if (count - start < 2) return count - start; for (i = start; i < last ; i++) { CULL_LINE(i, i+1, 1); } CULL_LINE(last, start, 1); return cullcount; } #define CULL_TRI( do_clip, do_area, i2, i1, i0, parity, nr ) \ do { \ GLubyte ClipOr = 0; \ if (do_clip) { \ ClipOr = (VB->ClipMask[i2] | \ VB->ClipMask[i1] | \ VB->ClipMask[i0]); \ } \ \ if (do_clip && (ClipOr&CLIP_ALL_BITS)) \ { \ if (VB->ClipMask[i2] & VB->ClipMask[i1] & VB->ClipMask[i0] & \ CLIP_ALL_BITS) \ { \ cullcount+=nr; \ } \ else \ { \ cullmask[i0] = cull_faces | PRIM_CLIPPED; \ cullmask[i1] |= cull_faces; \ cullmask[i2] |= cull_faces; \ } \ } \ else \ { \ GLfloat area; \ GLubyte face_flags; \ \ if (do_area) { \ area = ((proj[i2][0] - proj[i0][0]) * \ (proj[i1][1] - proj[i0][1]) - \ (proj[i2][1] - proj[i0][1]) * \ (proj[i1][0] - proj[i0][0])); \ \ face_flags = (((area<0.0F) ^ parity) + 1) & cull_faces; \ } else { \ face_flags = cull_faces; \ } \ \ if (!do_area || face_flags) \ { \ cullmask[i0] = face_flags | (face_flags << PRIM_FLAG_SHIFT); \ cullmask[i1] |= face_flags; \ cullmask[i2] |= face_flags; \ if (do_clip && ClipOr) cullmask[i0] |= PRIM_CLIPPED; \ } \ else \ { \ cullcount+=nr; \ } \ } \ } while (0) #define CULL_QUAD( do_clip, do_area, i3, i2, i1, i, nr ) \ do { \ GLubyte ClipOr = 0; \ \ if (do_clip) { \ ClipOr = (VB->ClipMask[i3] | \ VB->ClipMask[i2] | \ VB->ClipMask[i1] | \ VB->ClipMask[i]); \ } \ \ if (do_clip && (ClipOr&CLIP_ALL_BITS)) \ { \ if (VB->ClipMask[i3] & VB->ClipMask[i2] & \ VB->ClipMask[i1] & VB->ClipMask[i] & \ CLIP_ALL_BITS) \ { \ cullcount+=nr; \ } \ else \ { \ cullmask[i] = cull_faces | PRIM_CLIPPED; \ cullmask[i1] = cull_faces | PRIM_CLIPPED; \ cullmask[i2] |= cull_faces; \ cullmask[i3] |= cull_faces; \ } \ } \ else \ { \ GLfloat area; \ GLubyte face_flags; \ \ if (do_area) { \ area = ((proj[i1][0] - proj[i3][0]) * /* ex */ \ (proj[i ][1] - proj[i2][1]) - /* fy */ \ (proj[i1][1] - proj[i3][1]) * /* ey */ \ (proj[i ][0] - proj[i2][0])); /* fx */ \ \ face_flags = (((area<0.0F) ^ face_bit) + 1) & cull_faces; \ } else { \ face_flags = cull_faces; \ } \ \ if (do_area && !face_flags) \ { \ cullcount+=nr; \ } \ else \ { \ cullmask[i] = face_flags | (face_flags<ctx; GLubyte *cullmask = VB->CullMask; GLuint rv = 0; (void) start; (void) ovf; if (cullmask[count-1] == 0) { rv++; cullmask[count-1] = ctx->Polygon.CullBits; } VB->CopyCount = 1; VB->Copy[2] = count-1; COPY_4FV(VB->CopyProj[2], proj[count-1]); return rv; } static GLuint gl_copy_first_and_last_cull( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint ovf, CONST GLfloat (*proj)[4] ) { const GLcontext *ctx = VB->ctx; GLuint rv = 0; GLubyte *cullmask = VB->CullMask; (void) ovf; if (cullmask[count-1] == 0) { rv++; cullmask[count-1] = ctx->Polygon.CullBits; } if (cullmask[start] == 0) { rv++; cullmask[start] = ctx->Polygon.CullBits; } VB->CopyCount = 2; VB->Copy[1] = start; VB->Copy[2] = count-1; COPY_4FV(VB->CopyProj[1], proj[start]); COPY_4FV(VB->CopyProj[2], proj[count-1]); return rv; } /* Must be able to cope with zero or one overflow * */ static GLuint gl_copy_last_two_cull( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint ovf, CONST GLfloat (*proj)[4] ) { const GLcontext *ctx = VB->ctx; GLubyte *cullmask = VB->CullMask; GLuint rv = 0; (void) start; if (cullmask[count-1] == 0) { rv++; cullmask[count-1] = ctx->Polygon.CullBits; } if (cullmask[count-2] == 0) { rv++; cullmask[count-2] = ctx->Polygon.CullBits; } VB->CopyCount = 2; VB->Copy[1] = count-2; VB->Copy[2] = count-1; COPY_4FV(VB->CopyProj[1], proj[count-2]); COPY_4FV(VB->CopyProj[2], proj[count-1]); if (ovf == 1) { if (cullmask[count-3] == 0) { rv++; cullmask[count-3] = ctx->Polygon.CullBits; } VB->CopyCount = 3; VB->Copy[0] = count-3; COPY_4FV(VB->CopyProj[0], proj[count-3]); } return rv; } /* Eg, quads - just copy the overflow, guarenteed to all be culled. */ static GLuint gl_copy_overflow_cull( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint ovf, CONST GLfloat (*proj)[4] ) { const GLcontext *ctx = VB->ctx; GLubyte *cullmask = VB->CullMask; GLuint src_offset = count - ovf; GLuint dst_offset = 3 - ovf; GLuint i; (void) start; VB->CopyCount = ovf; for (i = 0 ; i < ovf ; i++) { cullmask[i+src_offset] = ctx->Polygon.CullBits; VB->Copy[i+dst_offset] = i+src_offset; COPY_4FV(VB->CopyProj[i+dst_offset], proj[i+src_offset]); } return ovf; } static GLuint gl_copy_last( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint ovf, CONST GLfloat (*proj)[4]) { (void) start; (void) ovf; VB->CopyCount = 1; VB->Copy[2] = count-1; COPY_4FV(VB->CopyProj[2], proj[count-1]); return 0; } static GLuint gl_copy_first_and_last( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint ovf, CONST GLfloat (*proj)[4]) { (void) ovf; VB->CopyCount = 2; VB->Copy[1] = start; VB->Copy[2] = count-1; COPY_4FV(VB->CopyProj[1], proj[start]); COPY_4FV(VB->CopyProj[2], proj[count-1]); return 0; } static GLuint gl_copy_last_two( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint ovf, CONST GLfloat (*proj)[4]) { (void) start; VB->CopyCount = 2; VB->Copy[1] = count-2; VB->Copy[2] = count-1; COPY_4FV(VB->CopyProj[1], proj[count-2]); COPY_4FV(VB->CopyProj[2], proj[count-1]); if (ovf == 1) { VB->CopyCount = 3; VB->Copy[0] = count-3; COPY_4FV(VB->CopyProj[0], proj[count-3]); } return 0; } static GLuint gl_copy_overflow( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint ovf, CONST GLfloat (*proj)[4] ) { GLuint src_offset = count - ovf; GLuint dst_offset = 3 - ovf; GLuint i; (void) start; VB->CopyCount = ovf; for (i = 0 ; i < ovf ; i++) { VB->Copy[i+dst_offset] = i+src_offset; COPY_4FV(VB->CopyProj[i+dst_offset], proj[i+src_offset]); } return 0; } static void gl_fast_copy_noop( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint ovf) { (void) start; (void) ovf; (void) VB; (void) count; } static void gl_fast_copy_last( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint ovf) { (void) start; (void) ovf; VB->CopyCount = 1; VB->Copy[2] = count-1; } static void gl_fast_copy_first_and_last( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint ovf) { (void) ovf; VB->CopyCount = 2; VB->Copy[1] = start; VB->Copy[2] = count-1; } static void gl_fast_copy_last_two( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint ovf ) { (void) start; VB->CopyCount = 2; VB->Copy[1] = count-2; VB->Copy[2] = count-1; if (ovf == 1) { VB->CopyCount = 3; VB->Copy[0] = count-3; } } static void gl_fast_copy_overflow( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint ovf ) { GLuint src_offset = count - ovf; GLuint dst_offset = 3 - ovf; GLuint i; (void) start; VB->CopyCount = ovf; for (i = 0 ; i < ovf ; i++) VB->Copy[i+dst_offset] = i+src_offset; } typedef void (*fast_copy_func)( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint ovf ); typedef GLuint (*cull_func)( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint parity, CONST GLfloat (*proj)[4]); typedef GLuint (*copy_func)( struct vertex_buffer *VB, GLuint start, GLuint end, GLuint ovf, CONST GLfloat (*proj)[4] ); static cull_func cull_tab_both[GL_POLYGON+2] = { gl_cull_points, gl_cull_lines, gl_cull_line_loop, gl_cull_line_strip, gl_cull_triangles, gl_cull_triangle_strip, gl_cull_triangle_fan, gl_cull_quads, gl_cull_quad_strip, gl_cull_triangle_fan, gl_cull_dummy_prim }; static cull_func cull_tab_area[GL_POLYGON+2] = { gl_cull_points_neither, gl_cull_points_neither, gl_cull_points_neither, gl_cull_points_neither, gl_cull_triangles_area, gl_cull_triangle_strip_area, gl_cull_triangle_fan_area, gl_cull_quads_area, gl_cull_quad_strip_area, gl_cull_triangle_fan_area, gl_cull_dummy_prim }; static cull_func cull_tab_clip[GL_POLYGON+2] = { gl_cull_points, gl_cull_lines, gl_cull_line_loop, gl_cull_line_strip, gl_cull_triangles_clip, gl_cull_triangle_strip_clip, gl_cull_triangle_fan_clip, gl_cull_quads_clip, gl_cull_quad_strip_clip, gl_cull_triangle_fan_clip, gl_cull_dummy_prim }; static cull_func *cull_tab[4] = { 0, cull_tab_area, cull_tab_clip, cull_tab_both }; static copy_func copy_tab_cull[GL_POLYGON+2] = { 0, gl_copy_overflow_cull, gl_copy_first_and_last_cull, gl_copy_last_cull, gl_copy_overflow_cull, gl_copy_last_two_cull, gl_copy_first_and_last_cull, gl_copy_overflow_cull, gl_copy_last_two_cull, gl_copy_first_and_last_cull, 0, }; static copy_func copy_tab_no_cull[GL_POLYGON+2] = { 0, gl_copy_overflow, gl_copy_first_and_last, gl_copy_last, gl_copy_overflow, gl_copy_last_two, gl_copy_first_and_last, gl_copy_overflow, gl_copy_last_two, gl_copy_first_and_last, 0, }; static fast_copy_func fast_copy_tab[GL_POLYGON+2] = { gl_fast_copy_noop, gl_fast_copy_overflow, gl_fast_copy_first_and_last, gl_fast_copy_last, gl_fast_copy_overflow, gl_fast_copy_last_two, gl_fast_copy_first_and_last, gl_fast_copy_overflow, gl_fast_copy_last_two, gl_fast_copy_first_and_last, gl_fast_copy_noop, }; /* Do this after (?) primitive fixup on buffers containing unwanted * eval coords. No early culling will be done on these vertices (it's * a degenerate case & not worth the code), and the vertices will be * rendered by a special 'indirect' case in gl_render_vb. Otherwise, * the cullmask will force (some) transforms to skip these vertices. */ void gl_purge_vertices( struct vertex_buffer *VB ) { GLuint *flags = VB->Flag; GLubyte *cullmask = VB->CullMask; GLuint *indirect = VB->Indirect = VB->EltPtr->start; GLuint *in_prim = VB->Primitive; GLuint *out_prim = VB->IM->Primitive; GLuint *in_nextprim = VB->NextPrimitive; GLuint *out_nextprim = VB->IM->NextPrimitive; GLuint count = VB->Count; GLuint purge = VB->PurgeFlags; GLuint next, start; GLuint j; /* */ for ( j = start = VB->CopyStart ; start < count ; start = next ) { GLuint startj = j; GLuint i; next = in_nextprim[start]; out_prim[j] = in_prim[start]; for ( i = start ; i < next ; i++) { if (~(flags[i] & purge)) { indirect[j] = i; cullmask[i] = PRIM_CLIPPED; /* nonzero */ j++; } } out_nextprim[startj] = j; } VB->Primitive = out_prim; VB->NextPrimitive = out_nextprim; VB->IndirectCount = j; } #define VERT_NOT_CLIPPED 0x80 static void build_clip_vert_bits( GLubyte *clipmask, const GLubyte *cullmask, GLuint count ) { GLuint i = 0; for (;;) if (cullmask[++i]==0) { clipmask[i] |= CLIP_CULLED_BIT; if (&cullmask[i] == &cullmask[count]) return; } } GLuint gl_cull_vb( struct vertex_buffer *VB ) { const GLcontext *ctx = VB->ctx; GLuint i, next, prim, n; GLfloat (*proj)[4] = VB->Projected->data; GLuint *in_prim = VB->Primitive; GLuint *out_prim = VB->IM->Primitive; GLuint cullcount = 0; GLuint lastprim = in_prim[VB->LastPrimitive]; GLuint first = VB->CopyStart; GLuint parity = VB->Parity; cull_func *cull_funcs; GLuint idx = 0; if (VB->CullDone) return 0; if (VB->ClipOrMask) idx |= 0x2; if (ctx->IndirectTriangles & (DD_TRI_CULL|DD_EARLY_CULL)) idx |= 0x1; cull_funcs = cull_tab[idx]; for (i = VB->CopyStart ; i < VB->Start ; i++) { COPY_4FV(proj[i], VB->CopyProj[i]); } VB->CopyCount = 0; MEMSET(VB->CullMask, 0, (VB->Count+1) * sizeof(GLubyte)); for ( i = VB->CopyStart ; i < VB->Count ; i = next, parity = 0 ) { first = i; next = VB->NextPrimitive[i]; prim = in_prim[i]; n = cull_funcs[prim]( VB, i, next, parity, (const GLfloat (*)[4])proj ); /* if (n) */ /* printf("vbcull %s culled %d of %d\n", gl_prim_name[prim], n, next-i); */ if (n == next - i) out_prim[i] = GL_POLYGON+1; else out_prim[i] = prim; cullcount += n; } if (VB->LastPrimitive < VB->Count) { if (copy_tab_cull[lastprim]) cullcount -= copy_tab_cull[prim]( VB, first, VB->Count, VB->Ovf, (const GLfloat (*)[4])proj ); } VB->Primitive = out_prim; VB->CullFlag[0] = VB->CullFlag[1] = 0; if (cullcount > 0 || (ctx->IndirectTriangles & DD_EARLY_CULL)) { VB->CullMode |= CULL_MASK_ACTIVE; VB->CullFlag[0] = VB->CullFlag[1] = CLIP_CULLED_BIT&ctx->AllowVertexCull; if (cullcount < VB->Count) build_clip_vert_bits( VB->ClipMask, VB->CullMask, VB->Count ); } if (VB->ClipOrMask) { VB->CullMode |= CLIP_MASK_ACTIVE; VB->CullFlag[1] |= (CLIP_ALL_BITS|CLIP_USER_BIT) & ctx->AllowVertexCull; } VB->CullDone = 1; return cullcount; } /* Need to set up to copy some vertices at the end of the buffer, even * if culling is disabled or the entire vb has been culled by clipping. */ void gl_dont_cull_vb( struct vertex_buffer *VB ) { GLfloat (*proj)[4] = VB->Projected->data; GLuint i; if (VB->CullDone) return; for (i = VB->CopyStart ; i < VB->Start ; i++) COPY_4FV(proj[i], VB->CopyProj[i]); VB->CopyCount = 0; if (VB->LastPrimitive < VB->Count) { GLuint first = VB->LastPrimitive; GLuint prim = VB->Primitive[first]; if (first == VB_START) first = VB->Start; if (copy_tab_no_cull[prim]) copy_tab_no_cull[prim]( VB, first, VB->Count, VB->Ovf, (const GLfloat (*)[4])proj ); } VB->CullDone = 1; } void gl_fast_copy_vb( struct vertex_buffer *VB ) { VB->CopyCount = 0; if (VB->LastPrimitive < VB->Count) { GLuint first = VB->LastPrimitive; GLuint prim = VB->Primitive[first]; if (first == VB_START) first = VB->Start; fast_copy_tab[prim]( VB, first, VB->Count, VB->Ovf ); } } void gl_make_normal_cullmask( struct vertex_buffer *VB ) { GLuint i; if (VB->CullMode & COMPACTED_NORMALS) { /* The shared normals case - never for cva. */ MEMSET(VB->NormCullMask, 0, VB->Count * sizeof(GLubyte)); VB->NormCullStart = VB->NormCullMask + VB->Start; if (VB->CullMode & CULL_MASK_ACTIVE) { GLubyte *lastnorm = VB->NormCullStart; for (i = VB->Start ;;) { *lastnorm |= VB->CullMask[i]; if (VB->Flag[++i] & (VERT_NORM|VERT_END_VB)) { lastnorm = &VB->NormCullMask[i]; if (VB->Flag[i] & VERT_END_VB) return; } } } else { VB->NormCullMask[VB->Start] = ~0; for (i = VB->Start ;; ) if (VB->Flag[++i] & (VERT_NORM|VERT_END_VB)) { VB->NormCullMask[i] = ~0; if (VB->Flag[i] & VERT_END_VB) return; } } } else { /* Non-shared normals. */ VB->NormCullStart = VB->CullMask + VB->Start; } } @ 3.15 log @Fixed a typo gl_copy_overflow_cull (copied to src instead of dst). @ text @d1 1 a1 1 /* $Id: vbcull.c,v 3.14 1999/06/14 11:53:20 keithw Exp $ */ d549 74 d724 16 d753 1 a753 1 GLuint *indirect = VB->Indirect = VB->Elt; a806 2 GLuint idx = ctx->NeedCull | (VB->ClipOrMask ? 0x2 : 0); cull_func *cull_funcs = cull_tab[idx]; d813 2 d816 1 a816 1 if (VB->Type != VB_IMMEDIATE) d819 8 d840 1 a840 1 n = cull_funcs[prim]( VB, i, next, parity, proj ); d860 1 a860 1 proj ); d867 1 a867 1 if (cullcount > 0 || ctx->LightTwoSide) { d869 1 a869 1 VB->CullFlag[0] = VB->CullFlag[1] = CLIP_CULLED_BIT; d877 1 a877 1 VB->CullFlag[1] |= CLIP_ALL_BITS|CLIP_USER_BIT; d879 2 d893 1 a893 1 if (VB->Type != VB_IMMEDIATE) d914 17 a930 1 proj ); @ 3.14 log @GL_LINE vertex copy bug @ text @d1 1 a1 1 /* $Id: vbcull.c,v 3.13 1999/05/16 17:09:59 keithw Exp $ */ d478 1 a478 1 COPY_4FV(VB->CopyProj[i+src_offset], proj[i+dst_offset]); @ 3.13 log @misc. bug fixes @ text @d1 1 a1 1 /* $Id: vbcull.c,v 3.12 1999/05/11 17:43:00 keithw Exp $ */ d379 1 a379 1 GLuint ovf, CONST GLfloat (*clip)[4]) d392 1 a392 1 COPY_4FV(VB->CopyClip[2], clip[count-1]); d399 1 a399 1 CONST GLfloat (*clip)[4] ) d416 2 a417 2 COPY_4FV(VB->CopyClip[1], clip[start]); COPY_4FV(VB->CopyClip[2], clip[count-1]); d427 1 a427 1 CONST GLfloat (*clip)[4] ) d445 2 a446 2 COPY_4FV(VB->CopyClip[1], clip[count-2]); COPY_4FV(VB->CopyClip[2], clip[count-1]); d455 1 a455 1 COPY_4FV(VB->CopyClip[0], clip[count-3]); d466 1 a466 1 GLuint ovf, CONST GLfloat (*clip)[4] ) d478 1 a478 1 COPY_4FV(VB->CopyClip[i+src_offset], clip[i+dst_offset]); d486 1 a486 1 GLuint ovf, CONST GLfloat (*clip)[4]) d492 1 a492 1 COPY_4FV(VB->CopyClip[2], clip[count-1]); d499 1 a499 1 GLuint ovf, CONST GLfloat (*clip)[4]) d505 2 a506 2 COPY_4FV(VB->CopyClip[1], clip[start]); COPY_4FV(VB->CopyClip[2], clip[count-1]); d512 1 a512 1 GLuint ovf, CONST GLfloat (*clip)[4]) d518 2 a519 2 COPY_4FV(VB->CopyClip[1], clip[count-2]); COPY_4FV(VB->CopyClip[2], clip[count-1]); d524 1 a524 1 COPY_4FV(VB->CopyClip[0], clip[count-3]); d534 1 a534 1 CONST GLfloat (*clip)[4] ) d543 1 a543 1 COPY_4FV(VB->CopyClip[i+dst_offset], clip[i+src_offset]); d621 1 a621 1 0, d637 1 a637 1 0, d716 1 a716 1 GLfloat (*clip)[4] = VB->Projected->data; d730 1 a730 1 COPY_4FV(clip[i], VB->CopyClip[i]); d742 1 a742 1 n = cull_funcs[prim]( VB, i, next, parity, clip ); d762 1 a762 1 clip ); d790 1 a790 1 GLfloat (*clip)[4] = VB->Projected->data; d797 1 a797 1 COPY_4FV(clip[i], VB->CopyClip[i]); d814 1 a814 1 clip ); @ 3.13.2.1 log @Quake3 inspired optimizations @ text @d1 1 a1 1 /* $Id: vbcull.c,v 3.13 1999/05/16 17:09:59 keithw Exp $ */ a548 74 static void gl_fast_copy_noop( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint ovf) { (void) start; (void) ovf; (void) VB; (void) count; } static void gl_fast_copy_last( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint ovf) { (void) start; (void) ovf; VB->CopyCount = 1; VB->Copy[2] = count-1; } static void gl_fast_copy_first_and_last( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint ovf) { (void) ovf; VB->CopyCount = 2; VB->Copy[1] = start; VB->Copy[2] = count-1; } static void gl_fast_copy_last_two( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint ovf ) { (void) start; VB->CopyCount = 2; VB->Copy[1] = count-2; VB->Copy[2] = count-1; if (ovf == 1) { VB->CopyCount = 3; VB->Copy[0] = count-3; } } static void gl_fast_copy_overflow( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint ovf ) { GLuint src_offset = count - ovf; GLuint dst_offset = 3 - ovf; GLuint i; (void) start; VB->CopyCount = ovf; for (i = 0 ; i < ovf ; i++) VB->Copy[i+dst_offset] = i+src_offset; } typedef void (*fast_copy_func)( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint ovf ); a649 16 static fast_copy_func fast_copy_tab[GL_POLYGON+2] = { 0, gl_fast_copy_noop, gl_fast_copy_first_and_last, gl_fast_copy_last, gl_fast_copy_overflow, gl_fast_copy_last_two, gl_fast_copy_first_and_last, gl_fast_copy_overflow, gl_fast_copy_last_two, gl_fast_copy_first_and_last, gl_fast_copy_noop, }; d663 1 a663 1 GLuint *indirect = VB->Indirect = VB->EltPtr->start; d726 1 a726 1 if (VB->CullDone) d742 1 a742 1 n = cull_funcs[prim]( VB, i, next, parity, (const GLfloat (*)[4])clip ); d762 1 a762 1 (const GLfloat (*)[4])clip ); d771 1 a771 1 VB->CullFlag[0] = VB->CullFlag[1] = CLIP_CULLED_BIT&ctx->AllowVertexCull; d779 1 a779 1 VB->CullFlag[1] |= (CLIP_ALL_BITS|CLIP_USER_BIT) & ctx->AllowVertexCull; a780 2 VB->CullDone = 1; d793 1 a793 1 if (VB->CullDone) d814 1 a814 17 (const GLfloat (*)[4])clip ); } VB->CullDone = 1; } void gl_fast_copy_vb( struct vertex_buffer *VB ) { VB->CopyCount = 0; if (VB->LastPrimitive < VB->Count) { GLuint first = VB->LastPrimitive; GLuint prim = VB->Primitive[first]; if (first == VB_START) first = VB->Start; fast_copy_tab[prim]( VB, first, VB->Count, VB->Ovf ); @ 3.13.2.2 log @clipping bugs @ text @d1 1 a1 1 /* $Id: vbcull.c,v 3.13.2.1 1999/05/21 21:29:28 keithw Exp $ */ d726 1 a726 1 gl_fast_copy_noop, @ 3.13.2.3 log @Removed SGIS multitexture, added FX/X86 assm directory @ text @d1 1 a1 1 /* $Id: vbcull.c,v 3.13.2.2 1999/05/22 09:44:26 keithw Exp $ */ d478 1 a478 1 COPY_4FV(VB->CopyClip[i+dst_offset], clip[i+src_offset]); d695 1 a695 1 gl_copy_overflow_cull, d711 1 a711 1 gl_copy_overflow, d727 1 a727 1 gl_fast_copy_overflow, d807 2 a814 2 cull_func *cull_funcs; GLuint idx = 0; a818 8 if (VB->ClipOrMask) idx |= 0x2; if (ctx->IndirectTriangles & (DD_TRI_CULL|DD_EARLY_CULL)) idx |= 0x1; cull_funcs = cull_tab[idx]; d859 1 a859 1 if (cullcount > 0 || (ctx->IndirectTriangles & DD_EARLY_CULL)) { @ 3.12 log @miscellaneous bug fixes @ text @d1 1 a1 1 /* $Id: vbcull.c,v 3.11 1999/05/01 18:46:15 keithw Exp $ */ d441 1 a441 1 @ 3.11 log @fix for miklos' overflow problem @ text @d1 1 a1 1 /* $Id: vbcull.c,v 3.10 1999/04/29 14:43:16 keithw Exp $ */ d133 2 a134 2 cullmask[i1] = VERT_FACE_FRONT; \ cullmask[i] = VERT_FACE_FRONT | PRIM_FACE_FRONT | PRIM_CLIPPED; \ d137 2 a138 2 cullmask[i1] = VERT_FACE_FRONT; \ cullmask[i] = VERT_FACE_FRONT | PRIM_FACE_FRONT; \ d183 1 a183 1 d298 1 a298 1 cullmask[i1] = cull_faces; \ d326 1 a326 1 cullmask[i1] = face_flags; \ @ 3.10 log @fixes for xlockmore problems @ text @d1 1 a1 1 /* $Id: vbcull.c,v 3.9 1999/04/07 22:19:04 brianp Exp $ */ d543 1 a543 1 COPY_4FV(VB->CopyClip[i+src_offset], clip[i+dst_offset]); @ 3.9 log @inserted copyright info @ text @d1 1 a1 1 /* $Id$ */ d219 1 a219 1 #define CULL_TRI( do_clip, do_area, i2, i1, i, parity, nr ) \ d221 1 a221 1 GLubyte ClipOr; \ d223 3 a225 5 ClipOr = (VB->ClipMask[i2] | \ VB->ClipMask[i1] | \ VB->ClipMask[i]); \ } else { \ ClipOr = 0; \ d227 1 a227 1 \ d230 2 a231 2 if (VB->ClipMask[i2] & VB->ClipMask[i1] & VB->ClipMask[i] & \ CLIP_ALL_BITS) \ d237 3 a239 3 cullmask[i] = cull_faces | PRIM_CLIPPED; \ cullmask[i1] |= cull_faces; \ cullmask[i2] |= cull_faces; \ d242 1 a242 1 else \ d248 5 a252 5 area = ((proj[i2][0] - proj[i][0]) * \ (proj[i1][1] - proj[i][1]) - \ (proj[i2][1] - proj[i][1]) * \ (proj[i1][0] - proj[i][0])); \ \ d255 1 a255 1 face_flags = cull_faces; \ d260 1 a260 1 cullmask[i] = face_flags | (face_flags << PRIM_FLAG_SHIFT); \ d263 3 a265 3 if (ClipOr) cullmask[i] |= PRIM_CLIPPED; \ } \ else \ d575 1 a575 1 gl_cull_polygon, d590 1 a590 1 gl_cull_polygon_area, d605 1 a605 1 gl_cull_polygon_clip, d743 3 @ 3.8 log @Compiled vertex arrays @ text @d1 1 a1 1 /* $Id: vbcull.c,v 3.7 1999/03/23 13:09:21 keithw Exp $ */ d6 19 a24 15 * Copyright (C) 1995-1998 Brian Paul * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. a26 1 d28 1 a28 1 * $Log: d30 1 @ 3.7 log @fixed bug in make_norm_cull_mask @ text @d1 1 a1 1 /* $Id: vbcull.c,v 3.6 1999/03/20 18:59:12 brianp Exp $ */ d6 15 a20 19 * * Copyright (C) 1999 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. d24 17 a60 15 #ifdef PC_HEADER #include "all.h" #else #include #include "context.h" #include "macros.h" #include "types.h" #include "vb.h" #include "vbcull.h" #include "vbrender.h" #include "xform.h" #endif d76 1 a76 1 static GLuint gl_cull_points( GLcontext *ctx, a81 1 struct vertex_buffer *VB = ctx->VB; d105 1 a105 1 static GLuint gl_cull_points_neither( GLcontext *ctx, a110 1 const struct vertex_buffer *VB = ctx->VB; d140 1 a140 1 static GLuint gl_cull_lines( GLcontext *ctx, a145 1 struct vertex_buffer *VB = ctx->VB; d165 1 a165 1 static GLuint gl_cull_line_strip( GLcontext *ctx, a170 1 struct vertex_buffer *VB = ctx->VB; d191 1 a191 1 static GLuint gl_cull_line_loop( GLcontext *ctx, a196 1 struct vertex_buffer *VB = ctx->VB; d352 1 a352 1 static GLuint gl_cull_dummy_prim( GLcontext *ctx, d358 1 a358 1 (void) ctx; d375 2 a376 1 static GLuint gl_copy_last_cull( GLcontext *ctx, GLuint start, GLuint count, d379 1 a379 1 struct vertex_buffer *VB = ctx->VB; d390 1 a390 1 COPY_4V(VB->CopyClip[2], clip[count-1]); d394 2 a395 1 static GLuint gl_copy_first_and_last_cull( GLcontext *ctx, GLuint start, d399 1 a400 1 struct vertex_buffer *VB = ctx->VB; d414 2 a415 2 COPY_4V(VB->CopyClip[1], clip[start]); COPY_4V(VB->CopyClip[2], clip[count-1]); d422 2 a423 1 static GLuint gl_copy_last_two_cull( GLcontext *ctx, GLuint start, d427 1 a427 1 struct vertex_buffer *VB = ctx->VB; d440 5 a444 5 ctx->VB->CopyCount = 2; ctx->VB->Copy[1] = count-2; ctx->VB->Copy[2] = count-1; COPY_4V(VB->CopyClip[1], clip[count-2]); COPY_4V(VB->CopyClip[2], clip[count-1]); d451 3 a453 3 ctx->VB->CopyCount = 3; ctx->VB->Copy[0] = count-3; COPY_4V(VB->CopyClip[0], clip[count-3]); d462 1 a462 1 static GLuint gl_copy_overflow_cull( GLcontext *ctx, d466 1 a466 1 struct vertex_buffer *VB = ctx->VB; d476 1 a476 1 COPY_4V(VB->CopyClip[i+src_offset], clip[i+dst_offset]); d482 3 a484 2 static GLuint gl_copy_last( GLcontext *ctx, GLuint start, GLuint count, GLuint ovf, CONST GLfloat (*clip)[4]) a485 1 struct vertex_buffer *VB = ctx->VB; d490 1 a490 1 COPY_4V(VB->CopyClip[2], clip[count-1]); d494 2 a495 1 static GLuint gl_copy_first_and_last( GLcontext *ctx, GLuint start, a498 1 struct vertex_buffer *VB = ctx->VB; d503 2 a504 2 COPY_4V(VB->CopyClip[1], clip[start]); COPY_4V(VB->CopyClip[2], clip[count-1]); d508 2 a509 1 static GLuint gl_copy_last_two( GLcontext *ctx, GLuint start, GLuint count, a511 1 struct vertex_buffer *VB = ctx->VB; d516 2 a517 2 COPY_4V(VB->CopyClip[1], clip[count-2]); COPY_4V(VB->CopyClip[2], clip[count-1]); d520 3 a522 3 ctx->VB->CopyCount = 3; ctx->VB->Copy[0] = count-3; COPY_4V(VB->CopyClip[0], clip[count-3]); d524 1 d528 1 a528 1 static GLuint gl_copy_overflow( GLcontext *ctx, a533 1 struct vertex_buffer *VB = ctx->VB; d541 1 a541 1 COPY_4V(VB->CopyClip[i+src_offset], clip[i+dst_offset]); d543 1 d547 1 a547 1 typedef GLuint (*cull_func)( GLcontext *ctx, d554 1 a554 1 typedef GLuint (*copy_func)( GLcontext *ctx, d657 1 a657 1 void gl_purge_vertices( GLcontext *ctx ) a658 1 struct vertex_buffer *VB = ctx->VB; d661 1 a661 1 GLuint *indirect = VB->Indirect; d663 1 a663 1 GLuint *out_prim = VB->store.Primitive; d665 1 a665 1 GLuint *out_nextprim = VB->store.NextPrimitive; d667 1 a667 1 GLuint purge = VB->NeedPurge; a672 1 d694 1 a694 1 VB->PurgeCount = j; d702 1 a702 1 GLuint i = VB_START-1; d710 1 a710 1 GLuint gl_cull_vb( GLcontext *ctx ) d712 1 a712 1 struct vertex_buffer *VB = ctx->VB; d718 1 a718 1 GLuint *out_prim = VB->store.Primitive; d721 1 d724 5 a728 2 for (i = VB->CopyStart ; i < VB_START ; i++) { COPY_4V(clip[i], VB->CopyClip[i]); d733 1 a733 3 MEMSET(VB->CullMask, 0, VB->Count * sizeof(GLubyte)); VB->CullMask[VB->Count] = 0; d737 1 d740 1 a740 1 n = cull_funcs[prim]( ctx, i, next, parity, clip ); d753 2 a754 2 cullcount -= copy_tab_cull[prim]( ctx, VB->LastPrimitive, d768 1 a768 1 if (VB->ClipOrMask && cullcount < VB->Count) d783 1 a783 1 void gl_dont_cull_vb( GLcontext *ctx ) a784 1 struct vertex_buffer *VB = ctx->VB; d788 5 a792 2 for (i = VB->CopyStart ; i < VB_START ; i++) COPY_4V(clip[i], VB->CopyClip[i]); d798 5 a802 1 GLuint prim = VB->Primitive[VB->LastPrimitive]; d805 2 a806 2 copy_tab_no_cull[prim]( ctx, VB->LastPrimitive, d817 1 a817 1 void gl_make_normal_cullmask( GLcontext *ctx ) a818 1 struct vertex_buffer *VB = ctx->VB; d822 1 a822 1 /* The shared normals case. d825 1 a825 1 VB->NormCullStart = VB->NormCullMask + VB_START; d830 1 a830 1 for (i = VB_START ;;) { d838 2 a839 2 VB->NormCullMask[VB_START] = ~0; for (i = VB_START ;; ) d848 1 a848 1 VB->NormCullStart = VB->CullMask + VB_START; @ 3.6 log @fixed IRIX compiler warnings @ text @d1 1 a1 1 /* $Id: vbcull.c,v 3.5 1999/03/17 16:51:17 keithw Exp $ */ d835 2 a836 1 for (i = VB_START-1 ;; ) @ 3.5 log @Fix for culling shared normals. @ text @d1 1 a1 1 /* $Id: vbcull.c,v 3.4 1999/03/17 12:08:22 keithw Exp $ */ d89 3 d116 2 d156 3 d183 3 d207 2 a208 1 d365 3 d388 2 d407 1 d434 1 d475 1 d490 2 d503 1 d516 1 d541 1 @ 3.4 log @Removed CLIP_4D_BIT, added CLIP_CULLED_BIT. Clipmask is now used to drive culling in vertex transformation, allowing us to skip both clipped and culled vertices with a single test. @ text @d1 1 a1 1 /* $Id: vbcull.c,v 3.3 1999/02/27 17:17:14 brianp Exp $ */ d793 1 a793 5 if (!(VB->CullMode & COMPACTED_NORMALS)) { /* Non-shared normals. */ VB->NormCullStart = VB->CullMask + VB_START; } else { a795 2 GLubyte *lastnorm; lastnorm = VB->NormCullStart = VB->NormCullMask + VB_START; d797 1 d799 2 a800 4 for (i = VB_START ; i < VB->Count ; i++) { if (VB->Flag[i] & VERT_NORM) lastnorm = &VB->NormCullMask[i]; d802 1 a802 1 if (VB->CullMask[i]) d804 11 d816 4 @ 3.3 log @replaced const with CONST @ text @d1 1 a1 1 /* $Id: vbcull.c,v 3.2 1999/02/26 03:37:25 brianp Exp $ */ d677 1 d679 10 d708 3 a710 1 MEMSET(VB->CullMask, 0, VB_MAX * sizeof(GLubyte)); d738 15 @ 3.2 log @added RCS Id tag @ text @d1 1 a1 1 /* $Id$ */ d82 1 a82 1 const GLfloat (*proj)[4]) d84 1 a84 1 const struct vertex_buffer *VB = ctx->VB; d109 1 a109 1 const GLfloat (*proj)[4]) d143 1 a143 1 const GLfloat (*proj)[4]) d166 1 a166 1 const GLfloat (*proj)[4]) d190 1 a190 1 const GLfloat (*proj)[4]) d351 1 a351 1 const GLfloat (*proj)[4]) d368 1 a368 1 GLuint ovf, const GLfloat (*clip)[4]) d385 1 a385 1 const GLfloat (*clip)[4] ) d411 1 a411 1 const GLfloat (*clip)[4] ) d449 1 a449 1 GLuint ovf, const GLfloat (*clip)[4] ) d467 1 a467 1 GLuint ovf, const GLfloat (*clip)[4]) d478 1 a478 1 GLuint ovf, const GLfloat (*clip)[4]) d490 1 a490 1 GLuint ovf, const GLfloat (*clip)[4]) d511 1 a511 1 const GLfloat (*clip)[4] ) d529 1 a529 1 const GLfloat (*proj)[4]); d536 1 a536 1 const GLfloat (*proj)[4] ); @ 3.1 log @Merged in kw3 patch @ text @d1 2 @