/* * 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. */ #define DO_CULL 0x1 #define DO_OFFSET 0x2 #define DO_LIGHT_TWOSIDE 0x4 #define DO_UNFILLED 0x8 #define HAVE_CULL_MASK 0x10 static void TAG(render_triangle)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv ) { struct vertex_buffer *VB = ctx->VB; #if ((IND & NEED_FACING) && !(IND & HAVE_CULL_MASK)) || (IND & DO_OFFSET) GLfloat (*win)[4] = VB->Win.data; GLfloat ex = win[v1][0] - win[v0][0]; GLfloat ey = win[v1][1] - win[v0][1]; GLfloat fx = win[v2][0] - win[v0][0]; GLfloat fy = win[v2][1] - win[v0][1]; GLfloat c = ex*fy-ey*fx; #endif #if (IND & NEED_FACING) #if (IND & HAVE_CULL_MASK) GLuint facing = ((VB->CullMask[pv]&PRIM_FACE_REAR)?1:0); #else GLuint facing = (c<0.0F) ^ (ctx->Polygon.FrontFace==GL_CW); #endif #endif #if (IND & DO_CULL) if ((facing+1) & ctx->Polygon.CullBits) return; #endif #if (IND & DO_OFFSET) { /* finish computing plane equation of polygon, compute offset */ GLfloat fz = win[v2][2] - win[v0][2]; GLfloat ez = win[v1][2] - win[v0][2]; GLfloat a = ey*fz-ez*fy; GLfloat b = ez*fx-ex*fz; offset_polygon( ctx, a, b, c ); } #endif #if (IND & DO_LIGHT_TWOSIDE) VB->Specular = VB->Spec[facing]; VB->ColorPtr = VB->Color[facing]; VB->IndexPtr = VB->Index[facing]; #endif #if (IND & DO_UNFILLED) { GLuint vlist[3]; vlist[0] = v0; vlist[1] = v1; vlist[2] = v2; unfilled_polygon( ctx, 3, vlist, pv, facing ); } #else ctx->Driver.TriangleFunc( ctx, v0, v1, v2, pv ); #endif } /* Implements quad rendering when direct_triangles is false. * * Need to implement cull check ? */ static void render_quad( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3, GLuint pv ) { struct vertex_buffer *VB = ctx->VB; GLuint facing = ((VB->CullMask[pv]&PRIM_FACE_REAR)?1:0); if (ctx->IndirectTriangles & DD_TRI_OFFSET) { GLfloat (*win)[4] = VB->Win.data; GLfloat ez = win[v2][2] - win[v0][2]; GLfloat fz = win[v3][2] - win[v1][2]; GLfloat ex = win[v2][0] - win[v0][0]; GLfloat ey = win[v2][1] - win[v0][1]; GLfloat fx = win[v3][0] - win[v1][0]; GLfloat fy = win[v3][1] - win[v1][1]; GLfloat a = ey*fz-ez*fy; GLfloat b = ez*fx-ex*fz; GLfloat c = ex*fy-ey*fx; offset_polygon( ctx, a, b, c ); } if (ctx->IndirectTriangles & DD_TRI_LIGHT_TWOSIDE) { VB->Specular = VB->Spec[facing]; VB->ColorPtr = VB->Color[facing]; VB->IndexPtr = VB->Index[facing]; } /* Render the quad! */ if (ctx->Polygon.Unfilled) { GLuint vlist[4]; vlist[0] = v0; vlist[1] = v1; vlist[2] = v2; vlist[3] = v3; unfilled_polygon( ctx, 4, vlist, pv, facing ); } else { (*ctx->Driver.QuadFunc)( ctx, v0, v1, v2, v3, pv ); } } void unfilled_triangle( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv ) { GLuint vlist[4]; vlist[0] = v0; vlist[1] = v1; vlist[2] = v2; unfilled_polygon( ctx, 3, vlist, pv, facing ); } void unfilled_quad( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3, GLuint pv ) { GLuint vlist[4]; vlist[0] = v0; vlist[1] = v1; vlist[2] = v2; vlist[3] = v3; unfilled_polygon( ctx, 4, vlist, pv, facing ); }