//===========================================================================// // Copyright (C) Microsoft Corporation. All rights reserved. // //===========================================================================// //--------------------------------------------------------------------------------------------------- // Screen Clip code for use with video cards without guard bands and BLADE. // // Generally, we will only need one or two of the below routines per triangle. // // If a triangle is completely on screen, none of the below should be called. // // Each triangle can be easily checked to see which of the below should be // called in its case. An easy, low-end machine optimization would be to // NOT call any of the below for TGL/MSL shapes which are partly off screen // and simply not to draw the shape. Profiling will indicate if this is // necessary. // // Color space clipping is HUGELY painful and we are cheating until it // becomes necessary to do otherwise. // // Triangles will be converted into polygons with as many as five sides. // It will be necessary in the draw code to hand the vertices down to // GOS/BLADE in triangles to avoid any weirdness in their code! // // These routines are easily optimized and assembled if and when it becomes // necessary to do so. Routines should be inlined for speed! //--------------------------------------------------------------------------------------------------- #ifndef CLIP_H #define CLIP_H #include //--------------------------------------------------------------------------------------------------- inline void xLeftEdgeclip (gos_VERTEX *vertices, long &numVertices, float leftEdge) { //------------------------------------------ //make local copy of all point data involved gos_VERTEX points[6]; memcpy(points,vertices,sizeof(gos_VERTEX)*numVertices); //------------------------------------------ long first = numVertices-1; long second = 0; //---------------------------------------------- // Index to current vertex in clipped polygon. //---------------------------------------------- long work = 0; //------------------------------ //final number of polygon points //------------------------------ long n_points= 0; //---------------------------- //process points in edge order //---------------------------- for (long s=0; s= leftEdge) { //------------------------------------------------------------ gos_VERTEX* workv = &(vertices[work]); memcpy(workv,&(points[first]),sizeof(gos_VERTEX)); //------------------------------------------------------------ work++; n_points++; } //------------------------------------------------------------ //if the line defined by first and second intersects the //clipping plane, generate a new point and calculate its info. //------------------------------------------------------------ if (((clipEdgeTest < leftEdge) && (points[second].x >= leftEdge)) || ((clipEdgeTest >= leftEdge) && (points[second].x < leftEdge))) { gos_VERTEX* workv = &(vertices[work]); float sry = points[second].y; float srx = points[second].x; float srz = points[second].z; float srw = points[second].rhw; float sru = points[second].u; float srv = points[second].v; float fry = points[first].y; float frx = points[first].x; float frz = points[first].z; float frw = points[first].rhw; float fru = points[first].u; float frv = points[first].v; float mu = (leftEdge - srx)/(frx - srx); workv->x = leftEdge; workv->y = ((fry - sry) * mu) + sry; workv->z = ((frz - srz) * mu) + srz; // Clipping color is HUGELY painful at this point. Try cheating first! if (clipEdgeTest < leftEdge) { workv->argb = points[first].argb; workv->frgb = points[first].frgb; } else { workv->argb = points[second].argb; workv->frgb = points[second].frgb; } workv->rhw = ((frw - srw) * mu) + srw; workv->u = ((fru - sru) * mu) + sru; workv->v = ((frv - srv) * mu) + srv; work++; n_points++; } first = second; } numVertices = n_points; } //--------------------------------------------------------------------------------------------------- inline void xRightEdgeclip (gos_VERTEX *vertices, long &numVertices, float rightEdge) { //------------------------------------------ //make local copy of all point data involved gos_VERTEX points[6]; memcpy(points,vertices,sizeof(gos_VERTEX)*numVertices); //------------------------------------------ long first = numVertices-1; long second = 0; //---------------------------------------------- // Index to current vertex in clipped polygon. //---------------------------------------------- long work = 0; //------------------------------ //final number of polygon points //------------------------------ long n_points= 0; //---------------------------- //process points in edge order //---------------------------- for (long s=0; s= rightEdge) && (points[second].x < rightEdge)) || ((clipEdgeTest < rightEdge) && (points[second].x >= rightEdge))) { gos_VERTEX* workv = &(vertices[work]); float sry = points[second].y; float srx = points[second].x; float srz = points[second].z; float srw = points[second].rhw; float sru = points[second].u; float srv = points[second].v; float fry = points[first].y; float frx = points[first].x; float frz = points[first].z; float frw = points[first].rhw; float fru = points[first].u; float frv = points[first].v; float mu = (rightEdge - srx)/(frx - srx); workv->x = rightEdge - 1.0f; workv->y = ((fry - sry) * mu) + sry; workv->z = ((frz - srz) * mu) + srz; // Clipping color is HUGELY painful at this point. Try cheating first! if (clipEdgeTest >= rightEdge) { workv->argb = points[first].argb; workv->frgb = points[first].frgb; } else { workv->argb = points[second].argb; workv->frgb = points[second].frgb; } workv->rhw = ((frw - srw) * mu) + srw; workv->u = ((fru - sru) * mu) + sru; workv->v = ((frv - srv) * mu) + srv; work++; n_points++; } first = second; } numVertices = n_points; } //--------------------------------------------------------------------------------------------------- inline void yTopEdgeclip (gos_VERTEX *vertices, long &numVertices, float topEdge) { //------------------------------------------ //make local copy of all point data involved gos_VERTEX points[6]; memcpy(points,vertices,sizeof(gos_VERTEX)*numVertices); //------------------------------------------ long first = numVertices-1; long second = 0; //---------------------------------------------- // Index to current vertex in clipped polygon. //---------------------------------------------- long work = 0; //------------------------------ //final number of polygon points //------------------------------ long n_points= 0; //---------------------------- //process points in edge order //---------------------------- for (long s=0; s= topEdge) { //------------------------------------------------------------ gos_VERTEX* workv = &(vertices[work]); memcpy(workv,&(points[first]),sizeof(gos_VERTEX)); //------------------------------------------------------------ work++; n_points++; } //------------------------------------------------------------ //if the line defined by first and second intersects the //clipping plane, generate a new point and calculate its info. //------------------------------------------------------------ if (((clipEdgeTest < topEdge) && (points[second].y >= topEdge)) || ((clipEdgeTest >= topEdge) && (points[second].y < topEdge))) { gos_VERTEX* workv = &(vertices[work]); float sry = points[second].y; float srx = points[second].x; float srz = points[second].z; float srw = points[second].rhw; float sru = points[second].u; float srv = points[second].v; float fry = points[first].y; float frx = points[first].x; float frz = points[first].z; float frw = points[first].rhw; float fru = points[first].u; float frv = points[first].v; float mu = (topEdge - sry)/(fry - sry); workv->y = topEdge; workv->x = ((frx - srx) * mu) + srx; workv->z = ((frz - srz) * mu) + srz; // Clipping color is HUGELY painful at this point. Try cheating first! if (clipEdgeTest < topEdge) { workv->argb = points[first].argb; workv->frgb = points[first].frgb; } else { workv->argb = points[second].argb; workv->frgb = points[second].frgb; } workv->rhw = ((frw - srw) * mu) + srw; workv->u = ((fru - sru) * mu) + sru; workv->v = ((frv - srv) * mu) + srv; work++; n_points++; } first = second; } numVertices = n_points; } //--------------------------------------------------------------------------------------------------- inline void yBottomEdgeclip (gos_VERTEX *vertices, long &numVertices, float bottomEdge) { //------------------------------------------ //make local copy of all point data involved gos_VERTEX points[6]; memcpy(points,vertices,sizeof(gos_VERTEX)*numVertices); //------------------------------------------ long first = numVertices-1; long second = 0; //---------------------------------------------- // Index to current vertex in clipped polygon. //---------------------------------------------- long work = 0; //------------------------------ //final number of polygon points //------------------------------ long n_points= 0; //---------------------------- //process points in edge order //---------------------------- for (long s=0; s= bottomEdge) && (points[second].y < bottomEdge)) || ((clipEdgeTest < bottomEdge) && (points[second].y >= bottomEdge))) { gos_VERTEX* workv = &(vertices[work]); float sry = points[second].y; float srx = points[second].x; float srz = points[second].z; float srw = points[second].rhw; float sru = points[second].u; float srv = points[second].v; float fry = points[first].y; float frx = points[first].x; float frz = points[first].z; float frw = points[first].rhw; float fru = points[first].u; float frv = points[first].v; float mu = (bottomEdge - sry)/(fry - sry); workv->y = bottomEdge - 1.0f; workv->x = ((frx - srx) * mu) + srx; workv->z = ((frz - srz) * mu) + srz; // Clipping color is HUGELY painful at this point. Try cheating first! if (clipEdgeTest >= bottomEdge) { workv->argb = points[first].argb; workv->frgb = points[first].frgb; } else { workv->argb = points[second].argb; workv->frgb = points[second].frgb; } workv->rhw = ((frw - srw) * mu) + srw; workv->u = ((fru - sru) * mu) + sru; workv->v = ((frv - srv) * mu) + srv; work++; n_points++; } first = second; } numVertices = n_points; } //--------------------------------------------------------------------------------------------------- #endif