implement backface culling; basic lighting direction
This commit is contained in:
102
src/main.cpp
102
src/main.cpp
@@ -12,6 +12,32 @@ const int windowHeight = 800;
|
|||||||
const int windowWidth = 800;
|
const int windowWidth = 800;
|
||||||
Model *model = NULL;
|
Model *model = NULL;
|
||||||
|
|
||||||
|
void line(Vec2i t0, Vec2i t1, TGAImage &image, TGAColor color) {
|
||||||
|
bool steep = false;
|
||||||
|
|
||||||
|
// if the line is steep, we transpose the image.
|
||||||
|
if (abs(t0.x - t1.x) < abs(t0.y - t1.y)) {
|
||||||
|
swap(t0.x, t0.y);
|
||||||
|
swap(t1.x, t1.y);
|
||||||
|
steep = true;
|
||||||
|
}
|
||||||
|
// Make it left to right.
|
||||||
|
if (t0.x > t1.x) {
|
||||||
|
swap(t0.x, t1.x);
|
||||||
|
swap(t0.y, t1.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int x = t0.x; x <= t1.x; x++) {
|
||||||
|
float t = (x - t0.x) / (float)(t1.x - t0.x);
|
||||||
|
int y = t0.y * (1.0 - t) + t1.y * t;
|
||||||
|
if (steep) {
|
||||||
|
image.set(y, x, color); // if transposed, de-transpose.
|
||||||
|
} else {
|
||||||
|
image.set(x, y, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Vec3f barycentric(Vec2i *pts, Vec2i P) {
|
Vec3f barycentric(Vec2i *pts, Vec2i P) {
|
||||||
Vec3f u = Vec3f(pts[2].x - pts[0].x, pts[1].x - pts[0].x, pts[0].x - P.x) ^
|
Vec3f u = Vec3f(pts[2].x - pts[0].x, pts[1].x - pts[0].x, pts[0].x - P.x) ^
|
||||||
Vec3f(pts[2].y - pts[0].y, pts[1].y - pts[0].y, pts[0].y - P.y);
|
Vec3f(pts[2].y - pts[0].y, pts[1].y - pts[0].y, pts[0].y - P.y);
|
||||||
@@ -25,32 +51,7 @@ Vec3f barycentric(Vec2i *pts, Vec2i P) {
|
|||||||
return Vec3f(1.f - (u.x + u.y) / u.z, u.y / u.z, u.x / u.z);
|
return Vec3f(1.f - (u.x + u.y) / u.z, u.y / u.z, u.x / u.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
void triangle(Vec2i t0, Vec2i t1, Vec2i t2, TGAImage &image, TGAColor color) {
|
// Triangle function with binding box.
|
||||||
if (t0.y == t1.y && t0.y == t2.y)
|
|
||||||
return;
|
|
||||||
if (t0.y > t1.y)
|
|
||||||
swap(t0, t1);
|
|
||||||
if (t0.y > t2.y)
|
|
||||||
swap(t0, t2);
|
|
||||||
if (t1.y > t2.y)
|
|
||||||
swap(t1, t2);
|
|
||||||
int total_height = t2.y - t0.y;
|
|
||||||
for (int i = 0; i < total_height; i++) {
|
|
||||||
bool second_half = i > t1.y - t0.y || t1.y == t0.y;
|
|
||||||
int segment_height = second_half ? t2.y - t1.y : t1.y - t0.y;
|
|
||||||
float alpha = (float)i / total_height;
|
|
||||||
float beta =
|
|
||||||
(float)(i - (second_half ? t1.y - t0.y : 0)) / segment_height;
|
|
||||||
Vec2i A = t0 + (t2 - t0) * alpha;
|
|
||||||
Vec2i B = second_half ? t1 + (t2 - t1) * beta : t0 + (t1 - t0) * beta;
|
|
||||||
if (A.x > B.x)
|
|
||||||
std::swap(A, B);
|
|
||||||
for (int j = A.x; j <= B.x; j++) {
|
|
||||||
image.set(j, t0.y + i, color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void triangle(Vec2i *pts, TGAImage &image, TGAColor colour) {
|
void triangle(Vec2i *pts, TGAImage &image, TGAColor colour) {
|
||||||
Vec2i boundingBoxMinimum(image.get_width() - 1, image.get_height() - 1);
|
Vec2i boundingBoxMinimum(image.get_width() - 1, image.get_height() - 1);
|
||||||
Vec2i boundingBoxMaximum(0, 0);
|
Vec2i boundingBoxMaximum(0, 0);
|
||||||
@@ -77,10 +78,37 @@ void triangle(Vec2i *pts, TGAImage &image, TGAColor colour) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Triangle function via line sweeping.
|
||||||
|
void triangle(Vec2i t0, Vec2i t1, Vec2i t2, TGAImage &image, TGAColor color) {
|
||||||
|
if (t0.y == t1.y && t0.y == t2.y)
|
||||||
|
return;
|
||||||
|
if (t0.y > t1.y)
|
||||||
|
swap(t0, t1);
|
||||||
|
if (t0.y > t2.y)
|
||||||
|
swap(t0, t2);
|
||||||
|
if (t1.y > t2.y)
|
||||||
|
swap(t1, t2);
|
||||||
|
int total_height = t2.y - t0.y;
|
||||||
|
for (int i = 0; i < total_height; i++) {
|
||||||
|
bool second_half = i > t1.y - t0.y || t1.y == t0.y;
|
||||||
|
int segment_height = second_half ? t2.y - t1.y : t1.y - t0.y;
|
||||||
|
float alpha = (float)i / total_height;
|
||||||
|
float beta =
|
||||||
|
(float)(i - (second_half ? t1.y - t0.y : 0)) / segment_height;
|
||||||
|
Vec2i A = t0 + (t2 - t0) * alpha;
|
||||||
|
Vec2i B = second_half ? t1 + (t2 - t1) * beta : t0 + (t1 - t0) * beta;
|
||||||
|
if (A.x > B.x)
|
||||||
|
std::swap(A, B);
|
||||||
|
for (int j = A.x; j <= B.x; j++) {
|
||||||
|
image.set(j, t0.y + i, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
TGAImage image(windowWidth, windowHeight, TGAImage::RGB);
|
TGAImage image(windowWidth, windowHeight, TGAImage::RGB);
|
||||||
Vec2i pts[3] = {Vec2i(30, 30), Vec2i(300, 90), Vec2i(570, 480)};
|
|
||||||
// triangle(pts, image, purple);
|
|
||||||
|
|
||||||
// Model stuff.
|
// Model stuff.
|
||||||
if (2 == argc)
|
if (2 == argc)
|
||||||
@@ -88,18 +116,24 @@ int main(int argc, char **argv) {
|
|||||||
else
|
else
|
||||||
model = new Model("../obj/wolf_head.obj");
|
model = new Model("../obj/wolf_head.obj");
|
||||||
|
|
||||||
|
|
||||||
|
Vec3f lightDirection(0,0,-1);
|
||||||
|
|
||||||
for (int i = 0; i < model->nfaces(); i++) {
|
for (int i = 0; i < model->nfaces(); i++) {
|
||||||
vector<int> face = model->face(i);
|
vector<int> face = model->face(i);
|
||||||
Vec2i screenCoordinates[3];
|
Vec2i screenCoordinates[3];
|
||||||
|
Vec3f worldCoordinates[3];
|
||||||
for (int j = 0; j < 3; j++) {
|
for (int j = 0; j < 3; j++) {
|
||||||
Vec3f worldCoordinates = model->vert(face[j]);
|
Vec3f v = model->vert(face[j]);
|
||||||
screenCoordinates[j] =
|
screenCoordinates[j] = Vec2i((v.x + 1.0) * windowWidth / 2.0, (v.y + 1.0) * windowHeight / 2.0);
|
||||||
Vec2i((worldCoordinates.x + 1) * windowWidth / 2.0,
|
worldCoordinates[j] = v;
|
||||||
(worldCoordinates.y + 1.0) * windowHeight / 2.0);
|
|
||||||
}
|
}
|
||||||
triangle(screenCoordinates[0], screenCoordinates[1],
|
Vec3f n = (worldCoordinates[2] - worldCoordinates[0]) ^ (worldCoordinates[1] - worldCoordinates[0]);
|
||||||
|
n.normalize();
|
||||||
|
float intensity = n * lightDirection;
|
||||||
|
if (intensity > 0) triangle(screenCoordinates[0], screenCoordinates[1],
|
||||||
screenCoordinates[2], image,
|
screenCoordinates[2], image,
|
||||||
TGAColor(rand() % 255, rand() % 255, rand() % 255, 255));
|
TGAColor(intensity * 255, intensity * 255, intensity * 255, 255));
|
||||||
}
|
}
|
||||||
image.flip_vertically();
|
image.flip_vertically();
|
||||||
image.write_tga_file("output.tga");
|
image.write_tga_file("output.tga");
|
||||||
|
Reference in New Issue
Block a user