int main() { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); GLFWwindow* window = glfwCreateWindow(800, 600, "OpengGL", nullptr, nullptr); glfwMakeContextCurrent(window); glewExperimental = GL_TRUE; glewInit(); //Create Vertex Array Object GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); //Create Vertex Buffer Object and copy data to it GLuint vbo; glGenBuffers(1, &vbo); GLfloat vertices[] = { // Position Color Texcoords -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // Top-left 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Top-right 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Bottom-right -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f // Bottom-left }; glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); //Create element array GLuint ebo; glGenBuffers(1, &ebo); GLuint elements[] = { 0,1,2, 2,3,0 }; glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW); //Create and compile vertex shader GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexSource, NULL); glCompileShader(vertexShader); //Create and compile fragment shader GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentSource, NULL); glCompileShader(fragmentShader); //Link vertex/fragment shader into shader program GLuint shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); glUseProgram(shaderProgram); // Specify the layout of the vertex data GLint posAttrib = glGetAttribLocation(shaderProgram, "position"); glEnableVertexAttribArray(posAttrib); glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 7*sizeof(float), 0); GLint colAttrib = glGetAttribLocation(shaderProgram, "color"); glEnableVertexAttribArray(colAttrib); glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 7*sizeof(float), (void*)(2*sizeof(float))); GLint texAttrib = glGetAttribLocation(shaderProgram, "texcoord"); glEnableVertexAttribArray(texAttrib); glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 7*sizeof(float), (void*)(5*sizeof(float))); //Create 2D textures GLuint textures[2]; glGenTextures(2, textures); //loading an image to be used as a texture int width, height; unsigned char* image; glActiveTexture(GL_TEXTURE0); //telling the GPU which texture unit to use glBindTexture(GL_TEXTURE_2D, textures[0]); image = SOIL_load_image("sample.png", &width, &height, 0, SOIL_LOAD_RGB); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); SOIL_free_image_data(image); //frees up memory for the image glUniform1i(glGetUniformLocation(shaderProgram, "texKitten"), 0); //texture units setting their texture in the shader //Wrapping for texture glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //(X,Y,Z) -> (S,T,R) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //downscaling texture glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //upscaling texture glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textures[1]); image = SOIL_load_image("sample02.png", &width, &height, 0, SOIL_LOAD_RGB); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); SOIL_free_image_data(image); glUniform1i(glGetUniformLocation(shaderProgram, "texPuppy"), 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); while (!glfwWindowShouldClose(window)) { glfwSwapBuffers(window); glfwPollEvents(); if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, GL_TRUE); // Draw a rectangle from the 2 triangles using 6 indices glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); } glDeleteTextures(2, textures); glDeleteProgram(shaderProgram); glDeleteShader(vertexShader); glDeleteShader(fragmentShader); glDeleteBuffers(1, &vbo); glDeleteBuffers(1, &ebo); glDeleteVertexArrays(1, &vao); glfwTerminate(); return 0; }
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { if (action != GLFW_PRESS) return; switch (key) { case GLFW_KEY_A: { animate_cursor = !animate_cursor; if (!animate_cursor) glfwSetCursor(window, NULL); break; } case GLFW_KEY_ESCAPE: { if (glfwGetInputMode(window, GLFW_CURSOR) != GLFW_CURSOR_DISABLED) { glfwSetWindowShouldClose(window, GLFW_TRUE); break; } /* FALLTHROUGH */ } case GLFW_KEY_N: glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); printf("(( cursor is normal ))\n"); break; case GLFW_KEY_D: glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); printf("(( cursor is disabled ))\n"); break; case GLFW_KEY_H: glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); printf("(( cursor is hidden ))\n"); break; case GLFW_KEY_SPACE: swap_interval = 1 - swap_interval; printf("(( swap interval: %i ))\n", swap_interval); glfwSwapInterval(swap_interval); break; case GLFW_KEY_W: wait_events = !wait_events; printf("(( %sing for events ))\n", wait_events ? "wait" : "poll"); break; case GLFW_KEY_T: track_cursor = !track_cursor; break; case GLFW_KEY_0: glfwSetCursor(window, NULL); break; case GLFW_KEY_1: glfwSetCursor(window, standard_cursors[0]); break; case GLFW_KEY_2: glfwSetCursor(window, standard_cursors[1]); break; case GLFW_KEY_3: glfwSetCursor(window, standard_cursors[2]); break; case GLFW_KEY_4: glfwSetCursor(window, standard_cursors[3]); break; case GLFW_KEY_5: glfwSetCursor(window, standard_cursors[4]); break; case GLFW_KEY_6: glfwSetCursor(window, standard_cursors[5]); break; } }
void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mode) { if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GL_TRUE); }
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; }
//Keys static void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) { //Navigation if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GL_TRUE); if(key == GLFW_KEY_W && action == GLFW_PRESS) camera.hold(Camera::FORWARD); if(key == GLFW_KEY_A && action == GLFW_PRESS) camera.hold(Camera::LEFT); if(key == GLFW_KEY_S && action == GLFW_PRESS) camera.hold(Camera::BACKWARD); if(key == GLFW_KEY_D && action == GLFW_PRESS) camera.hold(Camera::RIGHT); if(key == GLFW_KEY_Q && action == GLFW_PRESS) camera.hold(Camera::DOWN); if(key == GLFW_KEY_E && action == GLFW_PRESS) camera.hold(Camera::UP); //Looking if(key == GLFW_KEY_LEFT && action == GLFW_PRESS) camera.hold(Camera::LOOK_LEFT); if(key == GLFW_KEY_RIGHT && action == GLFW_PRESS) camera.hold(Camera::LOOK_RIGHT); if(key == GLFW_KEY_UP && action == GLFW_PRESS) camera.hold(Camera::LOOK_UP); if(key == GLFW_KEY_DOWN && action == GLFW_PRESS) camera.hold(Camera::LOOK_DOWN); if(action == GLFW_RELEASE) camera.hold(Camera::STILL); //Volume modification if(key == GLFW_KEY_F && action == GLFW_PRESS) mainProgram.simulation->addFluid(); if(key == GLFW_KEY_G && action == GLFW_PRESS) mainProgram.simulation->addForce(); if(key == GLFW_KEY_R && action == GLFW_PRESS) mainProgram.simulation->reset(); if(key == GLFW_KEY_C && action == GLFW_PRESS) mainProgram.simulation->clearEffects(); if(key == GLFW_KEY_EQUAL && action == GLFW_PRESS) { mainProgram.simulation->resize(mainProgram.simulation->getN() + 1); if(render) { mainProgram.rayCaster.setN(mainProgram.simulation->getN()); mainProgram.rayCaster.setVolume(mainProgram.simulation->getOutputVolume()); } } if(key == GLFW_KEY_MINUS && action == GLFW_PRESS) { mainProgram.simulation->resize(mainProgram.simulation->getN() - 1); if(render) { mainProgram.rayCaster.setN(mainProgram.simulation->getN()); mainProgram.rayCaster.setVolume(mainProgram.simulation->getOutputVolume()); } } //Output debug info (not used) if(key == GLFW_KEY_ENTER && action == GLFW_PRESS) mainProgram.simulation->debug(); }
void Application::closeWindow() { glfwSetWindowShouldClose(m_window,0); }
void GLFWBackendLeaveMainLoop() { glfwSetWindowShouldClose(s_pWindow, 1); }
void EGLView::end() { if(_mainWindow) glfwSetWindowShouldClose(_mainWindow,1); }
static void quit(void) { glfwSetWindowShouldClose(window, 1); }
int main() { restart_gl_log(); start_gl(); // 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" GLfloat points[] = { -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, 0.5f, 0.5f, 0.0f, 0.5f, 0.5f, 0.0f, -0.5f, 0.5f, 0.0f, -0.5f, -0.5f, 0.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 points_vbo; glGenBuffers( 1, &points_vbo ); glBindBuffer( GL_ARRAY_BUFFER, points_vbo ); glBufferData( GL_ARRAY_BUFFER, 18 * sizeof( GLfloat ), points, 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; glGenVertexArrays( 1, &vao ); glBindVertexArray( vao ); glBindBuffer( GL_ARRAY_BUFFER, points_vbo ); glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, NULL ); glBindBuffer( GL_ARRAY_BUFFER, texcoords_vbo ); glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, 0, NULL ); glEnableVertexAttribArray( 0 ); glEnableVertexAttribArray( 1 ); GLuint shader_programme = create_programme_from_files( "test_vs.glsl", "test_fs.glsl" ); #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 fov = 67.0f * ONE_DEG_IN_RAD; // convert 67 degrees to radians float aspect = (float)g_gl_width / (float)g_gl_height; // aspect ratio // matrix components float range = tan( fov * 0.5f ) * near; float Sx = ( 2.0f * near ) / ( range * aspect + range * aspect ); float Sy = near / range; float Sz = -( far + near ) / ( far - near ); float Pz = -( 2.0f * far * near ) / ( far - near ); GLfloat proj_mat[] = { Sx, 0.0f, 0.0f, 0.0f, 0.0f, Sy, 0.0f, 0.0f, 0.0f, 0.0f, Sz, -1.0f, 0.0f, 0.0f, Pz, 0.0f }; float cam_speed = 1.0f; // 1 unit per second float cam_yaw_speed = 10.0f; // 10 degrees per second float cam_pos[] = { 0.0f, 0.0f, 2.0f }; // don't start at zero, or we will be too close float cam_yaw = 0.0f; // y-rotation in degrees mat4 T = translate( identity_mat4(), vec3( -cam_pos[0], -cam_pos[1], -cam_pos[2] ) ); mat4 R = rotate_y_deg( identity_mat4(), -cam_yaw ); mat4 view_mat = R * T; mat4 model = identity_mat4(); int model_mat_location = glGetUniformLocation( shader_programme, "model" ); int view_mat_location = glGetUniformLocation( shader_programme, "view" ); int proj_mat_location = glGetUniformLocation( shader_programme, "proj" ); glUseProgram( shader_programme ); glUniformMatrix4fv( view_mat_location, 1, GL_FALSE, view_mat.m ); glUniformMatrix4fv( proj_mat_location, 1, GL_FALSE, proj_mat ); // load texture GLuint texa; ( load_texture( "blob.png", &texa ) ); GLuint texb; ( load_texture( "blob2.png", &texb ) ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glEnable( GL_BLEND ); // glDisable (GL_DEPTH_TEST); glClearColor( 0.2, 0.2, 0.2, 1.0 ); glEnable( GL_CULL_FACE ); // cull face glCullFace( GL_BACK ); // cull back face glFrontFace( GL_CCW ); // GL_CCW for counter clock-wise while ( !glfwWindowShouldClose( g_window ) ) { 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 ); glViewport( 0, 0, g_gl_width, g_gl_height ); glUseProgram( shader_programme ); glBindVertexArray( vao ); glDepthMask( GL_FALSE ); glBindTexture( GL_TEXTURE_2D, texa ); model = identity_mat4(); glUniformMatrix4fv( model_mat_location, 1, GL_FALSE, model.m ); glDrawArrays( GL_TRIANGLES, 0, 6 ); glBindTexture( GL_TEXTURE_2D, texb ); model.m[12] = 0.5; model.m[14] = 0.1; glUniformMatrix4fv( model_mat_location, 1, GL_FALSE, model.m ); glDrawArrays( GL_TRIANGLES, 0, 6 ); glDepthMask( GL_TRUE ); // update other events like input handling glfwPollEvents(); // control keys bool cam_moved = false; if ( glfwGetKey( g_window, GLFW_KEY_A ) ) { cam_pos[0] -= cam_speed * elapsed_seconds; cam_moved = true; } if ( glfwGetKey( g_window, GLFW_KEY_D ) ) { cam_pos[0] += cam_speed * elapsed_seconds; cam_moved = true; } if ( glfwGetKey( g_window, GLFW_KEY_PAGE_UP ) ) { cam_pos[1] += cam_speed * elapsed_seconds; cam_moved = true; } if ( glfwGetKey( g_window, GLFW_KEY_PAGE_DOWN ) ) { cam_pos[1] -= cam_speed * elapsed_seconds; cam_moved = true; } if ( glfwGetKey( g_window, GLFW_KEY_W ) ) { cam_pos[2] -= cam_speed * elapsed_seconds; cam_moved = true; } if ( glfwGetKey( g_window, GLFW_KEY_S ) ) { cam_pos[2] += cam_speed * elapsed_seconds; cam_moved = true; } if ( glfwGetKey( g_window, GLFW_KEY_LEFT ) ) { cam_yaw += cam_yaw_speed * elapsed_seconds; cam_moved = true; } if ( glfwGetKey( g_window, GLFW_KEY_RIGHT ) ) { cam_yaw -= cam_yaw_speed * elapsed_seconds; cam_moved = true; } // update view matrix if ( cam_moved ) { mat4 T = translate( identity_mat4(), vec3( -cam_pos[0], -cam_pos[1], -cam_pos[2] ) ); // cam translation mat4 R = rotate_y_deg( identity_mat4(), -cam_yaw ); // mat4 view_mat = R * 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; }
int main () { assert (restart_gl_log ()); // all the start-up code for GLFW and GLEW is called here assert (start_gl ()); // 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 */ GLfloat points[] = { 0.0f, 0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, -0.5f, 0.0f }; GLfloat colours[] = { 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }; GLuint points_vbo; glGenBuffers (1, &points_vbo); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), points, GL_STATIC_DRAW); /* create a second VBO, containing the array of colours. note that we could also put them both into a single vertex buffer. in this case we would use the pointer and stride parameters of glVertexAttribPointer() to describe the different data layouts */ GLuint colours_vbo; glGenBuffers (1, &colours_vbo); glBindBuffer (GL_ARRAY_BUFFER, colours_vbo); glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), colours, GL_STATIC_DRAW); /* create the VAO. we bind each VBO in turn, and call glVertexAttribPointer() to indicate where the memory should be fetched for vertex shader input variables 0, and 1, respectively. we also have to explicitly enable both 'attribute' variables. 'attribute' is the older name for vertex shader 'in' variables. */ GLuint vao; glGenVertexArrays (1, &vao); glBindVertexArray (vao); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glBindBuffer (GL_ARRAY_BUFFER, colours_vbo); glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (0); glEnableVertexAttribArray (1); char vertex_shader[1024 * 256]; char fragment_shader[1024 * 256]; assert (parse_file_into_str ("test_vs.glsl", vertex_shader, 1024 * 256)); assert (parse_file_into_str ("test_fs.glsl", fragment_shader, 1024 * 256)); GLuint vs = glCreateShader (GL_VERTEX_SHADER); const GLchar* p = (const GLchar*)vertex_shader; glShaderSource (vs, 1, &p, NULL); glCompileShader (vs); // check for compile errors int params = -1; glGetShaderiv (vs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { fprintf (stderr, "ERROR: GL shader index %i did not compile\n", vs); print_shader_info_log (vs); return 1; // or exit or something } GLuint fs = glCreateShader (GL_FRAGMENT_SHADER); p = (const GLchar*)fragment_shader; glShaderSource (fs, 1, &p, NULL); glCompileShader (fs); // check for compile errors glGetShaderiv (fs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { fprintf (stderr, "ERROR: GL shader index %i did not compile\n", fs); print_shader_info_log (fs); return 1; // or exit or something } GLuint shader_programme = glCreateProgram (); glAttachShader (shader_programme, fs); glAttachShader (shader_programme, vs); glLinkProgram (shader_programme); glGetProgramiv (shader_programme, GL_LINK_STATUS, ¶ms); if (GL_TRUE != params) { fprintf ( stderr, "ERROR: could not link shader programme GL index %i\n", shader_programme ); print_programme_info_log (shader_programme); return false; } glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CW); // GL_CCW for counter clock-wise while (!glfwWindowShouldClose (g_window)) { _update_fps_counter (g_window); // wipe the drawing surface clear glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport (0, 0, g_gl_width, g_gl_height); glUseProgram (shader_programme); glBindVertexArray (vao); // draw points 0-3 from the currently bound VAO with current in-use shader glDrawArrays (GL_TRIANGLES, 0, 3); // update other events like input handling glfwPollEvents (); 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; }
void keyboard(GLFWwindow* pWindow, int key, int codes, int action, int mods) { (void)pWindow; (void)codes; if ((key > -1) && (key <= GLFW_KEY_LAST)) { m_keyStates[key] = action; } switch (key) { default: break; case GLFW_KEY_BACKSLASH: { if (action == GLFW_PRESS) g_tweakbarQuad.MouseClick(1); else if (action == GLFW_RELEASE) g_tweakbarQuad.MouseClick(0); } break; case GLFW_KEY_SLASH: { if (action == GLFW_PRESS) g_tweakbarQuad.SetHoldingFlag(m_eyePoses[0], true); else if (action == GLFW_RELEASE) g_tweakbarQuad.SetHoldingFlag(m_eyePoses[0], false); } break; } const float yawIncr = 0.3f; if (action == GLFW_PRESS) { switch (key) { default: break; case GLFW_KEY_1: if (m_snapTurn == true) { m_chassisYaw -= yawIncr; } break; case GLFW_KEY_3: if (m_snapTurn == true) { m_chassisYaw += yawIncr; } break; case GLFW_KEY_SPACE: ovr_RecenterTrackingOrigin(g_session); break; case GLFW_KEY_R: m_chassisPos = glm::vec3(0.f, 1.f, 0.f); break; case GLFW_KEY_BACKSPACE: TogglePerfHud(); break; case GLFW_KEY_TAB: g_tweakbarQuad.m_showQuadInWorld = !g_tweakbarQuad.m_showQuadInWorld; break; case GLFW_KEY_ENTER: g_gallery.ToggleShaderWorld(); break; case GLFW_KEY_SLASH: break; case GLFW_KEY_ESCAPE: glfwSetWindowShouldClose(g_pMirrorWindow, 1); break; } } // Handle keyboard movement(WASD keys) const glm::vec3 forward(0.f, 0.f, -1.f); const glm::vec3 up(0.f, 1.f, 0.f); const glm::vec3 right(1.f, 0.f, 0.f); glm::vec3 keyboardMove(0.0f, 0.0f, 0.0f); float keyboardYaw = 0.f; if (m_keyStates['W'] != GLFW_RELEASE) { keyboardMove += forward; } if (m_keyStates['S'] != GLFW_RELEASE) { keyboardMove -= forward; } if (m_keyStates['A'] != GLFW_RELEASE) { keyboardMove -= right; } if (m_keyStates['D'] != GLFW_RELEASE) { keyboardMove += right; } if (m_keyStates['Q'] != GLFW_RELEASE) { keyboardMove -= up; } if (m_keyStates['E'] != GLFW_RELEASE) { keyboardMove += up; } if (m_keyStates[GLFW_KEY_UP] != GLFW_RELEASE) { keyboardMove += forward; } if (m_keyStates[GLFW_KEY_DOWN] != GLFW_RELEASE) { keyboardMove -= forward; } if (m_keyStates[GLFW_KEY_LEFT] != GLFW_RELEASE) { keyboardMove -= right; } if (m_keyStates[GLFW_KEY_RIGHT] != GLFW_RELEASE) { keyboardMove += right; } if (m_keyStates['1'] != GLFW_RELEASE) { keyboardYaw -= 1.f; } if (m_keyStates['3'] != GLFW_RELEASE) { keyboardYaw += 1.f; } float mag = 1.0f; if (m_keyStates[GLFW_KEY_LEFT_SHIFT] != GLFW_RELEASE) mag *= 0.1f; if (m_keyStates[GLFW_KEY_LEFT_CONTROL] != GLFW_RELEASE) mag *= 10.0f; m_keyboardMove = mag * keyboardMove; m_keyboardYaw = mag * keyboardYaw; }
// Display to an HMD with OVR SDK backend. void displayHMD() { ovrSessionStatus sessionStatus; ovr_GetSessionStatus(g_session, &sessionStatus); if (sessionStatus.HmdPresent == false) { displayMonitor(); return; } const ovrHmdDesc& hmdDesc = m_Hmd; double sensorSampleTime; // sensorSampleTime is fed into the layer later if (g_hmdVisible) { // Call ovr_GetRenderDesc each frame to get the ovrEyeRenderDesc, as the returned values (e.g. HmdToEyeOffset) may change at runtime. ovrEyeRenderDesc eyeRenderDesc[2]; eyeRenderDesc[0] = ovr_GetRenderDesc(g_session, ovrEye_Left, hmdDesc.DefaultEyeFov[0]); eyeRenderDesc[1] = ovr_GetRenderDesc(g_session, ovrEye_Right, hmdDesc.DefaultEyeFov[1]); // Get eye poses, feeding in correct IPD offset ovrVector3f HmdToEyeOffset[2] = { eyeRenderDesc[0].HmdToEyeOffset, eyeRenderDesc[1].HmdToEyeOffset }; #if 0 // Get both eye poses simultaneously, with IPD offset already included. double displayMidpointSeconds = ovr_GetPredictedDisplayTime(g_session, 0); ovrTrackingState hmdState = ovr_GetTrackingState(g_session, displayMidpointSeconds, ovrTrue); ovr_CalcEyePoses(hmdState.HeadPose.ThePose, HmdToEyeOffset, m_eyePoses); #else ovr_GetEyePoses(g_session, g_frameIndex, ovrTrue, HmdToEyeOffset, m_eyePoses, &sensorSampleTime); #endif storeHmdPose(m_eyePoses[0]); for (int eye = 0; eye < 2; ++eye) { const FBO& swapfbo = m_swapFBO[eye]; const ovrTextureSwapChain& chain = g_textureSwapChain[eye]; int curIndex; ovr_GetTextureSwapChainCurrentIndex(g_session, chain, &curIndex); GLuint curTexId; ovr_GetTextureSwapChainBufferGL(g_session, chain, curIndex, &curTexId); glBindFramebuffer(GL_FRAMEBUFFER, swapfbo.id); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, curTexId, 0); glViewport(0, 0, swapfbo.w, swapfbo.h); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_FRAMEBUFFER_SRGB); { glClearColor(0.3f, 0.3f, 0.3f, 0.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); const ovrSizei& downSize = ovr_GetFovTextureSize(g_session, ovrEyeType(eye), hmdDesc.DefaultEyeFov[eye], m_fboScale); ovrRecti vp = { 0, 0, downSize.w, downSize.h }; const int texh = swapfbo.h; vp.Pos.y = (texh - vp.Size.h) / 2; glViewport(vp.Pos.x, vp.Pos.y, vp.Size.w, vp.Size.h); // Cinemascope - letterbox bars scissoring off pixels above and below vp center const float hc = .5f * m_cinemaScope; const int scisPx = static_cast<int>(hc * static_cast<float>(vp.Size.h)); ovrRecti sp = vp; sp.Pos.y += scisPx; sp.Size.h -= 2 * scisPx; glScissor(sp.Pos.x, sp.Pos.y, sp.Size.w, sp.Size.h); glEnable(GL_SCISSOR_TEST); glEnable(GL_DEPTH_TEST); // Render the scene for the current eye const ovrPosef& eyePose = m_eyePoses[eye]; const glm::mat4 mview = makeWorldToChassisMatrix() * makeMatrixFromPose(eyePose, m_headSize); const ovrMatrix4f ovrproj = ovrMatrix4f_Projection(hmdDesc.DefaultEyeFov[eye], 0.2f, 1000.0f, ovrProjection_None); const glm::mat4 proj = makeGlmMatrixFromOvrMatrix(ovrproj); g_pScene->RenderForOneEye(glm::value_ptr(glm::inverse(mview)), glm::value_ptr(proj)); const ovrTextureSwapChain& chain = g_textureSwapChain[eye]; const ovrResult commitres = ovr_CommitTextureSwapChain(g_session, chain); if (!OVR_SUCCESS(commitres)) { LOG_ERROR("ovr_CommitTextureSwapChain returned %d", commitres); return; } } glDisable(GL_SCISSOR_TEST); // Grab a copy of the left eye's undistorted render output for presentation // to the desktop window instead of the barrel distorted mirror texture. // This blit, while cheap, could cost some framerate to the HMD. // An over-the-shoulder view is another option, at a greater performance cost. if (0) { if (eye == ovrEyeType::ovrEye_Left) { BlitLeftEyeRenderToUndistortedMirrorTexture(); } } glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); } } std::vector<const ovrLayerHeader*> layerHeaders; { // Do distortion rendering, Present and flush/sync ovrLayerEyeFov ld; ld.Header.Type = ovrLayerType_EyeFov; ld.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft; // Because OpenGL. for (int eye = 0; eye < 2; ++eye) { const FBO& swapfbo = m_swapFBO[eye]; const ovrTextureSwapChain& chain = g_textureSwapChain[eye]; ld.ColorTexture[eye] = chain; const ovrSizei& downSize = ovr_GetFovTextureSize(g_session, ovrEyeType(eye), hmdDesc.DefaultEyeFov[eye], m_fboScale); ovrRecti vp = { 0, 0, downSize.w, downSize.h }; const int texh = swapfbo.h; vp.Pos.y = (texh - vp.Size.h) / 2; ld.Viewport[eye] = vp; ld.Fov[eye] = hmdDesc.DefaultEyeFov[eye]; ld.RenderPose[eye] = m_eyePoses[eye]; ld.SensorSampleTime = sensorSampleTime; } layerHeaders.push_back(&ld.Header); // Submit layers to HMD for display ovrLayerQuad ql; if (g_tweakbarQuad.m_showQuadInWorld) { ql.Header.Type = ovrLayerType_Quad; ql.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft; // Because OpenGL. ql.ColorTexture = g_tweakbarQuad.m_swapChain; ovrRecti vp; vp.Pos.x = 0; vp.Pos.y = 0; vp.Size.w = 600; ///@todo vp.Size.h = 600; ///@todo ql.Viewport = vp; ql.QuadPoseCenter = g_tweakbarQuad.m_QuadPoseCenter; ql.QuadSize = { 1.f, 1.f }; ///@todo Pass in g_tweakbarQuad.SetHmdEyeRay(m_eyePoses[ovrEyeType::ovrEye_Left]); // Writes to m_layerQuad.QuadPoseCenter g_tweakbarQuad.DrawToQuad(); layerHeaders.push_back(&ql.Header); } } #if 0 ovrViewScaleDesc viewScaleDesc; viewScaleDesc.HmdToEyeOffset[0] = m_eyeOffsets[0]; viewScaleDesc.HmdToEyeOffset[1] = m_eyeOffsets[1]; viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.f; #endif const ovrResult result = ovr_SubmitFrame(g_session, g_frameIndex, nullptr, &layerHeaders[0], layerHeaders.size()); if (result == ovrSuccess) { g_hmdVisible = true; } else if (result == ovrSuccess_NotVisible) { g_hmdVisible = false; ///@todo Enter a lower-power, polling "no focus/HMD not worn" mode } else if (result == ovrError_DisplayLost) { LOG_INFO("ovr_SubmitFrame returned ovrError_DisplayLost"); g_hmdVisible = false; ///@todo Tear down textures and session and re-create } else { LOG_INFO("ovr_SubmitFrame returned %d", result); //g_hmdVisible = false; } // Handle OVR session events ovr_GetSessionStatus(g_session, &sessionStatus); if (sessionStatus.ShouldQuit) { glfwSetWindowShouldClose(g_pMirrorWindow, 1); } if (sessionStatus.ShouldRecenter) { ovr_RecenterTrackingOrigin(g_session); } // Blit mirror texture to monitor window if (g_hmdVisible) { glViewport(0, 0, g_mirrorWindowSz.x, g_mirrorWindowSz.y); const FBO& srcFBO = m_mirrorFBO; glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFBO.id); glBlitFramebuffer( 0, srcFBO.h, srcFBO.w, 0, 0, 0, g_mirrorWindowSz.x, g_mirrorWindowSz.y, GL_COLOR_BUFFER_BIT, GL_NEAREST); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); } else { displayMonitor(); } ++g_frameIndex; #ifdef USE_ANTTWEAKBAR if (g_tweakbarQuad.m_showQuadInWorld) { TwDraw(); } #endif }
int main () { restart_gl_log (); // use GLFW and GLEW to start GL context. see gl_utils.cpp for details start_gl (); /* create buffer of particle initial attributes and a VAO */ GLuint vao = gen_particles (); GLuint shader_programme = create_programme_from_files ( "test_vs.glsl", "test_fs.glsl"); #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 fov = 67.0f * ONE_DEG_IN_RAD; // convert 67 degrees to radians float aspect = (float)g_gl_width / (float)g_gl_height; // aspect ratio // matrix components float range = tan (fov * 0.5f) * near; float Sx = (2.0f * near) / (range * aspect + range * aspect); float Sy = near / range; float Sz = -(far + near) / (far - near); float Pz = -(2.0f * far * near) / (far - near); GLfloat proj_mat[] = { Sx, 0.0f, 0.0f, 0.0f, 0.0f, Sy, 0.0f, 0.0f, 0.0f, 0.0f, Sz, -1.0f, 0.0f, 0.0f, Pz, 0.0f }; float cam_speed = 1.0f; // 1 unit per second float cam_yaw_speed = 10.0f; // 10 degrees per second float cam_pos[] = {0.0f, 0.0f, 2.0f}; // don't start at zero, or we will be too close float cam_yaw = 0.0f; // y-rotation in degrees mat4 T = translate (identity_mat4 (), vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2])); mat4 R = rotate_y_deg (identity_mat4 (), -cam_yaw); mat4 view_mat = R * T; /* make up a world position for the emitter */ vec3 emitter_world_pos (0.0f, 0.0f, 0.0f); // locations of view and projection matrices int V_loc = glGetUniformLocation (shader_programme, "V"); assert (V_loc > -1); int P_loc = glGetUniformLocation (shader_programme, "P"); assert (P_loc > -1); int emitter_pos_wor_loc = glGetUniformLocation (shader_programme, "emitter_pos_wor"); assert (emitter_pos_wor_loc > -1); int elapsed_system_time_loc = glGetUniformLocation (shader_programme, "elapsed_system_time"); assert (elapsed_system_time_loc > -1); glUseProgram (shader_programme); glUniformMatrix4fv (V_loc, 1, GL_FALSE, view_mat.m); glUniformMatrix4fv (P_loc, 1, GL_FALSE, proj_mat); glUniform3f (emitter_pos_wor_loc, emitter_world_pos.v[0], emitter_world_pos.v[1], emitter_world_pos.v[2]); // load texture GLuint tex; if (!load_texture ("Droplet.png", &tex)) { gl_log_err ("ERROR: loading Droplet.png texture\n"); return 1; } glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CCW); // GL_CCW for counter clock-wise glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glEnable (GL_DEPTH_TEST); // enable depth-testing glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glClearColor (0.2, 0.2, 0.2, 1.0); /* MUST use this is in compatibility profile. doesn't exist in core glEnable(GL_POINT_SPRITE); */ while (!glfwWindowShouldClose (g_window)) { 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); glViewport (0, 0, g_gl_width, g_gl_height); /* Render Particles. Enabling point re-sizing in vertex shader */ glEnable (GL_PROGRAM_POINT_SIZE); glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); glEnable (GL_BLEND); glDepthMask (GL_FALSE); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, tex); glUseProgram (shader_programme); /* update time in shaders */ glUniform1f (elapsed_system_time_loc, (GLfloat)current_seconds); glBindVertexArray (vao); // draw points 0-3 from the currently bound VAO with current in-use shader glDrawArrays (GL_POINTS, 0, PARTICLE_COUNT); glDisable (GL_BLEND); glDepthMask (GL_TRUE); glDisable (GL_PROGRAM_POINT_SIZE); // update other events like input handling glfwPollEvents (); // control keys bool cam_moved = false; if (glfwGetKey (g_window, GLFW_KEY_A)) { cam_pos[0] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_D)) { cam_pos[0] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_PAGE_UP)) { cam_pos[1] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_PAGE_DOWN)) { cam_pos[1] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_W)) { cam_pos[2] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_S)) { cam_pos[2] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_LEFT)) { cam_yaw += cam_yaw_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_RIGHT)) { cam_yaw -= cam_yaw_speed * elapsed_seconds; cam_moved = true; } // update view matrix if (cam_moved) { mat4 T = translate (identity_mat4 (), vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2])); // cam translation mat4 R = rotate_y_deg (identity_mat4 (), -cam_yaw); // mat4 view_mat = R * T; glUniformMatrix4fv (V_loc, 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; }
int main(int argc, char ** argv) { game_state gamestate = {}; GLFWwindow *window = init(&gamestate); load_program_attrib_location(&gamestate); bool run = true; int max_frames_to_simulate = 2; gamestate.update = game_update_stub; gamestate.render = game_render_stub; gamestate.init = game_init_stub; gamestate.window_width_height = vec2(SCREEN_SIZE_X, SCREEN_SIZE_Y); load_game_dll(&gamestate); // glfwSetTime(0); double total_time = 0; double current_time = glfwGetTime(); double previous_time = current_time; double frame_time = 0; glfwSwapInterval(0); sh_circle testing(0, 0, 10, vec2(0, 1), vec4(1, 0, 0, 1)); while(run) { current_time = glfwGetTime(); frame_time = (current_time - previous_time); if(frame_time > 0.25) frame_time = 0.25; total_time += frame_time; previous_time = current_time; FILETIME last_write_dll = get_last_write_time("game_logic.dll"); if(CompareFileTime(&gamestate.last_write_time, &last_write_dll) != 0) { unload_game_dll(&gamestate); load_game_dll(&gamestate); } if(!gamestate.is_init) { gamestate.init(&gamestate); gamestate.is_init = 1; } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if((glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)) { run = false; glfwSetWindowShouldClose(window, true); } while(( total_time >= dt )) { gamestate.update(&gamestate, &mouse_st); total_time -= dt; } const double time_left_alpha = total_time/dt; gamestate.render(&gamestate, time_left_alpha); glfwSwapBuffers(window); glfwPollEvents(); } glfwDestroyWindow(window); return 0; }
void Window::close() { glfwSetWindowShouldClose(handler, 1); }
int main(int argc, char * argv[]) { int error = 0; /// GLFW init glfwInit(); /// GLFW window init glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", nullptr, nullptr); // Windowed //GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", glfwGetPrimaryMonitor(), nullptr); // Fullscreen glfwMakeContextCurrent(window); glewExperimental = true; glewInit(); /// float vertices[] = { // Position Color Texcoords -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // Top-left 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Top-right 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Bottom-right -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f // Bottom-left }; // ELEMENTS GLuint elements[] = { 0, 1, 2, 2, 3, 0 }; /// VERTEXT BUFFERS? GLuint vbo; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // Shaders GLint status = GL_FALSE; GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vs, NULL); glCompileShader(vertexShader); glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status); GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fs, NULL); glCompileShader(fragmentShader); glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status); GLuint shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); // FRAGMENT SHADER is allowed to write to multiple buffers, but 0 is default && there is only one output. glBindFragDataLocation(shaderProgram, 0, "outColor"); glLinkProgram(shaderProgram); glUseProgram(shaderProgram); // VAO will save any subsequent glVertexAttrib stuff. Binding it first to write to it. Bind it again to restore whatever was last written. GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); // Making a link between vertex data and attributes GLint posAttrib = glGetAttribLocation(shaderProgram, "position"); glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 7*sizeof(float), 0); glEnableVertexAttribArray(posAttrib); GLint colAttrib = glGetAttribLocation(shaderProgram, "color"); glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)(2*sizeof(float))); glEnableVertexAttribArray(colAttrib); GLint texAttrib = glGetAttribLocation(shaderProgram, "texcoord"); glEnableVertexAttribArray(texAttrib); glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)(5 * sizeof(float))); // UNIFORMS! //GLint uniColor = glGetUniformLocation(shaderProgram, "triangleColor"); //glUniform3f(uniColor, 1.0f, 0.0f, 0.0f); // ELEMENT BUFFER GLuint ebo; glGenBuffers(1, &ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW); // GL TEXTURE SETUP GLuint tex; glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); float color[] = { 1.0f, 0.0f, 0.0f, 0.0f }; glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glGenerateMipmap(GL_TEXTURE_2D); // Black/white checkerboard test image //float pixels[] = { // 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f //}; //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_FLOAT, pixels); // SOIL LOAD int width, height; unsigned char* image = SOIL_load_image("C:\\Projects\\Standalones\\GLFW_Test\\Debug\\Textures\\sample.png", &width, &height, 0, SOIL_LOAD_RGB); // SOIL_load_image("sample.png", &width, &height, 0, SOIL_LOAD_RGB); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); SOIL_free_image_data(image); // LOOP while (!glfwWindowShouldClose(window)) { //glDrawArrays(GL_TRIANGLES, 0, 3); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, GL_TRUE); glfwSwapBuffers(window); glfwPollEvents(); } glfwTerminate(); std::cout << "Hello World!" << std::endl; return 0; }
void GLFWView::setShouldClose() { glfwSetWindowShouldClose(window, true); glfwPostEmptyEvent(); }
// callback when a key is pressed void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) { /* key code goes here */ switch(key) { case GLFW_KEY_ESCAPE: glfwSetWindowShouldClose(window, GL_TRUE); break; case GLFW_KEY_Q: glfwSetWindowShouldClose(window, GL_TRUE); break; case GLFW_KEY_H: printHelp(); break; case GLFW_KEY_LEFT: c_state.arrL = (action == GLFW_RELEASE) ? 0 : 1; break; case GLFW_KEY_RIGHT: c_state.arrR = (action == GLFW_RELEASE) ? 0 : 1; break; case GLFW_KEY_UP: c_state.arrU = (action == GLFW_RELEASE) ? 0 : 1; break; case GLFW_KEY_DOWN: c_state.arrD = (action == GLFW_RELEASE) ? 0 : 1; break; case GLFW_KEY_W: c_state.gemMove[2] = (action == GLFW_RELEASE) ? 0 : 1; break; case GLFW_KEY_A: c_state.gemMove[0] = (action == GLFW_RELEASE) ? 0 : -1; break; case GLFW_KEY_S: c_state.gemMove[2] = (action == GLFW_RELEASE) ? 0 : -1; break; case GLFW_KEY_D: c_state.gemMove[0] = (action == GLFW_RELEASE) ? 0 : 1; break; case GLFW_KEY_X: c_state.gemMove[1] = (action == GLFW_RELEASE) ? 0 : -1; break; case GLFW_KEY_C: c_state.gemMove[1] = (action == GLFW_RELEASE) ? 0 : 1; break; case GLFW_KEY_R: c_state.gemMove[1] = (action == GLFW_RELEASE) ? 0 : 1; break; case GLFW_KEY_EQUAL: c_state.gemRadius = (action == GLFW_RELEASE) ? 0 : 1; break; case GLFW_KEY_MINUS: c_state.gemRadius = (action == GLFW_RELEASE) ? 0 : -1; break; case GLFW_KEY_M: if (action == GLFW_RELEASE) c_state.mode = (RENDER_MODE)((c_state.mode + 1) % MODE_MAX); break; } }
void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action, int mods) { GLFWView *view = reinterpret_cast<GLFWView *>(glfwGetWindowUserPointer(window)); if (action == GLFW_RELEASE) { switch (key) { case GLFW_KEY_ESCAPE: glfwSetWindowShouldClose(window, true); break; case GLFW_KEY_TAB: view->map->toggleDebug(); break; case GLFW_KEY_C: view->map->toggleCollisionDebug(); break; case GLFW_KEY_X: if (!mods) view->map->resetPosition(); break; case GLFW_KEY_S: if (view->changeStyleCallback) view->changeStyleCallback(); break; case GLFW_KEY_R: if (!mods) { view->map->setDefaultTransitionDuration(std::chrono::milliseconds(300)); if (view->map->hasClass("night")) { view->map->removeClass("night"); } else { view->map->addClass("night"); } } break; case GLFW_KEY_N: if (!mods) view->map->resetNorth(); break; case GLFW_KEY_Q: view->clearAnnotations(); break; case GLFW_KEY_P: { view->addRandomCustomPointAnnotations(1); } break; } } if (action == GLFW_RELEASE || action == GLFW_REPEAT) { switch (key) { case GLFW_KEY_W: view->popAnnotation(); break; case GLFW_KEY_1: view->addRandomPointAnnotations(1); break; case GLFW_KEY_2: view->addRandomPointAnnotations(10); break; case GLFW_KEY_3: view->addRandomPointAnnotations(100); break; case GLFW_KEY_4: view->addRandomPointAnnotations(1000); break; case GLFW_KEY_5: view->addRandomPointAnnotations(10000); break; case GLFW_KEY_6: view->addRandomPointAnnotations(100000); break; case GLFW_KEY_7: view->addRandomShapeAnnotations(1); break; case GLFW_KEY_8: view->addRandomShapeAnnotations(10); break; case GLFW_KEY_9: view->addRandomShapeAnnotations(100); break; case GLFW_KEY_0: view->addRandomShapeAnnotations(1000); break; } } }
static GLUSvoid glusInternalClose(GLFWwindow* window) { glfwSetWindowShouldClose(window, GLUS_TRUE); }
int main() { printf("Compiled against GLFW %i.%i.%i\n", GLFW_VERSION_MAJOR, GLFW_VERSION_MINOR, GLFW_VERSION_REVISION); if( !glfwInit() ) { fprintf( stderr, "Faild To Initialize glfw"); return EXIT_FAILURE; } glfwWindowHint( GLFW_SAMPLES, 4 ); glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 ); glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 ); glfwWindowHint( GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE) ; glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE ); glfwWindowHint( GLFW_VISIBLE, GL_TRUE ); /* Create Window */ GLFWwindow* window; window = glfwCreateWindow( 500, 500, "First GLFW", NULL, NULL ); if( window == NULL ) { fprintf( stderr, "Faild Create Window"); glfwTerminate(); return EXIT_FAILURE; } glfwMakeContextCurrent( window ); glewExperimental = true; if( glewInit() != GLEW_OK ) { fprintf(stderr, "Failed to initialize GLEW\n"); return EXIT_FAILURE; } glClearColor(0.0f, 0.0f, 0.0f, 0.0f); /* start shading */ init_shaders(); GLint uniformMat = glGetUniformLocation( prog, "trans" ); glGenVertexArrays( 1, &vao ); glBindVertexArray( vao ); glGenBuffers( 1, &vbo ); glBindBuffer( GL_ARRAY_BUFFER, vbo ); glBufferData( GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW ); GLuint vertexAttrib = glGetAttribLocation( prog, "in_coords"); printf("in_coords : %d\n", vertexAttrib ); glm::mat4 trans; trans = glm::translate( trans, glm::vec3( 0.5f, 0.5f, 0.5f )); //trans = glm::scale( trans, glm::vec3( 0.5f, 0.5f, 0.5f )); //trans = glm::rotate(trans, glm::radians(180.0f), glm::vec3(0.0f, 0.0f, 1.0f)); glm::vec4 result = trans * glm::vec4(1.0f, 1.0f, 1.0f, 1.0f); printf("%f, %f, %f\n", result.x, result.y, result.z); glfwSetInputMode( window, GLFW_STICKY_KEYS, GL_TRUE ); while ( !glfwWindowShouldClose( window )) { glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); glClear( GL_COLOR_BUFFER_BIT ); glUseProgram(prog); glUniformMatrix4fv( uniformMat, 1, GL_FALSE, glm::value_ptr( trans )); glVertexAttribPointer( vertexAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0 ); glEnableVertexAttribArray( vertexAttrib ); glDrawArrays( GL_TRIANGLES, 0, 3 ); glfwSwapBuffers( window ); glfwPollEvents(); } if( glfwGetKey( window, GLFW_KEY_ESCAPE ) != GLFW_PRESS ) glfwSetWindowShouldClose( window, GL_TRUE ); // Cleanup VBO glDeleteBuffers( 1, &vbo); glDeleteVertexArrays( 1, &vao ); glDeleteProgram(prog); // Close OpenGL window and terminate GLFW glfwTerminate(); }
void handleInput() { //Terminate the program if the escape key is pressed if (glfwGetKey(egWindowHandler->getWindow(), GLFW_KEY_ESCAPE)) glfwSetWindowShouldClose(egWindowHandler->getWindow(), true); }
// Is called whenever a key is pressed/released via GLFW void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) { std::cout << key << std::endl; if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GL_TRUE); }
void MainHudPage::onClick(View *view, int button, int action){ if(view == exitButton){ // EXIT application glfwSetWindowShouldClose(simulator->getFrame()->getWindow(), GL_TRUE); } }
void CWindow::Close() { glfwSetWindowShouldClose(WindowHandle, true); }
int main() { //setup to log some GLFW stuff char message[256]; sprintf (message, "starting GLFW %s", glfwGetVersionString ()); assert (gl_log (message, __FILE__, __LINE__)); glfwSetErrorCallback (glfw_error_callback); //open an OS window using GLFW 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); */ //Anti-Aliasing glfwWindowHint (GLFW_SAMPLES, 4); //get the primary monitor GLFWmonitor* mon = glfwGetPrimaryMonitor (); //this lets us the the video mode for the monitor we pass const GLFWvidmode* vmode = glfwGetVideoMode (mon); GLFWwindow* window = glfwCreateWindow ( vmode->width, vmode->height, "Extended GL Init",NULL/* mon*/, NULL ); glfwSetWindowSize(window, g_gl_width, g_gl_height); if (!window) { fprintf (stderr, "ERROR: could not open window with GLFW3\n"); glfwTerminate(); return 1; } //not sure if this works //log_gl_params (); 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); // 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" float speed = 1.0f; // move at 1 unit per second float last_position = 0.0f; //Quad * tester = new Quad(); Sprite * richard = new Sprite("./resources/simmons.png", 384, 324, Vector4(1,1,1,1), window); //int matrix_location = glGetUniformLocation (shaderProgram, "matrix"); //glUniform1i(glGetUniformLocation(shaderProgram, "Texture"), 0); Ortho = new Matrix4(); Orthographic(0, g_gl_width, g_gl_height, 0, 0, -1, Ortho); while (!glfwWindowShouldClose (window)) { /* add a timer for doing animation static double previous_seconds = glfwGetTime (); double current_seconds = glfwGetTime (); double elapsed_seconds = current_seconds - previous_seconds; previous_seconds = current_seconds; // reverse direction when going to far left or right if (fabs(last_position) > 1.0f) { speed = -speed; } */ glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CW); // GL_CCW for counter clock-wise // wipe the drawing surface clear glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //resize window glViewport (0, 0, g_gl_width, g_gl_height); // update the matrix // matrix[12] = elapsed_seconds * speed + last_position; // last_position = matrix[12]; //set the shader for this VAO // glUseProgram (shaderProgram); //Here is where we attach the marix // glUniformMatrix4fv (matrix_location, 1, GL_FALSE, matrix); //bind the VAO to be drawn // glBindVertexArray (VAO); // draw points 0-3 from the currently bound VAO with current in-use shader // glDrawArrays (GL_TRIANGLES, 0, 3); richard->Input(); richard->Draw(); // update other events like input handling glfwPollEvents (); // put the stuff we've been drawing onto the display glfwSwapBuffers (window); //When do i exit? if (GLFW_PRESS == glfwGetKey (window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (window, 1); } } // close GL context and any other GLFW resources glfwTerminate(); return 0; }
int main() { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", nullptr, nullptr); glfwMakeContextCurrent(window); // Initialize GLEW glewExperimental = GL_TRUE; glewInit(); // Create Vertex Array Object GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); // Create a Vertex Buffer Object and copy the vertex data to it GLuint vbo; glGenBuffers(1, &vbo); // Generate 1 buffer glBindBuffer(GL_ARRAY_BUFFER, vbo); float vertices[] = { 0.0f, 0.5f, 1.0f, 0.0f, 0.0f, // Vertex 1: Red 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // Vertex 2: Green -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Vertex 3: Blue }; int bytes = sizeof(vertices); int rows = 3; int stride = bytes / rows; glBufferData(GL_ARRAY_BUFFER, bytes, vertices, GL_STATIC_DRAW); // Create and compile the vertex shader GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); std::string shaderSource = readVertexSource(); const GLchar* vertexSource = shaderSource.c_str(); glShaderSource(vertexShader, 1, &vertexSource, NULL); glCompileShader(vertexShader); // Create and compile the fragment shader GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); shaderSource = readFragmentSource(); const GLchar* fragmentSource = shaderSource.c_str(); glShaderSource(fragmentShader, 1, &fragmentSource, NULL); glCompileShader(fragmentShader); // Link the vertex and fragment shader into a shader program GLuint shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glBindFragDataLocation(shaderProgram, 0, "outColor"); glLinkProgram(shaderProgram); glUseProgram(shaderProgram); // Specify the layout of the vertex data GLint posAttrib = glGetAttribLocation(shaderProgram, "position"); glEnableVertexAttribArray(posAttrib); glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, stride, 0); GLint colAttrib = glGetAttribLocation(shaderProgram, "color"); glEnableVertexAttribArray(colAttrib); glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, stride, (void*)(2 * sizeof(float))); while (!glfwWindowShouldClose(window)) { glfwPollEvents(); if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { glfwSetWindowShouldClose(window, GL_TRUE); break; } // Clear the screen to black glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLES, 0, rows); glfwSwapBuffers(window); } glDeleteProgram(shaderProgram); glDeleteShader(fragmentShader); glDeleteShader(vertexShader); glDeleteBuffers(1, &vbo); glDeleteVertexArrays(1, &vao); glfwTerminate(); }
/** The main function of the controller tester. \param argc the number of input arguments. \param argv a pointer to the raw input arguments. \return a general error code. \ingroup ControllerTest */ int main(int argc, char** argv) { // First, init/parse/load configuration. RenderingConfig config(std::vector<std::string>(argv, argv+argc)); // Override window dimensions. config.initialWidth = 800; config.initialHeight = 800; GLFWwindow* window = Interface::initWindow("Controller test", config); if(!window){ return -1; } // Enable raw mode for the input, that way all controllers will be raw controllers. Input::manager().preferRawControllers(true); // Will contain reference button/axes to raw input mappings. std::vector<int> buttonsMapping(Controller::ControllerInputCount, -1); std::vector<int> axesMapping(Controller::ControllerInputCount, -1); // Controller texture. const GLuint controllerTexId = Resources::manager().getTexture("ControllerLayout", {GL_RGBA8})->id; bool firstFrame = true; const ImU32 highlightColor = IM_COL32(172, 172, 172, 255); float threshold = 0.02f; // Start the display/interaction loop. while (!glfwWindowShouldClose(window)) { // Update events (inputs,...). Input::manager().update(); // Handle quitting. if(Input::manager().pressed(Input::KeyEscape)){ glfwSetWindowShouldClose(window, GL_TRUE); } // Reload resources. if(Input::manager().triggered(Input::KeyP)){ Resources::manager().reload(); } // Detect either a new connected controller or a first frame with an already connected controller. if(Input::manager().controllerConnected() || (firstFrame && Input::manager().controllerAvailable())){ firstFrame = false; const RawController * controller = static_cast<RawController*>(Input::manager().controller()); const int axesCount = int(controller->allAxes.size()); const int buttonsCount = int(controller->allButtons.size()); // Check if some elements were already modified. bool wereEmpty = true; for(int i = 0; i < int(buttonsMapping.size()); ++i){ if(wereEmpty && buttonsMapping[i] >= 0){ wereEmpty = false; } // Update mapping for extraneous button IDs. if(buttonsMapping[i] >= buttonsCount){ buttonsMapping[i] = -1; } } for(int i = 0; i < int(axesMapping.size()); ++i){ if(wereEmpty && axesMapping[i] >= 0){ wereEmpty = false; } if(axesMapping[i] >= axesCount){ axesMapping[i] = -1; } } // If everything was -1 (first launch), attribute the buttons and axes sequentially, just to help with the visualisation and assignment. if(wereEmpty){ for(int i = 0; i < std::min(int(buttonsMapping.size()), buttonsCount); ++i){ buttonsMapping[i] = i; } // Start from the end for the axes. for(int i = 0; i < std::min(int(axesMapping.size()), axesCount); ++i){ const int actionId = int(axesMapping.size()) - 1 - i; // Avoid double mappings. if(buttonsMapping[actionId] >= 0){ continue; } axesMapping[actionId] = i; } } } // Start a new frame for the interface. Interface::beginFrame(); // Render nothing. const glm::vec2 screenSize = Input::manager().size(); glViewport(0, 0, (GLsizei)screenSize[0], (GLsizei)screenSize[1]); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); // Set a fullscreen fixed window. ImGui::SetNextWindowPos(ImVec2(0,0)); ImGui::SetNextWindowBgAlpha(1.0f); ImGui::SetNextWindowSize(ImGui::GetIO().DisplaySize); const ImGuiWindowFlags windowOptions = ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoTitleBar; if(ImGui::Begin("Controller", nullptr, windowOptions)){ if(!Input::manager().controllerAvailable()){ ImGui::Text("No controller connected."); } else { // Load/save configuration files. if(ImGui::Button("Load...")){ std::string inputPath; const bool res = Interface::showPicker(Interface::Picker::Load, "", inputPath); if(res && !inputPath.empty()){ const std::string settingsContent = Resources::manager().loadStringFromExternalFile(inputPath); Controller::parseConfiguration(settingsContent, axesMapping, buttonsMapping); } } ImGui::SameLine(); if(ImGui::Button("Save...")){ std::string outputPath; const bool res = Interface::showPicker(Interface::Picker::Save, "", outputPath); if(res && !outputPath.empty()){ const Controller * controller = Input::manager().controller(); Controller::saveConfiguration(outputPath, controller->guid(), controller->name(), axesMapping, buttonsMapping); } } ImGui::Separator(); // Infos on the controller. RawController * controller = static_cast<RawController*>(Input::manager().controller()); const int axesCount = int(controller->allAxes.size()); const int buttonsCount = int(controller->allButtons.size()); ImGui::Text("%s, id: %d, axes: %d, buttons: %d", controller->name().c_str(), controller->id(), axesCount, buttonsCount); // Display raw axes and buttons and update their display when the user interacts with them. if(ImGui::CollapsingHeader("Raw inputs##HEADER", ImGuiTreeNodeFlags_DefaultOpen)){ ImGui::Columns(2); for(int aid = 0; aid < axesCount; ++aid){ const std::string axisName = "A" + std::to_string(aid); ImGui::SliderFloat(axisName.c_str(), &controller->allAxes[aid], -1.0f, 1.0f); ImGui::NextColumn(); } ImGui::Columns(1); ImGui::Separator(); ImGui::Columns(10); for(int bid = 0; bid < buttonsCount; ++bid){ const std::string buttonName = "B" + std::to_string(bid); ImGui::RadioButton(buttonName.c_str(), controller->allButtons[bid].pressed); ImGui::NextColumn(); } ImGui::Columns(1); } if(ImGui::CollapsingHeader("Assignment##HEADER", ImGuiTreeNodeFlags_DefaultOpen)){ // Display the controller layout, highlight pressed buttons. ImGui::BeginChild("##ControllerLayout", ImVec2(450, 300)); // Get current rnedering position on screen. const ImVec2 pos = ImGui::GetCursorScreenPos(); ImDrawList * drawList = ImGui::GetWindowDrawList(); // Render the left pad first. const int aidLX = axesMapping[Controller::PadLeftX]; const int aidLY = axesMapping[Controller::PadLeftY]; const float magLX = aidLX >= 0 ? controller->allAxes[aidLX] : 0.0f; const float magLY = aidLY >= 0 ? controller->allAxes[aidLY] : 0.0f; if((aidLX >= 0 || aidLY >= 0) && (magLX*magLX + magLY*magLY > threshold)){ drawList->AddCircleFilled(ImVec2(pos.x+154, pos.y+179), 34, highlightColor); drawList->AddCircleFilled(ImVec2(pos.x+154, pos.y+179), 26, IM_COL32(0, 0, 0, 255)); } // Then the right pad. const int aidRX = axesMapping[Controller::PadRightX]; const int aidRY = axesMapping[Controller::PadRightY]; const float magRX = aidRX >= 0 ? controller->allAxes[aidRX] : 0.0f; const float magRY = aidRY >= 0 ? controller->allAxes[aidRY] : 0.0f; if((aidRX >= 0 || aidRY >= 0) && (magRX*magRX + magRY*magRY > threshold)){ drawList->AddCircleFilled(ImVec2(pos.x+296, pos.y+179), 34, highlightColor); drawList->AddCircleFilled(ImVec2(pos.x+296, pos.y+179), 26, IM_COL32(0, 0, 0, 255)); } // Render the left trigger (assuming its default value is -1.0). const int aidLT = axesMapping[Controller::TriggerL2]; const float magLT = aidLT >= 0 ? controller->allAxes[aidLT]*0.5+0.5f : 0.0f; if(aidLT >= 0 && (magLT*magLT > threshold)){ drawButton(drawList, Controller::TriggerL2, pos, highlightColor); } // And the right trigger (assuming its default value is -1.0). const int aidRT = axesMapping[Controller::TriggerR2]; const float magRT = aidRT >= 0 ? controller->allAxes[aidRT]*0.5+0.5f : 0.0f; if(aidRT >= 0 && (magRT*magRT > threshold)){ drawButton(drawList, Controller::TriggerR2, pos, highlightColor); } // Render each button if active. for(int bid = 0; bid < int(buttonsMapping.size()); ++bid){ const int bmid = buttonsMapping[bid]; if(bmid >= 0 && controller->allButtons[bmid].pressed){ drawButton(drawList, Controller::ControllerInput(bid), pos, highlightColor); } } // Overlay the controller transparent texture. ImGui::Image(reinterpret_cast<void*>(controllerTexId), ImVec2(450, 300), ImVec2(0, 1), ImVec2(1,0)); ImGui::EndChild(); ImGui::SameLine(); // Display combo selectors to assign raw input to each button. ImGui::BeginChild("##Layout selection", ImVec2(0, 300)); ImGui::PushItemWidth(80); const int spacing = 160; showCombo("A", buttonsCount, "B", buttonsMapping[Controller::ButtonA]); ImGui::SameLine(spacing); showCombo("B", buttonsCount, "B", buttonsMapping[Controller::ButtonB]); showCombo("X", buttonsCount, "B", buttonsMapping[Controller::ButtonX]); ImGui::SameLine(spacing); showCombo("Y", buttonsCount, "B", buttonsMapping[Controller::ButtonY]); showCombo("Up", buttonsCount, "B", buttonsMapping[Controller::ButtonUp]); ImGui::SameLine(spacing); showCombo("Left", buttonsCount, "B", buttonsMapping[Controller::ButtonLeft]); showCombo("Down", buttonsCount, "B", buttonsMapping[Controller::ButtonDown]); ImGui::SameLine(spacing); showCombo("Right", buttonsCount, "B", buttonsMapping[Controller::ButtonRight]); showCombo("L1", buttonsCount, "B", buttonsMapping[Controller::BumperL1]); ImGui::SameLine(spacing); showCombo("R1", buttonsCount, "B", buttonsMapping[Controller::BumperR1]); showCombo("L2", buttonsCount, "B", buttonsMapping[Controller::TriggerL2]); ImGui::SameLine(spacing); showCombo("R2", buttonsCount, "B", buttonsMapping[Controller::TriggerR2]); showCombo("L3", buttonsCount, "B", buttonsMapping[Controller::ButtonL3]); ImGui::SameLine(spacing); showCombo("R3", buttonsCount, "B", buttonsMapping[Controller::ButtonR3]); showCombo("Menu", buttonsCount, "B", buttonsMapping[Controller::ButtonMenu]); ImGui::SameLine(spacing); showCombo("View", buttonsCount, "B", buttonsMapping[Controller::ButtonView]); showCombo("Logo", buttonsCount, "B", buttonsMapping[Controller::ButtonLogo]); ImGui::Separator(); showCombo("Left X", axesCount, "A", axesMapping[Controller::PadLeftX]); ImGui::SameLine(spacing); showCombo("Left Y", axesCount, "A", axesMapping[Controller::PadLeftY]); showCombo("Right X", axesCount, "A", axesMapping[Controller::PadRightX]); ImGui::SameLine(spacing); showCombo("Right Y", axesCount, "A", axesMapping[Controller::PadRightY]); showCombo("L. trigger", axesCount, "A", axesMapping[Controller::TriggerL2]); ImGui::SameLine(spacing); showCombo("R. trigger", axesCount, "A", axesMapping[Controller::TriggerR2]); ImGui::PopItemWidth(); // Add threshold setup slider. ImGui::PushItemWidth(240); ImGui::SliderFloat("Threshold", &threshold, 0.0f, 0.3f); ImGui::PopItemWidth(); ImGui::EndChild(); } // Display targets with the current axis positions. if(ImGui::CollapsingHeader("Calibration##HEADER", ImGuiTreeNodeFlags_DefaultOpen)){ const float threshRadius = sqrt(threshold) * 100; // Titles. ImGui::Text("Left pad & trigger"); ImGui::SameLine(300); ImGui::Text("Right pad & trigger"); // Left pad. ImGui::BeginChild("PadLeftTarget", ImVec2(200, 200)); drawPadTarget(axesMapping[Controller::PadLeftX], axesMapping[Controller::PadLeftY], controller->allAxes, threshRadius); ImGui::EndChild(); ImGui::SameLine(220); // Left trigger ImGui::BeginChild("TriggerL2", ImVec2(40, 200)); drawTriggerTarget(axesMapping[Controller::TriggerL2], controller->allAxes, threshRadius); ImGui::EndChild(); ImGui::SameLine(300); // Right pad. ImGui::BeginChild("PadRightTarget", ImVec2(200, 200)); drawPadTarget(axesMapping[Controller::PadRightX], axesMapping[Controller::PadRightY], controller->allAxes, threshRadius); ImGui::EndChild(); // Right trigger ImGui::SameLine(520); ImGui::BeginChild("TriggerR2", ImVec2(40, 200)); drawTriggerTarget(axesMapping[Controller::TriggerR2], controller->allAxes, threshRadius); ImGui::EndChild(); } } } ImGui::End(); // Then render the interface. Interface::endFrame(); //Display the result for the current rendering loop. glfwSwapBuffers(window); } // Clean the interface. Interface::clean(); Resources::manager().clean(); // Close GL context and any other GLFW resources. glfwDestroyWindow(window); glfwTerminate(); return 0; }
static void key_callback_user(GLFWwindow* window, int key, int scancode, int action, int mods) { if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GL_TRUE); e.UserKeyHandling(key, action, mods); }