From 2f5437396c8dfec0d527dc60db5fe975c6193805 Mon Sep 17 00:00:00 2001 From: mo7sener Date: Sun, 8 Dec 2019 18:47:16 +0200 Subject: [PATCH] Added messed up low performance camera rotation --- .gitignore | 3 - OpenWindow/main.cpp | 33 +++++- OpenWindow/model.cpp | 6 +- OpenWindow/output.tga | Bin 1820 -> 0 bytes OpenWindow/renderer.cpp | 215 ++++++++++++++++++++++--------------- OpenWindow/renderer.h | 9 ++ OpenWindow/util_window.cpp | 20 ++-- OpenWindow/util_window.h | 6 +- 8 files changed, 189 insertions(+), 103 deletions(-) delete mode 100644 OpenWindow/output.tga diff --git a/.gitignore b/.gitignore index 2f1229f..d5290c0 100644 --- a/.gitignore +++ b/.gitignore @@ -13,9 +13,6 @@ # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs -# Mono auto generated files -mono_crash.* - # Build results [Dd]ebug/ [Dd]ebugPublic/ diff --git a/OpenWindow/main.cpp b/OpenWindow/main.cpp index 85583cc..727ab03 100644 --- a/OpenWindow/main.cpp +++ b/OpenWindow/main.cpp @@ -3,15 +3,18 @@ #include "renderer.h" #include "ctime" -const int width = 800; -const int height = 800; +const int screen_width = 1000; +const int screen_height = 1000; + +int prev_mouse_x = 0; +int prev_mouse_y = 0; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HWND hwnd; MSG Msg; - hwnd = create_window(width, height, hInstance); + hwnd = create_window(hInstance); ShowWindow(hwnd, nCmdShow); char debug_str[100]; @@ -36,6 +39,30 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { + case WM_MOUSEMOVE: + int xPos, yPos; + xPos = LOWORD(lParam); + yPos = HIWORD(lParam); + + if (xPos == prev_mouse_x) + break; + else if (xPos > prev_mouse_x) + move_camera_right(); + else + move_camera_left(); + prev_mouse_x = xPos; + + if (yPos == prev_mouse_y) + break; + else if (yPos > prev_mouse_y) + move_camera_up(); + else + move_camera_down(); + prev_mouse_y = yPos; + + render(); + Update(); + break; case WM_RBUTTONDOWN: break; case WM_LBUTTONDOWN: diff --git a/OpenWindow/model.cpp b/OpenWindow/model.cpp index 2a327b5..d712c83 100644 --- a/OpenWindow/model.cpp +++ b/OpenWindow/model.cpp @@ -58,9 +58,9 @@ void Model::ApplyTransform() { } void Model::translate(Vec3f tr) { - Translation[0][3] += tr.x; - Translation[1][3] += tr.y; - Translation[2][3] += tr.z; + Translation[0][3] = tr.x; + Translation[1][3] = tr.y; + Translation[2][3] = tr.z; } void Model::rotate(Vec3f rot) { rot = rot * DEG2RAD; diff --git a/OpenWindow/output.tga b/OpenWindow/output.tga deleted file mode 100644 index 9eb084bf07dacb8a717fae7e0c171530f769714e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1820 zcmeH{*GdCn5Juaj)F#`~vq? z;Ad+3z2+(KBRt?f@&kU*{e9p&c*uP*54*pmW+a7g@T2aP$DFU=@f5zqPqDj7(eg+s0<(C7raJ!(Rm+UN@2~wvU}wf=N)*p0&i2Z<~3V^ zH{o^nkvH&MTb8(AVAc?RZ@!rM5A!^W@JuDl^UAJ!W%gh->{Zxv3DXZbaIZ{{tcIQy zm>vuLH6M8n&pgaCp8_*OVSeT#Pve=ldFG$Wu7t^>T)S5$qgF$f zf2<$(6?+)x6|)g@$hx+sWO^vl3^+`jf GPQCz+&DZt- diff --git a/OpenWindow/renderer.cpp b/OpenWindow/renderer.cpp index 09f8a03..6c0214c 100644 --- a/OpenWindow/renderer.cpp +++ b/OpenWindow/renderer.cpp @@ -9,6 +9,12 @@ #include "util_window.h" #include +#define DEG2RAD M_PI/180 +#define HORIZONTAL_CAMERA_SPEED 1 + +#define NEAR_CLIP_PLANE 0.1 +#define FAR_CLIP_PLANE 5 + const TGAColor white = TGAColor(255, 255, 255, 255); const TGAColor red = TGAColor(255, 0, 0, 255); const TGAColor green = TGAColor(0, 255, 0, 255); @@ -16,9 +22,17 @@ const TGAColor blue = TGAColor(0, 0, 255, 255); const int depth = 255; -float* z_buffer; +int angle_hor = 0; +int angle_ver = 0; + +bool wireframe = false; + + +Model* model = new Model("african_head.obj"); + +float* z_buffer = new float[screen_width * screen_height]; Vec3f light_dir = Vec3f(0, 0, 1).normalize(); -Vec3f eye(0, 0, 3); +Vec3f eye(0, 0, 5); Vec3f center(0, 0, 0); Matrix viewport(int x, int y, int w, int h) { @@ -33,7 +47,7 @@ Matrix viewport(int x, int y, int w, int h) { return m; } -void line(Vec2i p0, Vec2i p1, TGAImage &image, TGAColor color) +void line(Vec3f p0, Vec3f p1, TGAColor color) { bool steep = false; @@ -59,10 +73,10 @@ void line(Vec2i p0, Vec2i p1, TGAImage &image, TGAColor color) for (int x = p0[0]; x <= p1[0]; x++) { if (steep) { - image.set(y, x, color); + set_pixel(y, x, color_to_int(color)); } else { - image.set(x, y, color); + set_pixel(x, y, color_to_int(color)); } error2 += derror2; if (error2 > dx) { @@ -86,124 +100,153 @@ Vec3f barycentric(Vec3f* pts, Vec3f P) void triangle( Vec3f* pts, // Needed - Model* model, // Should be removed Vec2f* diff_pts, // Should be removed - float* intensities, - Vec3f camera_pos) // Not really sure yet + 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]); - std::swap(diff_pts[0], diff_pts[1]); - std::swap(intensities[0], intensities[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]); - std::swap(diff_pts[0], diff_pts[2]); - std::swap(intensities[0], intensities[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]); - std::swap(diff_pts[1], diff_pts[2]); - std::swap(intensities[1], intensities[2]); + if(diff_pts) + std::swap(diff_pts[1], diff_pts[2]); + if(intensities) + std::swap(intensities[1], intensities[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); - TGAColor color = white; - 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])); - } - } + if (wireframe) + { + line(pts[0], pts[1], white); + line(pts[1], pts[2], white); + line(pts[2], pts[0], white); + return; + } - Vec3f P; - 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; + 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; + + 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; + 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]; + 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]; + // 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)]) - { - z_buffer[(int)(P.x + P.y * screen_width)] = P.z; + // Coloring according to the Z-Buffer + if (P.z > z_buffer[(int)(P.x + P.y * screen_width)] && P.z > NEAR_CLIP_PLANE) + { + 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]; + // 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)); - } - } - } + color = model->diffuse(diff_pt); + } + color = color * intensity; + set_pixel(P.x, P.y, color_to_int(color)); + } + } + } } int color_to_int(TGAColor col) { return (col[2] << 16) | (col[1] << 8) | col[0]; } -void init_zbuffer() +void clear_zbuffer() { - z_buffer = new float[screen_width*screen_height]; 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; + 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 += HORIZONTAL_CAMERA_SPEED; +} + +void move_camera_down() { + angle_ver -= HORIZONTAL_CAMERA_SPEED; +} + +Matrix ViewPort = Matrix::identity(); +Matrix Projection = Matrix::identity(); +Matrix ModelView = Matrix::identity(); + void render() { - Model* model = new Model("african_head.obj"); - Matrix ViewPort = viewport(screen_width / 8, screen_height / 8, screen_width * 3 / 4, screen_height * 3 / 4); - Matrix Projection = Matrix::identity(); - Matrix ModelView = lookat(eye, center, Vec3f(0, 1, 0)); + 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); - Projection[3][2] = -1.f / (eye - center).norm(); + center = eye + forward; - model->rotate(Vec3f(0, 0, 90)); - model->scale(Vec3f(0.5, 0.5, 0.5)); - model->translate(Vec3f(0.5, 0.5, -1)); + ViewPort = viewport(0, 0, screen_width, screen_height); + ModelView = lookat(eye, center, cross(right, forward)); + Projection[3][2] = -1.f / (forward).norm(); - model->ApplyTransform(); - - Matrix z = ViewPort * Projection * ModelView * model->Transform; + Matrix z = ViewPort * Projection * ModelView * model->Transform;// *Projection * ModelView;// * model->Transform;// *Projection * ModelView * model->Transform; - init_zbuffer(); + clear_zbuffer(); for (int i = 0; i < model->nfaces(); i++) { std::vector face = model->face(i); @@ -211,22 +254,26 @@ void render() Vec3f world_coords[3]; Vec2f diffuse_coords[3]; float intensities[3]; + bool out = true; for (int j = 0; j < 3; j++) { Vec3f v = model->vert(face[j]); Vec4f v4(v); Vec3f coord(z * v4); - + + if (coord.x > 0 && coord.x < 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; } - triangle(screen_coords, model, diffuse_coords, intensities, Vec3f(0, 0, 5)); - } + if (out) continue; - delete model; + triangle(screen_coords, diffuse_coords, model, intensities); + } } diff --git a/OpenWindow/renderer.h b/OpenWindow/renderer.h index f92dacb..8e4bd94 100644 --- a/OpenWindow/renderer.h +++ b/OpenWindow/renderer.h @@ -2,6 +2,15 @@ #define RENDERER_HEADER #include "tgaimage.h" + +extern int angle_hor; +extern int angle_ver; +extern float* z_buffer; + +void move_camera_right(); +void move_camera_left(); +void move_camera_up(); +void move_camera_down(); void render(); int color_to_int(TGAColor col); #endif \ No newline at end of file diff --git a/OpenWindow/util_window.cpp b/OpenWindow/util_window.cpp index 5821618..7509429 100644 --- a/OpenWindow/util_window.cpp +++ b/OpenWindow/util_window.cpp @@ -8,8 +8,6 @@ BITMAPINFO info; HBITMAP hbm; const int BITCOUNT_PER_PIXEL = 24; const int title_height = 39; -int screen_width = 0; -int screen_height = 0; long long bytes_per_row; bool screen_changed = false; HDC hdc; @@ -17,15 +15,13 @@ HDRAWDIB hdd; HDC bitmap_dc; HGDIOBJ old_obj; -HWND create_window(int width, int height, HINSTANCE &hInstance) { +HWND create_window(HINSTANCE &hInstance) { HWND hWnd; WNDCLASSEX wnd_class = { 0 }; init_wnd_class(wnd_class, hInstance); RegisterClassEx(&wnd_class); - screen_width = width; - screen_height = height; create_hwnd(hWnd, hInstance); init(hWnd); @@ -107,6 +103,16 @@ void set_pixel(unsigned int x, unsigned int y, unsigned int color) { screen_changed = true; } -void Update() { - DrawDibDraw(hdd, hdc, 0, 0, screen_width, screen_height, &info.bmiHeader, pixels, 0, 0, screen_width, screen_height, 0); +void clear_screen() { + for (int x = 0; x < screen_width; x++) + for (int y = 0; y < screen_height; y++) + set_pixel(x, y, 0); +} + +void Update() { + if (screen_changed) { + DrawDibDraw(hdd, hdc, 0, 0, screen_width, screen_height, &info.bmiHeader, pixels, 0, 0, screen_width, screen_height, 0); + clear_screen(); + screen_changed = false; + } } diff --git a/OpenWindow/util_window.h b/OpenWindow/util_window.h index c9f5776..aaf7cff 100644 --- a/OpenWindow/util_window.h +++ b/OpenWindow/util_window.h @@ -18,13 +18,13 @@ extern HDC hdc; extern HDRAWDIB hdd; extern HDC bitmap_dc; extern HGDIOBJ old_obj; -extern int screen_width; -extern int screen_height; +extern const int screen_width; +extern const int screen_height; void init(HWND &hWnd); void destroy_window(); -HWND create_window(int width, int height, HINSTANCE &hInstance); +HWND create_window(HINSTANCE &hInstance); void create_hwnd(HWND &hwnd, HINSTANCE &hInstance); void init_wnd_class(WNDCLASSEX &wndClass, HINSTANCE &hInstance); void set_pixel(unsigned int x, unsigned int y, unsigned int color);