// Copyright (C) 1996 Keith Whitwell. // This file may only be copied under the terms of the GNU Library General // Public License - see the file COPYING in the lib3d distribution. #include #include #include #include #include WirePipeline::WirePipeline() : FlatPipeline() { } WirePipeline::~WirePipeline() { } void WirePipeline::render(Model &model, Viewport &viewport, const Light *lights, uint nrLights, uint clipPlanes, uint flags) { stitchModel(model); expand(nrLights); thisFrame++; renderFlags = flags; have_backface_info = false; clip = false; if ( !clipPlanes ) { transform( viewport ); } else if ( !transformForClipping( viewport ) ) { return; } if (!clip) { using_lit_normals = (nrLights && (nrPolygonNormals*nrMaterials < nrPolygons/2)); calculateLightData( viewport, lights, nrLights ); renderPolygons( viewport, nrLights ); } else { using_lit_normals = (nrLights && (nrPolygonNormals*nrMaterials < nrPolygons)); calculateLightData( viewport, lights, nrLights ); clipAndRenderPolygons( viewport, nrLights ); } viewport.setDirty( xmin, ymin, xmax, ymax ); } void WirePipeline::renderPolygons( Viewport &viewport, uint nrLights ) { if (have_backface_info) { for (int j = nrPolygons ; j-- ; ) { const Polygon &poly = polygons[j]; if (!ppool[j].backface) { pv[0] = &vpool[poly.vertex0]; pv[1] = &vpool[poly.vertex1]; pv[2] = &vpool[poly.vertex2]; uint colour = lightPolygon(poly, viewport, nrLights); viewport.wireTriangle(pv, colour); } } } else { for (int j = nrPolygons ; j-- ; ) { const Polygon &poly = polygons[j]; pv[0] = &vpool[poly.vertex0]; pv[1] = &vpool[poly.vertex1]; pv[2] = &vpool[poly.vertex2]; uint colour = lightPolygon(poly, viewport, nrLights); viewport.wireTriangle(pv, colour); } } } void WirePipeline::cullAndRenderPolygons( Viewport &viewport, uint nrLights ) { for (int j = nrPolygons ; j-- ; ) { const Polygon &poly = polygons[j]; pv[0] = &vpool[poly.vertex0]; pv[1] = &vpool[poly.vertex1]; pv[2] = &vpool[poly.vertex2]; bool cw =( ((pv[1]->device.v[1] - pv[0]->device.v[1]) * (pv[2]->device.v[0] - pv[0]->device.v[0])) >= ((pv[1]->device.v[0] - pv[0]->device.v[0]) * (pv[2]->device.v[1] - pv[0]->device.v[1]))); if (cw) { uint colour = lightPolygon(poly, viewport, nrLights); viewport.wireTriangle(pv, colour); } } } void WirePipeline::clipAndRenderPolygons( Viewport &viewport, uint nrLights ) { const Polygon *poly = polygons; Flat_PolygonData *pp = ppool; int j = nrPolygons; if (have_backface_info) { do { if (!pp->backface) { pv[0] = &vpool[poly->vertex0]; uint oc0 = vpool[poly->vertex0].outcodes; pv[1] = &vpool[poly->vertex1]; uint oc1 = vpool[poly->vertex1].outcodes; pv[2] = &vpool[poly->vertex2]; uint oc2 = vpool[poly->vertex2].outcodes; if ((oc0&oc1&oc2) == 0) { uint intersections = oc0|oc1|oc2; uint colour = lightPolygon(*poly, viewport, nrLights); if (intersections == 0) { viewport.wireTriangle(pv, colour); } else { uint nr = nrVpool; if (clipPolygon(*poly, intersections)) viewport.wirePolygon(nrClippedVertices, pv, colour); nrVpool = nr; } } } poly++; pp++; } while (--j); } else { do { pv[0] = &vpool[poly->vertex0]; uint oc0 = vpool[poly->vertex0].outcodes; pv[1] = &vpool[poly->vertex1]; uint oc1 = vpool[poly->vertex1].outcodes; pv[2] = &vpool[poly->vertex2]; uint oc2 = vpool[poly->vertex2].outcodes; if ((oc0&oc1&oc2) == 0) { uint intersections = oc0|oc1|oc2; uint colour = lightPolygon(*poly, viewport, nrLights); if (intersections == 0) { viewport.wireTriangle(pv, colour); } else { uint nr = nrVpool; if (clipPolygon(*poly, intersections)) viewport.wirePolygon(nrClippedVertices, pv, colour); nrVpool = nr; } } poly++; pp++; } while (--j); } }