parent
d3bd172d96
commit
2ee8fe4e4a
@ -1,23 +0,0 @@
|
||||
//
|
||||
// Created by Wouter Groeneveld on 10/07/20.
|
||||
//
|
||||
|
||||
#ifndef GBA_BITMAP_ENGINE_PROJECT_VECTOR2_H
|
||||
#define GBA_BITMAP_ENGINE_PROJECT_VECTOR2_H
|
||||
|
||||
// a 2D vector with pixel-based ints
|
||||
|
||||
class VectorPx {
|
||||
private:
|
||||
int v_x, v_y;
|
||||
|
||||
public:
|
||||
VectorPx(int theX, int theY) : v_x(theX), v_y(theY) {}
|
||||
|
||||
static inline VectorPx fromFx(FIXED x, FIXED y) { return VectorPx(fx2int(x), fx2int(y)); }
|
||||
|
||||
inline int x() const { return v_x; }
|
||||
inline int y() const { return v_y; }
|
||||
};
|
||||
|
||||
#endif //GBA_BITMAP_ENGINE_PROJECT_VECTOR2_H
|
@ -0,0 +1,82 @@
|
||||
//
|
||||
// Created by Wouter Groeneveld on 11/07/20.
|
||||
//
|
||||
|
||||
#include <libgba-sprite-engine/renderer/renderer.h>
|
||||
#include <libgba-sprite-engine/renderer/gba_engine.h>
|
||||
#include <libgba-sprite-engine/math.h>
|
||||
#include <libgba-sprite-engine/background/text_stream.h>
|
||||
|
||||
// drawing line between 2 points from left to right
|
||||
// papb -> pcpd
|
||||
// pa, pb, pc, pd must then be sorted before
|
||||
void RasterizerRenderer::processScanLine(FIXED y, const VectorFx& pa, const VectorFx& pb, const VectorFx& pc, const VectorFx& pd, COLOR color) {
|
||||
FIXED gradient1 = VectorFx::gradient(y, pa, pb), gradient2 = VectorFx::gradient(y, pc, pd);
|
||||
|
||||
int sx = fx2int(interpolate(pa.x(), pb.x(), gradient1));
|
||||
int ex = fx2int(interpolate(pc.x(), pd.x(), gradient2));
|
||||
int yy = fx2int(y);
|
||||
|
||||
engine.get()->plotLine(sx, yy, ex, yy, color);
|
||||
}
|
||||
|
||||
void RasterizerRenderer::plotTriangle(const VectorFx& pt1, const VectorFx& pt2, const VectorFx& pt3, COLOR color) {
|
||||
// Sorting the points in order to always have this order on screen p1, p2 & p3
|
||||
// with p1 always up (thus having the Y the lowest possible to be near the top screen)
|
||||
// then p2 between p1 & p3
|
||||
auto p1 = &pt1, p2 = &pt2, p3 = &pt3;
|
||||
|
||||
if (p1->y() > p2->y()) {
|
||||
auto temp = p2;
|
||||
p2 = p1;
|
||||
p1 = temp;
|
||||
}
|
||||
|
||||
if (p2->y() > p3->y()) {
|
||||
auto temp = p2;
|
||||
p2 = p3;
|
||||
p3 = temp;
|
||||
}
|
||||
|
||||
if (p1->y() > p2->y()) {
|
||||
auto temp = p2;
|
||||
p2 = p1;
|
||||
p1 = temp;
|
||||
}
|
||||
|
||||
FIXED dP1P2 = VectorFx::slope(*p1, *p2), dP1P3 = VectorFx::slope(*p1, *p3);
|
||||
if (dP1P2 > dP1P3) {
|
||||
for (auto y = p1->y(); y <= p3->y(); y+=ONE) {
|
||||
if (y < p2->y()) {
|
||||
processScanLine(y, *p1, *p3, *p1, *p2, color);
|
||||
} else {
|
||||
processScanLine(y, *p1, *p3, *p2, *p3, color);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (auto y = p1->y(); y <= p3->y(); y+=ONE) {
|
||||
if (y < p2->y()) {
|
||||
processScanLine(y, *p1, *p2, *p1, *p3, color);
|
||||
} else {
|
||||
processScanLine(y, *p2, *p3, *p1, *p3, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerRenderer::render(const MatrixFx &transformationMatrix, const Mesh *mesh) {
|
||||
bool colorSwitch = false;
|
||||
for (auto &face : mesh->faces()) {
|
||||
auto &vertexA = mesh->vertices()[face.a];
|
||||
auto &vertexB = mesh->vertices()[face.b];
|
||||
auto &vertexC = mesh->vertices()[face.c];
|
||||
|
||||
auto pixelA = engine->project(*vertexA.get(), transformationMatrix);
|
||||
auto pixelB = engine->project(*vertexB.get(), transformationMatrix);
|
||||
auto pixelC = engine->project(*vertexC.get(), transformationMatrix);
|
||||
|
||||
plotTriangle(pixelA, pixelB, pixelC, colorSwitch ? 2 : 1);
|
||||
colorSwitch = !colorSwitch;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in new issue