draw_pipe_cull.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  * 
00003  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  *
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  * 
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  * 
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025  * 
00026  **************************************************************************/
00027 
00032 /* Authors:  Keith Whitwell <keith@tungstengraphics.com>
00033  */
00034 
00035 
00036 #include "util/u_memory.h"
00037 #include "pipe/p_defines.h"
00038 #include "draw_pipe.h"
00039 
00040 
00041 struct cull_stage {
00042    struct draw_stage stage;
00043    unsigned winding;  
00044 };
00045 
00046 
00047 static INLINE struct cull_stage *cull_stage( struct draw_stage *stage )
00048 {
00049    return (struct cull_stage *)stage;
00050 }
00051 
00052 
00053 
00054 
00055 static void cull_tri( struct draw_stage *stage,
00056                       struct prim_header *header )
00057 {
00058    const unsigned pos = stage->draw->vs.position_output;
00059 
00060    /* Window coords: */
00061    const float *v0 = header->v[0]->data[pos];
00062    const float *v1 = header->v[1]->data[pos];
00063    const float *v2 = header->v[2]->data[pos];
00064 
00065    /* edge vectors e = v0 - v2, f = v1 - v2 */
00066    const float ex = v0[0] - v2[0];
00067    const float ey = v0[1] - v2[1];
00068    const float fx = v1[0] - v2[0];
00069    const float fy = v1[1] - v2[1];
00070    
00071    /* det = cross(e,f).z */
00072    header->det = ex * fy - ey * fx;
00073 
00074    if (header->det != 0) {
00075       /* if (det < 0 then Z points toward camera and triangle is 
00076        * counter-clockwise winding.
00077        */
00078       unsigned winding = (header->det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW;
00079 
00080       if ((winding & cull_stage(stage)->winding) == 0) {
00081          /* triangle is not culled, pass to next stage */
00082          stage->next->tri( stage->next, header );
00083       }
00084    }
00085 }
00086 
00087 static void cull_first_tri( struct draw_stage *stage, 
00088                             struct prim_header *header )
00089 {
00090    struct cull_stage *cull = cull_stage(stage);
00091 
00092    cull->winding = stage->draw->rasterizer->cull_mode;
00093 
00094    stage->tri = cull_tri;
00095    stage->tri( stage, header );
00096 }
00097 
00098 
00099 
00100 static void cull_flush( struct draw_stage *stage, unsigned flags )
00101 {
00102    stage->tri = cull_first_tri;
00103    stage->next->flush( stage->next, flags );
00104 }
00105 
00106 static void cull_reset_stipple_counter( struct draw_stage *stage )
00107 {
00108    stage->next->reset_stipple_counter( stage->next );
00109 }
00110 
00111 
00112 static void cull_destroy( struct draw_stage *stage )
00113 {
00114    draw_free_temp_verts( stage );
00115    FREE( stage );
00116 }
00117 
00118 
00122 struct draw_stage *draw_cull_stage( struct draw_context *draw )
00123 {
00124    struct cull_stage *cull = CALLOC_STRUCT(cull_stage);
00125    if (cull == NULL)
00126       goto fail;
00127 
00128    if (!draw_alloc_temp_verts( &cull->stage, 0 ))
00129       goto fail;
00130 
00131    cull->stage.draw = draw;
00132    cull->stage.next = NULL;
00133    cull->stage.point = draw_pipe_passthrough_point;
00134    cull->stage.line = draw_pipe_passthrough_line;
00135    cull->stage.tri = cull_first_tri;
00136    cull->stage.flush = cull_flush;
00137    cull->stage.reset_stipple_counter = cull_reset_stipple_counter;
00138    cull->stage.destroy = cull_destroy;
00139 
00140    return &cull->stage;
00141 
00142  fail:
00143    if (cull)
00144       cull->stage.destroy( &cull->stage );
00145 
00146    return NULL;
00147 }

Generated on Tue Sep 29 06:25:14 2009 for Gallium3D by  doxygen 1.5.4