diff --git a/OpenWindow/OpenWindow.vcxproj b/OpenWindow/OpenWindow.vcxproj
index 6ec45ac..f617bbd 100644
--- a/OpenWindow/OpenWindow.vcxproj
+++ b/OpenWindow/OpenWindow.vcxproj
@@ -115,6 +115,7 @@
+
@@ -124,6 +125,7 @@
+
diff --git a/OpenWindow/OpenWindow.vcxproj.filters b/OpenWindow/OpenWindow.vcxproj.filters
index 53f3b63..89db46c 100644
--- a/OpenWindow/OpenWindow.vcxproj.filters
+++ b/OpenWindow/OpenWindow.vcxproj.filters
@@ -33,6 +33,9 @@
Source Files
+
+ Source Files
+
@@ -50,5 +53,8 @@
Header Files
+
+ Header Files
+
\ No newline at end of file
diff --git a/OpenWindow/camera.cpp b/OpenWindow/camera.cpp
new file mode 100644
index 0000000..5c1742e
--- /dev/null
+++ b/OpenWindow/camera.cpp
@@ -0,0 +1,120 @@
+#include "camera.h"
+
+Camera::Camera()
+{
+ fov = 30;
+ position = Vec3f(0, 0, 0);
+ rotation = Vec3f(0, 0, 0);
+ up = Vec3f(0, 0, 0);
+ right = Vec3f(0, 0, 0);
+ forward = Vec3f(0, 0, 0);
+
+ near_plane = 0;
+ far_plane = 15;
+ horizontal_camera_speed = 0.5;
+ vertical_camera_speed = 0.5;
+ vertical_camera_clamp_up = 90;
+ vertical_camera_clamp_down = -90;
+}
+
+Vec3f Camera::GetForward() {
+ return forward;
+}
+
+void Camera::Move(Vec3f move_vec) {
+ position = position + move_vec;
+}
+
+void Camera::SetPosition(Vec3f pos) {
+ position = pos;
+}
+void Camera::Rotate(Vec3f rot_vec) {
+ rotation = rotation + rot_vec;
+}
+void Camera::SetRotation(Vec3f rot) {
+ rotation = rot;
+}
+void Camera::SetFOV(int angle) {
+ fov = angle;
+}
+void Camera::SetVerticalRotSpeed(float speed) {
+ vertical_camera_speed = speed;
+}
+void Camera::SetHorizontalRotSpeed(float speed) {
+ horizontal_camera_speed = speed;
+}
+void Camera::SetClampRotUp(float angle) {
+ vertical_camera_clamp_up = angle;
+}
+void Camera::SetClampRotDown(float angle) {
+ vertical_camera_clamp_down = angle;
+}
+void Camera::SetNearPlane(float near_val) {
+ near_plane = near_val;
+}
+void Camera::SetFarPlane(float far_val) {
+ far_plane = far_val;
+}
+
+
+void Camera::rotate_camera_right() {
+ rotation.y += horizontal_camera_speed;
+}
+void Camera::rotate_camera_left() {
+ rotation.y -= horizontal_camera_speed;
+}
+void Camera::rotate_camera_up() {
+ rotation.x += vertical_camera_speed;
+ if (rotation.x > vertical_camera_clamp_up) rotation.x = 90;
+}
+void Camera::rotate_camera_down() {
+ rotation.x -= vertical_camera_speed;
+ if (rotation.x < vertical_camera_clamp_down) rotation.x = -90;
+}
+
+#define MOVEMENT_SPEED 0.05f;
+
+void Camera::move_camera_left() {
+ position = position - right * MOVEMENT_SPEED;
+}
+void Camera::move_camera_right() {
+ position = position + right * MOVEMENT_SPEED;
+}
+void Camera::move_camera_forward() {
+ position = position + forward * MOVEMENT_SPEED;
+}
+void Camera::move_camera_backward() {
+ position = position - forward * MOVEMENT_SPEED;
+}
+
+void Camera::ApplyChanges() {
+ forward = Vec3f(sin(rotation.y * DEG2RAD), -sin(rotation.x * DEG2RAD), -cosf(rotation.y*DEG2RAD) * cosf(rotation.x*DEG2RAD));
+ right = Vec3f(cos(rotation.y*DEG2RAD), 0, sin(rotation.y * DEG2RAD));
+ up = cross(right, forward);
+}
+
+Matrix Camera::GetModelViewMatrix() {
+ Vec3f center = position + forward;
+ Vec3f z = (position - center).normalize();
+ Vec3f x = cross(up, z).normalize();
+ Vec3f y = cross(z, x).normalize();
+ Matrix Minv = Matrix::identity();
+ Matrix Tr = Matrix::identity();
+ for (int i = 0; i < 3; i++) {
+ Minv[0][i] = x[i];
+ Minv[1][i] = y[i];
+ Minv[2][i] = z[i];
+ Tr[i][3] = -center[i];
+ }
+ return Minv * Tr;
+}
+
+Matrix Camera::GetProjectionMatrix() {
+ Matrix Projection = Matrix::identity();
+ Projection[0][0] = 1 / tan(fov * DEG2RAD);
+ Projection[1][1] = 1 / tan(fov * DEG2RAD);
+ Projection[2][2] = (far_plane + near_plane) / (far_plane - near_plane);
+ Projection[2][3] = (-2 * far_plane * near_plane) / (far_plane - near_plane);
+ Projection[3][2] = -1;
+ return Projection;
+}
diff --git a/OpenWindow/camera.h b/OpenWindow/camera.h
new file mode 100644
index 0000000..a20117d
--- /dev/null
+++ b/OpenWindow/camera.h
@@ -0,0 +1,48 @@
+#ifndef __CAMERA_HEADER__
+#define __CAMERA_HEADER__
+#include "geometry.h"
+
+class Camera {
+private:
+ Vec3f position;
+ Vec3f rotation;
+ Vec3f up;
+ Vec3f right;
+ Vec3f forward;
+ float fov;
+ float near_plane;
+ float far_plane;
+ float horizontal_camera_speed;
+ float vertical_camera_speed;
+ float vertical_camera_clamp_up;
+ float vertical_camera_clamp_down;
+
+public:
+ Camera();
+ void SetPosition(Vec3f pos);
+ void SetRotation(Vec3f rot);
+ void Move(Vec3f move_vec);
+ void Rotate(Vec3f rot_vec);
+ void SetFOV(int angle);
+ void SetNearPlane(float near_val);
+ void SetFarPlane(float far_val);
+ void SetVerticalRotSpeed(float speed);
+ void SetHorizontalRotSpeed(float speed);
+ void SetClampRotUp(float angle);
+ void SetClampRotDown(float angle);
+ Vec3f GetForward();
+
+ void rotate_camera_right();
+ void rotate_camera_left();
+ void rotate_camera_up();
+ void rotate_camera_down();
+ void move_camera_left();
+ void move_camera_right();
+ void move_camera_forward();
+ void move_camera_backward();
+
+ void ApplyChanges();
+ Matrix GetModelViewMatrix();
+ Matrix GetProjectionMatrix();
+};
+#endif
\ No newline at end of file
diff --git a/OpenWindow/geometry.h b/OpenWindow/geometry.h
index 630234a..98d1221 100644
--- a/OpenWindow/geometry.h
+++ b/OpenWindow/geometry.h
@@ -1,10 +1,13 @@
#ifndef __GEOMETRY_H__
#define __GEOMETRY_H__
+#define _USE_MATH_DEFINES
#include
#include
#include
#include
+#define DEG2RAD M_PI/180
+
template class mat;
template struct vec {
diff --git a/OpenWindow/main.cpp b/OpenWindow/main.cpp
index 8c10ec9..3feaeee 100644
--- a/OpenWindow/main.cpp
+++ b/OpenWindow/main.cpp
@@ -6,8 +6,10 @@
const int screen_width = 1000;
const int screen_height = 1000;
-int prev_mouse_x = 0;
-int prev_mouse_y = 0;
+#define TARGET_FRAMERATE 30
+
+int prev_mouse_x = screen_width/2;
+int prev_mouse_y = screen_height/2;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
@@ -15,18 +17,14 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
MSG Msg;
hwnd = create_window(hInstance);
+ ShowCursor(false);
ShowWindow(hwnd, nCmdShow);
- char debug_str[100];
+ init_camera();
- clock_t first_time = clock();
- render();
- clock_t end_time = clock();
- Update();
- sprintf_s(debug_str, "%f\n", (double)(end_time - first_time) / CLOCKS_PER_SEC);
- OutputDebugString(debug_str);
-
+ SetTimer(hwnd, NULL, 1000 / TARGET_FRAMERATE, (TIMERPROC)FixedUpdate);
+
while (GetMessage(&Msg, NULL, 0, 0))
{
TranslateMessage(&Msg);
@@ -35,34 +33,49 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
return Msg.wParam;
}
-bool HandleMouseMovement(LPARAM lParam) {
+bool HandleMouseMovement() {
int xPos, yPos;
- xPos = LOWORD(lParam);
- yPos = HIWORD(lParam);
+ POINT point;
+ GetCursorPos(&point);
bool movement_detected_x = true;
bool movement_detected_y = true;
- if (xPos > prev_mouse_x)
- move_camera_right();
- else if (xPos < prev_mouse_x)
- move_camera_left();
+ if (point.x > prev_mouse_x)
+ camera.rotate_camera_right();
+ else if (point.x < prev_mouse_x)
+ camera.rotate_camera_left();
else
movement_detected_x = false;
- prev_mouse_x = xPos;
- if (yPos > prev_mouse_y)
- move_camera_up();
- else if (yPos < prev_mouse_y)
- move_camera_down();
+ if (point.y > prev_mouse_y)
+ camera.rotate_camera_up();
+ else if (point.y < prev_mouse_y)
+ camera.rotate_camera_down();
else
movement_detected_y = false;
- prev_mouse_y = yPos;
+ SetCursorPos(prev_mouse_x, prev_mouse_y);
return movement_detected_x || movement_detected_y;
}
-void Update_Window() {
+bool HandleButtonPressed() {
+ if (GetAsyncKeyState(VK_UP) & 0x8000)
+ camera.move_camera_forward();
+ if (GetAsyncKeyState(VK_DOWN) & 0x8000)
+ camera.move_camera_backward();
+ if (GetAsyncKeyState(VK_RIGHT) & 0x8000)
+ camera.move_camera_right();
+ if (GetAsyncKeyState(VK_LEFT) & 0x8000)
+ camera.move_camera_left();
+ return true;
+}
+
+void CALLBACK FixedUpdate(HWND hwnd, UINT message, UINT uInt, DWORD dWord)
+{
+ HandleMouseMovement();
+ HandleButtonPressed();
+ camera.ApplyChanges();
render();
Update();
}
@@ -72,8 +85,6 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
switch (message)
{
case WM_MOUSEMOVE:
- if(HandleMouseMovement(lParam))
- Update_Window();
break;
case WM_RBUTTONDOWN:
break;
diff --git a/OpenWindow/renderer.cpp b/OpenWindow/renderer.cpp
index cfdf9ca..aed5563 100644
--- a/OpenWindow/renderer.cpp
+++ b/OpenWindow/renderer.cpp
@@ -1,5 +1,4 @@
-#define _USE_MATH_DEFINES
-#include
+#include
#include
#include
#include "tgaimage.h"
@@ -8,44 +7,41 @@
#include "renderer.h"
#include "util_window.h"
#include
+#include "camera.h"
-#define DEG2RAD M_PI/180
-#define HORIZONTAL_CAMERA_SPEED 1
-#define VERTICAL_CAMERA_SPEED 1
-
-#define NEAR_CLIP_PLANE 0
-#define FAR_CLIP_PLANE 15
-#define FOV 15
+#define HORIZONTAL_CAMERA_SPEED 1
+#define VERTICAL_CAMERA_SPEED 1
+#define VERTICAL_CAMERA_CLAMP_UP 90
+#define VERTICAL_CAMERA_CLAMP_DOWN -90
+#define NEAR_CLIP_PLANE 0
+#define FAR_CLIP_PLANE 15
+#define FOV 30
+#define DEFAULT_CAMERA_POS Vec3f(0, 0, 5)
+#define DEFAULT_CAMERA_ROT Vec3f(0, 0, 0)
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);
-const int depth = 255;
-
-int angle_hor = 0;
-int angle_ver = 0;
-
bool wireframe = false;
Model* model = new Model("african_head.obj");
+Camera camera;
float* z_buffer = new float[screen_width * screen_height];
Vec3f light_dir = Vec3f(0, 0, 1).normalize();
-Vec3f eye(0, 0, 5);
-Vec3f center(0, 0, 0);
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] = depth / 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] = depth / 2.f;
+ m[2][2] = (FAR_CLIP_PLANE+NEAR_CLIP_PLANE) / 2.f;
return m;
}
@@ -143,6 +139,7 @@ void triangle(
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]));
@@ -151,6 +148,7 @@ void triangle(
}
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);
@@ -168,7 +166,7 @@ void triangle(
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 > 20 && P.z < 50)
+ 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;
@@ -196,77 +194,40 @@ int color_to_int(TGAColor col) {
return (col[2] << 16) | (col[1] << 8) | col[0];
}
+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.ApplyChanges();
+}
+
void clear_zbuffer()
{
for (int i = 0; i < screen_width * screen_height; i++)
z_buffer[i] = INT_MIN;
}
-Matrix lookat(Vec3f eye, Vec3f center, Vec3f up) {
- Vec3f z = (eye-center).normalize();
- Vec3f x = cross(up,z).normalize();
- Vec3f y = cross(z,x).normalize();
- Matrix Minv = Matrix::identity();
- Matrix Tr = Matrix::identity();
- for (int i=0; i<3; i++) {
- Minv[0][i] = x[i];
- Minv[1][i] = y[i];
- Minv[2][i] = z[i];
- Tr[i][3] = -center[i];
- }
- return Minv*Tr;
-}
-
-void move_camera_right() {
- angle_hor += HORIZONTAL_CAMERA_SPEED;
-}
-
-void move_camera_left() {
- angle_hor -= HORIZONTAL_CAMERA_SPEED;
-}
-
-void move_camera_up() {
- angle_ver += VERTICAL_CAMERA_SPEED;
- if (angle_ver > 90) angle_ver = 90;
-}
-
-void move_camera_down() {
- angle_ver -= VERTICAL_CAMERA_SPEED;
- if (angle_ver < -90) angle_ver = -90;
-}
-
Matrix ViewPort = Matrix::identity();
Matrix Projection = Matrix::identity();
Matrix ModelView = Matrix::identity();
void render()
{
-
- Vec3f forward = Vec3f(
- sinf(angle_hor * DEG2RAD),
- -sinf(angle_ver * DEG2RAD),
- -cosf(angle_hor*DEG2RAD) * cosf(angle_ver*DEG2RAD));
- Vec3f right = Vec3f(sinf(angle_hor*DEG2RAD + M_PI_2), 0, 0);
-
- center = eye + forward;
-
- //ViewPort = viewport(0, 0, screen_width, screen_height);
- ViewPort = viewport(screen_width / 8, screen_height / 8, screen_width * 3 / 4, screen_height * 3 / 4);
- ModelView = lookat(eye, center, cross(right, forward));
- Projection[0][0] = 1 / tanf(FOV * DEG2RAD);
- Projection[1][1] = 1 / tanf(FOV * DEG2RAD);
- Projection[2][2] = (FAR_CLIP_PLANE + NEAR_CLIP_PLANE) / (FAR_CLIP_PLANE - NEAR_CLIP_PLANE);
- Projection[2][3] = (-2 * FAR_CLIP_PLANE * NEAR_CLIP_PLANE) / (FAR_CLIP_PLANE - NEAR_CLIP_PLANE);
- Projection[3][2] = -1.f / (forward).norm();
- //Projection[3][2] = 1;
- //Projection[3][3] = 0;
-
-// model->rotate(Vec3f(0, 180, 0));
-// model->ApplyTransform();
+ light_dir = camera.GetForward() * -1;
+ ViewPort = viewport(0, 0, screen_width, screen_height);
+ Projection = camera.GetProjectionMatrix();
+ ModelView = camera.GetModelViewMatrix();
Matrix z = ViewPort * Projection * ModelView * model->Transform;
clear_zbuffer();
+ #pragma omp parallel for
for (int i = 0; i < model->nfaces(); i++)
{
std::vector face = model->face(i);
diff --git a/OpenWindow/renderer.h b/OpenWindow/renderer.h
index 8e4bd94..9aef4a6 100644
--- a/OpenWindow/renderer.h
+++ b/OpenWindow/renderer.h
@@ -1,16 +1,13 @@
#ifndef RENDERER_HEADER
#define RENDERER_HEADER
#include "tgaimage.h"
+#include "camera.h"
-extern int angle_hor;
-extern int angle_ver;
extern float* z_buffer;
+extern Camera camera;
-void move_camera_right();
-void move_camera_left();
-void move_camera_up();
-void move_camera_down();
+void init_camera();
void render();
int color_to_int(TGAColor col);
#endif
\ No newline at end of file
diff --git a/OpenWindow/util_window.h b/OpenWindow/util_window.h
index aaf7cff..ebcb042 100644
--- a/OpenWindow/util_window.h
+++ b/OpenWindow/util_window.h
@@ -31,5 +31,6 @@ void set_pixel(unsigned int x, unsigned int y, unsigned int color);
void Update();
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+void CALLBACK FixedUpdate(HWND hwnd, UINT message, UINT uInt, DWORD dWord);
#endif