Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "bitmap_image.hpp"
- #include<stdio.h>
- #include<stdlib.h>
- #include<math.h>
- #include<vector>
- #include<stack>
- #include<iostream>
- #include <windows.h>
- #include <glut.h>
- #define pi (2*acos(0.0))
- using std::vector;
- using namespace::std;
- double image_height = 768;
- double image_width=768;
- double window_height=500;
- double window_width= 500;
- double VIEW_ANGLE = 80;
- double cameraHeight;
- double cameraAngle;
- int drawgrid;
- int drawaxes;
- double angle;
- double height = 60;
- double radius = 20;
- int RecursionLevel=4;
- struct point
- {
- double x,y,z;
- };
- double Magnitude(point a){
- double val;
- val = a.x*a.x+a.y*a.y+a.z*a.z;
- val = sqrt(val);
- return val;
- }
- point VectorSub(point a, point b){
- point Sub;
- Sub.x = a.x-b.x;
- Sub.y = a.y-b.y;
- Sub.z = a.z-b.z;
- return Sub;
- }
- point CrossProduct(point a, point b){
- point cross;
- cross.x = a.y*b.z - a.z *b.y;
- cross.y = -(a.x*b.z - a.z*b.x);
- cross.z = a.x*b.y-b.x*a.y;
- return cross;
- }
- double DotProduct(point a, point b){
- double val;
- val = a.x*b.x + a.y*b.y + a.z*b.z;
- //cout <<"a.x*b.x" << a.x*b.x<<endl;
- //cout <<"a.y*b.y" << a.y*b.y <<endl;
- return val;
- }
- point pos,u,r,l;
- double tempX;
- double tempY;
- double tempZ;
- class Ray{
- public:
- point start;
- point dir;
- Ray(point start1, point dir1){
- start = start1;
- dir = dir1;
- }
- };
- point Normalize(point point1){
- double value1= sqrt(point1.x*point1.x+ point1.y*point1.y+point1.z*point1.z);
- point1.x = point1.x/value1;
- point1.y = point1.y/value1;
- point1.z = point1.z/value1;
- return point1;
- }
- class Object{
- public:
- point reference_point;
- double height,width,length;
- int shine;
- double color[3];
- double coefficients[4];
- Object(){
- }
- virtual double getIntersectingT(Ray r){
- return -1;
- }
- virtual void draw(){};
- virtual double intersect(Ray r, double *current_color, int level){
- return -1;
- }
- void setColor(double r, double g, double b){
- color[0] = r;
- color[1] = g;
- color[2] = b;
- }
- void setShine(int a) {
- shine = a;
- }
- void setCoefficients(double a, double b, double c, double d){
- coefficients[0] = a;
- coefficients[1] = b;
- coefficients[2] = c;
- coefficients[3] = d;
- }
- };
- vector<Object*> Objects;
- vector<point> lights;
- void drawSphere(double radius)
- {
- struct point points[100][100];
- int i,j;
- double h,r;
- int stacks = 16;
- int slices = 40;
- for(i=0;i<=stacks;i++)
- {
- h=radius*sin(((double)i/(double)stacks)*(pi/2));
- r=radius*cos(((double)i/(double)stacks)*(pi/2));
- for(j=0;j<=slices;j++)
- {
- points[i][j].x=r*cos(((double)j/(double)slices)*2*pi);
- points[i][j].y=r*sin(((double)j/(double)slices)*2*pi);
- points[i][j].z=h;
- }
- }
- //draw quads using generated points
- for(i=0;i<stacks;i++)
- {
- //glColor3f(1,0,0);
- for(j=0;j<slices;j++)
- {
- glBegin(GL_QUADS);{
- //upper hemisphere
- glVertex3f(points[i][j].x,points[i][j].y,points[i][j].z);
- glVertex3f(points[i][j+1].x,points[i][j+1].y,points[i][j+1].z);
- glVertex3f(points[i+1][j+1].x,points[i+1][j+1].y,points[i+1][j+1].z);
- glVertex3f(points[i+1][j].x,points[i+1][j].y,points[i+1][j].z);
- //lower hemisphere
- glVertex3f(points[i][j].x,points[i][j].y,-points[i][j].z);
- glVertex3f(points[i][j+1].x,points[i][j+1].y,-points[i][j+1].z);
- glVertex3f(points[i+1][j+1].x,points[i+1][j+1].y,-points[i+1][j+1].z);
- glVertex3f(points[i+1][j].x,points[i+1][j].y,-points[i+1][j].z);
- }glEnd();
- }
- }
- }
- class Sphere: public Object
- {
- public:
- Sphere(point Center, double Radius){
- reference_point = Center;
- length = Radius;
- }
- void draw(){
- glColor3f(color[0],color[1], color[2]);
- glPushMatrix();{
- glTranslatef(reference_point.x, reference_point.y, reference_point.z);
- drawSphere(length);
- }
- glPopMatrix();
- }
- double getIntersectingT(Ray r){
- double a = 1;
- double b = 2*DotProduct(r.dir, VectorSub(r.start, reference_point));
- //cout <<"b: " << b <<endl;
- double c = Magnitude(VectorSub(r.start,reference_point))*Magnitude(VectorSub(r.start,reference_point)) - length*length;
- //cout <<"c: " << c <<endl;
- double d = b*b - 4*a*c;
- //cout << d<<endl;
- if(d<0) return -1;
- d= sqrt(d);
- double t1 = (-b+d)/(2*a);
- double t2 = (-b-d)/(2*a);
- //cout << "t1: "<<t1<<endl;
- //cout <<"t2: " << t2<<endl;
- if(t1>0 && t2>0){
- if(t1<t2){
- //cout << t1 << endl;
- //cout << pos.x + r.dir.x*t1<<endl;
- //cout << pos.y + r.dir.y*t1<<endl;
- //cout << pos.z +r.dir.z*t1 << endl;
- return t1;
- }
- else{
- //cout << t2<<endl;
- return t2;
- }
- }
- else if(t1<0 && t2<0){
- //cout << pos.x - r.dir.x<<endl;
- //cout << pos.y - r.dir.y<<endl;
- //cout << pos.z -r.dir.z << endl;
- //cout <<"Eikhane"<<endl;
- return -1;
- }
- else if(t1>0 && t2<0){
- //cout << t2<<endl;
- return t1;
- }
- else if(t1<0 && t2>0){
- //cout << t2<<endl;
- return t2;
- }
- }
- void setColorAt(double* current_color, double* colorAt){
- current_color[0] = colorAt[0]*coefficients[0];
- current_color[1] = colorAt[1]*coefficients[0];
- current_color[2] = colorAt[2]*coefficients[0];
- }
- point getNormal(point intersectionPoint){
- point Normal;
- Normal.x = intersectionPoint.x - reference_point.x;
- Normal.y = intersectionPoint.y - reference_point.y;
- Normal.z = intersectionPoint.z - reference_point.z;
- Normal = Normalize(Normal);
- return Normal;
- }
- point getReflection(Ray r, point intersectionPoint, point Normal){
- point reflection;
- double a = 2*DotProduct(r.dir,Normal);
- reflection.x = -a*Normal.x + r.dir.x;
- reflection.y = -a*Normal.y + r.dir.y;
- reflection.z = -a*Normal.z + r.dir.z;
- reflection = Normalize(reflection);
- return reflection;
- }
- double intersect(Ray r, double *current_color, int level){
- double t = getIntersectingT(r);
- if(t<=0)
- return -1;
- if(level == 0 )
- return t;
- point intersectionPoint;
- intersectionPoint.x = r.start.x + r.dir.x*t;
- intersectionPoint.y = r.start.y + r.dir.y*t;
- intersectionPoint.z = r.start.z + r.dir.z*t;
- double* colorAt = new double[3];
- colorAt = color;
- setColorAt(current_color,colorAt);
- point normal;
- point reflection;
- normal = getNormal(intersectionPoint);
- reflection = getReflection(r,intersectionPoint,normal);
- for(int i=0 ;i<lights.size(); i++){
- point Start;
- point Direction;
- Direction = VectorSub(lights.at(i), intersectionPoint);
- Direction = Normalize(Direction);
- Start.x = intersectionPoint.x + Direction.x;
- Start.y = intersectionPoint.y + Direction.y;
- Start.z = intersectionPoint.z + Direction.z;
- Ray L(Start,Direction);
- double Lambert = max(DotProduct(L.dir,normal),0.0);
- point V;
- V.x = -r.dir.x;
- V.y = -r.dir.y;
- V.z = -r.dir.z;
- point R;
- double scalar = 2*DotProduct(L.dir,normal);
- R.x = scalar*normal.x - L.dir.x;
- R.y = scalar*normal.y - L.dir.y;
- R.z = scalar*normal.z - L.dir.z;
- double phong = max(pow(DotProduct(R,V),shine),0.0);
- current_color[0] += Lambert*coefficients[1]*colorAt[0]+phong*coefficients[2]*colorAt[0];
- current_color[1] += Lambert*coefficients[1]*colorAt[1]+phong*coefficients[2]*colorAt[1];
- current_color[2] += Lambert*coefficients[1]*colorAt[2]+phong*coefficients[2]*colorAt[2];
- }
- if(level < RecursionLevel){
- point start;
- start.x = intersectionPoint.x + reflection.x;
- start.y = intersectionPoint.y + reflection.y;
- start.z = intersectionPoint.z + reflection.z;
- Ray reflectionRay(start, reflection);
- int nearest = -1;
- double tmin= 999999;
- double dummyColorAt[3];
- for(int k=0; k<Objects.size(); k++){
- double t= Objects.at(k)->intersect(reflectionRay,dummyColorAt,0);
- //cout << t<<endl;
- if(t<=0) continue;
- if(t<tmin){
- tmin = t;
- nearest = k;
- }
- //double t = Objects.at(k)->intersect(ray, dummyColorAt, 1);
- //cout << t<<endl;
- }
- double Reflected_color[3];
- if(nearest!=-1){
- //double ColorAt[3]={1,234,45};
- double t = Objects.at(nearest)->intersect(reflectionRay,Reflected_color, level+1);
- //cout <<"i: " << i<<"j: " << j<< "t: " << t<<endl;
- current_color[0]+=Reflected_color[0] * coefficients[3];
- current_color[1]+=Reflected_color[1] * coefficients[3];
- current_color[2]+=Reflected_color[2] * coefficients[3];
- //image.set_pixel(i,j,ColorAt[0]*255,ColorAt[1]*255,ColorAt[2]*255);
- }
- //for(int l=0; l<3; l++){
- // cout << current_color[l] << endl;
- //}
- if(current_color[0]>1)
- current_color[0] = 1;
- if(current_color[1]>1)
- current_color[1] = 1;
- if(current_color[2]>1)
- current_color[2] = 1;
- }
- return t;
- }
- };
- class Triangle: public Object
- {
- public:
- point points[3];
- Triangle(point point1, point point2, point point3){
- points[0] = point1;
- points[1] = point2;
- points[2] = point3;
- }
- void draw(){
- glColor3f(color[0],color[1], color[2]);
- glBegin(GL_TRIANGLES);
- {
- glVertex3f(points[0].x, points[0].y,points[0].z);
- glVertex3f(points[1].x, points[1].y,points[1].z);
- glVertex3f(points[2].x, points[2].y, points[2].z);
- }
- glEnd();
- }
- double getIntersectingT(Ray r){
- point e1, e2;
- point P,Q,T;
- double det, inv_det, u, v;
- double t;
- e1 = VectorSub(points[1],points[0]);
- e2 = VectorSub(points[2],points[0]);
- P = CrossProduct(r.dir, e2);
- det = DotProduct(e1, P);
- if(det > -0.000001 && det < 0.000001) return 0;
- inv_det = 1.0 / det;
- T = VectorSub(r.start,points[0]);
- u = DotProduct(T,P) * inv_det;
- if(u<0.0000 || u>1.00000) return 0;
- Q = CrossProduct(T, e1);
- v = DotProduct(r.dir,Q)*inv_det;
- if(v<0.000 || u+v > 1.0000) return 0;
- t = DotProduct(e2, Q)*inv_det;
- if(t>0.000001){
- return t;
- }
- }
- void setColorAt(double* current_color, double* colorAt){
- current_color[0] = colorAt[0]*coefficients[0];
- current_color[1] = colorAt[1]*coefficients[0];
- current_color[2] = colorAt[2]*coefficients[0];
- }
- point getNormal(){
- point Normal;
- Normal = CrossProduct(VectorSub(points[1],points[0]),VectorSub(points[2],points[0]));
- Normal = Normalize(Normal);
- return Normal;
- }
- point getReflection(Ray r, point intersectionPoint, point Normal){
- point reflection;
- double a = 2*DotProduct(r.dir,Normal);
- reflection.x = -a*Normal.x + r.dir.x;
- reflection.y = -a*Normal.y + r.dir.y;
- reflection.z = -a*Normal.z + r.dir.z;
- reflection = Normalize(reflection);
- return reflection;
- }
- double intersect(Ray r, double *current_color, int level){
- double t = getIntersectingT(r);
- if(t<=0)
- return -1;
- if(level == 0 )
- return t;
- point intersectionPoint;
- intersectionPoint.x = r.start.x + r.dir.x*t;
- intersectionPoint.y = r.start.y + r.dir.y*t;
- intersectionPoint.z = r.start.z + r.dir.z*t;
- double* colorAt = new double[3];
- colorAt = color;
- setColorAt(current_color,colorAt);
- point normal;
- point reflection;
- normal = getNormal();
- reflection = getReflection(r,intersectionPoint,normal);
- for(int i=0 ;i<lights.size(); i++){
- point Start;
- point Direction;
- Direction = VectorSub(lights.at(i), intersectionPoint);
- double sumVal = sqrt(pow(Direction.x,2)+pow(Direction.y,2)+pow(Direction.z,2));
- Direction = Normalize(Direction);
- Start.x = intersectionPoint.x + Direction.x;
- Start.y = intersectionPoint.y + Direction.y;
- Start.z = intersectionPoint.z + Direction.z;
- Ray L(Start,Direction);
- int flag = -1;
- for(int j=0; j<Objects.size(); j++){
- double tempVal;
- tempVal = Objects.at(j) ->getIntersectingT(L);
- if(tempVal>0 && tempVal<sumVal){
- flag =1;
- break;
- }
- }
- if(flag!=1){
- double Lambert = max(DotProduct(L.dir,normal),0.0);
- point V;
- V.x = -r.dir.x;
- V.y = -r.dir.y;
- V.z = -r.dir.z;
- point R;
- double scalar = 2*DotProduct(L.dir,normal);
- R.x = scalar*normal.x - L.dir.x;
- R.y = scalar*normal.y - L.dir.y;
- R.z = scalar*normal.z - L.dir.z;
- R= Normalize(R);
- double phong = max(pow(DotProduct(R,V),shine),0.0);
- current_color[0] += Lambert*coefficients[1]*colorAt[0]+phong*coefficients[2]*colorAt[0];
- current_color[1] += Lambert*coefficients[1]*colorAt[1]+phong*coefficients[2]*colorAt[1];
- current_color[2] += Lambert*coefficients[1]*colorAt[2]+phong*coefficients[2]*colorAt[2];
- }
- if(level < RecursionLevel){
- point start;
- start.x = intersectionPoint.x + reflection.x;
- start.y = intersectionPoint.y + reflection.y;
- start.z = intersectionPoint.z + reflection.z;
- //cout << "KICHU" <<endl;
- //cout << "Start: " << start.x <<" " << start.y << " " << start.z<<endl;
- //cout << "ref: " << reflection.x << " " << reflection.y << " " << reflection.z << endl;
- Ray reflectionRay(start, reflection);
- int nearest = -1;
- double tmin= 999999;
- double dummyColorAt[3];
- for(int k=0; k<Objects.size(); k++){
- //double dummyColorAt[3]={1,234,45};
- double t= Objects.at(k)->intersect(reflectionRay,dummyColorAt,0);
- //cout << t<<endl;
- if(t<=0) continue;
- if(t<tmin){
- tmin = t;
- nearest = k;
- }
- //double t = Objects.at(k)->intersect(ray, dummyColorAt, 1);
- //cout << t<<endl;
- }
- double Reflected_color[3];
- if(nearest!=-1){
- //double ColorAt[3]={1,234,45};
- double t = Objects.at(nearest)->intersect(reflectionRay,Reflected_color, level+1);
- //cout <<"i: " << i<<"j: " << j<< "t: " << t<<endl;
- current_color[0]+=Reflected_color[0] * coefficients[3];
- current_color[1]+=Reflected_color[1] * coefficients[3];
- current_color[2]+=Reflected_color[2] * coefficients[3];
- //image.set_pixel(i,j,ColorAt[0]*255,ColorAt[1]*255,ColorAt[2]*255);
- }
- //for(int l=0; l<3; l++){
- // cout << current_color[l] << endl;
- //}
- if(current_color[0]>1)
- current_color[0] = 1;
- if(current_color[1]>1)
- current_color[1] = 1;
- if(current_color[2]>1)
- current_color[2] = 1;
- }
- }
- return t;
- }
- };
- class Floor: public Object{
- public:
- Floor(double FloorWidth,double TileWidth){
- reference_point.x = -FloorWidth/2;
- reference_point.y = -FloorWidth/2;
- reference_point.z = 0;
- length = TileWidth;
- }
- void draw(){
- int noOfIterations = -(reference_point.x * 2)/ length;
- double row = reference_point.x;
- int flag = 0; // White
- for(int i=0; i<noOfIterations; i++){
- double column = reference_point.x;
- for(int j=0; j<noOfIterations; j++){
- if(flag == 0){
- glColor3f(0,0,0);
- flag =1;
- }
- else{
- glColor3f(255,255,255);
- flag = 0;
- }
- glBegin(GL_QUADS);{
- glVertex3f( row, column,0);
- glVertex3f( row,column+length,0);
- glVertex3f( row+length,column+length,0);
- glVertex3f(row+length, column,0);
- }glEnd();
- column = column+ length;
- }
- row = row+length;
- if(flag==0) flag=1;
- else flag = 0;
- }
- }
- void setColorAt(double* current_color, double* colorAt){
- current_color[0] = colorAt[0]*coefficients[0];
- current_color[1] = colorAt[1]*coefficients[0];
- current_color[2] = colorAt[2]*coefficients[0];
- }
- double getIntersectingT(Ray r){
- double t = -r.start.z/r.dir.z;
- if(t<0){
- return -1;
- }
- else
- return t;
- }
- double* getColorAt(point intersection){
- int row = floor((intersection.x - reference_point.x)/(length));
- int col = floor((intersection.y -reference_point.y)/length);
- int a = row%2;
- int b = col%2;
- if(a==b){
- for(int i=0; i<3; i++){
- color[i] = 1;
- }
- }
- else{
- for(int i=0; i<3; i++){
- color[i] = 0;
- }
- }
- return color;
- }
- point getReflection(Ray r, point intersectionPoint, point Normal){
- point reflection;
- double a = 2*DotProduct(r.dir,Normal);
- reflection.x = -a*Normal.x + r.dir.x;
- reflection.y = -a*Normal.y + r.dir.y;
- reflection.z = -a*Normal.z + r.dir.z;
- reflection = Normalize(reflection);
- return reflection;
- }
- double intersect(Ray r, double *current_color, int level){
- double t = getIntersectingT(r);
- if(t<=0)
- return -1;
- if(level == 0 )
- return t;
- point intersectionPoint;
- intersectionPoint.x = r.start.x + r.dir.x*t;
- intersectionPoint.y = r.start.y + r.dir.y*t;
- intersectionPoint.z = r.start.z + r.dir.z*t;
- double* colorAt = new double[3];
- colorAt = getColorAt(intersectionPoint);
- setColorAt(current_color,colorAt);
- point normal;
- point reflection;
- normal.x = 0;
- normal.y = 0;
- normal.z = 1;
- reflection = getReflection(r,intersectionPoint,normal);
- for(int i=0 ;i<lights.size(); i++){
- point Start;
- point Direction;
- Direction = VectorSub(lights.at(i), intersectionPoint);
- Direction = Normalize(Direction);
- Start.x = intersectionPoint.x + Direction.x;
- Start.y = intersectionPoint.y + Direction.y;
- Start.z = intersectionPoint.z + Direction.z;
- Ray L(Start,Direction);
- double Lambert = max(DotProduct(L.dir,normal),0.0);
- point V;
- V.x = -r.dir.x;
- V.y = -r.dir.y;
- V.z = -r.dir.z;
- point R;
- double scalar = 2*DotProduct(L.dir,normal);
- R.x = scalar*normal.x - L.dir.x;
- R.y = scalar*normal.y - L.dir.y;
- R.z = scalar*normal.z - L.dir.z;
- double phong = max(pow(DotProduct(R,V),shine),0.0);
- current_color[0] += Lambert*coefficients[1]*colorAt[0]+phong*coefficients[2]*colorAt[0];
- current_color[1] += Lambert*coefficients[1]*colorAt[1]+phong*coefficients[2]*colorAt[1];
- current_color[2] += Lambert*coefficients[1]*colorAt[2]+phong*coefficients[2]*colorAt[2];
- }
- if(level < RecursionLevel){
- point start;
- start.x = intersectionPoint.x + reflection.x;
- start.y = intersectionPoint.y + reflection.y;
- start.z = intersectionPoint.z + reflection.z;
- //printf("start %lf %lf %lf \n",start.x,start.y,start.z);
- //printf("refle %lf %lf %lf \n",reflection.x,reflection.y,reflection.z);
- Ray reflectionRay(start, reflection);
- int nearest = -1;
- double tmin= 999999;
- for(int k=0; k<Objects.size(); k++){
- double dummyColorAt[3]={1,234,45};
- double t= Objects.at(k)->intersect(reflectionRay,dummyColorAt,0);
- //cout << t<<endl;
- if(t<=0) continue;
- if(t<tmin){
- tmin = t;
- nearest = k;
- }
- //double t = Objects.at(k)->intersect(ray, dummyColorAt, 1);
- //cout << t<<endl;
- }
- double Reflected_color[3];
- if(nearest!=-1){
- //double ColorAt[3]={1,234,45};
- double t = Objects.at(nearest)->intersect(reflectionRay,Reflected_color, level+1);
- //cout <<"i: " << i<<"j: " << j<< "t: " << t<<endl;
- current_color[0]+=Reflected_color[0] * coefficients[3];
- current_color[1]+=Reflected_color[1] * coefficients[3];
- current_color[2]+=Reflected_color[2] * coefficients[3];
- //image.set_pixel(i,j,ColorAt[0]*255,ColorAt[1]*255,ColorAt[2]*255);
- }
- //for(int l=0; l<3; l++){
- // cout << current_color[i] << endl;
- //}
- if(current_color[0]>1)
- current_color[0] = 1;
- if(current_color[1]>1)
- current_color[1] = 1;
- if(current_color[2]>1)
- current_color[2] = 1;
- }
- return t;
- }
- };
- class General: public Object
- {
- public:
- //point points[3];
- double A,B,C,D,E,F,G,H,I,J;
- //double Coeff[10];
- General(double* C1, point ref_point, double length1, double width1, double height1){
- A=C1[0];
- B=C1[1];
- C = C1[2];
- D = C1[3];
- E = C1[4];
- F = C1[5];
- G = C1[6];
- H = C1[7];
- I = C1[8];
- J = C1[9];
- reference_point.x = ref_point.x;
- reference_point.y = ref_point.y;
- reference_point.z = ref_point.z;
- this->length = length1;
- this->width = width1;
- this->height = height1;
- }
- void draw(){
- }
- double getIntersectingT(Ray r){
- double a = A*r.dir.x*r.dir.x + B*r.dir.y*r.dir.y+C*r.dir.z*r.dir.z + D*r.dir.x*r.dir.y+E*r.dir.y*r.dir.z + F*r.dir.z*r.dir.x;
- double b = 2*A*r.start.x*r.dir.x + 2*B*r.dir.y*r.start.y + 2*C*r.dir.z* r.start.z
- + D*r.start.x*r.dir.y + E*r.start.y*r.dir.z+E*r.dir.y*r.start.z
- + F*r.start.z*r.dir.x + F*r.dir.z*r.start.x + G*r.dir.x
- + H*r.dir.y + I*r.dir.z;
- double c = A*r.start.x*r.start.x + B*r.start.y*r.start.y+C*r.start.z*r.start.z + D*r.start.x*r.start.y+E*r.start.y*r.start.z + F*r.start.z*r.start.x
- +G*r.start.x + H*r.start.y + I*r.start.z + J;
- double d = b*b-4*a*c;
- if(d<0)
- return -1;
- d = sqrt(d);
- double t1 = (-b+d)/(2*a);
- double t2 = (-b-d)/(2*a);
- point intersectionPT1;
- point intersectionPT2;
- intersectionPT1.x = r.start.x + t1*r.dir.x;
- intersectionPT1.y = r.start.y + t1*r.dir.y;
- intersectionPT1.z = r.start.z + t1*r.dir.z;
- intersectionPT2.x = r.start.x + t2*r.dir.x;
- intersectionPT2.y = r.start.y + t2*r.dir.y;
- intersectionPT2.z = r.start.z + t2*r.dir.z;
- int temp1 = 0;
- int temp2 = 0;
- if(this->length != 0 && temp1==0){
- if(intersectionPT1.x<reference_point.x || intersectionPT1.x>reference_point.x + this->length)
- temp1 = 1;
- }
- if(temp1 == 0 && this->width!=0){
- if(intersectionPT1.y < reference_point.y || intersectionPT1.y > reference_point.y + this->width)
- temp1 = 1;
- }
- if(temp1 == 0 && this->height!=0){
- if(intersectionPT1.z < reference_point.z || intersectionPT1.z > reference_point.z + this->height)
- temp1 = 1;
- }
- if(temp2 == 0 && this->length!=0){
- if(intersectionPT2.x < reference_point.x || intersectionPT2.x > reference_point.x + this->length)
- temp2 = 1;
- }
- if(temp2 == 0 && this->width!=0){
- if(intersectionPT2.y < reference_point.y || intersectionPT2.y > reference_point.y + this->width)
- temp2 = 1;
- }
- if(temp2 == 0 && this->height!=0){
- if(intersectionPT2.z < reference_point.z || intersectionPT2.z > reference_point.z + this->height)
- temp2 = 1;
- }
- if(temp1 != 0 && temp2 !=0)
- return -1;
- if(temp1!=0)
- return t2;
- if(temp2!=0)
- return t1;
- if(t1<t2)
- return t1;
- else
- return t2;
- }
- void setColorAt(double* current_color, double* colorAt){
- current_color[0] = colorAt[0]*coefficients[0];
- current_color[1] = colorAt[1]*coefficients[0];
- current_color[2] = colorAt[2]*coefficients[0];
- }
- point getNormal(point IntersectionPoint){
- point Normal;
- Normal.x = IntersectionPoint.x*A*2 + IntersectionPoint.y*D + F*IntersectionPoint.z + G;
- Normal.y = IntersectionPoint.y*B*2 + IntersectionPoint.x*D + E*IntersectionPoint.z + H;
- Normal.z = IntersectionPoint.z*C*2 + IntersectionPoint.z*E + F*IntersectionPoint.x + I;
- return Normal;
- }
- point getReflection(Ray r, point intersectionPoint, point Normal){
- point reflection;
- double a = 2*DotProduct(r.dir,Normal);
- reflection.x = -a*Normal.x + r.dir.x;
- reflection.y = -a*Normal.y + r.dir.y;
- reflection.z = -a*Normal.z + r.dir.z;
- reflection = Normalize(reflection);
- return reflection;
- }
- double intersect(Ray r, double *current_color, int level){
- double t = getIntersectingT(r);
- if(t<=0)
- return -1;
- if(level == 0 )
- return t;
- point intersectionPoint;
- intersectionPoint.x = r.start.x + r.dir.x*t;
- intersectionPoint.y = r.start.y + r.dir.y*t;
- intersectionPoint.z = r.start.z + r.dir.z*t;
- double* colorAt = new double[3];
- colorAt = color;
- setColorAt(current_color,colorAt);
- point normal;
- point reflection;
- normal = getNormal(intersectionPoint);
- reflection = getReflection(r,intersectionPoint,normal);
- for(int i=0 ;i<lights.size(); i++){
- point Start;
- point Direction;
- Direction = VectorSub(lights.at(i), intersectionPoint);
- double sumVal = sqrt(pow(Direction.x,2)+pow(Direction.y,2)+pow(Direction.z,2));
- Direction = Normalize(Direction);
- Start.x = intersectionPoint.x + Direction.x;
- Start.y = intersectionPoint.y + Direction.y;
- Start.z = intersectionPoint.z + Direction.z;
- Ray L(Start,Direction);
- int flag = -1;
- for(int j=0; j<Objects.size(); j++){
- double tempVal;
- tempVal = Objects.at(j) ->getIntersectingT(L);
- if(tempVal>0 && tempVal<sumVal){
- flag =1;
- break;
- }
- }
- if(flag!=1){
- double Lambert = max(DotProduct(L.dir,normal),0.0);
- point V;
- V.x = -r.dir.x;
- V.y = -r.dir.y;
- V.z = -r.dir.z;
- point R;
- double scalar = 2*DotProduct(L.dir,normal);
- R.x = scalar*normal.x - L.dir.x;
- R.y = scalar*normal.y - L.dir.y;
- R.z = scalar*normal.z - L.dir.z;
- R= Normalize(R);
- double phong = max(pow(DotProduct(R,V),shine),0.0);
- current_color[0] += Lambert*coefficients[1]*colorAt[0]+phong*coefficients[2]*colorAt[0];
- current_color[1] += Lambert*coefficients[1]*colorAt[1]+phong*coefficients[2]*colorAt[1];
- current_color[2] += Lambert*coefficients[1]*colorAt[2]+phong*coefficients[2]*colorAt[2];
- }
- if(level < RecursionLevel){
- point start;
- start.x = intersectionPoint.x + reflection.x;
- start.y = intersectionPoint.y + reflection.y;
- start.z = intersectionPoint.z + reflection.z;
- //cout << "KICHU" <<endl;
- //cout << "Start: " << start.x <<" " << start.y << " " << start.z<<endl;
- //cout << "ref: " << reflection.x << " " << reflection.y << " " << reflection.z << endl;
- Ray reflectionRay(start, reflection);
- int nearest = -1;
- double tmin= 999999;
- double dummyColorAt[3];
- for(int k=0; k<Objects.size(); k++){
- //double dummyColorAt[3]={1,234,45};
- double t= Objects.at(k)->intersect(reflectionRay,dummyColorAt,0);
- //cout << t<<endl;
- if(t<=0) continue;
- if(t<tmin){
- tmin = t;
- nearest = k;
- }
- //double t = Objects.at(k)->intersect(ray, dummyColorAt, 1);
- //cout << t<<endl;
- }
- double Reflected_color[3];
- if(nearest!=-1){
- //double ColorAt[3]={1,234,45};
- double t = Objects.at(nearest)->intersect(reflectionRay,Reflected_color, level+1);
- //cout <<"i: " << i<<"j: " << j<< "t: " << t<<endl;
- current_color[0]+=Reflected_color[0] * coefficients[3];
- current_color[1]+=Reflected_color[1] * coefficients[3];
- current_color[2]+=Reflected_color[2] * coefficients[3];
- //image.set_pixel(i,j,ColorAt[0]*255,ColorAt[1]*255,ColorAt[2]*255);
- }
- //for(int l=0; l<3; l++){
- // cout << current_color[l] << endl;
- //}
- if(current_color[0]>1)
- current_color[0] = 1;
- if(current_color[1]>1)
- current_color[1] = 1;
- if(current_color[2]>1)
- current_color[2] = 1;
- }
- }
- return t;
- }
- };
- void drawAxes()
- {
- if(drawaxes==1)
- {
- glBegin(GL_LINES);{
- glColor3f(0, 0, 1); // BLUE
- glVertex3f( 100,0,0);
- glVertex3f(0,0,0);
- glColor3f(0,1,1);
- glVertex3f( -100,0,0);
- glVertex3f(0,0,0);
- glColor3f(0, 1, 0); // Green
- glVertex3f(0,100,0);
- glVertex3f(0, 0,0);
- glColor3f(0, 1, 1); // Green
- glVertex3f(0,-100,0);
- glVertex3f(0, 0,0);
- glColor3f(1, 0, 0);
- glVertex3f(0,0, 100);
- glVertex3f(0,0,0);
- glColor3f(0, 1, 1); // Green
- glVertex3f(0,0,-100);
- glVertex3f(0, 0,0);
- }glEnd();
- }
- }
- void Capture(){
- bitmap_image image(image_width,image_height);
- for(int i=0;i<image_width;i++){
- for(int j=0;j<image_height;j++){
- image.set_pixel(i,j,0,0,0);
- }
- }
- double plane_distance = (window_height/2)/(tan(2*pi*VIEW_ANGLE/(2*360)));
- point topLeft;
- topLeft.x = pos.x + l.x*plane_distance - r.x*(window_width/2)+u.x*(window_height/2);
- topLeft.y= pos.y + l.y*plane_distance - r.y*(window_width/2)+u.y*(window_height/2);
- topLeft.z = pos.z + l.z*plane_distance - r.z*(window_width/2)+u.z*(window_height/2);
- //cout << "Top Left: " << topLeft.x << " " << topLeft.y << " " << topLeft.z <<endl;
- double du = window_width/image_width;
- double dv = window_height/image_height;
- //Ray ray(pos, topLeft);
- point Corner;
- for(int i=0; i<image_width; i++){
- for(int j=0; j<image_width; j++){
- Corner.x = topLeft.x + ( i*du*r.x + j*dv*(-u.x));
- Corner.y = topLeft.y + (i*du*r.y + j*dv*(-u.y));
- Corner.z = topLeft.z +(i*du*r.z + j*dv*(-u.z));
- //Corner - Pos
- point Corner_dir_pos;
- Corner_dir_pos.x = Corner.x - pos.x;
- Corner_dir_pos.y = Corner.y - pos.y;
- Corner_dir_pos.z = Corner.z - pos.z;
- Corner_dir_pos = Normalize(Corner_dir_pos);
- Ray ray(pos, Corner_dir_pos);
- int nearest = -1;
- double tmin= 999999;
- for(int k=0; k<Objects.size(); k++){
- double dummyColorAt[3]={1,234,45};
- double t= Objects.at(k)->intersect(ray,dummyColorAt,0);
- //cout << t<<endl;
- if(t<=0) continue;
- if(t<tmin){
- tmin = t;
- nearest = k;
- }
- //double t = Objects.at(k)->intersect(ray, dummyColorAt, 1);
- //cout << t<<endl;
- }
- if(nearest!=-1){
- double ColorAt[3]={1,234,45};
- double t = Objects.at(nearest)->intersect(ray,ColorAt, 1);
- //cout <<"i: " << i<<"j: " << j<< "t: " << t<<endl;
- image.set_pixel(i,j,ColorAt[0]*255,ColorAt[1]*255,ColorAt[2]*255);
- }
- }
- }
- image.save_image("F:\\CSE 4-2 Study Resources\\CSE_410_Computer_Graphics_Sessional\\Assignment1 Solution\\New folder\\OpenGL\\OpenGL_CodeBlocks\\output.bmp");
- }
- void keyboardListener(unsigned char key, int x,int y){
- switch(key){
- case '0':
- Capture();
- break;
- case '1':
- l.x = l.x*cos((3*pi)/180) + r.x*sin((3*pi)/180);
- l.y = l.y*cos((3*pi)/180) + r.y*sin((3*pi)/180);
- l.z = l.z*cos((3*pi)/180) + r.z*sin((3*pi)/180);
- r.x = r.x*cos((3*pi)/180) - l.x* sin((3*pi)/180);
- r.y = r.y*cos((3*pi)/180) - l.y *sin((3*pi)/180);
- r.z = r.z*cos((3*pi)/180) - l.z *sin((3*pi)/180);
- break;
- case '2':
- l.x = l.x*cos((3*pi)/180) - r.x*sin((3*pi)/180);
- l.y = l.y*cos((3*pi)/180) - r.y*sin((3*pi)/180);
- l.z = l.z*cos((3*pi)/180) - r.z*sin((3*pi)/180);
- r.x = r.x*cos((3*pi)/180) + l.x* sin((3*pi)/180);
- r.y = r.y*cos((3*pi)/180) + l.y *sin((3*pi)/180);
- r.z = r.z*cos((3*pi)/180) + l.z *sin((3*pi)/180);
- break;
- case '3':
- tempX = l.x;
- tempY = l.y;
- tempZ = l.z;
- u.x = u.x*cos((3*pi)/180) - tempX*sin((3*pi)/180);
- u.y = u.y*cos((3*pi)/180) - tempY*sin((3*pi)/180);
- u.z = u.z*cos((3*pi)/180) - tempZ*sin((3*pi)/180);
- l.x = tempX*cos((3*pi)/180) + u.x* sin((3*pi)/180);
- l.y = tempY*cos((3*pi)/180) + u.y *sin((3*pi)/180);
- l.z = tempZ*cos((3*pi)/180) + u.z *sin((3*pi)/180);
- break;
- case '4':
- u.x = u.x*cos((3*pi)/180) + tempX*sin((3*pi)/180);
- u.y = u.y*cos((3*pi)/180) + tempY*sin((3*pi)/180);
- u.z = u.z*cos((3*pi)/180) + tempZ*sin((3*pi)/180);
- l.x = l.x*cos((3*pi)/180) - u.x* sin((3*pi)/180);
- l.y = l.y*cos((3*pi)/180) - u.y *sin((3*pi)/180);
- l.z = l.z*cos((3*pi)/180) - u.z *sin((3*pi)/180);
- break;
- //tilt clockwise
- case '5':
- r.x = r.x*cos((3*pi)/180) - u.x* sin((3*pi)/180);
- r.y = r.y*cos((3*pi)/180) - u.y *sin((3*pi)/180);
- r.z = r.z*cos((3*pi)/180) - u.z *sin((3*pi)/180);
- u.x = u.x*cos((3*pi)/180) + r.x*sin((3*pi)/180);
- u.y = u.y*cos((3*pi)/180) + r.y*sin((3*pi)/180);
- u.z = u.z*cos((3*pi)/180) + r.z*sin((3*pi)/180);
- break;
- //tilt anticlockwise
- case '6':
- r.x = r.x*cos((3*pi)/180) + u.x* sin((3*pi)/180);
- r.y = r.y*cos((3*pi)/180) + u.y *sin((3*pi)/180);
- r.z = r.z*cos((3*pi)/180) + u.z *sin((3*pi)/180);
- u.x = u.x*cos((3*pi)/180) - r.x*sin((3*pi)/180);
- u.y = u.y*cos((3*pi)/180) - r.y*sin((3*pi)/180);
- u.z = u.z*cos((3*pi)/180) - r.z*sin((3*pi)/180);
- break;
- default:
- break;
- }
- }
- void specialKeyListener(int key, int x,int y){
- switch(key){
- case GLUT_KEY_DOWN: //down arrow key
- //cameraHeight -= 3.0;
- pos.x = pos.x +2*l.x;
- pos.y = pos.y + 2*l.y;
- break;
- case GLUT_KEY_UP: // up arrow key
- //cameraHeight += 3.0;
- pos.x = pos.x - 2*l.x;
- pos.y = pos.y - 2*l.y;
- break;
- case GLUT_KEY_RIGHT:
- //cameraAngle += 0.03;
- pos.x = pos.x + 2*r.x;
- pos.y = pos.y + 2*r.y;
- break;
- case GLUT_KEY_LEFT:
- pos.x = pos.x - 2*r.x;
- pos.y = pos.y - 2*r.y;
- //cameraAngle -= 0.03;
- break;
- case GLUT_KEY_PAGE_UP:
- pos.z = pos.z + 2*u.z;
- break;
- case GLUT_KEY_PAGE_DOWN:
- pos.z = pos.z - 2*u.z;
- break;
- case GLUT_KEY_INSERT:
- break;
- case GLUT_KEY_HOME:
- if(height != 0){
- height = height-1;
- radius = radius+1;
- }
- break;
- case GLUT_KEY_END:
- if(radius !=0){
- height=height+1;
- radius = radius-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(0,0,200, 0,0,0, 0,1,0);
- gluLookAt(pos.x,pos.y,pos.z,pos.x+l.x, pos.y + l.y, pos.z + l.z, u.x, u.y, u.z);
- //again select MODEL-VIEW
- glMatrixMode(GL_MODELVIEW);
- /****************************
- / Add your objects from here
- ****************************/
- //add objects
- drawAxes();
- //drawGrid();
- for(int i=0; i<Objects.size(); i++){
- Objects.at(i)->draw();
- }
- for(int i=0; i<lights.size(); i++){
- glColor3f(1,0,0);
- glBegin(GL_QUADS);{
- glVertex3f(lights.at(i).x, lights.at(i).y, lights.at(i).z);
- }glEnd();
- }
- //glColor3f(1,0,0);
- //drawSquare(10);
- //drawSS();
- //drawCircle(30,24);
- //drawCone(20,50,24);
- //drawSphere(30,24,20);
- //drawCylinder(30,24,20);
- //DrawObject(height,radius);
- //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;
- pos.x = 0;
- pos.y = -200;
- pos.z = 50;
- u.x = 0;
- u.y = 0;
- u.z = 1;
- r.x = 1;
- r.y = 0;
- r.z = 0;
- l.x = 0;
- l.y = 1;
- l.z = 0;
- //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
- }
- void loadTestData(){
- Object *temp;
- point Center;
- Center.x = 40.0;
- Center.y = 0;
- Center.z = 10.0;
- temp = new Sphere(Center,10);
- temp->setColor(0,1,0);
- temp->setCoefficients(0.4,0.2,0.2,0.2);
- temp->setShine(10);
- Objects.push_back(temp);
- //point Center;
- Center.x = -30;
- Center.y = 60;
- Center.z = 20;
- temp = new Sphere(Center,20);
- temp->setColor(0,0,1);
- temp->setCoefficients(0.2,0.2,0.4,0.2);
- temp->setShine(15);
- Objects.push_back(temp);
- Center.x = -15;
- Center.y = 15;
- Center.z = 45;
- temp = new Sphere(Center,15);
- temp->setColor(1,0,0);
- temp->setCoefficients(0.4,0.3,0.1,0.2);
- temp->setShine(5);
- Objects.push_back(temp);
- point point1,point2, point3;
- point1.x = 50;
- point1.y = 30;
- point1.z = 0;
- point2.x = 70;
- point2.y = 60;
- point2.z = 0;
- point3.x = 50;
- point3.y = 45;
- point3.z = 50;
- temp = new Triangle(point1, point2, point3);
- temp->setColor(1,0,0);
- temp->setCoefficients(0.4,0.2,0.1,0.3);
- temp->setShine(5);
- Objects.push_back(temp);
- double* C1= new double[10];
- C1[0] = 1;
- C1[1] = 1;
- C1[2] = 1;
- C1[3] = 0;
- C1[4] = 0;
- C1[5] = 0;
- C1[6] =0;
- C1[7] =0;
- C1[8] = 0;
- C1[9] = -100;
- point Ref;
- Ref.x =0;
- Ref.y = 0;
- Ref.z = 0;
- temp = new General(C1,Ref,0,0,20);
- temp->setColor(0,1,0);
- temp->setCoefficients(0.4,0.2,0.1,0.3);
- temp->setShine(10);
- Objects.push_back(temp);
- point light1;
- light1.x = -50;
- light1.y = 50;
- light1.z = 50;
- lights.push_back(light1);
- temp = new Floor(1000,20);
- temp->setCoefficients(0.4,0.2,0.2,0.2);
- temp->setShine(1);
- Objects.push_back(temp);
- }
- int main(int argc, char **argv){
- loadTestData();
- 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
- point Start;
- Start.x = 0;
- Start.y = 100;
- Start.z = 10;
- point Dir;
- Dir.x = 0;
- Dir.y = 1;
- Dir.z = 0;
- Ray ray1(Start,Dir);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement