void eterm_show(int m, cmulti **x, func_t *fF, int bmax, int kappa) { int kmax,k,db=64; int *b=NULL,tau; func_t *fJ=NULL; cmulti **y=NULL; rmulti **e=NULL,**eps=NULL,**em=NULL,**r=NULL,*rmax=NULL,**p=NULL; kmax=(bmax-64)/db; if(kmax<0){ kmax=2; } tau=cvec_get_exp_max(m,x); printf("tau=%d\n",tau); fJ=func_grad(func_retain(fF),func_var1_list(m)); CVA(y,m); RVA(e,kmax); RVA(eps,kmax); RVA(em,kmax); RVA(r,kmax); RVA(p,kmax); RA(rmax); b=ivec_allocate(kmax); b[0]=53; for(k=1; k<kmax; k++){ b[k]=(k-1)*db+64; } for(k=0; k<kmax; k++){ printf("b=%4d ",b[k]); set_default_prec(b[k]); rset_d(eps[k],1); rmul_2exp(eps[k],eps[k],-b[k]+tau); mpfr_printf("2^(-b+tau)=%8.1Re ",eps[k]); cvec_round(m,y,b[k]); csolve_newton_map(m,y,x,fF,fJ); csolve_newton_e_norm(e[k],m,y,x,fF,fJ,bmax*4); if(rgt(eps[k],e[k])){ printf("> "); }else{ printf("< "); } mpfr_printf("e=%8.1Re ",e[k]); rset_d(em[k],1); rmul_2exp(em[k],em[k],-b[k]+tau+kappa); if(rgt(e[k],em[k])){ printf("> "); }else{ printf("< "); } mpfr_printf("em=%8.1Re ",em[k]); rlog2(p[k],e[k]); rsub_d1(p[k],tau,p[k]); rsub_d1(p[k],b[k],p[k]); mpfr_printf("b-tau+log2(e)=%+6.2Rf ",p[k]); rlog2(r[k],e[k]); rsub_d1(r[k],tau,r[k]); rdiv_d2(r[k],r[k],b[k]); rsub_d1(r[k],1,r[k]); mpfr_printf("κ=1-(tau-log2(e))/b=%+.10Rf ",r[k]); printf("\n"); } rvec_max(rmax,kmax,p); mpfr_printf("cancel bits=%+.2Rf\n",rmax); rvec_max(rmax,kmax,r); mpfr_printf("κ_max=%+.10Rf\n",rmax); // done fJ=func_del(fJ); b=ivec_free(b); CVF(y,m); RVF(e,kmax); RVF(eps,kmax); RVF(em,kmax); RVF(r,kmax); RVF(p,kmax); RF(rmax); }
int main () { // start GL context and O/S window using the GLFW helper library if (!glfwInit ()) { fprintf (stderr, "ERROR: could not start GLFW3\n"); return 1; } // uncomment these lines if on Apple OS X glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); GLFWwindow* window = glfwCreateWindow (640, 480, "Cube to Sphere", NULL, NULL); if (!window) { fprintf (stderr, "ERROR: could not open window with GLFW3\n"); glfwTerminate(); return 1; } GLFWwindow* window2 = glfwCreateWindow (640, 480, "Just checking", NULL, NULL); if (!window2) { fprintf (stderr, "ERROR: could not open window with GLFW3\n"); glfwTerminate(); return 1; } glfwMakeContextCurrent (window); //start GLEW extension handler glewExperimental = GL_TRUE; glewInit (); // get version info const GLubyte* renderer = glGetString (GL_RENDERER); // get renderer string const GLubyte* version = glGetString (GL_VERSION); // version as a string printf ("Renderer: %s\n", renderer); printf ("OpenGL version supported %s\n", version); //CLGLUtils::init(); boost::compute::context context; try { context = boost::compute::opengl_create_shared_context(); } catch (std::exception e) { std::cerr<<"Failed to initialize a CLGL context"<<e.what()<<std::endl; exit(0); } // tell GL to only draw onto a pixel if the shape is closer to the viewer glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" // OTHER STUFF GOES HERE NEXT float points[] = { -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f }; GLuint vbo; glGenBuffers (1, &vbo); glBindBuffer (GL_ARRAY_BUFFER, vbo); glBufferData (GL_ARRAY_BUFFER, 3 * 36 * sizeof (float), &points, GL_STATIC_DRAW); GLuint vao; glGenVertexArrays (1, &vao); glBindVertexArray (vao); glEnableVertexAttribArray (0); glBindBuffer (GL_ARRAY_BUFFER, vbo); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); //Create Cube map GLuint cube_map_texture; create_cube_map ((resource_dir+"negz.jpg").c_str(), (resource_dir+"posz.jpg").c_str(), (resource_dir+"posy.jpg").c_str(), (resource_dir+"negy.jpg").c_str(), (resource_dir+"negx.jpg").c_str(), (resource_dir+"posx.jpg").c_str(), &cube_map_texture); boost::shared_ptr<boost::compute::opengl_texture> cl_cube_map_texture; try { cl_cube_map_texture = boost::shared_ptr<boost::compute::opengl_texture>(new boost::compute::opengl_texture(context,GL_TEXTURE_2D_ARRAY,0,cube_map_texture,boost::compute::memory_object::mem_flags::read_only)); } catch ( const std::exception& e ) { std::cerr << e.what() << std::endl; } const char* vertex_shader = "#version 400\n" "in vec3 vp;" "uniform mat4 P, V;" // "uniform vec3 vertOut;" "out vec3 texcoords;" "vec3 newP;" "void main () {" " texcoords = vp;" // " vertOut = vp;" " gl_Position = P * V * vec4 (vp, 1.0);" "}"; const char* fragment_shader = loadShader(resource_dir+"fragmentShader.frag").c_str(); /*"#version 400\n" "in vec3 texcoords;" "uniform samplerCube cube_texture;" "out vec4 frag_colour;" "vec4 cubeToLatLon(samplerCube cubemap, vec3 inUV) {" "vec3 cubmapTexCoords;" //"cubmapTexCoords.x = inUV.x*sqrt(1 - ( (inUV.y * inUV.y)/2 ) - ( (inUV.z * inUV.z)/2 ) + ( ( (inUV.y * inUV.y) * (inUV.z * inUV.z))/3));" "cubmapTexCoords.x = inUV.x;" //"cubmapTexCoords.y= inUV.y*sqrt(1 - ( (inUV.z * inUV.z)/2 ) - ( (inUV.x * inUV.x)/2 ) + ( ( (inUV.z * inUV.z) * (inUV.x * inUV.x))/3));" "cubmapTexCoords.y = inUV.y;" "cubmapTexCoords.z = inUV.z*sqrt(1 - ( (inUV.x * inUV.x)/2 ) - ( (inUV.y * inUV.y)/2 ) + ( ( (inUV.x * inUV.x) * (inUV.y * inUV.y))/3));" //"cubmapTexCoords.z = inUV.z;" "return texture(cubemap, cubmapTexCoords);" "}" "void main () {" //" frag_colour = texture (cube_texture, texcoords);" " frag_colour = cubeToLatLon (cube_texture, texcoords);" "}";*/ GLuint vs = glCreateShader (GL_VERTEX_SHADER); glShaderSource (vs, 1, &vertex_shader, NULL); glCompileShader (vs); GLuint fs = glCreateShader (GL_FRAGMENT_SHADER); glShaderSource (fs, 1, &fragment_shader, NULL); glCompileShader (fs); GLuint cube_sp = glCreateProgram (); glAttachShader (cube_sp, fs); glAttachShader (cube_sp, vs); glLinkProgram (cube_sp); //*-----------------------------Compile Shaders for second window - square --------*/ glfwMakeContextCurrent(window2); //start GLEW extension handler glewExperimental = GL_TRUE; glewInit (); glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" float squarePoints[] = { -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f }; GLfloat texcoords[] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; GLuint vbo_square; glGenBuffers (1, &vbo_square); glBindBuffer (GL_ARRAY_BUFFER, vbo_square); glBufferData (GL_ARRAY_BUFFER, 3 * 6 * sizeof (float), &squarePoints, GL_STATIC_DRAW); GLuint texcoords_vbo; glGenBuffers (1, &texcoords_vbo); glBindBuffer (GL_ARRAY_BUFFER, texcoords_vbo); glBufferData (GL_ARRAY_BUFFER, 12 * sizeof (GLfloat), texcoords, GL_STATIC_DRAW); GLuint vao_square; glGenVertexArrays (1, &vao_square); glBindVertexArray (vao_square); glBindBuffer (GL_ARRAY_BUFFER, vbo_square); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glBindBuffer (GL_ARRAY_BUFFER, texcoords_vbo); glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 0, NULL); // normalise! glEnableVertexAttribArray (0); glEnableVertexAttribArray (1); GLuint square_sp = create_programme_from_files((resource_dir+"square.vert").c_str(), (resource_dir+"square.frag").c_str()); GLuint tex; assert (load_texture ((resource_dir+"negz.jpg").c_str(), &tex)); //*----------------------------------------------------------------------------------*/ glfwMakeContextCurrent (window); int cube_V_location = glGetUniformLocation (cube_sp, "V"); int cube_P_location = glGetUniformLocation (cube_sp, "P"); //int cube_vertOut = glGetUniformLocation (cube_sp, "vertOut"); /*-------------------------------CREATE GLOBAL CAMERA--------------------------------*/ #define ONE_DEG_IN_RAD (2.0 * M_PI) / 360.0 // 0.017444444 // input variables float near = 0.1f; // clipping plane float far = 100.0f; // clipping plane float fovy = 80.0f; // 67 degrees float aspect = (float)g_gl_width / (float)g_gl_height; // aspect ratio proj_mat = perspective (fovy, aspect, near, far); float cam_speed = 3.0f; // 1 unit per second float cam_heading_speed = 50.0f; // 30 degrees per second float cam_heading = 0.0f; // y-rotation in degrees mat4 T = translate (identity_mat4 (), vec3 (-cam_pos.v[0], -cam_pos.v[1], -cam_pos.v[2])); mat4 R = rotate_y_deg (identity_mat4 (), -cam_heading); versor q = quat_from_axis_deg (-cam_heading, 0.0f, 1.0f, 0.0f); view_mat = R * T; // keep track of some useful vectors that can be used for keyboard movement vec4 fwd (0.0f, 0.0f, -1.0f, 0.0f); vec4 rgt (1.0f, 0.0f, 0.0f, 0.0f); vec4 up (0.0f, 1.0f, 0.0f, 0.0f); /*---------------------------SET RENDERING DEFAULTS---------------------------*/ glUseProgram (cube_sp); glUniformMatrix4fv (cube_V_location, 1, GL_FALSE, R.m); glUniformMatrix4fv (cube_P_location, 1, GL_FALSE, proj_mat.m); // unique model matrix for each sphere mat4 model_mat = identity_mat4 (); glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CCW); // set counter-clock-wise vertex order to mean the front glClearColor (0.2, 0.2, 0.2, 1.0); // grey background to help spot mistakes glViewport (0, 0, g_gl_width, g_gl_height); while (!glfwWindowShouldClose (window) && !glfwWindowShouldClose (window2)) { // update timers static double previous_seconds = glfwGetTime (); double current_seconds = glfwGetTime (); double elapsed_seconds = current_seconds - previous_seconds; previous_seconds = current_seconds; //_update_fps_counter (window); // wipe the drawing surface clear glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // render a sky-box using the cube-map texture glDepthMask (GL_FALSE); glUseProgram (cube_sp); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_CUBE_MAP, cube_map_texture); glBindVertexArray (vao); glDrawArrays (GL_TRIANGLES, 0, 36); glDepthMask (GL_TRUE); //*---------------------------------Display for second window-------------------*/ glfwMakeContextCurrent (window2); glUseProgram (square_sp); int cubemap_vert = glGetUniformLocation (square_sp, "cubeMap_texcoords"); glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CCW); // set counter-clock-wise vertex order to mean the front glClearColor (0.3, 0.2, 0.3, 1.0); // grey background to help spot mistakes glViewport (0, 0, g_gl_width, g_gl_height); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDepthMask (GL_FALSE); glUseProgram (square_sp); glBindVertexArray (vao_square); glDrawArrays (GL_TRIANGLES, 0, 6); glDepthMask (GL_TRUE); //*------------------------------GO back to cubemap window--------------------*/ glfwMakeContextCurrent (window); // update other events like input handling glfwPollEvents (); // control keys bool cam_moved = false; vec3 move (0.0, 0.0, 0.0); float cam_yaw = 0.0f; // y-rotation in degrees float cam_pitch = 0.0f; float cam_roll = 0.0; if (glfwGetKey (window, GLFW_KEY_A)) { move.v[0] -= cam_speed * elapsed_seconds; cam_moved = true; print(move); } if (glfwGetKey (window, GLFW_KEY_D)) { move.v[0] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_Q)) { move.v[1] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_E)) { move.v[1] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_W)) { move.v[2] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_S)) { move.v[2] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_LEFT)) { cam_yaw += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_yaw = quat_from_axis_deg ( cam_yaw, up.v[0], up.v[1], up.v[2] ); q = q_yaw * q; } if (glfwGetKey (window, GLFW_KEY_RIGHT)) { cam_yaw -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_yaw = quat_from_axis_deg ( cam_yaw, up.v[0], up.v[1], up.v[2] ); q = q_yaw * q; } if (glfwGetKey (window, GLFW_KEY_UP)) { cam_pitch += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_pitch = quat_from_axis_deg ( cam_pitch, rgt.v[0], rgt.v[1], rgt.v[2] ); q = q_pitch * q; } if (glfwGetKey (window, GLFW_KEY_DOWN)) { cam_pitch -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_pitch = quat_from_axis_deg ( cam_pitch, rgt.v[0], rgt.v[1], rgt.v[2] ); q = q_pitch * q; } if (glfwGetKey (window, GLFW_KEY_Z)) { cam_roll -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_roll = quat_from_axis_deg ( cam_roll, fwd.v[0], fwd.v[1], fwd.v[2] ); q = q_roll * q; } if (glfwGetKey (window, GLFW_KEY_C)) { cam_roll += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_roll = quat_from_axis_deg ( cam_roll, fwd.v[0], fwd.v[1], fwd.v[2] ); q = q_roll * q; } // update view matrix if (cam_moved) { cam_heading += cam_yaw; // re-calculate local axes so can move fwd in dir cam is pointing R = quat_to_mat4 (q); fwd = R * vec4 (0.0, 0.0, -1.0, 0.0); rgt = R * vec4 (1.0, 0.0, 0.0, 0.0); up = R * vec4 (0.0, 1.0, 0.0, 0.0); cam_pos = cam_pos + vec3 (fwd) * -move.v[2]; cam_pos = cam_pos + vec3 (up) * move.v[1]; cam_pos = cam_pos + vec3 (rgt) * move.v[0]; mat4 T = translate (identity_mat4 (), vec3 (cam_pos)); view_mat = inverse (R) * inverse (T); //std::cout<<inverse(R).m<<std::endl; // cube-map view matrix has rotation, but not translation glUseProgram (cube_sp); glUniformMatrix4fv (cube_V_location, 1, GL_FALSE, inverse (R).m); } if (GLFW_PRESS == glfwGetKey (window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (window, 1); } if (GLFW_PRESS == glfwGetKey (window2, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (window2, 1); } // put the stuff we've been drawing onto the display glfwSwapBuffers (window); glfwMakeContextCurrent (window2); glfwSwapBuffers (window2); glfwMakeContextCurrent (window); } // close GL context and any other GLFW resources glfwTerminate(); return 0; }
int main () { // start GL context with helper libraries assert (glfwInit ()); /* We must specify 3.2 core if on Apple OS X -- other O/S can specify anything here. I defined 'APPLE' in the makefile for OS X */ #ifdef APPLE glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); #endif GLFWwindow* window = glfwCreateWindow ( g_viewport_width, g_viewport_height, "GUI Panels", NULL, NULL); glfwSetWindowSizeCallback (window, glfw_window_size_callback); glfwMakeContextCurrent (window); glewExperimental = GL_TRUE; glewInit (); const GLubyte* renderer = glGetString (GL_RENDERER); // get renderer string const GLubyte* version = glGetString (GL_VERSION); // version as a string printf ("Renderer: %s\n", renderer); printf ("OpenGL version supported %s\n", version); // create a 2d panel. from 2 triangles = 6 xy coords. float points[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f }; // for ground plane we can just re-use panel points but y is now z GLuint vp_vbo, vao; glGenBuffers (1, &vp_vbo); glBindBuffer (GL_ARRAY_BUFFER, vp_vbo); glBufferData (GL_ARRAY_BUFFER, sizeof (points), points, GL_STATIC_DRAW); glGenVertexArrays (1, &vao); glBindVertexArray (vao); // note: vertex buffer is already bound glVertexAttribPointer (0, 2, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (0); // create a 3d camera to move in 3d so that we can tell that the panel is 2d // keep track of some useful vectors that can be used for keyboard movement vec4 fwd (0.0f, 0.0f, -1.0f, 0.0f); vec4 rgt (1.0f, 0.0f, 0.0f, 0.0f); vec4 up (0.0f, 1.0f, 0.0f, 0.0f); vec3 cam_pos (0.0f, 1.0f, 5.0f); mat4 T_inv = translate (identity_mat4 (), cam_pos); // point slightly downwards to see the plane versor quaternion = quat_from_axis_deg (0.0f, 1.0f, 0.0f, 0.0f); mat4 R_inv = quat_to_mat4 (quaternion); // combine the inverse rotation and transformation to make a view matrix V = inverse (R_inv) * inverse (T_inv); // projection matrix P = perspective ( 67.0f, (float)g_viewport_width / (float)g_viewport_height, 0.1f, 100.0f); const float cam_speed = 3.0f; // 1 unit per second const float cam_heading_speed = 50.0f; // 30 degrees per second create_ground_plane_shaders (); create_gui_shaders (); // textures for ground plane and gui GLuint gp_tex, gui_tex; assert (load_texture ("tile2-diamonds256x256.png", &gp_tex)); assert (load_texture ("skulluvmap.png", &gui_tex)); // rendering defaults glDepthFunc (GL_LESS); // set depth function but don't enable yet glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CCW); // GL_CCW for counter clock-wise // absolute panel dimensions in pixels const float panel_width = 256.0f; const float panel_height = 256.0f; glViewport (0, 0, g_viewport_width, g_viewport_height); // start main rendering loop while (!glfwWindowShouldClose (window)) { // update timers static double previous_seconds = glfwGetTime (); double current_seconds = glfwGetTime (); double elapsed_seconds = current_seconds - previous_seconds; previous_seconds = current_seconds; bool cam_moved = false; vec3 move (0.0, 0.0, 0.0); // wipe the drawing surface clear glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // draw ground plane. note: depth test is enabled here glEnable (GL_DEPTH_TEST); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, gp_tex); glUseProgram (gp_sp); glBindVertexArray (vao); glDrawArrays (GL_TRIANGLES, 0, 6); // draw GUI panel. note: depth test is disabled here and drawn AFTER scene glDisable (GL_DEPTH_TEST); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, gui_tex); glUseProgram (gui_sp); // resize panel to size in pixels float x_scale = panel_width / g_viewport_width; float y_scale = panel_height / g_viewport_height; glUniform2f (gui_scale_loc, x_scale, y_scale); glBindVertexArray (vao); glDrawArrays (GL_TRIANGLES, 0, 6); // update other events like input handling glfwPollEvents (); if (GLFW_PRESS == glfwGetKey (window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (window, 1); } float cam_yaw = 0.0f; // y-rotation in degrees float cam_pitch = 0.0f; float cam_roll = 0.0; if (glfwGetKey (window, GLFW_KEY_A)) { move.v[0] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_D)) { move.v[0] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_Q)) { move.v[1] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_E)) { move.v[1] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_W)) { move.v[2] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_S)) { move.v[2] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (window, GLFW_KEY_LEFT)) { cam_yaw += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_yaw = quat_from_axis_deg (cam_yaw, up.v[0], up.v[1], up.v[2]); quaternion = q_yaw * quaternion; } if (glfwGetKey (window, GLFW_KEY_RIGHT)) { cam_yaw -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_yaw = quat_from_axis_deg (cam_yaw, up.v[0], up.v[1], up.v[2]); quaternion = q_yaw * quaternion; } if (glfwGetKey (window, GLFW_KEY_UP)) { cam_pitch += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_pitch = quat_from_axis_deg ( cam_pitch, rgt.v[0], rgt.v[1], rgt.v[2]); quaternion = q_pitch * quaternion; } if (glfwGetKey (window, GLFW_KEY_DOWN)) { cam_pitch -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_pitch = quat_from_axis_deg ( cam_pitch, rgt.v[0], rgt.v[1], rgt.v[2]); quaternion = q_pitch * quaternion; } if (glfwGetKey (window, GLFW_KEY_Z)) { cam_roll -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_roll = quat_from_axis_deg ( cam_roll, fwd.v[0], fwd.v[1], fwd.v[2]); quaternion = q_roll * quaternion; } if (glfwGetKey (window, GLFW_KEY_C)) { cam_roll += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_roll = quat_from_axis_deg ( cam_roll, fwd.v[0], fwd.v[1], fwd.v[2]); quaternion = q_roll * quaternion; } // update view matrix if (cam_moved) { // re-calculate local axes so can move fwd in dir cam is pointing R_inv = quat_to_mat4 (quaternion); fwd = R_inv * vec4 (0.0, 0.0, -1.0, 0.0); rgt = R_inv * vec4 (1.0, 0.0, 0.0, 0.0); up = R_inv * vec4 (0.0, 1.0, 0.0, 0.0); cam_pos = cam_pos + vec3 (fwd) * -move.v[2]; cam_pos = cam_pos + vec3 (up) * move.v[1]; cam_pos = cam_pos + vec3 (rgt) * move.v[0]; T_inv = translate (identity_mat4 (), cam_pos); V = inverse (R_inv) * inverse (T_inv); glUseProgram (gp_sp); glUniformMatrix4fv (gp_V_loc, 1, GL_FALSE, V.m); } // put the stuff we've been drawing onto the display glfwSwapBuffers (window); } // done glfwTerminate(); return 0; }
int main () { /*--------------------------------START OPENGL--------------------------------*/ assert (restart_gl_log ()); // start GL context and O/S window using the GLFW helper library assert (start_gl ()); // set a function to be called when the mouse is clicked glfwSetMouseButtonCallback (g_window, glfw_mouse_click_callback); /*------------------------------CREATE GEOMETRY-------------------------------*/ GLfloat* vp = NULL; // array of vertex points GLfloat* vn = NULL; // array of vertex normals GLfloat* vt = NULL; // array of texture coordinates int g_point_count = 0; assert (load_obj_file (MESH_FILE, vp, vt, vn, g_point_count)); GLuint vao; glGenVertexArrays (1, &vao); glBindVertexArray (vao); GLuint points_vbo; if (NULL != vp) { glGenBuffers (1, &points_vbo); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glBufferData ( GL_ARRAY_BUFFER, 3 * g_point_count * sizeof (GLfloat), vp, GL_STATIC_DRAW ); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (0); } /*-------------------------------CREATE SHADERS-------------------------------*/ GLuint shader_programme = create_programme_from_files ( VERTEX_SHADER_FILE, FRAGMENT_SHADER_FILE ); int model_mat_location = glGetUniformLocation (shader_programme, "model"); int view_mat_location = glGetUniformLocation (shader_programme, "view"); int proj_mat_location = glGetUniformLocation (shader_programme, "proj"); int blue_location = glGetUniformLocation (shader_programme, "blue"); /*-------------------------------CREATE CAMERA--------------------------------*/ #define ONE_DEG_IN_RAD (2.0 * M_PI) / 360.0 // 0.017444444 // input variables float near = 0.1f; // clipping plane float far = 100.0f; // clipping plane float fovy = 67.0f; // 67 degrees float aspect = (float)g_gl_width / (float)g_gl_height; // aspect ratio proj_mat = perspective (fovy, aspect, near, far); float cam_speed = 3.0f; // 1 unit per second float cam_heading_speed = 50.0f; // 30 degrees per second float cam_heading = 0.0f; // y-rotation in degrees mat4 T = translate ( identity_mat4 (), vec3 (-cam_pos.v[0], -cam_pos.v[1], -cam_pos.v[2]) ); mat4 R = rotate_y_deg (identity_mat4 (), -cam_heading); versor q = quat_from_axis_deg (-cam_heading, 0.0f, 1.0f, 0.0f); view_mat = R * T; // keep track of some useful vectors that can be used for keyboard movement vec4 fwd (0.0f, 0.0f, -1.0f, 0.0f); vec4 rgt (1.0f, 0.0f, 0.0f, 0.0f); vec4 up (0.0f, 1.0f, 0.0f, 0.0f); /*---------------------------SET RENDERING DEFAULTS---------------------------*/ glUseProgram (shader_programme); glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m); glUniformMatrix4fv (proj_mat_location, 1, GL_FALSE, proj_mat.m); // unique model matrix for each sphere mat4 model_mats[NUM_SPHERES]; for (int i = 0; i < NUM_SPHERES; i++) { model_mats[i] = translate (identity_mat4 (), sphere_pos_wor[i]); } glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CCW); // set counter-clock-wise vertex order to mean the front glClearColor (0.2, 0.2, 0.2, 1.0); // grey background to help spot mistakes glViewport (0, 0, g_gl_width, g_gl_height); /*-------------------------------RENDERING LOOP-------------------------------*/ while (!glfwWindowShouldClose (g_window)) { // update timers static double previous_seconds = glfwGetTime (); double current_seconds = glfwGetTime (); double elapsed_seconds = current_seconds - previous_seconds; previous_seconds = current_seconds; _update_fps_counter (g_window); // wipe the drawing surface clear glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram (shader_programme); glBindVertexArray (vao); for (int i = 0; i < NUM_SPHERES; i++) { if (g_selected_sphere == i) { glUniform1f (blue_location, 1.0f); } else { glUniform1f (blue_location, 0.0f); } glUniformMatrix4fv (model_mat_location, 1, GL_FALSE, model_mats[i].m); glDrawArrays (GL_TRIANGLES, 0, g_point_count); } // update other events like input handling glfwPollEvents (); // control keys bool cam_moved = false; vec3 move (0.0, 0.0, 0.0); float cam_yaw = 0.0f; // y-rotation in degrees float cam_pitch = 0.0f; float cam_roll = 0.0; if (glfwGetKey (g_window, GLFW_KEY_A)) { move.v[0] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_D)) { move.v[0] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_Q)) { move.v[1] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_E)) { move.v[1] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_W)) { move.v[2] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_S)) { move.v[2] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_LEFT)) { cam_yaw += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_yaw = quat_from_axis_deg ( cam_yaw, up.v[0], up.v[1], up.v[2] ); q = q_yaw * q; } if (glfwGetKey (g_window, GLFW_KEY_RIGHT)) { cam_yaw -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_yaw = quat_from_axis_deg ( cam_yaw, up.v[0], up.v[1], up.v[2] ); q = q_yaw * q; } if (glfwGetKey (g_window, GLFW_KEY_UP)) { cam_pitch += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_pitch = quat_from_axis_deg ( cam_pitch, rgt.v[0], rgt.v[1], rgt.v[2] ); q = q_pitch * q; } if (glfwGetKey (g_window, GLFW_KEY_DOWN)) { cam_pitch -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_pitch = quat_from_axis_deg ( cam_pitch, rgt.v[0], rgt.v[1], rgt.v[2] ); q = q_pitch * q; } if (glfwGetKey (g_window, GLFW_KEY_Z)) { cam_roll -= cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_roll = quat_from_axis_deg ( cam_roll, fwd.v[0], fwd.v[1], fwd.v[2] ); q = q_roll * q; } if (glfwGetKey (g_window, GLFW_KEY_C)) { cam_roll += cam_heading_speed * elapsed_seconds; cam_moved = true; versor q_roll = quat_from_axis_deg ( cam_roll, fwd.v[0], fwd.v[1], fwd.v[2] ); q = q_roll * q; } // update view matrix if (cam_moved) { // re-calculate local axes so can move fwd in dir cam is pointing R = quat_to_mat4 (q); fwd = R * vec4 (0.0, 0.0, -1.0, 0.0); rgt = R * vec4 (1.0, 0.0, 0.0, 0.0); up = R * vec4 (0.0, 1.0, 0.0, 0.0); cam_pos = cam_pos + vec3 (fwd) * -move.v[2]; cam_pos = cam_pos + vec3 (up) * move.v[1]; cam_pos = cam_pos + vec3 (rgt) * move.v[0]; mat4 T = translate (identity_mat4 (), vec3 (cam_pos)); view_mat = inverse (R) * inverse (T); glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m); } if (GLFW_PRESS == glfwGetKey (g_window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (g_window, 1); } // put the stuff we've been drawing onto the display glfwSwapBuffers (g_window); } // close GL context and any other GLFW resources glfwTerminate(); return 0; }