-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cpp
113 lines (90 loc) · 3.07 KB
/
main.cpp
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <cmath>
#include <limits>
#include <valarray>
#include <vector>
#include "model.h"
#include "geometry.h"
#include "tgaimage.h"
#include "gl.h"
const int width = 800;
const int height = 800;
const int depth = 255;
Vec3f light_dir = Vec3f(1,1,1).normalize();
Vec3f eye(1, 1, 3);
Vec3f center(0, 0, 0);
Model *model = NULL;
struct Shader : public IShader {
Vec3f varying_textures[3];
// uniform is used to signify that these variables are constant for shader instance
Matrix uniform_M; // Projection * ModelView;
Matrix uniform_MIT; // (Projection * ModelView).invert_transpose();
virtual Vec3f vertex(int iface, int nthvert) {
varying_textures[nthvert] = model->texture_vert(iface, nthvert);
Vec3f gl_Vertex = (model->vert(iface, nthvert));
gl_Vertex = (Viewport * Projection * ModelView * gl_Vertex).to_Vec3f();
return gl_Vertex;
}
virtual bool fragment(Vec3f bar, TGAColor &color) {
Vec2f uv(0.f, 0.f);
for (int i{0}; i < 3; i++) {
uv.x += varying_textures[i].x * bar.raw[i];
uv.y += varying_textures[i].y * bar.raw[i];
}
Vec3f n = (uniform_MIT * Matrix(model->normal(uv))).to_Vec3f().normalize();
Vec3f l = (uniform_M * Matrix(light_dir)).to_Vec3f().normalize();
Vec3f r = (n*(n*l*2.f) - l).normalize(); // reflected ray
float spec = pow(std::max(r.z, 0.f), model->specular(uv));
float diff = std::max(0.f, n*l);
TGAColor c = model->diffuse(uv);
color = c;
for (int i{0}; i < 3; i++) {
color.raw[i] = std::min<float>(3 + c.raw[i]*(diff + 1.2*spec), 255);
}
return false;
}
};
int main() {
model = new Model(
"./obj/african_head/african_head.obj",
"./obj/african_head/african_head_diffuse.tga",
"./obj/african_head/african_head_nm.tga",
"./obj/african_head/african_head_spec.tga"
);
//model = new Model(
// "./obj/diablo3_pose/diablo3_pose.obj",
// "./obj/diablo3_pose/diablo3_pose_diffuse.tga",
// "./obj/diablo3_pose/diablo3_pose_nm.tga",
// "./obj/diablo3_pose/diablo3_pose_spec.tga"
//);
float z_buffer[width*height];
for (int i{0}; i < width*height; i++) {
z_buffer[i] = -std::numeric_limits<float>::max();
}
projection(-1.f/(eye - center).norm());
viewport(width/8, height/8, width*3/4, height*3/4);
lookat(eye, center, Vec3f(0, 1, 0));
TGAImage render_image(width, height, TGAImage::RGB);
Shader shader;
shader.uniform_M = Projection * ModelView;
shader.uniform_MIT = (Projection * ModelView).inverse().transpose();
for (int i = 0; i < model->nfaces(); i++) {
Vec3f screen_coords[3];
Vec3f vt[3];
Vec3f vn[3];
for (int j = 0; j < 3; j++) {
vt[j] = model->texture_vert(i, j);
vn[j] = model->vert_norm(i, j);
Vec3f temp = shader.vertex(i, j);
screen_coords[j] = Vec3f(int(temp.x), int(temp.y), int(temp.z));
}
triangle(screen_coords, shader, render_image, z_buffer);
}
render_image.flip_vertically();
render_image.write_tga_file("output.tga");
delete model;
return 0;
}