├── .gitignore ├── App ├── .idea │ ├── .name │ ├── codeStyles │ │ └── Project.xml │ ├── misc.xml │ ├── modules.xml │ ├── obj.iml │ ├── vcs.xml │ └── workspace.xml ├── CMakeLists.txt ├── CPP_files │ ├── Graphics.cpp │ ├── Math.cpp │ ├── Transformation.cpp │ └── load.cpp ├── README ├── build.sh ├── header_files │ ├── Graphics.h │ ├── Math.h │ ├── Transformation.h │ ├── load.h │ └── main.h ├── main.cpp ├── resources │ ├── ICTC.obj │ └── README.win └── run.sh ├── README.md └── Reports ├── ICTC_model.pdf ├── Presentation-min.pdf └── pictures ├── five.png ├── four.png ├── one.png ├── three.png ├── two.png └── zero.png /.gitignore: -------------------------------------------------------------------------------- 1 | CMakeLists.txt.user 2 | CMakeCache.txt 3 | CMakeFiles 4 | CMakeScripts 5 | Testing 6 | Makefile 7 | cmake_install.cmake 8 | install_manifest.txt 9 | compile_commands.json 10 | CTestTestfile.cmake 11 | _deps 12 | -------------------------------------------------------------------------------- /App/.idea/.name: -------------------------------------------------------------------------------- 1 | ICTC -------------------------------------------------------------------------------- /App/.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /App/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | -------------------------------------------------------------------------------- /App/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /App/.idea/obj.iml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /App/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /App/.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 26 | 36 | 37 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 266 | 267 | 268 | 269 | 270 | 272 | 273 | 274 | 275 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 1551865603947 287 | 292 | 293 | 294 | 295 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 345 | 346 | 348 | 349 | 350 | 351 | 352 | file://$PROJECT_DIR$/main.cc 353 | 64 354 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | -------------------------------------------------------------------------------- /App/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.7) 2 | project(ICTC) 3 | 4 | INCLUDE_DIRECTORIES(/usr/include/) 5 | LINK_DIRECTORIES(/usr/lib) 6 | set(CMAKE_CXX_STANDARD 14) 7 | 8 | file(GLOB CPP_SRC_FILES 9 | "CPP_files/*.cpp" 10 | ) 11 | add_executable(ICTC main.cpp ${CPP_SRC_FILES}) 12 | TARGET_LINK_LIBRARIES(ICTC GL GLU glut X11 dl Xxf86vm Xrandr pthread Xi Xinerama Xcursor xcb) 13 | -------------------------------------------------------------------------------- /App/CPP_files/Graphics.cpp: -------------------------------------------------------------------------------- 1 | #include "../header_files/Graphics.h" 2 | #include "GL/glut.h" 3 | #include 4 | using namespace std; 5 | 6 | Vec3 ICTC_color = {1,0.4,0}; 7 | 8 | Window::Window(int w, int h, float nearz, float farz): 9 | width(w), height(h), nearz(nearz), farz(farz) 10 | { 11 | // initialize the zbuffer 12 | zbuffer = vector(w*h, farz-1); 13 | } 14 | 15 | void Window::clear() 16 | { 17 | glClear(GL_COLOR_BUFFER_BIT); 18 | zbuffer = vector(width*height, farz-1); 19 | } 20 | 21 | void Window::refresh() 22 | { 23 | glutSwapBuffers(); 24 | } 25 | 26 | void Window::start() 27 | { 28 | glutMainLoop(); 29 | } 30 | 31 | //function overloading not used 32 | 33 | //void Window::setPixel(const Vec2& p, const Vec3& c, float i) 34 | //{ 35 | // setPixel(ROUND(p.x), ROUND(p.y), p.z, c, i); 36 | //} 37 | 38 | void Window::setPixel(int x, int y, float z, const Vec3& c, float i) 39 | { 40 | // clipping 41 | if (x < 0 or x > width or y < 0 or y > height) 42 | return; 43 | 44 | // check z buffer 45 | // if (z <= zbuffer[x*height + y] or z < farz or z > nearz) 46 | // return; 47 | // zbuffer[x*height + y] = z; 48 | 49 | if (z <= zbuffer[width * y + x] or z < farz or z > nearz) 50 | return; 51 | zbuffer[width * y + x] = z; 52 | 53 | 54 | glColor3f(c.x*i, c.y*i, c.z*i); 55 | glBegin(GL_POINTS); 56 | glVertex2i(x, y); 57 | glEnd(); 58 | } 59 | 60 | 61 | //DDA Algorithm Implementation 62 | 63 | void Window::drawLine(const Vec2& p1, const Vec2& p2, const Vec3& c) 64 | { 65 | #ifdef SOLID 66 | int del_x = ROUND(p2.x) - ROUND(p1.x); 67 | int del_y = ROUND(p2.y) - ROUND(p1.y); 68 | #else 69 | float del_x = p2.x - p1.x; 70 | float del_y = p2.y - p1.y; 71 | #endif 72 | float d = p1.z, del_d = p2.z - p1.z; 73 | float i = p1.i, del_i = p2.i - p1.i; 74 | int step = (abs(del_x) > abs(del_y))? abs(del_x) : abs(del_y); 75 | 76 | float x = p1.x, y = p1.y; 77 | if (step == 0) { 78 | setPixel(ROUND(x), ROUND(y), d, c, i); 79 | return; 80 | } 81 | 82 | for (int k = 0; k <= step; k++) { 83 | setPixel(ROUND(x), ROUND(y), d, c, i); 84 | //setPixel(x, y, d, c, i); 85 | 86 | x += del_x / step; 87 | y += del_y / step; 88 | d += del_d / step; 89 | i += del_i / step; 90 | } 91 | } 92 | 93 | void Window::fillTriangle(const Vec2& v1, const Vec2& v2, const Vec2& v3) 94 | { 95 | // vec2 comparer 96 | struct Vec2Comparer{ bool operator()(const Vec2& a, const Vec2& b) { 97 | return a.y < b.y; }}; 98 | vector v = {v1, v2, v3}; 99 | sort(v.begin(), v.end(), Vec2Comparer()); 100 | 101 | float y, x1, z1, i1, x2, z2, i2; 102 | for (y = v[0].y; y < v[1].y; y++) { 103 | if (v[1].y == v[0].y) { 104 | drawLine(Vec2(v[0].x, y, v[0].z, v[0].i), Vec2(v[1].x, y, v[1].z, v[1].i), ICTC_color); 105 | break; 106 | } 107 | x1 = v[0].x + (y - v[0].y) * (v[1].x - v[0].x) / (v[1].y - v[0].y); 108 | z1 = v[0].z + (y - v[0].y) * (v[1].z - v[0].z) / (v[1].y - v[0].y); 109 | i1 = v[0].i + (y - v[0].y) * (v[1].i - v[0].i) / (v[1].y - v[0].y); 110 | x2 = v[0].x + (y - v[0].y) * (v[2].x - v[0].x) / (v[2].y - v[0].y); 111 | z2 = v[0].z + (y - v[0].y) * (v[2].z - v[0].z) / (v[2].y - v[0].y); 112 | i2 = v[0].i + (y - v[0].y) * (v[2].i - v[0].i) / (v[2].y - v[0].y); 113 | drawLine(Vec2(x1,y,z1,i1), Vec2(x2,y,z2,i2), ICTC_color); 114 | } 115 | 116 | for (y = v[1].y; y <= v[2].y; y++) { 117 | if (v[2].y == v[1].y) { 118 | drawLine(Vec2(v[1].x, y, v[1].z, v[1].i), Vec2(v[2].x, y, v[2].z, v[2].i),ICTC_color); 119 | break; 120 | } 121 | x1 = v[1].x + (y - v[1].y) * (v[2].x - v[1].x) / (v[2].y - v[1].y); 122 | z1 = v[1].z + (y - v[1].y) * (v[2].z - v[1].z) / (v[2].y - v[1].y); 123 | i1 = v[1].i + (y - v[1].y) * (v[2].i - v[1].i) / (v[2].y - v[1].y); 124 | x2 = v[0].x + (y - v[0].y) * (v[2].x - v[0].x) / (v[2].y - v[0].y); 125 | z2 = v[0].z + (y - v[0].y) * (v[2].z - v[0].z) / (v[2].y - v[0].y); 126 | i2 = v[0].i + (y - v[0].y) * (v[2].i - v[0].i) / (v[2].y - v[0].y); 127 | drawLine(Vec2(x1,y,z1,i1), Vec2(x2,y,z2,i2), ICTC_color); 128 | } 129 | } 130 | 131 | void Window::wireframe(const Scene& scene, const Vec3& camera, 132 | const Vec3& target, float angle_x, float scale, int axis_type, float Angle_x, float angle_y, float angle_z) 133 | { 134 | // project points to 2d 135 | vector vertices2d; 136 | for (unsigned long i = 0; i < scene.vertices.size(); i++) { 137 | // get the coordinate of vertex 138 | Vec3 point3d = scene.vertices[i]; 139 | // rotate the vertex about world y-axis 140 | // if(axis_type == 1) 141 | // point3d = RotateX(point3d, angle); 142 | // if(axis_type == 2) 143 | // point3d = RotateY(point3d, angle); 144 | // if(axis_type == 3) 145 | // point3d = RotateZ(point3d, angle); 146 | 147 | point3d = RotateX(point3d, Angle_x); 148 | point3d = RotateY(point3d, angle_y); 149 | point3d = RotateZ(point3d, angle_z); 150 | 151 | 152 | point3d = Scale(point3d,scale); 153 | // project 154 | Vec3 points3d = world_to_pixel(point3d, camera, target, width, height ); 155 | // Vec2 point2d = world_to_pixel_wireFrame(point3d, camera, target, width, height ); 156 | 157 | Vec2 point2d = project(points3d,width,height,angle_x); 158 | vertices2d.push_back(point2d); 159 | } 160 | 161 | // draw edges 162 | for (unsigned long i = 0; i < scene.faces.size(); i += 3) { 163 | // get the 3 vertex's index 164 | int index1 = scene.faces[i]; 165 | int index2 = scene.faces[i+1]; 166 | int index3 = scene.faces[i+2]; 167 | // get the vertices 168 | Vec2 p1 = vertices2d[index1]; 169 | Vec2 p2 = vertices2d[index2]; 170 | Vec2 p3 = vertices2d[index3]; 171 | // draw 172 | Vec3 Mesh_color = {1,0.2,0}; 173 | drawLine(p1, p2,Mesh_color); 174 | drawLine(p2, p3,Mesh_color); 175 | drawLine(p3, p1,Mesh_color); 176 | } 177 | } 178 | 179 | void Window::render(const Scene& scene, const Vec3& camera, const Vec3& target, 180 | const Vec3& light, float angle_x,float scale, int axis_type, float Angle_x, float angle_y, float angle_z) 181 | { 182 | vector vertices2d(scene.vertices.size()); 183 | 184 | // project to 2d as well as find the intensities 185 | Vec3 point3d, u, v, n, L, N, R, H, V; Mat M(4,4), P(4,1); float d; 186 | for (unsigned long i = 0; i < scene.vertices.size(); i++) { 187 | point3d = scene.vertices[i]; 188 | 189 | // // rotate the point in world axis 190 | // if(axis_type == 1) 191 | // point3d = RotateX(point3d, angle); 192 | // if(axis_type == 2) 193 | // point3d = RotateY(point3d, angle); 194 | // if(axis_type == 3) 195 | // point3d = RotateZ(point3d, angle); 196 | 197 | point3d = RotateX(point3d, Angle_x); 198 | point3d = RotateY(point3d, angle_y); 199 | point3d = RotateZ(point3d, angle_z); 200 | 201 | point3d = Scale(point3d,scale); 202 | 203 | point3d = world_to_pixel(point3d, camera , target, width , height); // this is in camera coordinates 204 | // // translate camera to origin 205 | // Vec3 temp_camera ={-camera.x, -camera.y, -camera.z}; 206 | // point3d = translate(point3d, temp_camera); 207 | // 208 | // // calculate u,v,n vectors 209 | // n = (camera - target).normalize(); 210 | // u = cross({0,1,0}, n).normalize(); 211 | // v = cross(n, u).normalize(); 212 | // 213 | // // align camera axes to world axes 214 | // M.set({u.x, u.y, u.z, 0, 215 | // v.x, v.y, v.z, 0, 216 | // n.x, n.y, n.z, 0, 217 | // 0, 0, 0, 1}); 218 | // P.set({point3d.x, point3d.y, point3d.z, 1}); 219 | // P = M*P; 220 | // point3d = {P(0), P(1), P(2)}; // this is in camera coordinates 221 | 222 | // calculate point intensity 223 | N = scene.normals[i].normalize(); 224 | L = (light - point3d).normalize(); 225 | d = (light - point3d).mag(); 226 | R = (N*(dot(N,L)*2) - L).normalize(); 227 | V = (camera - point3d).normalize(); 228 | //H = (L + V).normalize(); 229 | float intensity = 0.4 + 0.5*dot(N,L) + powf(dot(R,V), 50); 230 | if (intensity > 1) intensity = 1; 231 | 232 | // project to screen coordinates 233 | vertices2d[i] = project(point3d, width, height, angle_x); 234 | vertices2d[i].i = intensity; 235 | } 236 | 237 | // now fill every triangle 238 | Vec2 v1, v2, v3; 239 | for (unsigned long i = 0; i < scene.faces.size(); i += 3) { 240 | // get vertices 241 | v1 = vertices2d[scene.faces[i]]; 242 | v2 = vertices2d[scene.faces[i+1]]; 243 | v3 = vertices2d[scene.faces[i+2]]; 244 | 245 | // fill triangle 246 | fillTriangle(v1, v2, v3); 247 | } 248 | } 249 | -------------------------------------------------------------------------------- /App/CPP_files/Math.cpp: -------------------------------------------------------------------------------- 1 | #include "../header_files/Math.h" 2 | #include 3 | using namespace std; 4 | 5 | ostream& operator<<(ostream& o, const Vec3& v) 6 | { 7 | return o << "(" << v.x << ", " << v.y << ", " << v.z << ")"; 8 | } 9 | 10 | 11 | ostream& operator<<(ostream& o, const Vec2& v) 12 | { 13 | return o << "(" << v.x << ", " << v.y << ", " << v.z << ")"; 14 | } 15 | 16 | 17 | ostream& operator<<(ostream& o, const Mat& A) 18 | { 19 | o << "["; 20 | for (int i = 0; i < A.row; i++) { 21 | if (i != 0) o << "; "; 22 | for (int j = 0; j < A.col; j++) { 23 | if (j != 0) o << ", "; 24 | o << A(i,j); 25 | } 26 | } 27 | return o << "]"; 28 | } 29 | 30 | 31 | float Mat::mag(){ 32 | float res = 0; 33 | int pos; 34 | for (int i =0;i < this->row; i++) 35 | { 36 | for (int j=0;jcol;j++) 37 | { 38 | pos = (this->col)*i + j; 39 | //pos gives the value of this(i,j) 40 | 41 | res += data[pos] * data[pos]; 42 | 43 | } 44 | } 45 | return sqrt(res); 46 | } 47 | Mat& Mat::set(const std::initializer_list& args) { 48 | // if (_data.size() != data.size()) 49 | // throw std::length_error("invalid size of initializer_list to assign matrix"); 50 | // data = _data; 51 | std::initializer_list::iterator it; 52 | int i=0; 53 | for ( it=args.begin(); it!=args.end(); ++it) { 54 | (*this)(i) = *it; 55 | i++; 56 | } 57 | 58 | 59 | return *this; 60 | } 61 | 62 | float Mat::dot(Mat& mat){ 63 | if ((this->row != mat.row) || (this->col != mat.col)) 64 | throw "ERROR"; 65 | int pos; 66 | float res = 0; 67 | for (int i =0;i < this->row; i++) 68 | { 69 | for (int j=0;jcol;j++) 70 | { 71 | pos = (this->col)*i + j; 72 | //pos gives the value of this(i,j) 73 | 74 | res += data[pos] * mat(i,j); 75 | } 76 | } 77 | return res; 78 | 79 | } 80 | 81 | Mat Mat::operator*(Mat& mat) 82 | { 83 | if (this->col != mat.row) throw "ERROR"; 84 | int pos; 85 | Mat res(row,mat.col); 86 | 87 | for(int i = 0; i< this->row; i++ ) 88 | { 89 | for (int j= 0; j< mat.col; j++) 90 | { 91 | res(i,j) = 0; 92 | for(int k=0; k< this->col; k++) 93 | { 94 | pos = (this->col)*i + k ; // ith row kth column 95 | res(i,j) += data[pos] * mat(k,j); 96 | } 97 | } 98 | } 99 | return res; 100 | } 101 | 102 | float& Mat::operator() (int r, int c) 103 | { 104 | int pos = col* r + c ; 105 | return data[pos]; 106 | } 107 | 108 | const float Mat::operator() (int r, int c) const 109 | { 110 | int pos = col* r + c ; 111 | return data[pos]; 112 | } 113 | 114 | float& Mat::operator() (int pos) 115 | { 116 | return data[pos]; 117 | } 118 | 119 | const float Mat::operator() (int pos) const 120 | { 121 | return data[pos]; 122 | } 123 | 124 | Mat Mat::operator+(Mat& mat) 125 | { 126 | if ((this->row != mat.row) || (this->col != mat.col)) 127 | throw "ERROR"; 128 | Mat res(this->row,this->col); 129 | int pos; 130 | for (int i =0;i < this->row; i++) 131 | { 132 | for (int j=0;jcol;j++) 133 | { 134 | pos = (this->col)*i + j; 135 | res(i,j) = data[pos] + mat(i,j); 136 | } 137 | } 138 | return res; 139 | } 140 | 141 | Mat Mat::operator - (Mat& mat) 142 | { 143 | if ((this->row != mat.row) || (this->col != mat.col)) 144 | throw "ERROR"; 145 | Mat res(this->row,this->col); 146 | int pos; 147 | for (int i =0;i < this->row; i++) 148 | { 149 | for (int j=0;jcol;j++) 150 | { 151 | pos = (this->col)*i + j; 152 | res(i,j) = data[pos] - mat(i,j); 153 | } 154 | } 155 | return res; 156 | } 157 | 158 | Mat Mat::operator / (float val) 159 | { 160 | Mat res(this->row,this->col); 161 | int pos; 162 | 163 | for (int i =0;i < this->row; i++) 164 | { 165 | for (int j=0;jcol;j++) 166 | { 167 | pos = (this->col)*i + j; 168 | res(i,j) = data[pos] / val ; 169 | } 170 | } 171 | 172 | return res; 173 | } 174 | -------------------------------------------------------------------------------- /App/CPP_files/Transformation.cpp: -------------------------------------------------------------------------------- 1 | #include "../header_files/Transformation.h" 2 | #include 3 | #include 4 | #include "../header_files/Math.h" 5 | using namespace std; 6 | 7 | Vec3 RotateX(Vec3& Point,float theta){ 8 | Mat T(4,4); //Transformation matrix 9 | Mat P(4,1); //Point matrix 10 | float angle = theta/180*pi; 11 | //Transformation matrix 12 | T(0,0) = 1; T(0,1) = 0; T(0,2) = 0; T(0,3) = 0; 13 | T(1,0) = 0; T(1,1) = cos(angle);T(1,2) = -sin(angle); T(1,3) = 0; 14 | T(2,0) = 0; T(2,1) = sin(angle);T(2,2) = cos(angle); T(2,3) = 0; 15 | T(3,0) = 0; T(3,1) = 0; T(3,2) = 0; T(3,3) = 1; 16 | //Point in matrix form 17 | P(0,0) = Point.x; P(0,1) = Point.y; P(0,2) = Point.z; P(0,3) = 1; 18 | 19 | P = T*P; 20 | Point.x = P(0,0); 21 | Point.y = P(0,1); 22 | Point.z = P(0,2); 23 | 24 | return Point; 25 | 26 | } 27 | 28 | Vec3 RotateY(Vec3& Point,float theta){ 29 | Mat T(4,4); //Transformation matrix 30 | Mat P(4,1); //Point matrix 31 | float angle = theta/180*pi; 32 | //Transformation matrix 33 | T(0,0) = cos(angle); T(0,1) = 0; T(0,2) = sin(angle); T(0,3) = 0; 34 | T(1,0) = 0; T(1,1) = 1; T(1,2) = 0; T(1,3) = 0; 35 | T(2,0) = -sin(angle); T(2,1) = 0; T(2,2) = cos(angle); T(2,3) = 0; 36 | T(3,0) = 0; T(3,1) = 0; T(3,2) = 0; T(3,3) = 1; 37 | //Point in matrix form 38 | P(0,0) = Point.x; P(0,1) = Point.y; P(0,2) = Point.z; P(0,3) = 1; 39 | 40 | P = T*P; 41 | Point.x = P(0,0); 42 | Point.y = P(0,1); 43 | Point.z = P(0,2); 44 | 45 | return Point; 46 | 47 | } 48 | 49 | 50 | Vec3 RotateZ(Vec3& Point,float theta){ 51 | Mat T(4,4); //Transformation matrix 52 | Mat P(4,1); //Point matrix 53 | float angle = theta/180*pi; 54 | //Transformation matrix 55 | T(0,0) = cos(angle); T(0,1) = -sin(theta); T(0,2) = 0; T(0,3) = 0; 56 | T(1,0) = sin(angle); T(1,1) = cos(theta); T(1,2) = 0; T(1,3) = 0; 57 | T(2,0) = 0; T(2,1) = 0; T(2,2) = 1; T(2,3) = 0; 58 | T(3,0) = 0; T(3,1) = 0; T(3,2) = 0; T(3,3) = 1; 59 | //Point in matrix form 60 | P(0,0) = Point.x; P(0,1) = Point.y; P(0,2) = Point.z; P(0,3) = 1; 61 | 62 | P = T*P; 63 | Point.x = P(0,0); 64 | Point.y = P(0,1); 65 | Point.z = P(0,2); 66 | 67 | return Point; 68 | 69 | 70 | } 71 | 72 | Vec3 translate(Vec3& Point,const Vec3& tMat){ 73 | Mat T(4,4); //Transformation matrix 74 | Mat P(4,1); //Point matrix 75 | //Transformation matrix 76 | T(0,0) = 1; T(0,1) = 0; T(0,2) = 0; T(0,3) = tMat.x; 77 | T(1,0) = 0; T(1,1) = 1; T(1,2) = 0; T(1,3) = tMat.y; 78 | T(2,0) = 0; T(2,1) = 0; T(2,2) = 1; T(2,3) = tMat.z; 79 | T(3,0) = 0; T(3,1) = 0; T(3,2) = 0; T(3,3) = 1; 80 | //Point in matrix form 81 | P(0,0) = Point.x; P(0,1) = Point.y; P(0,2) = Point.z; P(0,3) = 1; 82 | 83 | P = T*P; 84 | Point.x = P(0,0); 85 | Point.y = P(0,1); 86 | Point.z = P(0,2); 87 | 88 | return Point; 89 | 90 | } 91 | 92 | Vec3 Reflect_Y(Vec3& Point,const Vec3& tMat){ 93 | Mat T(4,4); //Transformation matrix 94 | Mat P(4,1); //Point matrix 95 | //Transformation matrix 96 | T(0,0) = 0; T(0,1) = 1; T(0,2) = 0; T(0,3) = tMat.x; 97 | T(1,0) = 1; T(1,1) = 0; T(1,2) = 0; T(1,3) = tMat.y; 98 | T(2,0) = 0; T(2,1) = 0; T(2,2) = 1; T(2,3) = tMat.z; 99 | T(3,0) = 0; T(3,1) = 0; T(3,2) = 0; T(3,3) = 1; 100 | //Point in matrix form 101 | P(0,0) = Point.x; P(0,1) = Point.y; P(0,2) = Point.z; P(0,3) = 1; 102 | 103 | P = T*P; 104 | Point.x = P(0,0); 105 | Point.y = P(0,1); 106 | Point.z = P(0,2); 107 | 108 | return Point; 109 | 110 | } 111 | 112 | 113 | Vec3 Scale(Vec3& Point,float scale){ 114 | Mat T(4,4); //Transformation matrix 115 | Mat P(4,1); //Point matrix 116 | //Transformation matrix 117 | T(0,0) = scale; T(0,1) = 0; T(0,2) = 0; T(0,3) = 0; 118 | T(1,0) = 0; T(1,1) = scale; T(1,2) = 0; T(1,3) = 0; 119 | T(2,0) = 0; T(2,1) = 0; T(2,2) = scale; T(2,3) = 0; 120 | T(3,0) = 0; T(3,1) = 0; T(3,2) = 0; T(3,3) = 1; 121 | //Point in matrix form 122 | P(0,0) = Point.x; P(0,1) = Point.y; P(0,2) = Point.z; P(0,3) = 1; 123 | 124 | P = T*P; 125 | Point.x = P(0,0); 126 | Point.y = P(0,1); 127 | Point.z = P(0,2); 128 | 129 | return Point; 130 | 131 | } 132 | 133 | //Vec2 world_to_pixel(const Vec3& source ,const Vec3& camera, const Vec3& LookTo,float planeWidth, float planeHeight, float winWidth, float winHeight){ 134 | // //first determine the World to Camera transforming matrix 135 | // Mat WtoC(4,4); 136 | // //for that use the concept of N, U and V unit vectors 137 | // Vec3 N,U,V(0,1,0); 138 | // 139 | // //calculate the N unit vector 140 | // //N is the vector from LookTo point to Camera point 141 | // N = (camera-LookTo).normalize(); 142 | //// N = N/ N.mag(); 143 | // 144 | // //U = V X N 145 | // U = cross(V,N).normalize(); 146 | //// U = U / U.mag(); 147 | // 148 | // 149 | // //readjust the V vector 150 | // V = cross(N,U).normalize(); 151 | //// V = V / V.mag(); 152 | // 153 | // //Transpose matrix from World co-ordinate to View co-ordinate 154 | // Mat T(4,4); 155 | // T(0,0) = 1 ; T(0,1) = 0; T(0,2) = 0; T(0,3) = -camera.x; 156 | // T(1,0) = 0 ; T(1,1) = 1; T(1,2) = 0; T(1,3) = -camera.y; 157 | // T(2,0) = 0 ; T(2,1) = 0; T(2,2) = 1; T(2,3) = -camera.z; 158 | // T(3,0) = 0 ; T(3,1) = 0; T(3,2) = 0; T(3,3) = 1; 159 | // 160 | // //Rotation Matrix 161 | // Mat R(4,4); 162 | // R(0,0) = U[0] ; R(0,1) = U[1]; R(0,2) = U[2]; R(0,3) = 0; 163 | // R(1,0) = V[0] ; R(1,1) = V[1]; R(1,2) = V[2]; R(1,3) = 0; 164 | // R(2,0) = N[0] ; R(2,1) = N[1]; R(2,2) = N[2]; R(2,3) = 0; 165 | // R(3,0) = 0 ; R(3,1) = 0; R(3,2) = 0; R(3,3) = 1; 166 | // 167 | // 168 | // //Calculating the WtoC matrix W = T*R (rotate and then translate) 169 | // WtoC = R*T; 170 | //// 171 | //// std::cout << std::endl << " MATRIX START" << std::endl; 172 | //// WtoC.print(); 173 | //// std::cout <<"MATRIX END"<< std::endl << std::endl; 174 | // 175 | // Mat S(4,1); //The source point in matrix form 176 | // S(0) = source.x ; S(1) = source.y; S(2) = source.z ; S(3) = 1; 177 | // 178 | // S = WtoC * S; 179 | // //S now represents the camera co-ordinate system's values 180 | // //calculate the screen pixels 181 | // 182 | // // Perspective projection: 183 | // 184 | // float zprp = 1; 185 | // Mat Persp(4,4); 186 | // Mat Projected(4,1); 187 | // Persp(0,0) = zprp ; Persp(0,1) = 0; Persp(0,2) = 0; Persp(0,3) = 0; 188 | // Persp(1,0) = 0 ; Persp(1,1) = zprp; Persp(1,2) = 0; Persp(1,3) = 0; 189 | // Persp(2,0) = 0 ; Persp(2,1) = 0; Persp(2,2) = 0; Persp(2,3) = 0; 190 | // Persp(3,0) = 0 ; Persp(3,1) = 0; Persp(3,2) = -1; Persp(3,3) = zprp; 191 | // Projected = Persp * S; 192 | // 193 | // //normalize the screen pixels 194 | // Vec2 retVal; 195 | // retVal.x = Projected(0)/Projected(3); 196 | // retVal.y = Projected(1)/Projected(3); 197 | // retVal.z = S(2); 198 | // 199 | // retVal.x = (retVal.x + planeWidth*0.5)/planeWidth; 200 | // retVal.y = (retVal.y + planeHeight*0.5)/planeHeight; 201 | // 202 | // //now to original screen pos in computer 203 | // retVal.x = (int)(retVal.x * winWidth); 204 | // retVal.y = (int)((1-retVal.y) * winHeight); 205 | // 206 | // return retVal; 207 | //} 208 | 209 | Vec2 project(Vec3 p, float width, float height, float angle_x) 210 | { 211 | // float angle_y, aspect_ratio; 212 | // aspect_ratio = width / height; 213 | // angle_x = deg2rad(angle_x); 214 | // angle_y = 2*atan(tan(angle_x/2) / aspect_ratio); 215 | // 216 | // Vec2 v; 217 | // v.x = (1 + p.x/fabs(p.z*tan(angle_x/2))) * (width/2); 218 | // v.y = (1 + p.y/fabs(p.z*tan(angle_y/2))) * (height/2); 219 | // v.z = p.z; 220 | // return v; 221 | 222 | 223 | Mat S(4,1); //The source point in matrix form 224 | S(0) = p.x ; S(1) = p.y; S(2) = p.z ; S(3) = 1; 225 | float zprp = -1; 226 | Mat Persp(4,4); 227 | Mat Projected(4,1); 228 | Persp(0,0) = zprp ; Persp(0,1) = 0; Persp(0,2) = 0; Persp(0,3) = 0; 229 | Persp(1,0) = 0 ; Persp(1,1) = zprp; Persp(1,2) = 0; Persp(1,3) = 0; 230 | Persp(2,0) = 0 ; Persp(2,1) = 0; Persp(2,2) = zprp; Persp(2,3) = 0; 231 | Persp(3,0) = 0 ; Persp(3,1) = 0; Persp(3,2) = -1; Persp(3,3) = -zprp; 232 | Projected = Persp * S; 233 | p.x = Projected(0); 234 | p.y = Projected(1); 235 | p.z = Projected(2); 236 | 237 | // Projected = Reflect_Y(p,p); 238 | 239 | p = translate(p,{0,3,0}); 240 | Projected(0) = p.x; 241 | Projected(1) = p.y; 242 | Projected(2) = p.z; 243 | 244 | 245 | //normalize the screen pixels 246 | Vec2 retVal; 247 | retVal.x = Projected(0)/Projected(3); 248 | retVal.y = Projected(1)/Projected(3); 249 | retVal.z = S(2); 250 | 251 | float planeWidth = .5; 252 | float planeHeight = .3; 253 | retVal.x = (retVal.x + planeWidth*0.5)/planeWidth; 254 | retVal.y = (retVal.y + planeHeight*0.5)/planeHeight; 255 | 256 | //now to original screen pos in computer 257 | retVal.x = (int)((1-retVal.x) * width); 258 | retVal.y = (int)((1-retVal.y) * height); 259 | 260 | return retVal; 261 | } 262 | 263 | 264 | 265 | Vec2 world_to_pixel_wireFrame(Vec3 p, Vec3 cam, Vec3 target, float win_width, float win_height, float angle_x){ 266 | 267 | p = world_to_pixel(p,cam,target,win_height,win_height); 268 | float angle_y, aspect_ratio; 269 | aspect_ratio = win_width / win_height; 270 | angle_x = deg2rad(angle_x); 271 | angle_y = 2*atan(tan(angle_x/2) / aspect_ratio); 272 | 273 | Vec2 v; 274 | v.x = (1 + p.x/fabs(p.z*tan(angle_x/2))) * (win_width/2); 275 | v.y = (1 + p.y/fabs(p.z*tan(angle_y/2))) * (win_height/2); 276 | v.z = p.z; 277 | return v; 278 | 279 | 280 | } 281 | 282 | Vec3 world_to_pixel(Vec3 p, Vec3 cam, Vec3 target, float win_width, float win_height, float angle_x) 283 | { 284 | //first determine the World to Camera transforming matrix 285 | Mat WtoC(4,4); 286 | //for that use the concept of N, U and V unit vectors 287 | Vec3 N,U,V(0,1,0); 288 | 289 | //calculate the N unit vector 290 | //N is the vector from LookTo point to Camera point 291 | // N = (cam-target).normalize(); 292 | target = {-target.x, -target.y, -target.z}; 293 | N = translate(cam,target).normalize(); 294 | 295 | 296 | //U = V X N 297 | U = cross(V,N).normalize(); 298 | 299 | 300 | //readjust the V vector 301 | V = cross(N,U).normalize(); 302 | 303 | //Transpose matrix from World co-ordinate to View co-ordinate 304 | Mat T(4,4); 305 | T(0,0) = 1 ; T(0,1) = 0; T(0,2) = 0; T(0,3) = -cam.x; 306 | T(1,0) = 0 ; T(1,1) = 1; T(1,2) = 0; T(1,3) = -cam.y; 307 | T(2,0) = 0 ; T(2,1) = 0; T(2,2) = 1; T(2,3) = -cam.z; 308 | T(3,0) = 0 ; T(3,1) = 0; T(3,2) = 0; T(3,3) = 1; 309 | 310 | //Rotation Matrix 311 | Mat R(4,4); 312 | R(0,0) = U[0] ; R(0,1) = U[1]; R(0,2) = U[2]; R(0,3) = 0; 313 | R(1,0) = V[0] ; R(1,1) = V[1]; R(1,2) = V[2]; R(1,3) = 0; 314 | R(2,0) = N[0] ; R(2,1) = N[1]; R(2,2) = N[2]; R(2,3) = 0; 315 | R(3,0) = 0 ; R(3,1) = 0; R(3,2) = 0; R(3,3) = 1; 316 | 317 | 318 | //Calculating the WtoC matrix W = T*R (rotate and then translate) 319 | WtoC = R*T; 320 | 321 | Mat S(4,1); //The source point in matrix form 322 | S(0) = p.x ; S(1) = p.y; S(2) = p.z ; S(3) = 1; 323 | 324 | S = WtoC * S; 325 | //S now represents the camera co-ordinate system's values 326 | 327 | p = {S(0), S(1), S(2)}; 328 | 329 | 330 | 331 | 332 | 333 | // // calculate u, v, n vectors 334 | // Vec3 n = (cam - target).normalize(); 335 | // Vec3 u = cross(Vec3(0,1,0), n).normalize(); 336 | // Vec3 v = cross(n, u).normalize(); 337 | // 338 | // // translate cam to origin 339 | // Vec3 temp_cam = {-cam.x, -cam.y, -cam.z}; 340 | // p = translate(p, temp_cam); 341 | // //cout << "Translated point = " << p << endl; // DEBUG 342 | // 343 | // // rotate to align the axes 344 | // Mat R(4,4); 345 | // R.set({u.x, u.y, u.z, 0, 346 | // v.x, v.y, v.z, 0, 347 | // n.x, n.y, n.z, 0, 348 | // 0, 0, 0, 1}); 349 | // Mat P(4,1); P.set({p.x, p.y, p.z, 1}); 350 | // P = R * P; 351 | // p = {P(0), P(1), P(2)}; 352 | 353 | // return project(p, win_width, win_height, angle_x); 354 | return p; 355 | 356 | } 357 | 358 | -------------------------------------------------------------------------------- /App/CPP_files/load.cpp: -------------------------------------------------------------------------------- 1 | #include "../header_files/load.h" 2 | #include 3 | #include 4 | #include 5 | #include "../header_files/Math.h" 6 | using namespace std; 7 | 8 | void Scene::load(const string& filename) 9 | { 10 | vertices.clear(); 11 | faces.clear(); 12 | 13 | ifstream objfile(filename); 14 | if (!objfile) throw runtime_error("unable to open the object file"); 15 | 16 | string line, keyword; 17 | while (getline(objfile, line)) { 18 | istringstream linestream(line); 19 | linestream >> keyword; 20 | 21 | if (keyword == "v") { 22 | Vec3 v; 23 | linestream >> v.x >> v.y >> v.z; 24 | vertices.push_back(v); 25 | } 26 | 27 | else if (keyword == "f") { 28 | // get three strings 29 | string temp; 30 | for (int i = 0; i < 3; i++) { 31 | linestream >> temp; 32 | faces.push_back(stoi(temp) - 1); 33 | } 34 | 35 | } 36 | } 37 | 38 | // don't forget to close the file 39 | objfile.close(); 40 | calculateNormal(); 41 | } 42 | 43 | void Scene::print() const 44 | { 45 | // print vertices and normals 46 | for (unsigned long i = 0; i < vertices.size(); i++) 47 | cout << vertices[i] << " ==> " << normals[i] << endl; 48 | } 49 | 50 | void Scene::calculateNormal() 51 | { 52 | vector count(vertices.size(), 0); 53 | normals = vector(vertices.size(), Vec3(0,0,0)); 54 | 55 | for (unsigned long i = 0; i < faces.size(); i += 3) { 56 | // get 3 indices of vertices of this face 57 | int i1 = faces[i]; 58 | int i2 = faces[i+1]; 59 | int i3 = faces[i+2]; 60 | 61 | // get the vertices 62 | Vec3 v1 = vertices[i1]; 63 | Vec3 v2 = vertices[i2]; 64 | Vec3 v3 = vertices[i3]; 65 | 66 | // calculate normal of face 67 | if ((v2-v1).mag() < 0.00001) v2 = v2 * 1.000001; 68 | if ((v3-v2).mag() < 0.00001) v3 = v3 * 1.000001; 69 | Vec3 A = (v2 - v1).normalize(); 70 | Vec3 B = (v3 - v2).normalize(); 71 | Vec3 N = cross(A,B).normalize(); 72 | 73 | // add this normal to all 3 vertices and increment respective counts 74 | normals[i1] = normals[i1] + N; count[i1]++; 75 | normals[i2] = normals[i2] + N; count[i2]++; 76 | normals[i3] = normals[i3] + N; count[i3]++; 77 | } 78 | 79 | // find mean normals of all vertices 80 | for (unsigned long i = 0; i < vertices.size(); i++) 81 | normals[i] = (normals[i]).normalize(); 82 | } 83 | -------------------------------------------------------------------------------- /App/README: -------------------------------------------------------------------------------- 1 | ICTC_Model_ 2 | This is a simple graphics project where we have rendered a blender prepared ICTC model in graphics from scratch written in C++ and using Opengl Specification. 3 | 4 | #Algorithms used 5 | 1.Line drawing using points. 6 | 2.Drawing Triangles using lines. 7 | 3.Drawing surface and solids from the Triangles. 8 | 4.Using Transformations. 9 | 10 | #Build from source 11 | 12 | Windows 13 | Run the project in clion IDE. 14 | 15 | Linux 16 | make build.sh and run.sh executable 17 | run build.sh 18 | after then, always run.sh 19 | 20 | #Executables for 64_bit arch 21 | Provided in Executables folder or can be obtained from releases. 22 | -------------------------------------------------------------------------------- /App/build.sh: -------------------------------------------------------------------------------- 1 | mkdir build 2 | cd build 3 | cmake .. 4 | make 5 | ./ICTC ../resources/ICTC.obj 6 | -------------------------------------------------------------------------------- /App/header_files/Graphics.h: -------------------------------------------------------------------------------- 1 | #ifndef GRAPHICS_H 2 | #define GRAPHICS_H 3 | #include "Math.h" 4 | #include 5 | #include "load.h" 6 | #include "main.h" 7 | 8 | class Window { 9 | public: 10 | int width, height; 11 | float nearz, farz; 12 | std::vector zbuffer; 13 | 14 | public: 15 | Window(int w=640, int h=480, float nearz=-1, float farz=-100); 16 | 17 | public: 18 | void clear(); 19 | void refresh(); 20 | void start(); 21 | 22 | // void setPixel(const Vec2& p, const Vec3& c={1,1,1}, float i=1); 23 | void setPixel(int x, int y, float d, const Vec3& c={1,1,1}, float i=1); 24 | 25 | void drawLine(const Vec2& p1, const Vec2& p2, const Vec3& c={1,1,1}); 26 | 27 | void fillTriangle(const Vec2&, const Vec2&, const Vec2&); 28 | 29 | void wireframe(const Scene& scene, const Vec3& camera={0,0,10}, 30 | const Vec3& target={0,0,0}, float angle_x=50, float scale=1.0, int axis_type=2, float Angle_x=0, float angle_y=0, float angle_z=0); 31 | void render(const Scene& scene, const Vec3& camera={0,0,10}, 32 | const Vec3& target={0,0,0}, const Vec3& light={10,10,10}, 33 | float angle_x=45, float scale=1.0, int axis_type=2, float Angle_x=0, float angle_y=0, float angle_z=0); 34 | }; 35 | 36 | #endif // GRAPHICS_H 37 | -------------------------------------------------------------------------------- /App/header_files/Math.h: -------------------------------------------------------------------------------- 1 | #ifndef MATH_H 2 | #define MATH_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #define ROUND(x) (static_cast(x + 0.5)) 8 | 9 | 10 | class Vec3 11 | { 12 | public: float x,y,z; 13 | public: Vec3(float xx=0, float yy=0, float zz=0): x(xx) ,y(yy), z(zz) {} 14 | Vec3 operator + (const Vec3& vec) const {return Vec3(x+vec.x,y+vec.y,z+vec.z); } 15 | Vec3 operator - (const Vec3& vec) const {return Vec3(x-vec.x,y-vec.y,z-vec.z); } 16 | Vec3 operator / (const float& d) const {return Vec3(x/d,y/d,z/d);} 17 | Vec3 operator * (const float& d) const {return Vec3(x*d,y*d,z*d);} 18 | friend Vec3 operator*(float d, const Vec3& u) { return u*d; } 19 | 20 | friend std::ostream& operator<<(std::ostream&, const Vec3&); 21 | friend float dot(const Vec3& u, const Vec3& v) { 22 | return u.x*v.x + u.y*v.y + u.z*v.z; } 23 | friend Vec3 cross(const Vec3& u, const Vec3& v) { 24 | return Vec3(u.y*v.z - u.z*v.y, u.z*v.x - u.x*v.z, u.x*v.y - u.y*v.x); } 25 | float norm() const {return x*x + y*y + z*z ;} 26 | float mag() const {return sqrt(norm());} 27 | float& operator [] (int i){return (&x)[i];} 28 | Vec3 normalize() const { return (*this)/mag(); } 29 | }; 30 | 31 | class Vec2 32 | { 33 | public: float x, y,z ; //z for depth 34 | Vec3 c; //c for color 35 | float i; // i for intensity 36 | 37 | 38 | public:Vec2(float xx=0, float yy=0,float zz=0,float ii=10): x(xx) ,y(yy),z(zz),i(ii){} 39 | Vec2(const Vec2& in):x(in.x),y(in.y),z(in.z),i(in.i){} 40 | void operator = (const Vec2& in){ 41 | x = in.x; 42 | y = in.y; 43 | z = in.z; 44 | i = in.i; 45 | } 46 | friend std::ostream& operator<<(std::ostream& o, const Vec2& v); 47 | }; 48 | 49 | 50 | class Mat 51 | { 52 | private: 53 | float* data; 54 | int row, col; 55 | public: 56 | Mat(int rows,int column) : row(rows), col(column) 57 | { 58 | data = new float[row*col]; 59 | } 60 | 61 | Mat(const Mat& mat) 62 | { 63 | row = mat.row; 64 | col = mat.col; 65 | data = new float[row*col]; 66 | 67 | for (int i =0;i& _data); 71 | friend std::ostream& operator<<(std::ostream&, const Mat&); 72 | 73 | void operator=(const Mat& mat) 74 | { 75 | delete[] data; 76 | row = mat.row; 77 | col = mat.col; 78 | data = new float[row*col]; 79 | 80 | for (int i =0;i 5 | const float pi = 3.1415926535897; 6 | 7 | inline float deg2rad(float deg) { return deg*M_PI/180; } 8 | 9 | Vec3 RotateX(Vec3& Point,float theta); 10 | Vec3 RotateY(Vec3& Point,float theta); 11 | Vec3 RotateZ(Vec3& Point,float theta); 12 | Vec3 translate(Vec3& Point,const Vec3& tMat); 13 | Vec3 Scale(Vec3& Point,float scale); 14 | Vec2 project(Vec3 p, float width, float height, float angle_x=45); 15 | Vec3 Reflect_Y(Vec3& Point,const Vec3& tMat); 16 | 17 | 18 | Vec3 world_to_pixel(Vec3 p, Vec3 cam, Vec3 target, float win_width, float win_height, float angle_x=45); 19 | 20 | Vec2 world_to_pixel_wireFrame(Vec3 p, Vec3 cam, Vec3 target, float win_width, float win_height, float angle_x=45); 21 | 22 | 23 | //Vec3 world_to_pixel(Vec3 p, Vec3 cam, Vec3 target); 24 | 25 | //Vec2 world_to_pixel(const Vec3& source , //World pofloat to convert floato pixel pofloat 26 | // const Vec3& camera, //Point from where you are watching 27 | // const Vec3& LookTo, //Where are we looking at from the camera pos 28 | // float planeWidth, //width of the perspective plane 29 | // float planeHeight, //height of the perspectice plane 30 | // float winWidth, //width of the screen window 31 | // float winHeight); //height of the screen window 32 | -------------------------------------------------------------------------------- /App/header_files/load.h: -------------------------------------------------------------------------------- 1 | #ifndef SCENE_H 2 | #define SCENE_H 3 | #include "Math.h" 4 | #include "Transformation.h" 5 | #include 6 | #include 7 | 8 | // 3D vertex 9 | class Vertex { 10 | public: // data 11 | Vec3 p, n; // position and normal 12 | 13 | public: // constructor 14 | Vertex(Vec3 position = {0,0,0}): p(position), n(0,0,0) {} 15 | }; 16 | 17 | // a scene is a collection of vertices, edges, normals, and faces 18 | class Scene { 19 | public: // data 20 | std::vector normals; 21 | std::vector faces; 22 | std::vector vertices; 23 | 24 | public: // file manipulators 25 | void load(const std::string& filename); 26 | 27 | public: 28 | void print() const; 29 | void calculateNormal(); 30 | }; 31 | 32 | #endif // SCENE_H 33 | -------------------------------------------------------------------------------- /App/header_files/main.h: -------------------------------------------------------------------------------- 1 | #define SOLID 2 | -------------------------------------------------------------------------------- /App/main.cpp: -------------------------------------------------------------------------------- 1 | #include "header_files/Math.h" 2 | #include 3 | #include "GL/glut.h" 4 | #include "header_files/load.h" 5 | #include "header_files/Graphics.h" 6 | #include "header_files/Transformation.h" 7 | #include "header_files/main.h" 8 | using namespace std; 9 | 10 | // global variables 11 | Vec3 CAMERA(0, 0, 40), TARGET(0, 0, 0), LIGHT(10, 10, 10); 12 | Scene SCENE; 13 | float FIELD_OF_VIEW = 45, ANGLE_X = 0, ANGLE_Y = 0, ANGLE_Z = 0; 14 | Window WINDOW; 15 | int type = 1; 16 | int axis_type = 2; 17 | float scale = 1.0; 18 | 19 | void display(); 20 | void keyboard(unsigned char key, int x, int y); 21 | void special(int key, int x, int y); 22 | 23 | int main(int argc, char **argv) 24 | { 25 | SCENE.load(string(argv[1])); 26 | WINDOW = Window(1366, 768, -1, -200); 27 | 28 | // initialize GL 29 | glutInit(&argc, argv); 30 | glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); 31 | glutInitWindowSize(WINDOW.width, WINDOW.height); 32 | glutCreateWindow("ICTC"); 33 | 34 | glClearColor(1, 1, 1, 0); 35 | glMatrixMode(GL_PROJECTION); 36 | glLoadIdentity(); 37 | gluOrtho2D(0, WINDOW.width, 0, WINDOW.height); 38 | 39 | glutDisplayFunc(display); 40 | glutKeyboardFunc(keyboard); 41 | glutSpecialFunc(special); 42 | 43 | WINDOW.start(); 44 | } 45 | 46 | void display() 47 | { 48 | WINDOW.clear(); 49 | if(type == 1) 50 | WINDOW.render(SCENE, CAMERA, TARGET, LIGHT, FIELD_OF_VIEW, scale, axis_type, ANGLE_X, ANGLE_Y, ANGLE_Z); 51 | else if(type == 2) 52 | WINDOW.wireframe(SCENE, CAMERA, TARGET, FIELD_OF_VIEW, scale, axis_type, ANGLE_X, ANGLE_Y, ANGLE_Z); 53 | WINDOW.refresh(); 54 | } 55 | 56 | void keyboard(unsigned char key, int x, int y) 57 | { 58 | if (key == 'x') 59 | type = 1; 60 | if (key == 'z') 61 | type = 2; 62 | 63 | if (key == 27) 64 | exit(EXIT_SUCCESS); 65 | 66 | else if (key == 'w') 67 | CAMERA.z--; 68 | else if (key == 's') 69 | CAMERA.z++; 70 | else if (key == 'a') 71 | CAMERA.x--; 72 | else if (key == 'd') 73 | CAMERA.x++; 74 | else if (key == 'q') 75 | CAMERA.y--; 76 | else if (key == 'e') 77 | CAMERA.y++; 78 | 79 | else if (key == 'i') 80 | LIGHT.z--; 81 | else if (key == 'k') 82 | LIGHT.z++; 83 | else if (key == 'j') 84 | LIGHT.x--; 85 | else if (key == 'l') 86 | LIGHT.x++; 87 | else if (key == 'u') 88 | LIGHT.y--; 89 | else if (key == 'o') 90 | LIGHT.y++; 91 | 92 | else if (key == 't') 93 | TARGET.z--; 94 | else if (key == 'g') 95 | TARGET.z++; 96 | else if (key == 'f') 97 | TARGET.x--; 98 | else if (key == 'h') 99 | TARGET.x++; 100 | else if (key == 'r') 101 | TARGET.y--; 102 | else if (key == 'y') 103 | TARGET.y++; 104 | else if (key == 'b') 105 | axis_type = 1; 106 | else if (key == 'n') 107 | axis_type = 2; 108 | else if (key == 'm') 109 | axis_type = 3; 110 | 111 | 112 | glutPostRedisplay(); 113 | } 114 | 115 | void special(int key, int x, int y) 116 | { 117 | if (key == GLUT_KEY_LEFT) 118 | ANGLE_Y -= 1; 119 | else if (key == GLUT_KEY_RIGHT) 120 | ANGLE_Y += 1; 121 | else if (key == GLUT_KEY_DOWN) 122 | ANGLE_Z -= .01; 123 | else if (key == GLUT_KEY_UP) 124 | ANGLE_Z += .01; 125 | else if (key == GLUT_KEY_PAGE_UP) 126 | ANGLE_X += 1; 127 | else if (key == GLUT_KEY_PAGE_DOWN) 128 | ANGLE_X -= 1; 129 | else if (key ==GLUT_KEY_F1) 130 | scale = scale* 1.1; 131 | else if (key ==GLUT_KEY_F2) 132 | scale = scale* 0.9; 133 | 134 | 135 | 136 | glutPostRedisplay(); 137 | } 138 | -------------------------------------------------------------------------------- /App/resources/README.win: -------------------------------------------------------------------------------- 1 | 2 | 3 | GLUT for Win32 README 4 | --------------------- 5 | 6 | 7 | VERSION/INFO: 8 | 9 | This is GLUT for Win32 version 3.6 as of December 10th 1997. 10 | See the COPYRIGHT section for distribution and copyright notices. 11 | Send all bug reports/questions to Nate Robins (ndr@pobox.com) 12 | and Mark Kilgard (mjk@sgi.com). 13 | 14 | For information about GLUT for Win32, see the web page: 15 | www.pobox.com/~ndr/glut.html or subscribe to the mailing list: 16 | mail to majordomo@perp.com with "subscribe glut-win32" in the 17 | body of the message. 18 | 19 | For general information about GLUT, see the GLUT web page: 20 | http://reality.sgi.com/mjk/glut3/glut3.html 21 | 22 | There are two versions of the library. One for use with the 23 | Microsoft implementation of OpenGL (opengl32) and one for use 24 | with the SGI implementation of OpenGL (opengl). The trailing 25 | '32' indicates a Microsoft implementation. Therefore, if you 26 | are using opengl32.dll, use glut32.dll and if you are using 27 | opengl.dll use glut.dll. 28 | 29 | 30 | COMPILING/INSTALLATION: 31 | 32 | o Precompiled versions of the DLL and import library can be 33 | found on the GLUT for Win32 web page mentioned above. 34 | 35 | o Edit the glutwin32.mak file to reflect your system configuration 36 | (see the glutwin32.mak file for more information). 37 | 38 | o Type "glutmake" to make everything. Try "glutmake clean" to 39 | delete all intermediate files, and "glutmake clobber" to 40 | delete all intermediate files and executables. The build 41 | system will automatically install everything in the places 42 | specified in the glutwin32.mak file. 43 | 44 | o Other ways to compile GLUT for Windows: 45 | 46 | For no debugging info (ie, glutmake): nmake nodebug=1 47 | For debugging info: nmake 48 | For working set tuner info: nmake tune=1 49 | For call attribute profiling info: nmake profile=1 50 | 51 | 52 | BORLAND NOTES: 53 | 54 | From what I understand, Borland supplies a utility that 55 | converts Microsoft Visual C++ .libs into Borland compatible 56 | files. Therefore, the best method for Borland users is 57 | probably to get the precompiled versions of the library and 58 | convert the library. 59 | 60 | 61 | MISC NOTES: 62 | 63 | o Overlay support is currently not implemented. I _had_ it 64 | implemented, but Microsoft has such LAME fluidity in its 65 | header files from version to version that I've decided it 66 | is easier just to wait for everything to settle down and 67 | (hopefully) vendors to provide better support for overlays. 68 | 69 | o To customize the windows icon, you can use the resource name 70 | GLUT_ICON. For example, create an icon named "glut.ico", and 71 | create a file called glut.rc that contains the following: 72 | GLUT_ICON ICON glut.ico 73 | then compile the glut.rc file with the following: 74 | rc /r glut 75 | and link the resulting glut.res file into your executable 76 | (just like you would an object file). 77 | 78 | 79 | 80 | IMPLEMENTATION DEPENDENT DIFFERENCES: 81 | 82 | There are a few differences between the Win32 version of GLUT 83 | and the X11 version of GLUT. Those are outlined here. Note 84 | that MOST of these differences are allowed by the GLUT 85 | specification. Bugs and unsupported features are outlined in 86 | the UNSUPPORTED/BUGS section. 87 | 88 | o glutInit: 89 | The following command line options have no meaning (and are 90 | ignored) in GLUT for Win32: 91 | -display, -indirect, -direct, -sync. 92 | 93 | o glutInitWindowPosition, glutPositionWindow: 94 | Win32 has two different coordinate systems for windows. 95 | One is in terms of client space and the other is the whole 96 | window space (including the decorations). If you 97 | glutPositionWindow(0, 0), GLUT for Win32 will place the 98 | window CLIENT area at 0, 0. This will cause the window 99 | decorations (title bar and left edge) to be OFF-SCREEN, but 100 | it gives the user the most flexibility in positioning. 101 | HOWEVER, if the user specifies glutInitWindowPosition(0, 0), 102 | the window is placed relative to window space at 0, 0. 103 | This will cause the window to be opened in the upper left 104 | corner with all the decorations showing. This behaviour is 105 | acceptable under the current GLUT specification. 106 | 107 | o glutSetIconTitle, glutSetWindowTitle: 108 | There is no separation between Icon title and Window title 109 | in Win32. Therefore, changing the icon title will change 110 | the window title and vice-versa. This could be worked around 111 | by saving the icon and window titles and changing the window 112 | title when the state of the window is changed. 113 | 114 | o glutSetCursor: 115 | As indicated in the GLUT specification, cursors may be 116 | different on different platforms. This is the case in GLUT 117 | for Win32. For the most part, the cursors will match the 118 | meaning, but not necessarily the shape. Notable exceptions 119 | are the GLUT_CURSOR_INFO & GLUT_CURSOR_SPRAY which use the 120 | crosshair cursor and the GLUT_CURSOR_CYCLE which uses the 121 | 'no' or 'destroy' cursor in Win32. 122 | 123 | o glutVisibilityFunc: 124 | Win32 seems to be unable to determine if a window is fully 125 | obscured. Therefore, the visibility of a GLUT window is 126 | only reflected by its Iconic, Hidden or Shown state. That 127 | is, even if a window is fully obscured, in GLUT for Win32, 128 | it is still "visible". 129 | 130 | o glutEntryFunc: 131 | Window Focus is handled differently in Win32 and X. 132 | Specifically, the "window manager" in Win32 uses a "click to 133 | focus" policy. That is, in order for a window to receive 134 | focus, a mouse button must be clicked in it. Likewise, in 135 | order for a window to loose focus, a mouse button must be 136 | clicked outside the window (or in another window). 137 | Therefore, the Enter and Leave notification provided by GLUT 138 | may behave differently in the Win32 and in X11 versions. 139 | There is a viable workaround for this. A program called 140 | "Tweak UI" is provided by Microsoft which can be used to 141 | change the focus policy in Win32 to "focus follows mouse". 142 | It is available from the Microsoft Web Pages: 143 | http://www.microsoft.com/windows/software/PowerToy.htm 144 | 145 | o glutCopyColormap: 146 | GLUT for Win32 always copies the colormap. There is never 147 | any sharing of colormaps. This is probably okay, since 148 | Win32 merges the logical palette and the physical palette 149 | anyway, so even if there are two windows with totally 150 | different colors in their colormaps, Win32 will find a 151 | (hopefully) good match between them. 152 | 153 | o glutIdleFunc + menus: 154 | The glut idle function will NOT be called when a menu is 155 | active. This causes all animation to stop when a menu is 156 | active (in general, this is probably okay). Timer 157 | functions will still fire, however. If the timer callback 158 | draws into the rendering context, the drawing will not show 159 | up until after the menu has finished, though. 160 | 161 | 162 | UNSUPPORTED/BUGS: 163 | 164 | o glutAttachMenu: 165 | Win32 only likes to work with left and right mouse buttons. 166 | Especially so with popup menus. Therefore, when attaching 167 | the menu to the middle mouse button, the LEFT mouse button 168 | must be used to select from the menu (c'mon Microsoft - 169 | can't you do more than 2 buttons?). 170 | 171 | o glutSpaceball*, glutButtonBox*, glutTablet*, glutDials*: 172 | None of the special input devices are supported at this 173 | time. 174 | 175 | o When resizing or moving a GLUT for Win32 window, no updating 176 | is performed. This causes the window to leave "tracks" on 177 | the screen when getting bigger or when previously obscured 178 | parts are being revealed. I put in a bit of a kludgy 179 | workaround for those that absolutely can't have the weird 180 | lines. The reshape callback is called multiple times for 181 | reshapes. Therefore, in the reshape callback, some drawing 182 | can be done. 183 | 184 | o The video resizing capabilities of GLUT 3.3+ for X11 is 185 | currently unimplemented (this is probably ok, since it 186 | really isn't part of the spec until 4.0). I doubt that 187 | this will ever be part of GLUT for Win32, since there is no 188 | hardware to support it. A hack could simply change the 189 | resolution of the desktop. 190 | 191 | 192 | CHANGES/FIXES: 193 | 194 | (May 22, '97) 195 | o Menus don't work under Windows 95 196 | x Fixed! Added a unique identifier to each menu item, and a 197 | search function to grab a menu item given the unique identifier. 198 | 199 | (May 21, '97) 200 | o A few minor bug fixes here and there. 201 | x Thanks to Bruce Silberman and Chris Vale for their help with 202 | this. We now have a DLL! 203 | 204 | (Apr 25, '97) 205 | o DLL version of the library is coming (as soon as I figure out 206 | how to do it -- if you know, let me know). 207 | x Thanks to Bruce Silberman and Chris Vale for their help with 208 | this. We now have a DLL! 209 | 210 | (Apr 24, '97) 211 | x Added returns to KEY_DOWN etc messages so that the F10 key 212 | doesn't toggle the system menu anymore. 213 | 214 | (Apr 7, '97) 215 | o Palette is incorrect for modes other than TrueColor. 216 | x Fixed this by forcing a default palette in modes that aren't 217 | Truecolor in order to 'simulate' it. The applications 218 | program shouldn't have to do this IMHO, but I guess we 219 | can't argue with Microsoft (well, we can, but what good 220 | will it do?). 221 | 222 | (Apr 2, '97) 223 | x Added glut.ide file for Borland users. 224 | 225 | (Apr 2, '97) 226 | x Fixed a bug in the WM_QUERYNEWPALETTE message. Wasn't 227 | checking for a null colormap, then de-ref'd it. Oops. 228 | 229 | (Mar 13, '97) 230 | o glutTimerFunc: 231 | Currently, GLUT for Win32 programs busy waits when there is 232 | an outstanding timer event (i.e., there is no select() 233 | call). I haven't found this to be a problem, but I plan to 234 | fix it just because I can't bear the thought of a busy wait. 235 | x Added a timer event and a wait in the main loop. This fixes 236 | the CPU spike. 237 | 238 | (Mar 11, '97) 239 | x Fixed subwindow visibility. The visibility callback of 240 | subwindows wasn't being called, now it is. 241 | 242 | (Mar 11, '97) 243 | o glutGetHDC, glutGetHWND: 244 | In order to support additional dialog boxes, wgl fonts, and 245 | a host of other Win32 dependent structures, two functions 246 | have been added that operate on the current window in GLUT. 247 | The first (glutGetHDC) returns a handle to the current 248 | windows device context. The second (glutGetHWND) returns 249 | handle to the current window. 250 | x Took these out to preserve GLUT portability. 251 | 252 | (Mar 11, '97) 253 | x Fixed the glutWarpPointer() coordinates. Were relative to 254 | the screen, now relative to window (client area) origin 255 | (which is what they're supposed to be). 256 | 257 | (Mar 11, '97) 258 | o glutCreateMenu, glutIdleFunc: 259 | Menu's are modal in Win32. That is, they don't allow any 260 | messages to be processed while they are up. Therefore, if 261 | an idle function exists, it will not be called while 262 | processing a menu. 263 | x Fixed! I've put in a timer function that fires every 264 | millisecond while a menu is up. The timer function handles 265 | idle and timer events only (which should be the only 266 | functions that are firing when a menu is up anyway). 267 | 268 | (Mar 7 '97) 269 | x Fixed minor bugs tracked down by the example programs. 270 | 271 | (Mar 6, '97) 272 | x Merged 3.3 GLUT for X11 into 3.2 GLUT for Win32. New code 273 | structure allows for EASY merging! 274 | 275 | o In Win32, the parent gets the right to set the cursor of 276 | any of its children. Therefore, a child windows cursor 277 | will 'blink' between its cursor and its parent. 278 | x Fixed this by checking whether the cursor is in a child 279 | window or not. 280 | 281 | (Feb 28 '97) 282 | o On initial bringup apps are getting 2 display callbacks. 283 | x Fixed by the Fev 28 re-write. 284 | 285 | o Some multiple window (not subwindow) functionality is messed up. 286 | See the sphere.exe program. 287 | x Fixed by the Feb 28 re-write. 288 | 289 | o GLUT for Win32 supports color index mode ONLY in a paletted 290 | display mode (i.e., 256 or 16 color mode). 291 | x Fixed this in the re-write. If you can get a color index 292 | visual (pixel format) you can use color index mode. 293 | 294 | (Feb 28 '97) 295 | o Quite a few bugs (and incompatibilities) were being caused 296 | by the structure that I used in the previous port of GLUT. 297 | Therefore I decided that it would be best to "get back to 298 | the roots". I re-implemented most of glut trying to stick 299 | with the structure layed out by Mark. The result is a much 300 | more stable version that passes ALL (!) (except overlay) 301 | the tests provided by Mark. In addition, this new 302 | structure will allow future enhancements by Mark to be 303 | integrated much more quickly into the Win32 version. Also, 304 | I'm now ordering the bugs in reverse, so that the most 305 | recently fixed appear at the top of the list. 306 | 307 | (9/8/96) 308 | o Changed the glutGetModifiers code to produce an error if not 309 | called in the core input callbacks. 310 | 311 | (9/11/96) 312 | o If the alt key is pressed with more than one other modifier key 313 | it acts as if it is stuck -- it stays selected until pressed 314 | and released again. 315 | x Fixed. 316 | 317 | (9/12/96) 318 | o When a submenu is attached to a menu, sometimes a GPF occurs. 319 | Fixed. Needed to set the submenu before referencing it's members. 320 | 321 | o Kenny: Also, one little problem, I attached the menu to the 322 | right-button, but when the left-button is pressed I detach 323 | it to give the right-button new meaning; if I pop-up the menu and I 324 | don't want to select anything, like most users, I click off of the 325 | menu to make it disappear. When I do this, I get a GLUT error and 326 | the program terminates because I am altering the menu attachment 327 | from within the button press while the menu is active. 328 | x Fixed. Needed to finish the menu when the user presses the button, 329 | not just when a button is released. 330 | 331 | o GLUT for Win32 emulates a middle mouse button by checking if 332 | both mouse 333 | buttons are down. This causes a lot of problems with the menu 334 | and other multiple mouse button things. 335 | x Fixed. No more middle mouse button emulation. Perhaps it would 336 | be a good idea to emulate the middle mouse button (if not present) 337 | with a key? 338 | 339 | (9/15/96) 340 | o Added code to accept a user defined icon. If no icon is provided, 341 | a default icon is loaded. 342 | 343 | (9/19/96) 344 | o Shane: Command line options seem to be screwed up. (9/13) 345 | x Fixed. The geometry command line was broken, and so was the 346 | gldebug command line. 347 | 348 | o Fixed a bug in the default glut reshape. It was looking for the 349 | parent of the current window and GPF'ing if there wasn't a parent. 350 | Put in a check for a parent, and if none is there, use the 351 | child. 352 | 353 | o Idle function sucks up all processor cycles. (9/8/96) 354 | x I don't know if this is avoidable. If you have a tight rendering 355 | loop, it may be that the processor time is going to be sucked up 356 | no matter what. You can add a sleep() to the end of your render 357 | loop if you would like to yeild to other processes and you don't 358 | care too much about the speed of your rendering loop. If you have 359 | Hardware that supports OpenGL (like a 3Dpro card, or GLint card) 360 | then this should be less of a problem, since it won't be rendering 361 | in software. (9/11/96) 362 | 363 | o If a window is fully obscured by another window, the visibility 364 | callback is NOT called. As far as I can tell, this is a limitation 365 | of the Win32 api, but a workaround is being searched for. (9/8/96) 366 | x Limitation of the Win32 API 367 | 368 | o Fixed the entry functions. They only work if the keyboard focus 369 | changes. Therefore, in most Win32 systems, the mouse must be 370 | pressed outside of the window to get a GLUT_LEFT message and 371 | then pressed inside the window for a GLUT_ENTERED message. 372 | 373 | o Alt modifier key doesn't work with keyboard callback. (9/8/96) 374 | x Probably okay, because the glut spec says that these keys can 375 | be intercepted by the system (which the alt key is...) (9/11/96) 376 | 377 | (11/17/96) 378 | o glutRemoveMenuItem() not working properly. 379 | x Thanks to Gary (grc@maple.civeng.rutgers.edu) for the fix to 380 | this one. 381 | 382 | o Timer functions are messed up. 383 | x Thanks to Joseph Galbraith for the fix to this one. 384 | 385 | (12/9/96) 386 | o One (minor) difference came up between the X version of glut 387 | and the nt one which you should know about. It is not a new 388 | problem, and it concerns co-ords returned to the pointer 389 | callbacks. (glutMotionFunc, glutMouseFunc) 390 | Under X, you get co-ords in the range 0 +/- 2^15, under NT 391 | you get 0..2^16. This is only really a problem when moving 392 | above or to the left of the window. 393 | eg dragging one pixel ABOVE the window will give :- 394 | under x11 : y = -1 395 | under nt : y = 2^16 -1 396 | x Put in fix provided by Shane Clauson. 397 | 398 | (12/17/96) 399 | o Idle functions not working properly for multiple windows. 400 | x Fixed this by posting an idle message to every window in the 401 | window list when idle. 402 | 403 | (12/18/96) 404 | o glutSetCursor() was misbehaving (lthomas@cco.caltech.edu). 405 | x Win32 requires that the hCursor member of the window class 406 | be set to NULL when the class is registered or whenever the 407 | mouse is moved, the original cursor is replaced (go 408 | figure!). Now sets the cursor whenever a WM_MOUSEMOVE message 409 | is received, because the WM_SETCURSOR event resets the cursor 410 | even when in the decoration area. 411 | 412 | o Geometry is not being handled quite right. The numbers don't 413 | take into account the window decorations. That is, if I say 414 | make a window 100x100, then the WHOLE window (not just the 415 | client area) is 100x100. Therefore, the client (opengl) area 416 | is smaller than 100x100. (9/8/96) 417 | x Fixed. Added code to subtract the decoration size on glutGet() 418 | and add the decoration size on glutReshapeWindow(). 419 | 420 | o Multiple glutPostRedisplay() calls are NOT being combined. 421 | To get round the "coalesce" problem on glutPostRedisplay, 422 | the easiest solution is to roll-your-own coalesce by 423 | keeping a global "dirty" flag in the app (eg replace all 424 | calls to glutPostRedisplay with image_dirty=TRUE;), and to 425 | handle image_dirty with a single glutPostRedisplay in the 426 | idle callback when required. (erk - but increases 427 | performance for my particular app (a rendering engine on 428 | the end of a pipleine with a stream of graphics updates) by 429 | a couple of orders of magnitude ! ) (9/8/96) 430 | x Added code to coalesce redisplays. Every idle cycle, a 431 | check is made to see which windows need redisplay, if they 432 | need it, a redisplay is posted. The glutPostRedisplay() 433 | call is just a stub that sets a flag. 434 | 435 | 436 | THANKS: 437 | 438 | Special thanks to the following people: 439 | 440 | Shane Clauson (sc@datamine.co.uk) [ also provided the GLUT bug icon ] 441 | Kenny Hoff (hoff@cs.unc.edu) 442 | Richard Readings (readings@reo.dec.com) 443 | Paul McQuesten (paulmcq@cs.utexas.edu) 444 | Philip Winston (winston@cs.unc.edu) 445 | JaeWoo Ahn (jaewoo@violet.seri.re.kr) 446 | Joseph Galbraith (galb@unm.edu) 447 | Paula Higgins (paulah@unm.edu) 448 | Sam Fortin (sfortin@searchtech.com) 449 | Chris Vale (chris.vale@autodesk.com) 450 | 451 | and of course, the original author of GLUT: 452 | Mark Kilgard (mjk@sgi.com) 453 | 454 | and many others... 455 | 456 | 457 | COPYRIGHT: 458 | 459 | The OpenGL Utility Toolkit distribution for Win32 (Windows NT & 460 | Windows 95) contains source code modified from the original source 461 | code for GLUT version 3.3 which was developed by Mark J. Kilgard. The 462 | original source code for GLUT is Copyright 1997 by Mark J. Kilgard. 463 | GLUT for Win32 is Copyright 1997 by Nate Robins and is not in the 464 | public domain, but it is freely distributable without licensing fees. 465 | It is provided without guarantee or warrantee expressed or implied. 466 | It was ported with the permission of Mark J. Kilgard by Nate Robins. 467 | 468 | THIS SOURCE CODE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER 469 | EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 470 | OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 471 | 472 | OpenGL (R) is a registered trademark of Silicon Graphics, Inc. 473 | -------------------------------------------------------------------------------- /App/run.sh: -------------------------------------------------------------------------------- 1 | cd build 2 | ./ICTC ../resources/ICTC.obj 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ICTC_Model 2 | ## 5th semester Graphics project from scratch. 3 | > This is a simple graphics project. Here we have rendered a blender prepared ICTC model.The project is written from scratch in C++ using Opengl Specification. 4 | 5 | ## Algorithms used 6 | 1. Line drawing using points. 7 | 2. Drawing Triangles using lines. 8 | 3. Drawing surface and solids from the Triangles. 9 | 4. Using Transformations. 10 | 11 | ### Functionalities 12 | 13 | * Wireframe and Block model 14 | * key `z` for wireframe 15 | * key `x` for block 16 | 17 | * Camera position 18 | * key `w` for z-axis decrement. 19 | * key `s` for z-axis increment. 20 | * key `a` for x-axis decrement. 21 | * key `d` for x-axis increment. 22 | * key `q` for y-axis decrement. 23 | * key `e` for y-axis increment. 24 | 25 | 26 | * Light position 27 | * key `i` for z-axis decrement. 28 | * key `j` for z-axis increment. 29 | * key `k` for x-axis decrement. 30 | * key `l` for x-axis increment. 31 | * key `u` for y-axis decrement. 32 | * key `o` for y-axis increment. 33 | 34 | 35 | * ICTC position 36 | * key `t` for z-axis decrement. 37 | * key `g` for z-axis increment. 38 | * key `f` for x-axis decrement. 39 | * key `h` for x-axis increment. 40 | * key `r` for y-axis decrement. 41 | * key `y` for y-axis increment. 42 | 43 | 44 | * AXES angle position 45 | * key `Left Arrow` for y-axis decrement. 46 | * key `Right Arrow` for y-axis increment. 47 | * key `Down Arrow` for z-axis decrement. 48 | * key `Up Arrow` for z-axis increment. 49 | * key `Page Down` for x-axis decrement. 50 | * key `Page Up` for x-axis increment. 51 | 52 | * Scaling the ICTC 53 | * key `F1` for 10% increment. 54 | * key `F2` for 10% decrement. 55 | 56 | ## Pictures 57 | ### Wireframe 58 | ![image1](./Reports/pictures/zero.png) 59 | 60 | ### Block 61 | ![image1](./Reports/pictures/two.png) 62 | ![image1](./Reports/pictures/three.png) 63 | ![image1](./Reports/pictures/four.png) 64 | 65 | ### Sideview 66 | ![image1](./Reports/pictures/one.png) 67 | 68 | ### More top view and isometric 69 | ![image1](./Reports/pictures/five.png) 70 | 71 | ## Build from source 72 | 73 | ### Windows 74 | * Run the project in clion IDE. 75 | 76 | ### Linux 77 | * make sure build.sh and run.sh are executable 78 | * run build.sh 79 | * after then, always run.sh for execution 80 | 81 | ## Executables for 64_bit architecture 82 | > Provided in Executables folder or can be obtained from releases. 83 | -------------------------------------------------------------------------------- /Reports/ICTC_model.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CRLannister/OpenGL-Graphics-Modelling-with-Blender-Object/be9ece07799935ff58280a21fa52e4252b0df1a3/Reports/ICTC_model.pdf -------------------------------------------------------------------------------- /Reports/Presentation-min.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CRLannister/OpenGL-Graphics-Modelling-with-Blender-Object/be9ece07799935ff58280a21fa52e4252b0df1a3/Reports/Presentation-min.pdf -------------------------------------------------------------------------------- /Reports/pictures/five.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CRLannister/OpenGL-Graphics-Modelling-with-Blender-Object/be9ece07799935ff58280a21fa52e4252b0df1a3/Reports/pictures/five.png -------------------------------------------------------------------------------- /Reports/pictures/four.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CRLannister/OpenGL-Graphics-Modelling-with-Blender-Object/be9ece07799935ff58280a21fa52e4252b0df1a3/Reports/pictures/four.png -------------------------------------------------------------------------------- /Reports/pictures/one.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CRLannister/OpenGL-Graphics-Modelling-with-Blender-Object/be9ece07799935ff58280a21fa52e4252b0df1a3/Reports/pictures/one.png -------------------------------------------------------------------------------- /Reports/pictures/three.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CRLannister/OpenGL-Graphics-Modelling-with-Blender-Object/be9ece07799935ff58280a21fa52e4252b0df1a3/Reports/pictures/three.png -------------------------------------------------------------------------------- /Reports/pictures/two.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CRLannister/OpenGL-Graphics-Modelling-with-Blender-Object/be9ece07799935ff58280a21fa52e4252b0df1a3/Reports/pictures/two.png -------------------------------------------------------------------------------- /Reports/pictures/zero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CRLannister/OpenGL-Graphics-Modelling-with-Blender-Object/be9ece07799935ff58280a21fa52e4252b0df1a3/Reports/pictures/zero.png --------------------------------------------------------------------------------