1848b8605Smrg/* 2848b8605Smrg * Mesa 3-D graphics library 3848b8605Smrg * 4848b8605Smrg * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 5848b8605Smrg * 6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7848b8605Smrg * copy of this software and associated documentation files (the "Software"), 8848b8605Smrg * to deal in the Software without restriction, including without limitation 9848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 11848b8605Smrg * Software is furnished to do so, subject to the following conditions: 12848b8605Smrg * 13848b8605Smrg * The above copyright notice and this permission notice shall be included 14848b8605Smrg * in all copies or substantial portions of the Software. 15848b8605Smrg * 16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE. 23848b8605Smrg * 24848b8605Smrg * Authors: 25848b8605Smrg * Keith Whitwell <keithw@vmware.com> 26848b8605Smrg */ 27848b8605Smrg 28b8e80941Smrg#include "c99_math.h" 29848b8605Smrg#include "main/glheader.h" 30848b8605Smrg#include "main/macros.h" 31848b8605Smrg#include "main/mtypes.h" 32b8e80941Smrg#include "main/stencil.h" 33b8e80941Smrg#include "main/state.h" 34848b8605Smrg 35848b8605Smrg#include "tnl/t_context.h" 36848b8605Smrg 37848b8605Smrg#include "ss_triangle.h" 38848b8605Smrg#include "ss_context.h" 39848b8605Smrg 40848b8605Smrg#define SS_OFFSET_BIT 0x1 41848b8605Smrg#define SS_TWOSIDE_BIT 0x2 42848b8605Smrg#define SS_UNFILLED_BIT 0x4 43848b8605Smrg#define SS_MAX_TRIFUNC 0x8 44848b8605Smrg 45848b8605Smrgstatic tnl_triangle_func tri_tab[SS_MAX_TRIFUNC]; 46848b8605Smrgstatic tnl_quad_func quad_tab[SS_MAX_TRIFUNC]; 47848b8605Smrg 48848b8605Smrg 49848b8605Smrg/* 50848b8605Smrg * Render a triangle respecting edge flags. 51848b8605Smrg */ 52848b8605Smrgtypedef void (* swsetup_edge_render_prim_tri)(struct gl_context *ctx, 53848b8605Smrg const GLubyte *ef, 54848b8605Smrg GLuint e0, 55848b8605Smrg GLuint e1, 56848b8605Smrg GLuint e2, 57848b8605Smrg const SWvertex *v0, 58848b8605Smrg const SWvertex *v1, 59848b8605Smrg const SWvertex *v2); 60848b8605Smrg 61848b8605Smrg/* 62848b8605Smrg * Render a triangle using lines and respecting edge flags. 63848b8605Smrg */ 64848b8605Smrgstatic void 65848b8605Smrg_swsetup_edge_render_line_tri(struct gl_context *ctx, 66848b8605Smrg const GLubyte *ef, 67848b8605Smrg GLuint e0, 68848b8605Smrg GLuint e1, 69848b8605Smrg GLuint e2, 70848b8605Smrg const SWvertex *v0, 71848b8605Smrg const SWvertex *v1, 72848b8605Smrg const SWvertex *v2) 73848b8605Smrg{ 74848b8605Smrg SScontext *swsetup = SWSETUP_CONTEXT(ctx); 75848b8605Smrg 76848b8605Smrg if (swsetup->render_prim == GL_POLYGON) { 77848b8605Smrg if (ef[e2]) _swrast_Line( ctx, v2, v0 ); 78848b8605Smrg if (ef[e0]) _swrast_Line( ctx, v0, v1 ); 79848b8605Smrg if (ef[e1]) _swrast_Line( ctx, v1, v2 ); 80848b8605Smrg } else { 81848b8605Smrg if (ef[e0]) _swrast_Line( ctx, v0, v1 ); 82848b8605Smrg if (ef[e1]) _swrast_Line( ctx, v1, v2 ); 83848b8605Smrg if (ef[e2]) _swrast_Line( ctx, v2, v0 ); 84848b8605Smrg } 85848b8605Smrg} 86848b8605Smrg 87848b8605Smrg/* 88848b8605Smrg * Render a triangle using points and respecting edge flags. 89848b8605Smrg */ 90848b8605Smrgstatic void 91848b8605Smrg_swsetup_edge_render_point_tri(struct gl_context *ctx, 92848b8605Smrg const GLubyte *ef, 93848b8605Smrg GLuint e0, 94848b8605Smrg GLuint e1, 95848b8605Smrg GLuint e2, 96848b8605Smrg const SWvertex *v0, 97848b8605Smrg const SWvertex *v1, 98848b8605Smrg const SWvertex *v2) 99848b8605Smrg{ 100848b8605Smrg if (ef[e0]) _swrast_Point( ctx, v0 ); 101848b8605Smrg if (ef[e1]) _swrast_Point( ctx, v1 ); 102848b8605Smrg if (ef[e2]) _swrast_Point( ctx, v2 ); 103848b8605Smrg 104848b8605Smrg _swrast_flush(ctx); 105848b8605Smrg} 106848b8605Smrg 107848b8605Smrg/* 108848b8605Smrg * Render a triangle respecting cull and shade model. 109848b8605Smrg */ 110848b8605Smrgstatic void _swsetup_render_tri(struct gl_context *ctx, 111848b8605Smrg GLuint e0, 112848b8605Smrg GLuint e1, 113848b8605Smrg GLuint e2, 114848b8605Smrg GLuint facing, 115848b8605Smrg swsetup_edge_render_prim_tri render) 116848b8605Smrg{ 117848b8605Smrg SScontext *swsetup = SWSETUP_CONTEXT(ctx); 118848b8605Smrg struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; 119848b8605Smrg GLubyte *ef = VB->EdgeFlag; 120848b8605Smrg SWvertex *verts = swsetup->verts; 121848b8605Smrg SWvertex *v0 = &verts[e0]; 122848b8605Smrg SWvertex *v1 = &verts[e1]; 123848b8605Smrg SWvertex *v2 = &verts[e2]; 124848b8605Smrg 125848b8605Smrg /* cull testing */ 126848b8605Smrg if (ctx->Polygon.CullFlag) { 127848b8605Smrg if (facing == 1 && ctx->Polygon.CullFaceMode != GL_FRONT) 128848b8605Smrg return; 129848b8605Smrg if (facing == 0 && ctx->Polygon.CullFaceMode != GL_BACK) 130848b8605Smrg return; 131848b8605Smrg } 132848b8605Smrg 133848b8605Smrg _swrast_SetFacing(ctx, facing); 134848b8605Smrg 135848b8605Smrg if (ctx->Light.ShadeModel == GL_FLAT) { 136848b8605Smrg GLchan c[2][4]; 137848b8605Smrg GLfloat s[2][4]; 138848b8605Smrg 139848b8605Smrg /* save colors/indexes for v0, v1 vertices */ 140848b8605Smrg COPY_CHAN4(c[0], v0->color); 141848b8605Smrg COPY_CHAN4(c[1], v1->color); 142848b8605Smrg COPY_4V(s[0], v0->attrib[VARYING_SLOT_COL1]); 143848b8605Smrg COPY_4V(s[1], v1->attrib[VARYING_SLOT_COL1]); 144848b8605Smrg 145848b8605Smrg /* copy v2 color/indexes to v0, v1 indexes */ 146848b8605Smrg COPY_CHAN4(v0->color, v2->color); 147848b8605Smrg COPY_CHAN4(v1->color, v2->color); 148848b8605Smrg COPY_4V(v0->attrib[VARYING_SLOT_COL1], v2->attrib[VARYING_SLOT_COL1]); 149848b8605Smrg COPY_4V(v1->attrib[VARYING_SLOT_COL1], v2->attrib[VARYING_SLOT_COL1]); 150848b8605Smrg 151848b8605Smrg render(ctx, ef, e0, e1, e2, v0, v1, v2); 152848b8605Smrg 153848b8605Smrg COPY_CHAN4(v0->color, c[0]); 154848b8605Smrg COPY_CHAN4(v1->color, c[1]); 155848b8605Smrg COPY_4V(v0->attrib[VARYING_SLOT_COL1], s[0]); 156848b8605Smrg COPY_4V(v1->attrib[VARYING_SLOT_COL1], s[1]); 157848b8605Smrg } 158848b8605Smrg else { 159848b8605Smrg render(ctx, ef, e0, e1, e2, v0, v1, v2); 160848b8605Smrg } 161848b8605Smrg} 162848b8605Smrg 163848b8605Smrg#define SS_COLOR(a,b) UNCLAMPED_FLOAT_TO_RGBA_CHAN(a,b) 164848b8605Smrg#define SS_SPEC(a,b) COPY_4V(a,b) 165848b8605Smrg#define SS_IND(a,b) (a = b) 166848b8605Smrg 167848b8605Smrg#define IND (0) 168848b8605Smrg#define TAG(x) x##_rgba 169848b8605Smrg#include "ss_tritmp.h" 170848b8605Smrg 171848b8605Smrg#define IND (SS_OFFSET_BIT) 172848b8605Smrg#define TAG(x) x##_offset_rgba 173848b8605Smrg#include "ss_tritmp.h" 174848b8605Smrg 175848b8605Smrg#define IND (SS_TWOSIDE_BIT) 176848b8605Smrg#define TAG(x) x##_twoside_rgba 177848b8605Smrg#include "ss_tritmp.h" 178848b8605Smrg 179848b8605Smrg#define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT) 180848b8605Smrg#define TAG(x) x##_offset_twoside_rgba 181848b8605Smrg#include "ss_tritmp.h" 182848b8605Smrg 183848b8605Smrg#define IND (SS_UNFILLED_BIT) 184848b8605Smrg#define TAG(x) x##_unfilled_rgba 185848b8605Smrg#include "ss_tritmp.h" 186848b8605Smrg 187848b8605Smrg#define IND (SS_OFFSET_BIT|SS_UNFILLED_BIT) 188848b8605Smrg#define TAG(x) x##_offset_unfilled_rgba 189848b8605Smrg#include "ss_tritmp.h" 190848b8605Smrg 191848b8605Smrg#define IND (SS_TWOSIDE_BIT|SS_UNFILLED_BIT) 192848b8605Smrg#define TAG(x) x##_twoside_unfilled_rgba 193848b8605Smrg#include "ss_tritmp.h" 194848b8605Smrg 195848b8605Smrg#define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT|SS_UNFILLED_BIT) 196848b8605Smrg#define TAG(x) x##_offset_twoside_unfilled_rgba 197848b8605Smrg#include "ss_tritmp.h" 198848b8605Smrg 199848b8605Smrg 200848b8605Smrgvoid _swsetup_trifuncs_init( struct gl_context *ctx ) 201848b8605Smrg{ 202848b8605Smrg (void) ctx; 203848b8605Smrg 204848b8605Smrg init_rgba(); 205848b8605Smrg init_offset_rgba(); 206848b8605Smrg init_twoside_rgba(); 207848b8605Smrg init_offset_twoside_rgba(); 208848b8605Smrg init_unfilled_rgba(); 209848b8605Smrg init_offset_unfilled_rgba(); 210848b8605Smrg init_twoside_unfilled_rgba(); 211848b8605Smrg init_offset_twoside_unfilled_rgba(); 212848b8605Smrg} 213848b8605Smrg 214848b8605Smrg 215848b8605Smrgstatic void swsetup_points( struct gl_context *ctx, GLuint first, GLuint last ) 216848b8605Smrg{ 217848b8605Smrg struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; 218848b8605Smrg SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts; 219848b8605Smrg GLuint i; 220848b8605Smrg 221848b8605Smrg if (VB->Elts) { 222848b8605Smrg for (i = first; i < last; i++) 223848b8605Smrg if (VB->ClipMask[VB->Elts[i]] == 0) 224848b8605Smrg _swrast_Point( ctx, &verts[VB->Elts[i]] ); 225848b8605Smrg } 226848b8605Smrg else { 227848b8605Smrg for (i = first; i < last; i++) 228848b8605Smrg if (VB->ClipMask[i] == 0) 229848b8605Smrg _swrast_Point( ctx, &verts[i] ); 230848b8605Smrg } 231848b8605Smrg} 232848b8605Smrg 233848b8605Smrgstatic void swsetup_line( struct gl_context *ctx, GLuint v0, GLuint v1 ) 234848b8605Smrg{ 235848b8605Smrg SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts; 236848b8605Smrg _swrast_Line( ctx, &verts[v0], &verts[v1] ); 237848b8605Smrg} 238848b8605Smrg 239848b8605Smrg 240848b8605Smrg 241848b8605Smrgvoid _swsetup_choose_trifuncs( struct gl_context *ctx ) 242848b8605Smrg{ 243848b8605Smrg TNLcontext *tnl = TNL_CONTEXT(ctx); 244848b8605Smrg GLuint ind = 0; 245848b8605Smrg 246848b8605Smrg if (ctx->Polygon.OffsetPoint || 247848b8605Smrg ctx->Polygon.OffsetLine || 248848b8605Smrg ctx->Polygon.OffsetFill) 249848b8605Smrg ind |= SS_OFFSET_BIT; 250848b8605Smrg 251848b8605Smrg if ((ctx->Light.Enabled && ctx->Light.Model.TwoSide) || 252848b8605Smrg (ctx->VertexProgram._Current && ctx->VertexProgram.TwoSideEnabled)) 253848b8605Smrg ind |= SS_TWOSIDE_BIT; 254848b8605Smrg 255848b8605Smrg /* We piggyback the two-sided stencil front/back determination on the 256848b8605Smrg * unfilled triangle path. 257848b8605Smrg */ 258848b8605Smrg if (ctx->Polygon.FrontMode != GL_FILL || 259848b8605Smrg ctx->Polygon.BackMode != GL_FILL || 260b8e80941Smrg (ctx->Stencil.Enabled && _mesa_stencil_is_two_sided(ctx))) 261848b8605Smrg ind |= SS_UNFILLED_BIT; 262848b8605Smrg 263848b8605Smrg tnl->Driver.Render.Triangle = tri_tab[ind]; 264848b8605Smrg tnl->Driver.Render.Quad = quad_tab[ind]; 265848b8605Smrg tnl->Driver.Render.Line = swsetup_line; 266848b8605Smrg tnl->Driver.Render.Points = swsetup_points; 267848b8605Smrg} 268