void OcclusionBuffer::DrawTriangle(Vector4* vertices) { unsigned clipMask = 0; unsigned andClipMask = 0; bool drawOk = false; Vector3 projected[3]; // Build the clip plane mask for the triangle for (unsigned i = 0; i < 3; ++i) { unsigned vertexClipMask = 0; if (vertices[i].x_ > vertices[i].w_) vertexClipMask |= CLIPMASK_X_POS; if (vertices[i].x_ < -vertices[i].w_) vertexClipMask |= CLIPMASK_X_NEG; if (vertices[i].y_ > vertices[i].w_) vertexClipMask |= CLIPMASK_Y_POS; if (vertices[i].y_ < -vertices[i].w_) vertexClipMask |= CLIPMASK_Y_NEG; if (vertices[i].z_ > vertices[i].w_) vertexClipMask |= CLIPMASK_Z_POS; if (vertices[i].z_ < 0.0f) vertexClipMask |= CLIPMASK_Z_NEG; clipMask |= vertexClipMask; if (!i) andClipMask = vertexClipMask; else andClipMask &= vertexClipMask; } // If triangle is fully behind any clip plane, can reject quickly if (andClipMask) return; // Check if triangle is fully inside if (!clipMask) { projected[0] = ViewportTransform(vertices[0]); projected[1] = ViewportTransform(vertices[1]); projected[2] = ViewportTransform(vertices[2]); if (CheckFacing(projected[0], projected[1], projected[2])) { DrawTriangle2D(projected); drawOk = true; } } else { bool triangles[64]; // Initial triangle triangles[0] = true; unsigned numTriangles = 1; if (clipMask & CLIPMASK_X_POS) ClipVertices(Vector4(-1.0f, 0.0f, 0.0f, 1.0f), vertices, triangles, numTriangles); if (clipMask & CLIPMASK_X_NEG) ClipVertices(Vector4(1.0f, 0.0f, 0.0f, 1.0f), vertices, triangles, numTriangles); if (clipMask & CLIPMASK_Y_POS) ClipVertices(Vector4(0.0f, -1.0f, 0.0f, 1.0f), vertices, triangles, numTriangles); if (clipMask & CLIPMASK_Y_NEG) ClipVertices(Vector4(0.0f, 1.0f, 0.0f, 1.0f), vertices, triangles, numTriangles); if (clipMask & CLIPMASK_Z_POS) ClipVertices(Vector4(0.0f, 0.0f, -1.0f, 1.0f), vertices, triangles, numTriangles); if (clipMask & CLIPMASK_Z_NEG) ClipVertices(Vector4(0.0f, 0.0f, 1.0f, 0.0f), vertices, triangles, numTriangles); // Draw each accepted triangle for (unsigned i = 0; i < numTriangles; ++i) { if (triangles[i]) { unsigned index = i * 3; projected[0] = ViewportTransform(vertices[index]); projected[1] = ViewportTransform(vertices[index + 1]); projected[2] = ViewportTransform(vertices[index + 2]); if (CheckFacing(projected[0], projected[1], projected[2])) { DrawTriangle2D(projected); drawOk = true; } } } } if (drawOk) ++numTriangles_; }
void iGraphics::draw_triangle (int x1, int y1, int x2, int y2, int x3, int y3) { DrawTriangle2D (x1, invert (y1), x2, invert (y2), x3, invert (y3)); };