#include "color.h" #include "engine.h" #include "geometry.h" #include "util.h" #include // MACROS #define DrawPixel(buffer, width, color, x, y)\ {\ buffer[width * y + x] = color;\ } // STRUCTURES struct BoundingBox { BoundingBox(Point &v0, Point &v1, Point &v2) { yMin = MIN(v0.y, MIN(v1.y, v2.y)); yMax = MAX(v0.y, MAX(v1.y, v2.y)); xMin = MIN(v0.x, MIN(v1.x, v2.x)); xMax = MAX(v0.x, MAX(v1.x, v2.x)); } float yMin, yMax; float xMin, xMax; }; static void ComputeBarycenter(float *w, Point &v0, Point &v1, Point &v2, Point &p) { float area = (v2.x - v0.x) * (v1.y - v0.y) - (v2.y - v0.y) * (v1.x - v0.x); float result[3]; result[0] = (p.x - v1.x) * (v2.y - v1.y) - (p.y - v1.y) * (v2.x - v1.x); result[1] = (p.x - v2.x) * (v0.y - v2.y) - (p.y - v2.y) * (v0.x - v2.x); result[2] = (p.x - v0.x) * (v1.y - v0.y) - (p.y - v0.y) * (v1.x - v0.x); result[0] /= area; result[1] /= area; result[2] /= area; w[0] = result[0]; w[1] = result[1]; w[2] = result[2]; } // PUBLIC FUNCTIONS void FillTriangle( Engine_Buffer &buffer, ColorU32 &color, Point &v0, Point &v1, Point &v2) { BoundingBox box(v0, v1, v2); int yMin = (int)ceilf(box.yMin); int yMax = (int)ceilf(box.yMax) - 1; int xMin = (int)ceilf(box.xMin); int xMax = (int)ceilf(box.xMax) - 1; for (int y = yMin; y <= yMax; ++y) { for (int x = xMin; x <= xMax; ++x) { Point p(x, y, 1.0f); float barycenter[3]; ComputeBarycenter(barycenter, v0, v1, v2, p); if (barycenter[0] >= 0 && barycenter[1] >= 0 && barycenter[2] >= 0) { float zInv = (barycenter[0] * (1.0f/v0.z)) + (barycenter[1] * (1.0f/v1.z)) + (barycenter[2] * (1.0f/v2.z)); int pixel = (y * buffer.width + x); if (zInv > buffer.zbuffer[pixel]) { DrawPixel(buffer.buffer, buffer.width, color.u32, x, y); buffer.zbuffer[pixel] = zInv; } } } } }