1
0
Fork 0
2018-soft-3d-renderer/src/geometry.cpp

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;
}
}
}
}
}