117 lines
3.5 KiB
C++
117 lines
3.5 KiB
C++
#include "model.h"
|
|
#include "renderer.h"
|
|
#include "util_window.h"
|
|
#include "camera.h"
|
|
#include "util_renderer.h"
|
|
|
|
#define HORIZONTAL_CAMERA_SPEED 0.1
|
|
#define VERTICAL_CAMERA_SPEED 0.1
|
|
#define VERTICAL_CAMERA_CLAMP_UP 90
|
|
#define VERTICAL_CAMERA_CLAMP_DOWN -90
|
|
#define NEAR_CLIP_PLANE 0
|
|
#define FAR_CLIP_PLANE 10
|
|
#define FOV 30
|
|
#define CAMERA_MOVEMENT_SPEED 0.05f
|
|
#define DEFAULT_CAMERA_POS Vec3f(0, 0, 5)
|
|
#define DEFAULT_CAMERA_ROT Vec3f(0, 0, 0)
|
|
#define LIGHT_INTENSITY 2.f
|
|
|
|
const TGAColor white = TGAColor(255, 255, 255, 255);
|
|
const TGAColor red = TGAColor(255, 0, 0, 255);
|
|
const TGAColor green = TGAColor(0, 255, 0, 255);
|
|
const TGAColor blue = TGAColor(0, 0, 255, 255);
|
|
|
|
Matrix ViewPort = Matrix::identity();
|
|
Matrix ModelView = Matrix::identity();
|
|
Matrix Projection = Matrix::identity();
|
|
|
|
Model* model = new Model("african_head.obj");
|
|
Camera camera;
|
|
|
|
Vec3f light_dir = Vec3f(1, 1, 1).normalize();
|
|
|
|
void init_camera() {
|
|
camera.SetPosition(DEFAULT_CAMERA_POS);
|
|
camera.SetRotation(DEFAULT_CAMERA_ROT);
|
|
camera.SetFOV(FOV);
|
|
camera.SetNearPlane(NEAR_CLIP_PLANE);
|
|
camera.SetFarPlane(FAR_CLIP_PLANE);
|
|
camera.SetClampRotDown(VERTICAL_CAMERA_CLAMP_DOWN);
|
|
camera.SetClampRotUp(VERTICAL_CAMERA_CLAMP_UP);
|
|
camera.SetHorizontalRotSpeed(HORIZONTAL_CAMERA_SPEED);
|
|
camera.SetVerticalRotSpeed(VERTICAL_CAMERA_SPEED);
|
|
camera.SetMovementSpeed(CAMERA_MOVEMENT_SPEED);
|
|
camera.ApplyChanges();
|
|
}
|
|
|
|
void clear_zbuffer()
|
|
{
|
|
for (int i = 0; i < screen_width * screen_height; i++)
|
|
z_buffer[i] = 0;
|
|
}
|
|
|
|
|
|
struct TextureShader : public IShader {
|
|
mat<2, 3, float> varying_uv_coords;
|
|
Matrix uniform_mit;
|
|
Matrix uniform_m;
|
|
|
|
virtual Vec4f vertex(int iface, int nthvert) {
|
|
varying_uv_coords.set_col(nthvert, model->uv(iface, nthvert));
|
|
Vec4f gl_Vertex = embed<4>(model->vert(iface, nthvert));
|
|
return ViewPort * Projection * ModelView * gl_Vertex; // transform it to screen coordinates
|
|
}
|
|
|
|
virtual bool fragment(Vec3f bar, TGAColor &color) {
|
|
Vec2f uv = varying_uv_coords * bar;
|
|
Vec3f normal = Vec3f(uniform_mit * Vec4f(model->normal(uv))).normalize();
|
|
Vec3f light = Vec3f(uniform_m * Vec4f(light_dir)).normalize();
|
|
Vec3f reflection = (normal * (normal*light*2.f) - light).normalize();
|
|
float spec_intensity = pow(std::fmax(reflection.z, 0.f), model->specular(uv));
|
|
float diff_intensity = std::fmax(0.f, (normal*light));
|
|
TGAColor c = model->diffuse(uv);
|
|
color = c;
|
|
for (int i = 0; i < 3; i++)
|
|
color[i] = std::fmin(1 + c[i] * (diff_intensity + 0.8 * spec_intensity), 255) * LIGHT_INTENSITY;
|
|
return false;
|
|
}
|
|
};
|
|
|
|
|
|
void render()
|
|
{
|
|
{
|
|
//light_dir = camera.GetForward().normalize() * -1;
|
|
}
|
|
|
|
{
|
|
viewport(0, 0, screen_width, screen_height, FAR_CLIP_PLANE, NEAR_CLIP_PLANE);
|
|
Projection = camera.GetProjectionMatrix();
|
|
ModelView = camera.GetModelViewMatrix();
|
|
}
|
|
|
|
|
|
//Matrix z = ViewPort * Projection * ModelView * model->Transform;
|
|
|
|
clear_zbuffer();
|
|
TextureShader shader;
|
|
shader.uniform_m = (Projection);
|
|
shader.uniform_mit = (Projection).invert_transpose();
|
|
|
|
#pragma omp parallel for
|
|
for (int i = 0; i < model->nfaces(); i++) {
|
|
Vec4f screen_coords[3];
|
|
bool out = true;
|
|
#pragma omp parallel for
|
|
for (int j = 0; j < 3; j++) {
|
|
screen_coords[j] = shader.vertex(i, j);
|
|
Vec3f screen3(screen_coords[j]);
|
|
|
|
if (screen3.x > 0 && screen3.x < screen_width && screen3.y > 0 && screen3.y < screen_height) out = false;
|
|
}
|
|
if(!out)
|
|
triangle(screen_coords, shader);
|
|
}
|
|
}
|
|
|