ray tracing
unknown
plain_text
a year ago
18 kB
3
Indexable
Never
/* * GLUT Shapes Demo * * Written by Nigel Stewart November 2003 * * This program is test harness for the sphere, cone * and torus shapes in GLUT. * * Spinning wireframe and smooth shaded shapes are * displayed until the ESC or q key is pressed. The * number of geometry stacks and slices can be adjusted * using the + and - keys. */ #ifdef __APPLE__ #include <GLUT/glut.h> #else #include <GL/glut.h> #endif #include <stdlib.h> #include <sstream> #include <fstream> #include "1705005_classes.h" #include "bitmap_image.hpp" static int slices = 16; static int stacks = 16; extern vector<Object*> Objects; extern vector<PointLight*> pointLights; extern vector<SpotLight*> spotlights; int level_recursion; int pixels; double cameraHeight; double cameraAngle; int drawgrid; int drawaxes; double angle; int windowWidth = 1000; int windowHeight = 1000; Point eye; Point u, r, l; double mov_angle; double glob_rx = 10; double glob_ry = 10; double glob_rz = 10; double glob_radius = 6 ; void rotate_axis(Point* unit_vec1, Point* unit_vec2){ double radian_angle = mov_angle * pi / 180; unit_vec1->x = unit_vec1->x * cos(radian_angle) + unit_vec2->x * sin(radian_angle); unit_vec1->y = unit_vec1->y * cos(radian_angle) + unit_vec2->y * sin(radian_angle); unit_vec1->z = unit_vec1->z * cos(radian_angle) + unit_vec2->z * sin(radian_angle); unit_vec2->x = unit_vec2->x * cos(radian_angle) - unit_vec1->x * sin(radian_angle); unit_vec2->y = unit_vec2->y * cos(radian_angle) - unit_vec1->y * sin(radian_angle); unit_vec2->z = unit_vec2->z * cos(radian_angle) - unit_vec1->z * sin(radian_angle); } void drawAxes() { if(drawaxes==1) { glColor3f(1.0, 1.0, 1.0); glBegin(GL_LINES);{ glVertex3f( 100,0,0); glVertex3f(-100,0,0); glVertex3f(0,-100,0); glVertex3f(0, 100,0); glVertex3f(0,0, 100); glVertex3f(0,0,-100); }glEnd(); } } void drawGrid() { int i; if(drawgrid==1) { glColor3f(0.6, 0.6, 0.6); //grey glBegin(GL_LINES);{ for(i=-8;i<=8;i++){ if(i==0) continue; //SKIP the MAIN axes //lines parallel to Y-axis glVertex3f(i*10, -90, 0); glVertex3f(i*10, 90, 0); //lines parallel to X-axis glVertex3f(-90, i*10, 0); glVertex3f( 90, i*10, 0); } }glEnd(); } } /* GLUT callback Handlers */ static void resize(int width, int height) { const float ar = (float) width / (float) height; glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity() ; } static void key(unsigned char key, int x, int y) { switch (key) { case 27 : case 'q': exit(0); break; case '+': slices++; stacks++; break; case '-': if (slices>3 && stacks>3) { slices--; stacks--; } break; } glutPostRedisplay(); } static void idle(void) { glutPostRedisplay(); } const GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f }; const GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f }; const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; const GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f }; const GLfloat mat_ambient[] = { 0.7f, 0.7f, 0.7f, 1.0f }; const GLfloat mat_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f }; const GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; const GLfloat high_shininess[] = { 100.0f }; void loadData(){ cout<<"hello"<<endl; ifstream fin; string line; // by default open mode = ios::in mode fin.open("E:/4-1/CSE410/Offline3/offline3/scene.txt"); fin>>level_recursion; fin>>pixels; int count_obj; fin>>count_obj; double color[3]; double coeff[4]; int shine; for(int i = 0 ; i < count_obj ; i++){ string obj_type; fin >> obj_type; cout << obj_type << endl; if(obj_type == "triangle"){ Object *temp; Point vertices[3]; for(int j = 0 ; j < 3 ; j++){ fin >> vertices[j].x >> vertices[j].y >> vertices[j].z; } temp = new Triangle(vertices[0], vertices[1], vertices[2]); fin >> color[0] >> color[1] >> color[2]; temp->setColor(color); fin >> coeff[0] >> coeff[1] >> coeff[2] >> coeff[3]; temp->setCoefficients(coeff); fin >> shine; temp->setShine(shine); Objects.push_back(temp); } else if(obj_type == "sphere"){ Object *temp; Point center; fin >> center.x >> center.y >> center.z; double radius; fin >> radius; temp = new Sphere(center, radius); fin >> color[0] >> color[1] >> color[2]; temp->setColor(color); fin >> coeff[0] >> coeff[1] >> coeff[2] >> coeff[3]; temp->setCoefficients(coeff); fin >> shine; temp->setShine(shine); Objects.push_back(temp); } else if(obj_type == "general"){ string line; getline(fin, line); getline(fin, line); // cout << line << endl; istringstream ss(line); string token; vector<double> degree_coeff; while(getline(ss, token, ',')) { // cout << token << '\n'; degree_coeff.push_back( stod(token) ); } Object* temp = new General(degree_coeff); Point ref_point; double length, width, height; double color[3]; double coeff[4]; int shine; fin >> ref_point.x >> ref_point.y >> ref_point.z >> length >> width >> height; fin >> color[0] >> color[1] >> color[2]; fin >> coeff[0] >> coeff[1] >> coeff[2] >> coeff[3]; fin >> shine; temp->reference_point = ref_point; temp->height = height; temp->width = width; temp->length = length; temp->setColor(color); temp->setCoefficients(coeff); temp->setShine(shine); Objects.push_back(temp); } } // POINT LIGHT for(int j = 0 ; j < 4 ; j++ ){ Point pos; fin >> pos.x >> pos.y >> pos.z; double color[3]; fin >> color[0] >> color[1] >> color[2]; PointLight* pl = new PointLight(pos); pl->setColor(color); pointLights.push_back(pl); } // SPOT LIGHTS SpotLight* sl; Point pos; Point dir; double angle; fin >> pos.x >> pos.y >> pos.z ; fin >> color[0] >> color[1] >> color[2]; fin >> dir.x >> dir.y >> dir.z; fin >> angle; PointLight pl(pos); pl.setColor(color); sl = new SpotLight(pl, dir, angle); spotlights.push_back(sl); // Close the file fin.close(); } void printObjects(){ for (auto & element : Objects) { element->print_object(); } } /* Program entry point */ void Capture(){ bitmap_image image(pixels, pixels); for(int i=0;i<pixels;i++){ for(int j=0;j<pixels;j++){ image.set_pixel(i, j, 0, 0, 0); } } int imageWidth = pixels; int imageHeight = pixels; double planeDistance = ( windowHeight / 2.0 ) / ( tan(cameraAngle / 2.0 ) ); Point topLeft; topLeft.x = eye.x + ( l.x * planeDistance ) - ( r.x * windowWidth / 2 ) + ( u.x * windowHeight / 2) ; topLeft.y = eye.y + ( l.y * planeDistance ) - ( r.y * windowWidth / 2 ) + ( u.y * windowHeight / 2) ; topLeft.z = eye.z + ( l.z * planeDistance ) - ( r.z * windowWidth / 2 ) + ( u.z * windowHeight / 2) ; double du = windowWidth / imageWidth; double dv = windowHeight / imageHeight; topLeft.x = topLeft.x + (r.x) * ( 0.5 * du ) - (u.x) * ( 0.5 * dv ); topLeft.y = topLeft.y + (r.y) * ( 0.5 * du ) - (u.y) * ( 0.5 * dv ); topLeft.z = topLeft.z + (r.z) * ( 0.5 * du ) - (u.z) * ( 0.5 * dv ); int nearest; double t, tMin; for(int i = 1 ; i <= imageWidth ; i++ ){ for(int j = 1 ; j <= imageHeight ; j++ ){ Point curPixel; curPixel.x = topLeft.x + ( i * r.x * du ) - ( j * u.x * dv ) ; curPixel.y = topLeft.y + ( i * r.y * du ) - ( j * u.y * dv ); curPixel.z = topLeft.z + ( i * r.z * du ) - ( j * u.z * dv ); // curPixel.printPoint(); Ray* ray = new Ray(eye, curPixel); // ray.printRay(); double *color_ray = new double[3]; Object *nearest = NULL; int near_idx; double t_min = INT_MAX; int count = 0; for (auto & element : Objects) { // element->intersect(); double* color_temp = new double[3]; double t = element->intersect(ray, color_temp, 0); if(t < t_min){ t_min = t; near_idx = count; } count += 1; } // cout << t_min << endl; if(t_min != INT_MAX ){ cout << near_idx << endl; nearest = Objects[near_idx]; t_min = nearest->intersect(ray, color_ray, 1); // cout << color_ray[0] << " " << color_ray[1] << " " << color_ray[2] << endl; image.set_pixel(i, j, round( color_ray[0] * 255 ) , round( color_ray[1] * 255 ), round( color_ray[2] * 255) ); } } } image.save_image("E:/4-1/CSE410/Offline3/offline3/test.bmp"); } void drawSS() { // cout << "Inside ss " << endl; // Objects[3]->draw(); for (auto & element : Objects) { glPushMatrix(); glTranslatef(element->reference_point.x, element->reference_point.y, element->reference_point.z); element->draw(); glPopMatrix(); } /*int slices = 20; int direction = 1; int height = 5; glTranslatef(translate_x, translate_y, radius); glRotatef( mov_theta, 0, 0, 1); glRotatef( mov_angle, 0, 1, 0); glTranslatef( 0, 0, -radius); drawWheel(slices, height);*/ } void keyboardListener(unsigned char key, int x,int y){ switch(key){ case '0': Capture(); break; case '1': //drawgrid=1-drawgrid; mov_angle = - mov_angle; rotate_axis(&l, &r); mov_angle = - mov_angle; break; case '2': rotate_axis(&l, &r); break; case '3': rotate_axis(&l, &u); break; case '4': mov_angle = - mov_angle; rotate_axis(&l, &u); mov_angle = - mov_angle; break; case '5': rotate_axis(&u, &r); break; case '6': mov_angle = - mov_angle; rotate_axis(&u, &r); mov_angle = - mov_angle; break; default: break; } } void specialKeyListener(int key, int x,int y){ switch(key){ case GLUT_KEY_DOWN: //down arrow key cameraHeight -= 3.0; eye.x -= 5.0*l.x; eye.y -= 5.0*l.y; eye.z -= 5.0*l.z; break; case GLUT_KEY_UP: // up arrow key cameraHeight += 3.0; eye.x += 5.0*l.x; eye.y += 5.0*l.y; eye.z += 5.0*l.z; break; case GLUT_KEY_RIGHT: cameraAngle += 0.03; eye.x += 5.0*r.x; eye.y += 5.0*r.y; eye.z += 5.0*r.z; break; case GLUT_KEY_LEFT: cameraAngle -= 0.03; eye.x -= 5.0*r.x; eye.y -= 5.0*r.y; eye.z -= 5.0*r.z; break; case GLUT_KEY_PAGE_UP: eye.x += 5.0*u.x; eye.y += 5.0*u.y; eye.z += 5.0*u.z; break; case GLUT_KEY_PAGE_DOWN: eye.x -= 5.0*u.x; eye.y -= 5.0*u.y; eye.z -= 5.0*u.z; break; case GLUT_KEY_INSERT: break; case GLUT_KEY_HOME: if(glob_rx >= 1){ glob_radius += 1; glob_rx -= 1; glob_ry -= 1; glob_rz -= 1; } break; case GLUT_KEY_END: if(glob_radius >= 1){ glob_radius -= 1; glob_rx += 1; glob_ry += 1; glob_rz += 1; } break; default: break; } } void mouseListener(int button, int state, int x, int y){ //x, y is the x-y of the screen (2D) switch(button){ case GLUT_LEFT_BUTTON: if(state == GLUT_DOWN){ // 2 times?? in ONE click? -- solution is checking DOWN or UP drawaxes=1-drawaxes; } break; case GLUT_RIGHT_BUTTON: //........ break; case GLUT_MIDDLE_BUTTON: //........ break; default: break; } } void display(){ //clear the display glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(0,0,0,0); //color black glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /******************** / set-up camera here ********************/ //load the correct matrix -- MODEL-VIEW matrix glMatrixMode(GL_MODELVIEW); //initialize the matrix glLoadIdentity(); //now give three info //1. where is the camera (viewer)? //2. where is the camera looking? //3. Which direction is the camera's UP direction? //gluLookAt(100,100,100, 0,0,0, 0,0,1); //gluLookAt(200*cos(cameraAngle), 200*sin(cameraAngle), cameraHeight, 0,0,0, 0,0,1); //gluLookAt(eye.x, eye.y, eye.z, eye.x + 0,eye.y + 0,eye.z + 0, 0,1,0); //printf("%f %f %f\n", eye.x, eye.y, eye.z); gluLookAt(eye.x, eye.y, eye.z, eye.x + l.x, eye.y + l.y, eye.z + l.z, u.x, u.y , u.z); //gluLookAt(eye.x, eye.y, eye.z, 0, 0, 0, 0, 1.0, 0); //again select MODEL-VIEW glMatrixMode(GL_MODELVIEW); /**************************** / Add your objects from here ****************************/ //add objects drawAxes(); drawGrid(); //glColor3f(1,0,0); //drawSquare(10); drawSS(); //drawCircle(30,24); //drawCone(20,50,24); //drawSphere(30,24,20); //ADD this line in the end --- if you use double buffer (i.e. GL_DOUBLE) glutSwapBuffers(); } void animate(){ angle+=0.05; //codes for any changes in Models, Camera glutPostRedisplay(); } void init(){ //codes for initialization drawgrid=0; drawaxes=1; cameraHeight=150.0; cameraAngle=1.0; angle=0; u.x = 0; u.y = 0; u.z = 1; r.x = - 0.70710678118; r.y = 0.70710678118; r.z = 0; l.x = - 0.70710678118; l.y = - 0.70710678118; l.z = 0; eye.x = 100; eye.y = 100; eye.z = 0; mov_angle = 5.0; Object* floor_tile = new Floor(200, 10); // 200 - floorwidth, 10 - tilewidth double color[3]={1, 1, 1}; floor_tile->setColor(color); Objects.push_back(floor_tile); //clear the screen glClearColor(0,0,0,0); /************************ / set-up projection here ************************/ //load the PROJECTION matrix glMatrixMode(GL_PROJECTION); //initialize the matrix glLoadIdentity(); //give PERSPECTIVE parameters gluPerspective(80, 1, 1, 1000.0); //field of view in the Y (vertically) //aspect ratio that determines the field of view in the X direction (horizontally) //near distance //far distance } int main(int argc, char *argv[]) { loadData(); printObjects(); glutInit(&argc,argv); glutInitWindowSize(windowWidth, windowHeight); glutInitWindowPosition(0, 0); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB); //Depth, Double buffer, RGB color glutCreateWindow("My OpenGL Program"); init(); glEnable(GL_DEPTH_TEST); //enable Depth Testing glutDisplayFunc(display); //display callback function glutIdleFunc(animate); //what you want to do in the idle time (when no drawing is occuring) glutKeyboardFunc(keyboardListener); glutSpecialFunc(specialKeyListener); glutMouseFunc(mouseListener); glutMainLoop(); //The main loop of OpenGL /* glutInit(&argc,argv); glutInitWindowSize(500, 500); glutInitWindowPosition(0, 0); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB); //Depth, Double buffer, RGB color glutCreateWindow("My OpenGL Program"); init(); glEnable(GL_DEPTH_TEST); //enable Depth Testing glutDisplayFunc(display); //display callback function glutIdleFunc(animate); //what you want to do in the idle time (when no drawing is occuring) glutKeyboardFunc(keyboardListener); glutSpecialFunc(specialKeyListener); glutMouseFunc(mouseListener); glutMainLoop(); //The main loop of OpenGL /* glutInit(&argc, argv); glutInitWindowSize(640,480); glutInitWindowPosition(10,10); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutCreateWindow("GLUT Shapes"); glutReshapeFunc(resize); glutDisplayFunc(display); glutKeyboardFunc(key); glutIdleFunc(idle); // glClearColor(1,1,1,1); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glEnable(GL_LIGHT0); glEnable(GL_NORMALIZE); glEnable(GL_COLOR_MATERIAL); glEnable(GL_LIGHTING); glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess); glutMainLoop(); */ return EXIT_SUCCESS; }