forked from ssloy/tinyrenderer
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathour_gl.cpp
More file actions
71 lines (62 loc) · 2.61 KB
/
Copy pathour_gl.cpp
File metadata and controls
71 lines (62 loc) · 2.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <cmath>
#include <limits>
#include "our_gl.h"
//Matrix ModelView;
Matrix Viewport;
//Matrix Projection;
void viewport(int x, int y, int w, int h) {
Viewport[0]=Viewport[0].fill();
Viewport[1]=Viewport[1].fill();
Viewport[2]=Viewport[2].fill();
Viewport[3]=Viewport[3].fill();
Viewport[0][3] = x+w/2.f;
Viewport[1][3] = y+h/2.f;
Viewport[2][3] = 255.f/2.f;
Viewport[0][0] = w/2.f;
Viewport[1][1] = h/2.f;
Viewport[2][2] = 255.f/2.f;
}
//void projection(float coeff) {
// Projection = Matrix::identity(4);
// Projection[3][2] = coeff;
//}/*
//void lookat(Vec3f eye, Vec3f center, Vec3f up) {
// Vec3f z = (eye-center).normalize();
// Vec3f x = (up^z).normalize();
// Vec3f y = (z^x).normalize();
// ModelView = Matrix::identity(4);
// for (int i=0; i<3; i++) {
// ModelView[0][i] = x[i];
// ModelView[1][i] = y[i];
// ModelView[2][i] = z[i];
// ModelView[i][3] = -center[i];
// }
//}*/
Vec3f barycentric(Vec3i A, Vec3i B, Vec3i C, Vec3i P) {
Vec3f u = ((Vec3f){static_cast<float>(C[0]-A[0]), static_cast<float>(B[0]-A[0]), static_cast<float>(A[0]-P[0])})^((Vec3f){static_cast<float>(C[1]-A[1]), static_cast<float>(B[1]-A[1]), static_cast<float>(A[1]-P[1])});
return std::abs(u[2])>.5 ? (Vec3f){1.f-(u[0]+u[1])/u[2], u[1]/u[2], u[0]/u[2]} : (Vec3f){static_cast<float>(-1),static_cast<float>(1),static_cast<float>(1)}; // dont forget that u[2] is an integer. If it is zero then triangle ABC is degenerate
}
void triangle(Vec3i *pts, IShader &shader, TGAImage &image, TGAImage &zbuffer) {
Vec2i bboxmin=(Vec2i){ std::numeric_limits<int>::max(), std::numeric_limits<int>::max()};
Vec2i bboxmax=(Vec2i){-std::numeric_limits<int>::max(), -std::numeric_limits<int>::max()};
for (int i=0; i<3; i++) {
for (int j=0; j<2; j++) {
bboxmin[j] = std::min(bboxmin[j], pts[i][j]);
bboxmax[j] = std::max(bboxmax[j], pts[i][j]);
}
}
Vec3i P;
for (P[0]=bboxmin[0]; P[0]<=bboxmax[0]; P[0]++) {
for (P[1]=bboxmin[1]; P[1]<=bboxmax[1]; P[1]++) {
Vec3f c = barycentric(pts[0], pts[1], pts[2], P);
P[2] = std::max(0, std::min(255, int(pts[0][2]*c[0] + pts[1][2]*c[1] + pts[2][2]*c[2] + .5))); // clamping to 0-255 since it is stored in unsigned char
if (c[0]<0 || c[1]<0 || c[2]<0 || zbuffer.get(P[0], P[1])[0]>P[2]) continue;
TGAColor color;
bool discard = shader.fragment(c, color);
if (!discard) {
zbuffer.set(P[0], P[1], TGAColor(P[2]));
image.set(P[0], P[1], color);
}
}
}
}