/*
* 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;
}