92 lines
2.1 KiB
C++
92 lines
2.1 KiB
C++
#include "color.h"
|
|
#include "engine.h"
|
|
#include "geometry.h"
|
|
#include "util.h"
|
|
#include <cstdio>
|
|
|
|
|
|
// 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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|