ss_tritmp.h revision 23caf20169ac38436ee9c13914f1d6aa7cf6bb5e
1/* 2 * Mesa 3-D graphics library 3 * Version: 3.5 4 * 5 * Copyright (C) 1999 Brian Paul All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: 25 * Keith Whitwell <keithw@valinux.com> 26 */ 27 28 29static void TAG(triangle)(GLcontext *ctx, 30 GLuint e0, GLuint e1, GLuint e2, 31 GLuint pv) 32{ 33 struct vertex_buffer *VB = TNL_VB(ctx); 34 SWvertex *verts = SWSETUP_VB(VB)->verts; 35 SWvertex *v[3]; 36 GLfloat offset; 37 GLfloat z[3]; 38 GLubyte c[3][4], s[3][4]; 39 GLuint i[3]; 40 GLenum mode = GL_FILL; 41 42 v[0] = &verts[e0]; 43 v[1] = &verts[e1]; 44 v[2] = &verts[e2]; 45 46 if (IND & (SS_TWOSIDE_BIT | SS_FLAT_BIT)) { 47 SS_COLOR(c[0], v[0]->color); 48 49 if (IND & SS_TWOSIDE_BIT) { 50 SS_COLOR(c[1], v[1]->color); 51 SS_COLOR(c[2], v[2]->color); 52 } 53 54 if (IND & SS_COPY_EXTRAS) { 55 SS_SPEC(s[0], v[0]->specular); 56 SS_IND(i[0], v[0]->index); 57 58 if (IND & SS_TWOSIDE_BIT) { 59 SS_SPEC(s[1], v[1]->specular); 60 SS_IND(i[1], v[1]->index); 61 62 SS_SPEC(s[2], v[2]->specular); 63 SS_IND(i[2], v[2]->index); 64 } 65 } 66 } 67 68 if (IND & (SS_TWOSIDE_BIT | SS_OFFSET_BIT | SS_UNFILLED_BIT)) 69 { 70 GLfloat ex = v[0]->win[0] - v[2]->win[0]; 71 GLfloat ey = v[0]->win[1] - v[2]->win[1]; 72 GLfloat fx = v[1]->win[0] - v[2]->win[0]; 73 GLfloat fy = v[1]->win[1] - v[2]->win[1]; 74 GLfloat cc = ex*fy - ey*fx; 75 76 if (IND & (SS_TWOSIDE_BIT | SS_UNFILLED_BIT)) 77 { 78 GLuint facing = (cc < 0.0) ^ ctx->Polygon.FrontBit; 79 80 if (IND & SS_UNFILLED_BIT) 81 mode = facing ? ctx->Polygon.BackMode : ctx->Polygon.FrontMode; 82 83 if (IND & SS_TWOSIDE_BIT) { 84 GLubyte (*vbcolor)[4] = VB->Color[facing]->data; 85 GLubyte (*vbspec)[4] = VB->SecondaryColor[facing]->data; 86 GLuint *vbindex = VB->Index[facing]->data; 87 88 if (IND & SS_FLAT_BIT) { 89 SS_COLOR(v[0]->color, vbcolor[pv]); 90 SS_COLOR(v[1]->color, vbcolor[pv]); 91 SS_COLOR(v[2]->color, vbcolor[pv]); 92 93 if (IND & SS_COPY_EXTRAS) { 94 SS_SPEC(v[0]->specular, vbspec[pv]); 95 SS_SPEC(v[1]->specular, vbspec[pv]); 96 SS_SPEC(v[2]->specular, vbspec[pv]); 97 98 SS_IND(v[0]->index, vbindex[pv]); 99 SS_IND(v[1]->index, vbindex[pv]); 100 SS_IND(v[2]->index, vbindex[pv]); 101 } 102 } else { 103 SS_COLOR(v[0]->color, vbcolor[e0]); 104 SS_COLOR(v[1]->color, vbcolor[e1]); 105 SS_COLOR(v[2]->color, vbcolor[e2]); 106 107 if (IND & SS_COPY_EXTRAS) { 108 SS_SPEC(v[0]->specular, vbspec[e0]); 109 SS_SPEC(v[1]->specular, vbspec[e1]); 110 SS_SPEC(v[2]->specular, vbspec[e2]); 111 112 SS_IND(v[0]->index, vbindex[e0]); 113 SS_IND(v[1]->index, vbindex[e1]); 114 SS_IND(v[2]->index, vbindex[e2]); 115 } 116 } 117 } 118 } 119 120 if (IND & SS_OFFSET_BIT) 121 { 122 offset = ctx->Polygon.OffsetUnits; 123 z[0] = v[0]->win[2]; 124 z[1] = v[1]->win[2]; 125 z[2] = v[2]->win[2]; 126 if (cc * cc > 1e-16) { 127 GLfloat ez = z[0] - z[2]; 128 GLfloat fz = z[1] - z[2]; 129 GLfloat a = ey*fz - ez*fy; 130 GLfloat b = ez*fx - ex*fz; 131 GLfloat ic = 1.0 / cc; 132 GLfloat ac = a * ic; 133 GLfloat bc = b * ic; 134 if (ac < 0.0f) ac = -ac; 135 if (bc < 0.0f) bc = -bc; 136 offset += MAX2(ac, bc) * ctx->Polygon.OffsetFactor; 137 } 138 } 139 } 140 else if (IND & SS_FLAT_BIT) 141 { 142 GLubyte *color = VB->Color[0]->data[pv]; 143 GLubyte *spec = VB->SecondaryColor[0]->data[pv]; 144 GLuint index = VB->Index[0]->data[pv]; 145 146 SS_COLOR(v[0]->color, color); 147 148 if (IND & SS_COPY_EXTRAS) { 149 SS_SPEC(v[0]->specular, spec); 150 SS_IND(v[0]->index, index); 151 } 152 } 153 154 if (mode == GL_POINT) { 155 GLubyte *ef = VB->EdgeFlagPtr->data; 156 if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetPoint) { 157 v[0]->win[2] += offset; 158 v[1]->win[2] += offset; 159 v[2]->win[2] += offset; 160 } 161 if (ef[e0]&0x1) { ef[e0] &= ~0x1; _swrast_Point( ctx, v[0] ); } 162 if (ef[e1]&0x1) { ef[e1] &= ~0x1; _swrast_Point( ctx, v[1] ); } 163 if (ef[e2]&0x2) { ef[e2] &= ~0x2; _swrast_Point( ctx, v[2] ); } 164 } else if (mode == GL_LINE) { 165 GLubyte *ef = VB->EdgeFlagPtr->data; 166 if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetLine) { 167 v[0]->win[2] += offset; 168 v[1]->win[2] += offset; 169 v[2]->win[2] += offset; 170 } 171 if (ef[e0]&0x1) { ef[e0] &= ~0x1; _swrast_Line( ctx, v[0], v[1] ); } 172 if (ef[e1]&0x1) { ef[e1] &= ~0x1; _swrast_Line( ctx, v[1], v[2] ); } 173 if (ef[e2]&0x2) { ef[e2] &= ~0x2; _swrast_Line( ctx, v[2], v[0] ); } 174 } else { 175 if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetFill) { 176 v[0]->win[2] += offset; 177 v[1]->win[2] += offset; 178 v[2]->win[2] += offset; 179 } 180 _swrast_Triangle( ctx, v[0], v[1], v[2] ); 181 } 182 183 if (IND & SS_OFFSET_BIT) { 184 v[0]->win[2] = z[0]; 185 v[1]->win[2] = z[1]; 186 v[2]->win[2] = z[2]; 187 } 188 189 if (IND & (SS_FLAT_BIT | SS_TWOSIDE_BIT)) { 190 SS_COLOR(v[0]->color, c[0]); 191 192 if (IND & SS_TWOSIDE_BIT) { 193 SS_COLOR(v[1]->color, c[1]); 194 SS_COLOR(v[2]->color, c[2]); 195 } 196 197 if (IND & SS_COPY_EXTRAS) { 198 SS_SPEC(v[0]->specular, s[0]); 199 SS_IND(v[0]->index, i[0]); 200 201 if (IND & SS_TWOSIDE_BIT) { 202 SS_SPEC(v[1]->specular, s[1]); 203 SS_IND(v[1]->index, i[1]); 204 205 SS_SPEC(v[2]->specular, s[2]); 206 SS_IND(v[2]->index, i[2]); 207 } 208 } 209 } 210} 211 212 213 214/* Need to do something with edgeflags: 215 */ 216static void TAG(quad)( GLcontext *ctx, GLuint v0, 217 GLuint v1, GLuint v2, GLuint v3, 218 GLuint pv ) 219{ 220 TAG(triangle)( ctx, v0, v1, v3, pv ); 221 TAG(triangle)( ctx, v1, v2, v3, pv ); 222} 223 224 225static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv ) 226{ 227 struct vertex_buffer *VB = TNL_VB(ctx); 228 SWvertex *verts = SWSETUP_VB(VB)->verts; 229 GLubyte c[2][4], s[2][4]; 230 GLuint i[2]; 231 SWvertex *vert0 = &verts[v0]; 232 SWvertex *vert1 = &verts[v1]; 233 234 235 if (IND & SS_FLAT_BIT) { 236 GLubyte *color = VB->Color[0]->data[pv]; 237 GLubyte *spec = VB->SecondaryColor[0]->data[pv]; 238 GLuint index = VB->Index[0]->data[pv]; 239 240 SS_COLOR(c[0], vert0->color); 241 SS_COLOR(vert0->color, color); 242 243 if (IND & SS_COPY_EXTRAS) { 244 SS_SPEC(s[0], vert0->specular); 245 SS_SPEC(vert0->specular, spec); 246 247 SS_IND(i[0], vert0->index); 248 SS_IND(vert0->index, index); 249 } 250 } 251 252 _swrast_Line( ctx, vert0, vert1 ); 253 254 if (IND & SS_FLAT_BIT) { 255 SS_COLOR(vert0->color, c[0]); 256 257 if (IND & SS_COPY_EXTRAS) { 258 SS_SPEC(vert0->specular, s[0]); 259 SS_IND(vert0->index, i[0]); 260 } 261 } 262} 263 264 265static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last ) 266{ 267 struct vertex_buffer *VB = TNL_VB(ctx); 268 SWvertex *verts = SWSETUP_VB(VB)->verts; 269 int i; 270 271 for(i=first;i<=last;i++) 272 if(VB->ClipMask[i]==0) 273 _swrast_Point( ctx, &verts[i] ); 274} 275 276 277 278 279static void TAG(init)( void ) 280{ 281 tri_tab[IND] = TAG(triangle); 282 quad_tab[IND] = TAG(quad); 283 line_tab[IND] = TAG(line); 284 points_tab[IND] = TAG(points); 285} 286 287 288#undef IND 289#undef TAG 290 291 292 293