#include #ifdef NEEDGLEE #include "GLee.h" #endif #include "openglcanvas.h" #include #ifdef WINDOWS #include #define GET_WORKDIR _getcwd #else #include #define GET_WORKDIR getcwd #endif #include // for fstat #include // for fstat #define PROGNAME "pano_interface" #define INPUT_IMAGE_FILE "input_images/image_4_input.pnm" #define VERT_SHADER_FILE "shaders/test_vertex_shader.vert" #define FRAG_SHADER_FILE "shaders/fragment_shader.frag" OpenGLCanvas::OpenGLCanvas(QWidget *parent) : QGLWidget(parent) { setFormat(QGL::DoubleBuffer | QGL::DepthBuffer); fov = 60.f; scale = 1.0f; center_lambda = 0.f; center_phi = 0.f; fov_scale_relation = "Square Root"; visualization = "Perspective"; time_frames = 0; time_timer.setInterval(0); connect(&time_timer, SIGNAL(timeout()), this, SLOT(slotTimer())); time_start = time_time.time(); } void OpenGLCanvas::slotTimer(void) { updateGL(); } void OpenGLCanvas::change_fov(double f){ if (fov!=f && f>=1.f && f<=360.f) fov = f; if (fov<60.f) scale = 1.f; else if (fov>295.f) scale = 0.02f; else { if (fov_scale_relation == "Square Root") scale = sqrt((300.f-fov)/240.f); else if (fov_scale_relation == "Linear") scale = (300.f-fov)/240.f; else if (fov_scale_relation == "Square Power") scale = powf((300.f-fov)/240.f,2); else if (fov_scale_relation == "Cubic Power") scale = powf((300.f-fov)/240.f,3); else if (fov_scale_relation == "Logarithm") scale = log(exp(1.f) + (1.f-exp(1.f))*(fov-60.f)/240.f); } // scale = 0.3f; updateGL(); } //void OpenGLCanvas::change_scale(double s){ // if (scale!=s && s>=0.0 && s<=1.0) scale = s; // updateGL(); //} void OpenGLCanvas::change_center_lambda(double lambda){ if (center_lambda!=lambda && lambda>=-3.14f && lambda<=3.14f) { center_lambda = lambda; updateGL(); } } void OpenGLCanvas::change_center_phi(double phi){ if (center_phi!=phi && phi>=-1.57f && phi<=1.57f) { center_phi = phi; updateGL(); } } void OpenGLCanvas::change_fov_scale_relation(QString name){ fov_scale_relation = name; if (fov<60.f) scale = 1.f; else if (fov>295.f) scale = 0.01f; else{ if (fov_scale_relation == "Square Root") scale = sqrt((300.f-fov)/240.f); else if (fov_scale_relation == "Linear") scale = (300.f-fov)/240.f; else if (fov_scale_relation == "Square Power") scale = powf((300.f-fov)/240.f,2); else if (fov_scale_relation == "Cubic Power") scale = powf((300.f-fov)/240.f,3); else if (fov_scale_relation == "Logarithm") scale = log(exp(1.f) + (1.f-exp(1.f))*(fov-60.f)/240.f); } updateGL(); } void OpenGLCanvas::change_visualization(QString name){ visualization = name; updateGL(); } void OpenGLCanvas::load_image(const char *new_image){ const char * const progname=(char*)(PROGNAME); int textureSize=getTextureSize(progname,new_image); unsigned char * textureBytes=(unsigned char*)malloc(textureSize); int width,height; readTextureBytes(progname,new_image,textureBytes,&width,&height); glPixelStorei(GL_UNPACK_ALIGNMENT,1); GLuint tex; glGenTextures(1,&tex); glBindTexture(GL_TEXTURE_2D,tex); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D,0, GL_RGB, width,height,0,GL_RGB,GL_UNSIGNED_BYTE,textureBytes); } void OpenGLCanvas::change_input_image(){ load_image(QFileDialog::getOpenFileName(this,tr("Choose Panorama File")).toStdString().c_str()); updateGL(); } void OpenGLCanvas::initializeGL(){ glShadeModel(GL_SMOOTH); glClearColor(1.0f,1.0f,1.0f,0.0f); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); char *input_image=(char*)malloc(512*sizeof(char*)); GET_WORKDIR(input_image,512); strcat(input_image,"/\0"); strcat(input_image,INPUT_IMAGE_FILE); #ifdef __APPLE__ const char * const progname = "PROJ_ROOT_DIR"; //const char * input_image = INPUT_IMAGE_FILE; #else // progname is a file name or a path??? const char * const progname = (char*)(PROGNAME); //const char * input_image = (char*)(INPUT_IMAGE_FILE); #endif fprintf(stderr,"progname=%s\n",progname); fprintf(stderr,"default image=%s\n",input_image); // what to do if the input file does not exist struct stat testbuf; if(stat(input_image,&testbuf)){ fprintf(stderr,"the default image file does not exist!\n"); free(input_image); load_image(QFileDialog::getOpenFileName(this,tr("Choose Panorama File")).toStdString().c_str()); }else{ load_image(input_image); } // mesh resolution int m,n; m = n = 100; //defining texture coordinates int meshNumTexCoord = m*n; float *texCoord = (float *)malloc(2*meshNumTexCoord*sizeof(float)); if (texCoord == NULL){ printf("problem allocating memory for texture coordinates \n"); } define_texture_coordinates(texCoord, m, n, -1.57f, 1.57f, -3.14f, 3.14f); //defining positions of the sphere vertices int meshNumVertices = m*n; float* positions = (float *)malloc(3*meshNumVertices*sizeof(float)); if (positions == NULL){ printf("problem allocating memory for positions \n"); } // vertex_transformation(positions, m, n, center_lambda, center_phi, fov_rads, scale); //passar pelo vertex shader load_sphere_mesh(positions, m, n); //colocar essa e funcoes para textura e triangulos no initializeGL //defining triagle indices unsigned int meshNumFaces = 2*(m-1)*(n-1); unsigned int meshNumIndices = 3*meshNumFaces; unsigned int * indices = (unsigned int *)malloc(meshNumIndices*sizeof(unsigned int)); define_triangle_indices(indices, m, n); // draw setup verticesPositions = positions; textureCoordinates = texCoord; numberOfIndices = meshNumIndices; triangleIndices = indices; free(input_image); setShaders(); } void OpenGLCanvas::define_texture_coordinates(float *texCoord, int m, int n, float min_phi, float max_phi, float min_lambda, float max_lambda){ float delta_lambda = (max_lambda-min_lambda)/(1.0*(n-1)); float delta_phi = (max_phi-min_phi)/(1.0*(m-1)); for (int i = 0; i 0) { content = (char *)malloc(sizeof(char) * (count+1)); count = fread(content,sizeof(char),count,fp); content[count] = '\0'; } fclose(fp); } } return content; } void OpenGLCanvas::setShaders() { char *vs,*fs; #ifdef GLEW_VERSION_1_5 GLenum err=glewInit(); if(err!=GLEW_OK){ fprintf(stderr,"error in GLEW initialization: %s\n",glewGetString(err)); exit(-1); } #endif GLuint v = glCreateShader(GL_VERTEX_SHADER); GLuint f = glCreateShader(GL_FRAGMENT_SHADER); char *vs_file=(char*)malloc(512*sizeof(char*)); GET_WORKDIR(vs_file,512); strcat(vs_file,"/\0"); strcat(vs_file,VERT_SHADER_FILE); fprintf(stderr,"vs_file=%s\n",vs_file); char *fs_file=(char*)malloc(512*sizeof(char*)); GET_WORKDIR(fs_file,512); strcat(fs_file,"/\0"); strcat(fs_file,FRAG_SHADER_FILE); fprintf(stderr,"fs_file=%s\n",fs_file); struct stat vs_testbuf,fs_testbuf; if(stat(vs_file,&vs_testbuf)||stat(fs_file,&fs_testbuf)){ fprintf(stderr,"a shader file does not exist!\n"); free(vs_file); free(fs_file); exit(-1); } //#ifdef __APPLE__ // in Mac //vs = textFileRead(VERT_SHADER_FILE); //fs = textFileRead(FRAG_SHADER_FILE); //#else // in Linux (I think this would also work in mac, I just need to try) vs=textFileRead(vs_file); fs=textFileRead(fs_file); //#endif const char * vv = vs; const char * ff = fs; glShaderSource(v, 1, &vv,NULL); glShaderSource(f, 1, &ff,NULL); free(vs);free(fs); free(vs_file);free(fs_file); glCompileShader(v); glCompileShader(f); GLuint p = glCreateProgram(); glAttachShader(p,v); glAttachShader(p,f); glLinkProgram(p); glUseProgram(p); } void OpenGLCanvas::paintGL(){ float fov_rads = (fov/180.f)*1.5708f; // // changing scale to generate the figures for the paper (remove it after) // scale = 0.8; // defining transformation parameters (that will be passed to the vertex shader) float extent = calculate_extent(fov_rads); float vis_mode; if (visualization=="Perspective") vis_mode=1.0; else if (visualization=="3D Sphere") vis_mode=2.0; else if (visualization=="Equi-Rectangular") vis_mode=3.0; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, 2.0/extent, 0.0, 2.0/scale, 0.0, -2.0/vis_mode); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glOrtho(0.0, 2.0/center_lambda, 0.0, 2.0/center_phi, -1.0, 1.0); // drawing the mesh glClearColor(1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_TEXTURE_2D); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glColor3f(1, 0, 0); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, 0, verticesPositions); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, textureCoordinates); glDrawElements(GL_TRIANGLES, numberOfIndices, GL_UNSIGNED_INT, triangleIndices); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); time_frames++; // if (time_frames > 0) { double dt = time_time.elapsed(); // if (dt > 0.5) { time_fps = time_frames/dt; time_frames = 0; time_time.reset(); emit fps(QString("%1 fps").arg((int)(time_fps+0.5))); printf("fps = %d ", (int)(time_fps+0.5)); // } // } }