ss_tritmp.h revision f782b8189e718974a40d72ac4f6b8d213ca99e1e
1/* $Id: ss_tritmp.h,v 1.17 2002/10/04 17:37:47 brianp Exp $ */ 2 3/* 4 * Mesa 3-D graphics library 5 * Version: 3.5 6 * 7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the "Software"), 11 * to deal in the Software without restriction, including without limitation 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13 * and/or sell copies of the Software, and to permit persons to whom the 14 * Software is furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included 17 * in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 * Authors: 27 * Keith Whitwell <keithw@valinux.com> 28 */ 29 30 31static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 ) 32{ 33 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; 34 SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts; 35 SWvertex *v[3]; 36 GLfloat z[3]; 37 GLfloat offset; 38 GLenum mode = GL_FILL; 39 GLuint facing; 40 41 v[0] = &verts[e0]; 42 v[1] = &verts[e1]; 43 v[2] = &verts[e2]; 44 45 46 if (IND & (SS_TWOSIDE_BIT | SS_OFFSET_BIT | SS_UNFILLED_BIT)) 47 { 48 GLfloat ex = v[0]->win[0] - v[2]->win[0]; 49 GLfloat ey = v[0]->win[1] - v[2]->win[1]; 50 GLfloat fx = v[1]->win[0] - v[2]->win[0]; 51 GLfloat fy = v[1]->win[1] - v[2]->win[1]; 52 GLfloat cc = ex*fy - ey*fx; 53 54 if (IND & (SS_TWOSIDE_BIT | SS_UNFILLED_BIT)) 55 { 56 facing = (cc < 0.0) ^ ctx->Polygon._FrontBit; 57 if (ctx->Stencil.TestTwoSide) 58 ctx->_Facing = facing; /* for 2-sided stencil test */ 59 60 if (IND & SS_UNFILLED_BIT) 61 mode = facing ? ctx->Polygon.BackMode : ctx->Polygon.FrontMode; 62 63 if (facing == 1) { 64 if (IND & SS_TWOSIDE_BIT) { 65 if (IND & SS_RGBA_BIT) { 66 GLchan (*vbcolor)[4] = (GLchan (*)[4])VB->ColorPtr[1]->Ptr; 67 SS_COLOR(v[0]->color, vbcolor[e0]); 68 SS_COLOR(v[1]->color, vbcolor[e1]); 69 SS_COLOR(v[2]->color, vbcolor[e2]); 70 if (VB->SecondaryColorPtr[1]) { 71 GLchan (*vbspec)[4] = (GLchan (*)[4])VB->SecondaryColorPtr[1]->Ptr; 72 SS_SPEC(v[0]->specular, vbspec[e0]); 73 SS_SPEC(v[1]->specular, vbspec[e1]); 74 SS_SPEC(v[2]->specular, vbspec[e2]); 75 } 76 } else { 77 GLuint *vbindex = VB->IndexPtr[1]->data; 78 SS_IND(v[0]->index, vbindex[e0]); 79 SS_IND(v[1]->index, vbindex[e1]); 80 SS_IND(v[2]->index, vbindex[e2]); 81 } 82 } 83 } 84 } 85 86 if (IND & SS_OFFSET_BIT) 87 { 88 offset = ctx->Polygon.OffsetUnits; 89 z[0] = v[0]->win[2]; 90 z[1] = v[1]->win[2]; 91 z[2] = v[2]->win[2]; 92 if (cc * cc > 1e-16) { 93 GLfloat ez = z[0] - z[2]; 94 GLfloat fz = z[1] - z[2]; 95 GLfloat a = ey*fz - ez*fy; 96 GLfloat b = ez*fx - ex*fz; 97 GLfloat ic = 1.0F / cc; 98 GLfloat ac = a * ic; 99 GLfloat bc = b * ic; 100 if (ac < 0.0F) ac = -ac; 101 if (bc < 0.0F) bc = -bc; 102 offset += MAX2(ac, bc) * ctx->Polygon.OffsetFactor; 103 } 104 offset *= ctx->MRD; 105 /*printf("offset %g\n", offset);*/ 106 } 107 } 108 109 if (mode == GL_POINT) { 110 if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetPoint) { 111 v[0]->win[2] += offset; 112 v[1]->win[2] += offset; 113 v[2]->win[2] += offset; 114 } 115 _swsetup_render_point_tri( ctx, e0, e1, e2 ); 116 } else if (mode == GL_LINE) { 117 if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetLine) { 118 v[0]->win[2] += offset; 119 v[1]->win[2] += offset; 120 v[2]->win[2] += offset; 121 } 122 _swsetup_render_line_tri( ctx, e0, e1, e2 ); 123 } else { 124 if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetFill) { 125 v[0]->win[2] += offset; 126 v[1]->win[2] += offset; 127 v[2]->win[2] += offset; 128 } 129 _swrast_Triangle( ctx, v[0], v[1], v[2] ); 130 } 131 132 if (IND & SS_OFFSET_BIT) { 133 v[0]->win[2] = z[0]; 134 v[1]->win[2] = z[1]; 135 v[2]->win[2] = z[2]; 136 } 137 138 if (IND & SS_TWOSIDE_BIT) { 139 if (facing == 1) { 140 if (IND & SS_RGBA_BIT) { 141 GLchan (*vbcolor)[4] = (GLchan (*)[4])VB->ColorPtr[0]->Ptr; 142 SS_COLOR(v[0]->color, vbcolor[e0]); 143 SS_COLOR(v[1]->color, vbcolor[e1]); 144 SS_COLOR(v[2]->color, vbcolor[e2]); 145 if (VB->SecondaryColorPtr[0]) { 146 GLchan (*vbspec)[4] = (GLchan (*)[4])VB->SecondaryColorPtr[0]->Ptr; 147 SS_SPEC(v[0]->specular, vbspec[e0]); 148 SS_SPEC(v[1]->specular, vbspec[e1]); 149 SS_SPEC(v[2]->specular, vbspec[e2]); 150 } 151 } else { 152 GLuint *vbindex = VB->IndexPtr[0]->data; 153 SS_IND(v[0]->index, vbindex[e0]); 154 SS_IND(v[1]->index, vbindex[e1]); 155 SS_IND(v[2]->index, vbindex[e2]); 156 } 157 } 158 } 159} 160 161 162 163/* Need to fixup edgeflags when decomposing to triangles: 164 */ 165static void TAG(quadfunc)( GLcontext *ctx, GLuint v0, 166 GLuint v1, GLuint v2, GLuint v3 ) 167{ 168 if (IND & SS_UNFILLED_BIT) { 169 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; 170 GLubyte ef1 = VB->EdgeFlag[v1]; 171 GLubyte ef3 = VB->EdgeFlag[v3]; 172 VB->EdgeFlag[v1] = 0; 173 TAG(triangle)( ctx, v0, v1, v3 ); 174 VB->EdgeFlag[v1] = ef1; 175 VB->EdgeFlag[v3] = 0; 176 TAG(triangle)( ctx, v1, v2, v3 ); 177 VB->EdgeFlag[v3] = ef3; 178 } else { 179 TAG(triangle)( ctx, v0, v1, v3 ); 180 TAG(triangle)( ctx, v1, v2, v3 ); 181 } 182} 183 184 185 186 187static void TAG(init)( void ) 188{ 189 tri_tab[IND] = TAG(triangle); 190 quad_tab[IND] = TAG(quadfunc); 191} 192 193 194#undef IND 195#undef TAG 196