Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8b1546cb54 | |||
| 26a7e48784 |
@@ -121,6 +121,7 @@
|
|||||||
<ClCompile Include="model.cpp" />
|
<ClCompile Include="model.cpp" />
|
||||||
<ClCompile Include="renderer.cpp" />
|
<ClCompile Include="renderer.cpp" />
|
||||||
<ClCompile Include="tgaimage.cpp" />
|
<ClCompile Include="tgaimage.cpp" />
|
||||||
|
<ClCompile Include="util_renderer.cpp" />
|
||||||
<ClCompile Include="util_window.cpp" />
|
<ClCompile Include="util_window.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -129,6 +130,7 @@
|
|||||||
<ClInclude Include="model.h" />
|
<ClInclude Include="model.h" />
|
||||||
<ClInclude Include="renderer.h" />
|
<ClInclude Include="renderer.h" />
|
||||||
<ClInclude Include="tgaimage.h" />
|
<ClInclude Include="tgaimage.h" />
|
||||||
|
<ClInclude Include="util_renderer.h" />
|
||||||
<ClInclude Include="util_window.h" />
|
<ClInclude Include="util_window.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
|||||||
@@ -36,6 +36,9 @@
|
|||||||
<ClCompile Include="camera.cpp">
|
<ClCompile Include="camera.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="util_renderer.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="util_window.h">
|
<ClInclude Include="util_window.h">
|
||||||
@@ -56,5 +59,8 @@
|
|||||||
<ClInclude Include="camera.h">
|
<ClInclude Include="camera.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="util_renderer.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
Binary file not shown.
+12
-8
@@ -79,27 +79,31 @@ void Camera::move_camera_forward() {
|
|||||||
void Camera::move_camera_backward() {
|
void Camera::move_camera_backward() {
|
||||||
position = position - forward * movement_speed;
|
position = position - forward * movement_speed;
|
||||||
}
|
}
|
||||||
|
void Camera::rise() {
|
||||||
|
position = position + Vec3f(0, movement_speed, 0);
|
||||||
|
}
|
||||||
|
void Camera::fall() {
|
||||||
|
position = position - Vec3f(0, movement_speed, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void Camera::SetMovementSpeed(float speed) {
|
void Camera::SetMovementSpeed(float speed) {
|
||||||
movement_speed = speed;
|
movement_speed = speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::ApplyChanges() {
|
void Camera::ApplyChanges() {
|
||||||
forward = Vec3f(sin(rotation.y * DEG2RAD), -sin(rotation.x * DEG2RAD), -cosf(rotation.y*DEG2RAD) * cosf(rotation.x*DEG2RAD));
|
forward = Vec3f(sin(rotation.y * DEG2RAD), -sin(rotation.x * DEG2RAD), -cosf(rotation.y*DEG2RAD) * cosf(rotation.x*DEG2RAD)).normalize();
|
||||||
right = Vec3f(cos(rotation.y*DEG2RAD), 0, sin(rotation.y * DEG2RAD));
|
right = Vec3f(cos(rotation.y*DEG2RAD), 0, sin(rotation.y * DEG2RAD)).normalize();
|
||||||
up = cross(right, forward);
|
up = cross(right, forward).normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix Camera::GetModelViewMatrix() {
|
Matrix Camera::GetModelViewMatrix() {
|
||||||
Vec3f center = position + forward;
|
Vec3f center = position + forward;
|
||||||
Vec3f z = (position - center).normalize();
|
Vec3f z = forward * -1;
|
||||||
Vec3f x = cross(up, z).normalize();
|
|
||||||
Vec3f y = cross(z, x).normalize();
|
|
||||||
Matrix Minv = Matrix::identity();
|
Matrix Minv = Matrix::identity();
|
||||||
Matrix Tr = Matrix::identity();
|
Matrix Tr = Matrix::identity();
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
Minv[0][i] = x[i];
|
Minv[0][i] = right[i];
|
||||||
Minv[1][i] = y[i];
|
Minv[1][i] = up[i];
|
||||||
Minv[2][i] = z[i];
|
Minv[2][i] = z[i];
|
||||||
Tr[i][3] = -center[i];
|
Tr[i][3] = -center[i];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ public:
|
|||||||
void move_camera_right();
|
void move_camera_right();
|
||||||
void move_camera_forward();
|
void move_camera_forward();
|
||||||
void move_camera_backward();
|
void move_camera_backward();
|
||||||
|
void rise();
|
||||||
|
void fall();
|
||||||
|
|
||||||
void ApplyChanges();
|
void ApplyChanges();
|
||||||
Matrix GetModelViewMatrix();
|
Matrix GetModelViewMatrix();
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ const int screen_height = 1000;
|
|||||||
int prev_mouse_x = screen_width/2;
|
int prev_mouse_x = screen_width/2;
|
||||||
int prev_mouse_y = screen_height/2;
|
int prev_mouse_y = screen_height/2;
|
||||||
|
|
||||||
|
float TIME = 0;
|
||||||
|
|
||||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
||||||
{
|
{
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
@@ -52,11 +54,16 @@ bool HandleButtonPressed() {
|
|||||||
camera.move_camera_right();
|
camera.move_camera_right();
|
||||||
if (GetAsyncKeyState(VK_LEFT) & 0x8000)
|
if (GetAsyncKeyState(VK_LEFT) & 0x8000)
|
||||||
camera.move_camera_left();
|
camera.move_camera_left();
|
||||||
|
if (GetAsyncKeyState(VK_SPACE) & 0x8000)
|
||||||
|
camera.rise();
|
||||||
|
if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
|
||||||
|
camera.fall();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CALLBACK FixedUpdate(HWND hwnd, UINT message, UINT uInt, DWORD dWord)
|
void CALLBACK FixedUpdate(HWND hwnd, UINT message, UINT uInt, DWORD dWord)
|
||||||
{
|
{
|
||||||
|
TIME += 0.167;
|
||||||
HandleButtonPressed();
|
HandleButtonPressed();
|
||||||
camera.ApplyChanges();
|
camera.ApplyChanges();
|
||||||
render();
|
render();
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ Model::Model(const char *filename) : verts_(), faces_(), norms_(), uv_(), diffus
|
|||||||
std::cerr << "# v# " << verts_.size() << " f# " << faces_.size() << " vt# " << uv_.size() << " vn# " << norms_.size() << std::endl;
|
std::cerr << "# v# " << verts_.size() << " f# " << faces_.size() << " vt# " << uv_.size() << " vn# " << norms_.size() << std::endl;
|
||||||
load_texture(filename, "_diffuse.tga", diffusemap_);
|
load_texture(filename, "_diffuse.tga", diffusemap_);
|
||||||
load_texture(filename, "_nm_tangent.tga", normalmap_);
|
load_texture(filename, "_nm_tangent.tga", normalmap_);
|
||||||
//load_texture(filename, "_spec.tga", specularmap_);
|
load_texture(filename, "_spec.tga", specularmap_);
|
||||||
}
|
}
|
||||||
|
|
||||||
Model::~Model() {}
|
Model::~Model() {}
|
||||||
|
|||||||
+65
-212
@@ -1,199 +1,34 @@
|
|||||||
#include <vector>
|
#include "model.h"
|
||||||
#include <algorithm>
|
|
||||||
#include <limits>
|
|
||||||
#include "tgaimage.h"
|
|
||||||
#include "model.h"
|
|
||||||
#include "geometry.h"
|
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
#include "util_window.h"
|
#include "util_window.h"
|
||||||
#include <ctime>
|
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
|
#include "util_renderer.h"
|
||||||
|
|
||||||
#define HORIZONTAL_CAMERA_SPEED 0.1
|
#define HORIZONTAL_CAMERA_SPEED 0.1
|
||||||
#define VERTICAL_CAMERA_SPEED 0.1
|
#define VERTICAL_CAMERA_SPEED 0.1
|
||||||
#define VERTICAL_CAMERA_CLAMP_UP 90
|
#define VERTICAL_CAMERA_CLAMP_UP 90
|
||||||
#define VERTICAL_CAMERA_CLAMP_DOWN -90
|
#define VERTICAL_CAMERA_CLAMP_DOWN -90
|
||||||
#define NEAR_CLIP_PLANE 0
|
#define NEAR_CLIP_PLANE 0
|
||||||
#define FAR_CLIP_PLANE 15
|
#define FAR_CLIP_PLANE 10
|
||||||
#define FOV 30
|
#define FOV 30
|
||||||
#define DEFAULT_CAMERA_POS Vec3f(0, 0, 5)
|
#define CAMERA_MOVEMENT_SPEED 0.05f
|
||||||
#define DEFAULT_CAMERA_ROT Vec3f(0, 0, 0)
|
#define DEFAULT_CAMERA_POS Vec3f(0, 0, 5)
|
||||||
#define CAMERA_MOVEMENT_SPEED 1.f
|
#define DEFAULT_CAMERA_ROT Vec3f(0, 0, 0)
|
||||||
|
#define LIGHT_INTENSITY 2.f
|
||||||
|
|
||||||
const TGAColor white = TGAColor(255, 255, 255, 255);
|
const TGAColor white = TGAColor(255, 255, 255, 255);
|
||||||
const TGAColor red = TGAColor(255, 0, 0, 255);
|
const TGAColor red = TGAColor(255, 0, 0, 255);
|
||||||
const TGAColor green = TGAColor(0, 255, 0, 255);
|
const TGAColor green = TGAColor(0, 255, 0, 255);
|
||||||
const TGAColor blue = TGAColor(0, 0, 255, 255);
|
const TGAColor blue = TGAColor(0, 0, 255, 255);
|
||||||
|
|
||||||
bool wireframe = false;
|
Matrix ViewPort = Matrix::identity();
|
||||||
|
Matrix ModelView = Matrix::identity();
|
||||||
|
Matrix Projection = Matrix::identity();
|
||||||
|
|
||||||
Model* model = new Model("african_head.obj");
|
Model* model = new Model("african_head.obj");
|
||||||
Camera camera;
|
Camera camera;
|
||||||
|
|
||||||
float* z_buffer = new float[screen_width * screen_height];
|
Vec3f light_dir = Vec3f(1, 1, 1).normalize();
|
||||||
Vec3f light_dir = Vec3f(0, 0, 1).normalize();
|
|
||||||
|
|
||||||
Matrix viewport(int x, int y, int w, int h) {
|
|
||||||
Matrix m = Matrix::identity();
|
|
||||||
m[0][3] = x + w / 2.f;
|
|
||||||
m[1][3] = y + h / 2.f;
|
|
||||||
m[2][3] = (FAR_CLIP_PLANE-NEAR_CLIP_PLANE) / 2.f;
|
|
||||||
|
|
||||||
m[0][0] = w / 2.f;
|
|
||||||
m[1][1] = h / 2.f;
|
|
||||||
m[2][2] = (FAR_CLIP_PLANE+NEAR_CLIP_PLANE) / 2.f;
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
void line(Vec3f p0, Vec3f p1, TGAColor color)
|
|
||||||
{
|
|
||||||
bool steep = false;
|
|
||||||
|
|
||||||
if (std::abs(p0[0] - p1[0]) < std::abs(p0[1] - p1[1])) {
|
|
||||||
std::swap(p0[0], p0[1]);
|
|
||||||
std::swap(p1[0], p1[1]);
|
|
||||||
steep = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p0[0] > p1[0]) {
|
|
||||||
std::swap(p0[0], p1[0]);
|
|
||||||
std::swap(p0[1], p1[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
int dx = p1[0] - p0[0];
|
|
||||||
int dy = p1[1] - p0[1];
|
|
||||||
int derror2 = std::abs(dy) * 2;
|
|
||||||
int error2 = 0;
|
|
||||||
int y = p0[1];
|
|
||||||
int y_step = p1[1] > p0[1] ? 1 : -1;
|
|
||||||
int dx_2 = 2 * dx;
|
|
||||||
|
|
||||||
for (int x = p0[0]; x <= p1[0]; x++) {
|
|
||||||
if (steep) {
|
|
||||||
set_pixel(y, x, color_to_int(color));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
set_pixel(x, y, color_to_int(color));
|
|
||||||
}
|
|
||||||
error2 += derror2;
|
|
||||||
if (error2 > dx) {
|
|
||||||
y += (y_step);
|
|
||||||
error2 -= dx_2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3f barycentric(Vec3f* pts, Vec3f P)
|
|
||||||
{
|
|
||||||
Vec3f u = cross(
|
|
||||||
Vec3f(pts[2][0] - pts[0][0], pts[1][0] - pts[0][0], pts[0][0] - P[0]), // AC_x, AB_x, distance_x
|
|
||||||
Vec3f(pts[2][1] - pts[0][1], pts[1][1] - pts[0][1], pts[0][1] - P[1]) // AC_y, AB_y, distance_y
|
|
||||||
);
|
|
||||||
|
|
||||||
if (std::abs(u[2]) < 1) return Vec3f(-1, 1, 1);
|
|
||||||
return Vec3f(1.f - (u.x + u.y) / u.z, u.y / u.z, u.x / u.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void triangle(
|
|
||||||
Vec3f* pts, // Needed
|
|
||||||
Vec2f* diff_pts, // Should be removed
|
|
||||||
Model* model,
|
|
||||||
float* intensities)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (pts[0].y == pts[1].y && pts[0].y == pts[2].y) return; // i dont care about degenerate triangles
|
|
||||||
if (pts[0].y > pts[1].y) {
|
|
||||||
std::swap(pts[0], pts[1]);
|
|
||||||
if(diff_pts)
|
|
||||||
std::swap(diff_pts[0], diff_pts[1]);
|
|
||||||
if(intensities)
|
|
||||||
std::swap(intensities[0], intensities[1]);
|
|
||||||
}
|
|
||||||
if (pts[0].y > pts[2].y) {
|
|
||||||
std::swap(pts[0], pts[2]);
|
|
||||||
if(diff_pts)
|
|
||||||
std::swap(diff_pts[0], diff_pts[2]);
|
|
||||||
if(intensities)
|
|
||||||
std::swap(intensities[0], intensities[2]);
|
|
||||||
}
|
|
||||||
if (pts[1].y > pts[2].y) {
|
|
||||||
std::swap(pts[1], pts[2]);
|
|
||||||
if(diff_pts)
|
|
||||||
std::swap(diff_pts[1], diff_pts[2]);
|
|
||||||
if(intensities)
|
|
||||||
std::swap(intensities[1], intensities[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wireframe)
|
|
||||||
{
|
|
||||||
line(pts[0], pts[1], white);
|
|
||||||
line(pts[1], pts[2], white);
|
|
||||||
line(pts[2], pts[0], white);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2i bounding_box_min(screen_width - 1, screen_height - 1);
|
|
||||||
Vec2i bounding_box_max(0, 0);
|
|
||||||
Vec2i clamp(screen_width - 1, screen_height - 1);
|
|
||||||
TGAColor color = white;
|
|
||||||
|
|
||||||
#pragma omp parallel for
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
for (int j = 0; j < 2; j++) {
|
|
||||||
bounding_box_min[j] = std::fmax(0, std::fmin(bounding_box_min[j], (int)pts[i][j]));
|
|
||||||
bounding_box_max[j] = std::fmin(clamp[j], std::fmax(bounding_box_max[j], (int)pts[i][j]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3f P;
|
|
||||||
#pragma omp parallel for
|
|
||||||
for (P.x = bounding_box_min.x; P.x <= bounding_box_max.x; P.x++) {
|
|
||||||
for (P.y = bounding_box_min.y; P.y <= bounding_box_max.y; P.y++) {
|
|
||||||
Vec3f bc_coord = barycentric(pts, P);
|
|
||||||
if (bc_coord.x < 0 || bc_coord.y < 0 || bc_coord.z < 0) continue;
|
|
||||||
|
|
||||||
|
|
||||||
float intensity =
|
|
||||||
intensities[0]
|
|
||||||
+ (intensities[1] - intensities[0]) * bc_coord[1]
|
|
||||||
+ (intensities[2] - intensities[0]) * bc_coord[2];
|
|
||||||
|
|
||||||
|
|
||||||
// Interpolating Z using the barycentric coordinates
|
|
||||||
P.z = 0;
|
|
||||||
for (int i = 0; i < 3; i++) P.z += pts[i][2] * bc_coord[i];
|
|
||||||
|
|
||||||
// Coloring according to the Z-Buffer
|
|
||||||
if (P.z > z_buffer[(int)(P.x + P.y * screen_width)] && P.z > 0)
|
|
||||||
{
|
|
||||||
z_buffer[(int)(P.x + P.y * screen_width)] = P.z;
|
|
||||||
|
|
||||||
// If diff_pts (Diffusemap Points) were passed, then find the
|
|
||||||
// color of the current pixel
|
|
||||||
if (diff_pts) {
|
|
||||||
Vec2f diff_pt =
|
|
||||||
diff_pts[0]
|
|
||||||
+ (diff_pts[1] - diff_pts[0]) * bc_coord[1]
|
|
||||||
+ (diff_pts[2] - diff_pts[0]) * bc_coord[2];
|
|
||||||
|
|
||||||
color = model->diffuse(diff_pt);
|
|
||||||
}
|
|
||||||
color = color * intensity;
|
|
||||||
set_pixel(P.x, P.y, color_to_int(color));
|
|
||||||
//char debugStr[200];
|
|
||||||
//sprintf_s(debugStr, "%f\n", P.z);
|
|
||||||
//OutputDebugString(debugStr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int color_to_int(TGAColor col) {
|
|
||||||
return (col[2] << 16) | (col[1] << 8) | col[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_camera() {
|
void init_camera() {
|
||||||
camera.SetPosition(DEFAULT_CAMERA_POS);
|
camera.SetPosition(DEFAULT_CAMERA_POS);
|
||||||
@@ -212,52 +47,70 @@ void init_camera() {
|
|||||||
void clear_zbuffer()
|
void clear_zbuffer()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < screen_width * screen_height; i++)
|
for (int i = 0; i < screen_width * screen_height; i++)
|
||||||
z_buffer[i] = INT_MIN;
|
z_buffer[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix ViewPort = Matrix::identity();
|
|
||||||
Matrix Projection = Matrix::identity();
|
struct TextureShader : public IShader {
|
||||||
Matrix ModelView = Matrix::identity();
|
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()
|
void render()
|
||||||
{
|
{
|
||||||
light_dir = camera.GetForward() * -1;
|
{
|
||||||
ViewPort = viewport(0, 0, screen_width, screen_height);
|
//light_dir = camera.GetForward().normalize() * -1;
|
||||||
Projection = camera.GetProjectionMatrix();
|
}
|
||||||
ModelView = camera.GetModelViewMatrix();
|
|
||||||
|
|
||||||
Matrix z = ViewPort * Projection * ModelView * model->Transform;
|
{
|
||||||
|
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();
|
clear_zbuffer();
|
||||||
|
TextureShader shader;
|
||||||
|
shader.uniform_m = (Projection);
|
||||||
|
shader.uniform_mit = (Projection).invert_transpose();
|
||||||
|
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
for (int i = 0; i < model->nfaces(); i++)
|
for (int i = 0; i < model->nfaces(); i++) {
|
||||||
{
|
Vec4f screen_coords[3];
|
||||||
std::vector<int> face = model->face(i);
|
|
||||||
Vec3f screen_coords[3];
|
|
||||||
Vec3f world_coords[3];
|
|
||||||
Vec2f diffuse_coords[3];
|
|
||||||
float intensities[3];
|
|
||||||
bool out = true;
|
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]);
|
||||||
|
|
||||||
for (int j = 0; j < 3; j++)
|
if (screen3.x > 0 && screen3.x < screen_width && screen3.y > 0 && screen3.y < screen_height) out = false;
|
||||||
{
|
|
||||||
Vec3f v = model->vert(face[j]);
|
|
||||||
Vec4f v4(v);
|
|
||||||
Vec3f coord(z * v4);
|
|
||||||
|
|
||||||
if (coord.x > 0 && coord.x < screen_width
|
|
||||||
&& coord.y > 0 && coord.y < screen_height)
|
|
||||||
out = false;
|
|
||||||
|
|
||||||
screen_coords[j] = coord;
|
|
||||||
world_coords[j] = v;
|
|
||||||
diffuse_coords[j] = model->uv(i, j);
|
|
||||||
intensities[j] = model->normal(i, j) * light_dir;
|
|
||||||
}
|
}
|
||||||
|
if(!out)
|
||||||
if (out) continue;
|
triangle(screen_coords, shader);
|
||||||
|
|
||||||
triangle(screen_coords, diffuse_coords, model, intensities);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
extern float* z_buffer;
|
extern float* z_buffer;
|
||||||
extern Camera camera;
|
extern Camera camera;
|
||||||
|
extern float TIME;
|
||||||
|
|
||||||
void init_camera();
|
void init_camera();
|
||||||
void render();
|
void render();
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
#include "util_renderer.h"
|
||||||
|
#include "util_window.h"
|
||||||
|
|
||||||
|
IShader::~IShader() {}
|
||||||
|
|
||||||
|
float* z_buffer = new float[screen_width * screen_height];
|
||||||
|
|
||||||
|
void viewport(int x, int y, int w, int h, int far_plane, int near_plane) {
|
||||||
|
ViewPort[0][3] = x + w / 2.f;
|
||||||
|
ViewPort[1][3] = y + h / 2.f;
|
||||||
|
ViewPort[2][3] = (far_plane-near_plane) / 2.f;
|
||||||
|
|
||||||
|
ViewPort[0][0] = w / 2.f;
|
||||||
|
ViewPort[1][1] = h / 2.f;
|
||||||
|
ViewPort[2][2] = (far_plane+near_plane) / 2.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
int color_to_int(TGAColor col) {
|
||||||
|
return (col[2] << 16) | (col[1] << 8) | col[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3f barycentric(Vec3f* pts, Vec3f P)
|
||||||
|
{
|
||||||
|
Vec3f u = cross(
|
||||||
|
Vec3f(pts[2][0] - pts[0][0], pts[1][0] - pts[0][0], pts[0][0] - P[0]), // AC_x, AB_x, distance_x
|
||||||
|
Vec3f(pts[2][1] - pts[0][1], pts[1][1] - pts[0][1], pts[0][1] - P[1]) // AC_y, AB_y, distance_y
|
||||||
|
);
|
||||||
|
|
||||||
|
if (std::abs(u[2]) < 1) return Vec3f(-1, 1, 1);
|
||||||
|
return Vec3f(1.f - (u.x + u.y) / u.z, u.y / u.z, u.x / u.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void triangle( Vec4f* pts, IShader &shader)
|
||||||
|
{
|
||||||
|
Vec3f pts3[3];
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
pts3[i] = Vec3f(pts[i]);
|
||||||
|
|
||||||
|
if (pts3[0].y == pts3[1].y && pts3[0].y == pts3[2].y) return; // i dont care about degenerate triangles
|
||||||
|
//if (pts3[0].y > pts3[1].y) { std::swap(pts3[0], pts3[1]); }
|
||||||
|
//if (pts3[0].y > pts3[2].y) { std::swap(pts3[0], pts3[2]); }
|
||||||
|
//if (pts3[1].y > pts3[2].y) { std::swap(pts3[1], pts3[2]); }
|
||||||
|
|
||||||
|
Vec2i bounding_box_min(screen_width - 1, screen_height - 1);
|
||||||
|
Vec2i bounding_box_max(0, 0);
|
||||||
|
Vec2i clamp(screen_width - 1, screen_height - 1);
|
||||||
|
|
||||||
|
#pragma omp parallel for
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
for (int j = 0; j < 2; j++) {
|
||||||
|
bounding_box_min[j] = std::fmax(0, std::fmin(bounding_box_min[j], (int)pts3[i][j]));
|
||||||
|
bounding_box_max[j] = std::fmin(clamp[j], std::fmax(bounding_box_max[j], (int)pts3[i][j]));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Vec3i P;
|
||||||
|
#pragma omp parallel for
|
||||||
|
for (P.x = bounding_box_min.x; P.x <= bounding_box_max.x; P.x++) {
|
||||||
|
for (P.y = bounding_box_min.y; P.y <= bounding_box_max.y; P.y++) {
|
||||||
|
Vec3f bc_coord = barycentric(pts3, P);
|
||||||
|
float frag_depth = 0;
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
frag_depth += pts3[i][2] * bc_coord[i];
|
||||||
|
if (bc_coord.x < 0 || bc_coord.y < 0 || bc_coord.z < 0 || z_buffer[ P.x + P.y * screen_width ]>frag_depth) continue;
|
||||||
|
TGAColor color;
|
||||||
|
bool discard = shader.fragment(bc_coord, color);
|
||||||
|
if (!discard) {
|
||||||
|
z_buffer[P.x + P.y * screen_width] = frag_depth;
|
||||||
|
set_pixel(P.x, P.y, color_to_int(color));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "tgaimage.h"
|
||||||
|
#include "model.h"
|
||||||
|
#include "geometry.h"
|
||||||
|
|
||||||
|
extern Matrix ModelView;
|
||||||
|
extern Matrix ViewPort;
|
||||||
|
extern Matrix Projection;
|
||||||
|
|
||||||
|
void viewport(int x, int y, int w, int h, int far, int near);
|
||||||
|
|
||||||
|
struct IShader {
|
||||||
|
virtual ~IShader();
|
||||||
|
virtual Vec4f vertex(int iface, int nthvert) = 0;
|
||||||
|
virtual bool fragment(Vec3f bar, TGAColor &color) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
//void triangle(Vec4f *pts, IShader &shader, TGAImage &image, TGAImage &zbuffer);
|
||||||
|
|
||||||
|
//void triangle( Vec3f* pts, Vec2f* diff_pts, Model* model, float* intensities)
|
||||||
|
|
||||||
|
void triangle(Vec4f* pts, IShader &shader);
|
||||||
Reference in New Issue
Block a user