// the program starts here void AppMain() { // initialise GLFW if(!glfwInit()) throw std::runtime_error("glfwInit failed"); // open a window with GLFW glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2); glfwOpenWindowHint(GLFW_WINDOW_NO_RESIZE, GL_TRUE); if(!glfwOpenWindow((int)SCREEN_SIZE.x, (int)SCREEN_SIZE.y, 8, 8, 8, 8, 16, 0, GLFW_WINDOW)) throw std::runtime_error("glfwOpenWindow failed. Can your hardware handle OpenGL 3.2?"); // GLFW settings glfwDisable(GLFW_MOUSE_CURSOR); glfwSetMousePos(0, 0); glfwSetMouseWheel(0); // initialise GLEW glewExperimental = GL_TRUE; //stops glew crashing on OSX :-/ if(glewInit() != GLEW_OK) throw std::runtime_error("glewInit failed"); // GLEW throws some errors, so discard all the errors so far while(glGetError() != GL_NO_ERROR) {} // print out some info about the graphics drivers std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl; std::cout << "GLSL version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl; std::cout << "Vendor: " << glGetString(GL_VENDOR) << std::endl; std::cout << "Renderer: " << glGetString(GL_RENDERER) << std::endl; // make sure OpenGL version 3.2 API is available if(!GLEW_VERSION_3_2) throw std::runtime_error("OpenGL 3.2 API is not available."); // OpenGL settings glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); // initialise the gWoodenCrate asset LoadWoodenCrateAsset(); // create all the instances in the 3D scene based on the gWoodenCrate asset CreateInstances(); // setup gCamera gCamera.setPosition(glm::vec3(-4,0,17)); gCamera.setViewportAspectRatio(SCREEN_SIZE.x / SCREEN_SIZE.y); gCamera.setNearAndFarPlanes(0.5f, 100.0f); // setup gLight gLight.position = glm::vec3(-4,0,4); gLight.intensities = glm::vec3(1,1,1); //white gLight.attenuation = 0.2f; gLight.ambientCoefficient = 0.005f; // run while the window is open double lastTime = glfwGetTime(); while(glfwGetWindowParam(GLFW_OPENED)){ // update the scene based on the time elapsed since last update double thisTime = glfwGetTime(); Update((float)(thisTime - lastTime)); lastTime = thisTime; // draw one frame Render(); // check for errors GLenum error = glGetError(); if(error != GL_NO_ERROR) glPrintError(); //exit program if escape key is pressed if(glfwGetKey(GLFW_KEY_ESC)) glfwCloseWindow(); } // clean up and exit glfwTerminate(); }
int main(void) { // Initialise GLFW if (!glfwInit()) { fprintf(stderr, "Failed to initialize GLFW\n"); return -1; } glfwWindowHint(GLFW_SAMPLES, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Open a window and create its OpenGL context window = glfwCreateWindow(1024, 768, "MyMesh class", NULL, NULL); if (window == NULL){ fprintf(stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n"); glfwTerminate(); return -1; } glfwMakeContextCurrent(window); // Initialize GLEW glewExperimental = true; // Needed for core profile if (glewInit() != GLEW_OK) { fprintf(stderr, "Failed to initialize GLEW\n"); return -1; } // Ensure we can capture the escape key being pressed below glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE); // Dark blue background glClearColor(0.0f, 0.0f, 0.4f, 0.0f); MyMesh* pMesh = new MyMesh(); pMesh->AddVertexPosition(glm::vec3(-5.0f, -2.5f, 0.0f)); pMesh->AddVertexPosition(glm::vec3(5.0f, -2.5f, 0.0f)); pMesh->AddVertexPosition(glm::vec3(0.0f, 2.5f, 0.0f)); pMesh->AddVertexColor(glm::vec3(1.0f, 1.0f, 0.0f)); pMesh->AddVertexColor(glm::vec3(1.0f, 0.0f, 0.0f)); pMesh->AddVertexColor(glm::vec3(0.0f, 1.0f, 0.0f)); pMesh->CompileOpenGL3X(); //glEnable(GL_DEPTH_TEST); do{ // Clear the screen glClear(GL_COLOR_BUFFER_BIT); pMesh->Render(glm::mat4(1.0f)); // Swap buffers glfwSwapBuffers(window); glfwPollEvents(); } // Check if the ESC key was pressed or the window was closed while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0); // Close OpenGL window and terminate GLFW glfwTerminate(); delete pMesh; return 0; }
int main(int argc, char * argv[]) { // Load GLFW and Create a Window glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); auto mWindow = glfwCreateWindow(mWidth, mHeight, "OpenGL", nullptr, nullptr); // Check for Valid Context if (mWindow == nullptr) { fprintf(stderr, "Failed to Create OpenGL Context"); return EXIT_FAILURE; } // Create Context and Load OpenGL Functions glfwMakeContextCurrent(mWindow); gladLoadGL(); fprintf(stderr, "OpenGL %s\n", glGetString(GL_VERSION)); glfwSetErrorCallback(&errorCallback); float vertices[] = { 0.0f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f, }; // 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); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); std::ifstream vertexShaderFile(PROJECT_SOURCE_DIR "/Glitter/Shaders/main.vert"); std::string vertexShaderStr((std::istreambuf_iterator<char>(vertexShaderFile)), std::istreambuf_iterator<char>()); auto vertexSource = vertexShaderStr.c_str(); // Create and compile the vertex shader GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexSource, NULL); glCompileShader(vertexShader); assertShaderCompile(vertexShader); std::ifstream fragmentShaderFile(PROJECT_SOURCE_DIR "/Glitter/Shaders/main.frag"); std::string fragmentShaderStr((std::istreambuf_iterator<char>(fragmentShaderFile)), std::istreambuf_iterator<char>()); auto fragmentSource = fragmentShaderStr.c_str(); // Create and compile the fragment shader GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentSource, NULL); glCompileShader(fragmentShader); assertShaderCompile(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); std::cout << glGetError() << std::endl; glUseProgram(shaderProgram); std::cout << glGetError() << std::endl; std::cout << glGetError() << std::endl; // Specify the layout of the vertex data GLint posAttrib = glGetAttribLocation(shaderProgram, "position"); glEnableVertexAttribArray(posAttrib); glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0); std::cout << glGetError() << std::endl; // Rendering Loop while (glfwWindowShouldClose(mWindow) == false) { if (glfwGetKey(mWindow, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(mWindow, true); // Background Fill Color glClearColor(0.25f, 0.25f, 0.25f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); // Draw a triangle from the 3 vertices glDrawArrays(GL_TRIANGLES, 0, 3); // Flip Buffers and Draw glfwSwapBuffers(mWindow); glfwPollEvents(); } glfwTerminate(); glDeleteProgram(shaderProgram); glDeleteShader(fragmentShader); glDeleteShader(vertexShader); glDeleteBuffers(1, &vbo); glDeleteVertexArrays(1, &vao); return EXIT_SUCCESS; }
void transform() { glm::mat4 origin; origin = glm::translate(origin, glm::vec3(-center.x, -center.y, -center.z)); glm::mat4 transf; glm::mat4 replace; replace = glm::translate(replace, glm::vec3(center.x, center.y, center.z)); if (glfwGetKey(window, GLFW_KEY_A)) transf = glm::rotate(transf, glm::radians(2.0f), glm::vec3(1.0f, 0.0f, 0.0f)); if (glfwGetKey(window, GLFW_KEY_D)) transf = glm::rotate(transf, glm::radians(-2.0f), glm::vec3(1.0f, 0.0f, 0.0f)); if (glfwGetKey(window, GLFW_KEY_W)) transf = glm::rotate(transf, glm::radians(2.0f), glm::vec3(0.0f, 0.0f, 1.0f)); if (glfwGetKey(window, GLFW_KEY_S)) transf = glm::rotate(transf, glm::radians(-2.0f), glm::vec3(0.0f, 0.0f, 1.0f)); if (glfwGetKey(window, GLFW_KEY_Q)) transf = glm::rotate(transf, glm::radians(2.0f), glm::vec3(0.0f, 1.0f, 0.0f)); if (glfwGetKey(window, GLFW_KEY_E)) transf = glm::rotate(transf, glm::radians(-2.0f), glm::vec3(0.0f, 1.0f, 0.0f)); if (glfwGetKey(window, GLFW_KEY_EQUAL)) zoom-=1.0; if (glfwGetKey(window, GLFW_KEY_MINUS)) zoom += 1.0; if (glfwGetKey(window, GLFW_KEY_UP)) camLook.y += 0.02f; if (glfwGetKey(window, GLFW_KEY_DOWN)) camLook.y -=0.02f; if (glfwGetKey(window, GLFW_KEY_RIGHT)) camLook.x += 0.02f; if (glfwGetKey(window, GLFW_KEY_LEFT)) camLook.x -= 0.02f; //transf = glm::rotaqte(transf, glm::radians(42.0f), glm::vec3(1.0f, 0.0f, 0.0f)); glm::mat4 finalMat; finalMat = replace * transf * origin; nmodel = nmodel * transf; model = model * finalMat; //model = finalMat * model; //model = glm::rotate(model, glm::radians(1.0f), glm::vec3(1.0f, 0.0f, 0.0f)); }
void AppMain() { //Init everything in the game. fps = new FPS(glfwGetTime()); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); std::vector<Shader> shaders; shaders.push_back(Shader::shaderFromFile(ResourcePath("vertex-shader.txt"), GL_VERTEX_SHADER)); shaders.push_back(Shader::shaderFromFile(ResourcePath("fragment-shader.txt"), GL_FRAGMENT_SHADER)); _program = new Program(shaders); World* world = new World(); world->generateWorld(_program); gLight.position = world->_player->_camera->position(); gLight.intensities = glm::vec3(1, 1, 1); gLight.attenuation = 0.00f; /* 0.01f; */ gLight.ambientCoefficient = 0.01f; //Run the game. while(glfwGetWindowParam(GLFW_OPENED)) { //update fps->_thisTime = glfwGetTime(); { world->update(fps->_thisTime - fps->_lastTime); gLight.position = world->_player->_camera->position(); if(glfwGetKey('1')) gLight.intensities = glm::vec3(0,0,1); //blue if(glfwGetKey('2')) gLight.intensities = glm::vec3(1,0,0); //red else if(glfwGetKey('3')) gLight.intensities = glm::vec3(0,1,0); //green else if(glfwGetKey('4')) gLight.intensities = glm::vec3(1,1,1); //white } fps->_lastTime = fps->_thisTime; //render _program->use(); { glClearColor(0.2, 0.2, 0.2, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); _program->setUniform("camera", world->_player->_camera->matrix()); _program->setUniform("light.position", gLight.position); _program->setUniform("light.intensities", gLight.intensities); _program->setUniform("light.attenuation", gLight.attenuation); _program->setUniform("light.ambientCoefficient", gLight.ambientCoefficient); world->render(); } _program->stopUsing(); fps->update(glfwGetTime()); if(glfwGetKey(GLFW_KEY_ESC) || (fps->_fps < 5.0 && fps->_counter > 5)) { glfwCloseWindow(); } //Display. glfwSwapBuffers(); } //It's time to close, KILL EVERYTHING!!! MUHAHAHA!!! delete world; delete _program; delete fps; glfwTerminate(); }
int main () { // start GL context with helper libraries assert (glfwInit ()); // 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 ( 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(void) { if(!glfwInit()) { printf("Could not init GLFW"); getchar(); return -1; } glfwWindowHint(GLFW_SAMPLES, 4); //Opengl 2.1 //glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); //glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); //Opengl 3.3 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // MacOS fix glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); if(window_init(&window, 640, 480, "Test")) { fprintf( stderr, "Failed to open window.\n" ); getchar(); glfwTerminate(); }; window_set_size_callback(&window, window_size_callback); glewExperimental = GL_TRUE; // Needed for core profile if (glewInit() != GLEW_OK) { fprintf(stderr, "Failed to initialize GLEW\n"); getchar(); glfwTerminate(); return -1; } //#clear errors GLEW may trigger printError(); glClearColor(0.0f, 0.0f, 0.4f, 0.0f); GLuint VertexArrayID; glGenVertexArrays(1, &VertexArrayID); glBindVertexArray(VertexArrayID); //Load model //---------- Model cube; model_init(&cube); model_set_data_length(&cube, sizeof(cube_vertex_data)); model_set_vertices(&cube, cube_vertex_data); model_set_colors(&cube, cube_color_data); model_set_uv_map(&cube, cube_uv_data); model_set_texture(&cube, "./textures/bricks.dds"); model_bind(&cube); //Create shaders //-------------- GLuint vertexShader, fragmentShader; loadShader(&vertexShader, GL_VERTEX_SHADER, mvpVertexShaderSource); loadShader(&fragmentShader, GL_FRAGMENT_SHADER, fragmentShaderSource); //Create program //-------------- GLuint program; createProgram(&program, vertexShader, fragmentShader); // Enable z-buffer // --------------- glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); // Enable culling // -------------- glEnable(GL_CULL_FACE); // Get MVP uniform // --------------- GLuint mvp_ul = glGetUniformLocation(program, "MVP"); // Model Matrix // ------------ Mat4 s; scale_m4(&s, 0.1f, 0.1f, 0.1f); printf("Scale:\n"); print_m4(&s); Mat4 r; rotate_m4(&r, 0.0f, 1.0f, 0.0f, 0.0f); printf("Rotate:\n"); print_m4(&r); Mat4 t; translate_m4(&t, 0.0f, 0.0f, 0.0f); printf("Translate:\n"); print_m4(&t); Mat4 rs; printf("Rotated*Scaled:\n"); mul_m4(&rs, &r, &s); print_m4(&rs); Mat4 model; printf("Model:\n"); mul_m4(&model, &t, &rs); print_m4(&model); // Camera // ------ Vec3 pos; Vec3 center; Vec3 up; Vec3 direction; Vec3 right; camera_init(&camera); camera_set_fov(&camera, 1.0f); camera_set_aspect(&camera, (float)window.width/(float)window.height); Input input; input_init(&input, &window, 0.5f, 0.5f, 0.8f, -5.7f, -2.7f); do { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glUseProgram(program); input_get_data(&input, &pos, &direction, &right); add_v3(¢er, &pos, &direction); cross_v3(&up, &direction, &right); camera_set_position(&camera, &pos); camera_set_center(&camera, ¢er); camera_set_up(&camera, &up); // Mvp Matrix // ---------- Mat4 vp; camera_get_matrix(&camera, &vp); Mat4 mvp; mul_m4(&mvp, &vp, &model); printf("Perspective:\n"); print_m4(&mvp); // Set MVP transform glUniformMatrix4fv(mvp_ul, 1, GL_TRUE, &mvp[0][0]); model_render(&cube); window_swap_buffers(&window); glfwPollEvents(); } while( glfwGetKey(window.handle, GLFW_KEY_ESCAPE ) != GLFW_PRESS && glfwWindowShouldClose(window.handle) == 0 ); // Dispose // ------- model_dispose(&cube); glDeleteVertexArrays(1, &VertexArrayID); glDetachShader(program, fragmentShader); glDetachShader(program, vertexShader); glDeleteShader(fragmentShader); glDeleteShader(vertexShader); glDeleteProgram(program); glfwTerminate(); return 0; }
static void GetInput(GLFWwindow * window, int key, int scancode, int action, int mods) { bool shiftPressed(false); if(glfwGetKey(window, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS || glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) shiftPressed = true; if(action == GLFW_PRESS) { switch(key) { case GLFW_KEY_A: LETTER = "a"; break; case GLFW_KEY_B: LETTER = "b"; break; case GLFW_KEY_C: LETTER = "c"; break; case GLFW_KEY_D: LETTER = "d"; break; case GLFW_KEY_E: LETTER = "e"; break; case GLFW_KEY_F: LETTER = "f"; break; case GLFW_KEY_G: LETTER = "g"; break; case GLFW_KEY_H: LETTER = "h"; break; case GLFW_KEY_I: LETTER = "i"; break; case GLFW_KEY_J: LETTER = "j"; break; case GLFW_KEY_K: LETTER = "k"; break; case GLFW_KEY_L: LETTER = "l"; break; case GLFW_KEY_M: LETTER = "m"; break; case GLFW_KEY_N: LETTER = "n"; break; case GLFW_KEY_O: LETTER = "o"; break; case GLFW_KEY_P: LETTER = "p"; break; case GLFW_KEY_Q: LETTER = "q"; break; case GLFW_KEY_R: LETTER = "r"; break; case GLFW_KEY_S: LETTER = "s"; break; case GLFW_KEY_T: LETTER = "t"; break; case GLFW_KEY_U: LETTER = "u"; break; case GLFW_KEY_V: LETTER = "v"; break; case GLFW_KEY_W: LETTER = "w"; break; case GLFW_KEY_X: LETTER = "x"; break; case GLFW_KEY_Y: LETTER = "y"; break; case GLFW_KEY_Z: LETTER = "z"; break; case GLFW_KEY_0: LETTER = "0"; break; case GLFW_KEY_1: LETTER = "1"; break; case GLFW_KEY_2: LETTER = "2"; break; case GLFW_KEY_3: LETTER = "3"; break; case GLFW_KEY_4: LETTER = "4"; break; case GLFW_KEY_5: LETTER = "5"; break; case GLFW_KEY_6: LETTER = "6"; break; case GLFW_KEY_7: LETTER = "7"; break; case GLFW_KEY_8: LETTER = "8"; break; case GLFW_KEY_9: LETTER = "9"; case GLFW_KEY_SPACE: LETTER = " "; break; case GLFW_KEY_BACKSPACE: LETTER = "-"; break; default: LETTER.clear(); } } if(!(LETTER.empty() || LETTER == "-" || LETTER == " ")) { if(shiftPressed) LETTER.front() = std::toupper(LETTER.front()); } }
bool CApplication::IsCtrlDown() { return glfwGetKey(GLFW_KEY_LCTRL) || glfwGetKey(GLFW_KEY_RCTRL); }
int main() { std::cout << "Starting GLFW context, OpenGL 3.3.." << std::endl; if (!glfwInit()) { std::cout << "Failed to initialize GLFW" << std::endl; return -1; } glfwWindowHint(GLFW_SAMPLES, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "Tutorial", NULL, NULL); if (window == NULL) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glViewport(0, 0, WIDTH, HEIGHT); glEnable(GL_DEPTH_TEST); glfwSetKeyCallback(window, keyCallback); glfwSetCursorPosCallback(window, mouseCallback); glfwSetScrollCallback(window, scrollCallback); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE); //-------------------- glewExperimental = true; // So GLEW uses more modern techniques for managing OpenGL functionality. if (glewInit() != GLEW_OK) { fprintf(stderr, "Failed to initialize GLEW!\n"); return -1; } Shader ourShader("VertexShader.txt", "FragmentShader.txt"); Shader lightShader("LampVertexShader.txt", "LampFragmentShader.txt"); //-------------------- GLfloat vertices[] = { // Positions // Normals // Texture Coords -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }; GLfloat lampVertices[] = { -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f }; //glm::vec3 cubePositions[] = { // glm::vec3(0.0f, 0.0f, 0.0f), // glm::vec3(2.0f, 5.0f, -5.0f), // glm::vec3(-1.5f, -2.2f, -2.5f), // glm::vec3(-3.8f, -2.0f, 6.3f), // glm::vec3(2.4f, -0.4f, 3.5f), // glm::vec3(-1.7f, 3.0f, -7.5f), // glm::vec3(1.3f, -2.0f, 2.5f), // glm::vec3(1.5f, 2.0f, -2.5f), // glm::vec3(1.5f, 0.2f, 1.5f), // glm::vec3(-1.3f, 1.0f, -1.5f) //}; glm::vec3 cubePositions[] = { glm::vec3(-12.0f, 0.0f, 0.0f), glm::vec3(-10.0f, 0.0f, 0.0f), glm::vec3(-8.0f, 0.0f, 0.0f), glm::vec3(-6.0f, 0.0f, 0.0f), glm::vec3(-4.0f, 0.0f, 0.0f), glm::vec3(-2.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(2.0f, 0.0f, 0.0f), glm::vec3(4.0f, 0.0f, 0.0f), glm::vec3(6.0f, 0.0f, 0.0f), }; GLuint vertexBufferObject, vertexArrayObject, elementBufferObject; glGenVertexArrays(1, &vertexArrayObject); glGenBuffers(1, &vertexBufferObject); glBindVertexArray(vertexArrayObject); glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // Position attribute glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); // Normal vectors glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*) (3*sizeof(GLfloat))); glEnableVertexAttribArray(1); // Texture coordinate attribute glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat))); glEnableVertexAttribArray(2); // Color attribute //glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); //glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); //-------------------- COLOR GLuint lightVAO, lightVBO; glGenVertexArrays(1, &lightVAO); glGenBuffers(1, &lightVBO); glBindBuffer(GL_ARRAY_BUFFER, lightVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(lampVertices), lampVertices, GL_STATIC_DRAW); glGenVertexArrays(1, &lightVAO); glBindVertexArray(lightVAO); glBindBuffer(GL_ARRAY_BUFFER, lightVBO); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); glBindVertexArray(0); //-------------------- TEXTURE std::vector<unsigned char> file; std::vector<unsigned char> pixels; GLuint width, height; GLuint diffuseMap; glGenTextures(1, &diffuseMap); glBindTexture(GL_TEXTURE_2D, diffuseMap); // All upcoming GL_TEXTURE_2D operations now have effect on this texture object // Set the texture wrapping parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture wrapping to GL_REPEAT (usually basic wrapping method) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture filtering parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Load image, create texture and generate mipmaps lodepng::load_file(file, "container2.png"); lodepng::decode(pixels, width, height, file.data(), file.size()); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data()); glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); // Unbind texture when done, so we won't accidentily mess up our texture. //-------------------- GLuint specularMap; file.clear(); pixels.clear(); glGenTextures(1, &specularMap); glBindTexture(GL_TEXTURE_2D, specularMap); lodepng::load_file(file, "container2_specular2.png"); lodepng::decode(pixels, width, height, file.data(), file.size()); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data()); glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); //-------------------- do { GLfloat currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; glfwPollEvents(); doMovement(); glClearColor(0.2f, 0.2f, 0.2f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); lightPos.x = 1.0f + sin(glfwGetTime()) * 6.0f; lightPos.y = cos(glfwGetTime() / 2.0f) * 1.0f; //-------------------- ourShader.Use(); GLint lightColorLoc = glGetUniformLocation(ourShader.Program, "lightColor"); GLint lightPosLoc = glGetUniformLocation(ourShader.Program, "light.position"); GLint viewPosLoc = glGetUniformLocation(ourShader.Program, "viewPos"); glUniform3f(lightColorLoc, 1.0f, 0.5f, 1.0f); glUniform3f(lightPosLoc, lightPos.x, lightPos.y, lightPos.z); glUniform3f(viewPosLoc, camera.Position.x, camera.Position.y, camera.Position.z); //---------- //GLint matAmbientLoc = glGetUniformLocation(ourShader.Program, "material.ambient"); //GLint matDiffuseLoc = glGetUniformLocation(ourShader.Program, "material.diffuse"); //GLint matSpecularLoc = glGetUniformLocation(ourShader.Program, "material.specular"); GLint matShineLoc = glGetUniformLocation(ourShader.Program, "material.shininess"); //glUniform3f(matAmbientLoc, 0.19225f, 0.19225f, 0.19225f); //glUniform3f(matDiffuseLoc, 0.50754f, 0.50754f, 0.50754f); glUniform1i(glGetUniformLocation(ourShader.Program, "material.diffuse"), 0); //glUniform3f(matSpecularLoc, 0.8f, 0.8f, 0.8f); glUniform1i(glGetUniformLocation(ourShader.Program, "material.specular"), 1); glUniform1f(matShineLoc, 128.0f * 0.2f); //---------- glm::vec3 lightColor; lightColor.x = sin(glfwGetTime() * 2.0f); lightColor.y = sin(glfwGetTime() * 0.7f); lightColor.z = sin(glfwGetTime() * 1.3f); glm::vec3 diffuseColor = lightColor * glm::vec3(1.0f); glm::vec3 ambientColor = diffuseColor * glm::vec3(1.0f); GLint lightAmbientLoc = glGetUniformLocation(ourShader.Program, "light.ambient"); GLint lightDiffuseLoc = glGetUniformLocation(ourShader.Program, "light.diffuse"); GLint lightSpecularLoc = glGetUniformLocation(ourShader.Program, "light.specular"); //glUniform3f(lightAmbientLoc, ambientColor.x, ambientColor.y, ambientColor.z); //glUniform3f(lightDiffuseLoc, diffuseColor.x, diffuseColor.y, diffuseColor.z); glUniform3f(lightAmbientLoc, 0.3f, 0.3f, 0.3f); glUniform3f(lightDiffuseLoc, 1.0f, 1.0f, 1.0f); glUniform3f(lightSpecularLoc, 1.0f, 1.0f, 1.0f); //-------------------- glm::mat4 view; view = camera.GetViewMatrix(); glm::mat4 projection; projection = glm::perspective(glm::radians(camera.Zoom), (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f); GLint viewLoc = glGetUniformLocation(ourShader.Program, "view"); GLint projLoc = glGetUniformLocation(ourShader.Program, "projection"); glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection)); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, diffuseMap); glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture1"), 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, specularMap); /*GLfloat timeValue = glfwGetTime(); GLfloat greenValue = (sin(timeValue) / 2) + 0.5; GLint vertexColorLocation = glGetUniformLocation(ourShader.Program, "ourColor"); glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.4f, 1.0f);*/ glBindVertexArray(vertexArrayObject); GLint modelLoc = glGetUniformLocation(ourShader.Program, "model"); for (GLuint i = 0; i < 10; i++) { glm::mat4 model; model = glm::translate(model, cubePositions[i]); GLfloat angle = 50.0f; //model = glm::rotate(model, i * (GLfloat)sin(glfwGetTime() / 10.0f), glm::vec3(1.0f, 0.2f * i, i)); //model = glm::scale(model, glm::vec3(0.1f * i)); glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); glDrawArrays(GL_TRIANGLES, 0, 36); } glBindVertexArray(0); lightShader.Use(); // Get location objects for the matrices on the lamp shader (these could be different on a different shader) modelLoc = glGetUniformLocation(lightShader.Program, "model"); viewLoc = glGetUniformLocation(lightShader.Program, "view"); projLoc = glGetUniformLocation(lightShader.Program, "projection"); // Set matrices glm::mat4 model; glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection)); model = glm::mat4(); model = glm::translate(model, lightPos); model = glm::scale(model, glm::vec3(0.2f)); // Make it a smaller cube glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); // Draw the light object (using light's vertex attributes) glBindVertexArray(lightVAO); glDrawArrays(GL_TRIANGLES, 0, 36); glBindVertexArray(0); glfwSwapBuffers(window); } while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0); glfwTerminate(); return 0; }
int main() { if(!initGL()) return 1; Portal::init(); Shader shader("res/shaders/portal_vert.glsl","res/shaders/portal_frag.glsl"); shader.bind(); f32 vCube[24] = { -0.5, 0.5,-0.5, 0.5, 0.5,-0.5, -0.5,-0.5,-0.5, 0.5,-0.5,-0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5,-0.5, 0.5, 0.5,-0.5, 0.5 }; u32 iCube[36] = { 0,1,2, //Front 1,3,2, 0,4,5, //Top 1,0,5, 5,4,6, //Back 5,6,7, 2,3,7, //Bottom 6,2,7, 3,1,5, //Right 3,5,7, 4,0,6, //Left 0,2,6}; Mesh cube = Mesh( "v3f", GL_STATIC_DRAW, 24*sizeof(f32), vCube, GL_UNSIGNED_INT, GL_STATIC_DRAW, GL_TRIANGLES, 36*sizeof(u32), iCube, 36); Material red; red.setColor(vec3(1,0,0)); Material green; green.setColor(vec3(0,1,0)); Material blue; blue.setColor(vec3(0,0,1)); Material white; white.setColor(vec3(1,1,1)); Material yellow; yellow.setColor(vec3(1,1,0)); // MODULE A Model wallFrontA(&cube, &red); wallFrontA.setScale(vec3(10.0,2.0,1.0)); wallFrontA.setPosition(vec3(0,0,-2.5)); Model wallBackA(&cube, &blue); wallBackA.setScale(vec3(10.0,2.0,1.0)); wallBackA.setPosition(vec3(0,0,2.5)); Model wallLeftA(&cube, &green); wallLeftA.setScale(vec3(1.0,2.0,5.0)); wallLeftA.setPosition(vec3(-5.0,0,0)); Model wallRightA(&cube, &yellow); wallRightA.setScale(vec3(1.0,2.0,5.0)); wallRightA.setPosition(vec3(5.0,0,0)); Model floorModelA(&cube, &white); floorModelA.setScale(vec3(10,1,5)); floorModelA.setPosition(vec3(0,-1.5,0)); Model cubeModelA(&cube, &green); cubeModelA.setPosition(vec3(2,0,0)); Portal portalA(1.5f, 2.0f); portalA.setPosition(vec3(-4.49,0,0.0)); portalA.rotateY(90.0f); Portal portalA2(1.5f, 2.0f); portalA2.setPosition(vec3(-4.49,0,1.0)); portalA2.rotateY(90.0f); Module moduleA; moduleA.addGameObject(&wallFrontA); moduleA.addGameObject(&wallBackA); moduleA.addGameObject(&wallLeftA); moduleA.addGameObject(&wallRightA); moduleA.addGameObject(&floorModelA); moduleA.addGameObject(&cubeModelA); moduleA.addGameObject(&portalA); //moduleA.addGameObject(&portalA2); // MODULE B Model wallFrontB(&cube, &white); wallFrontB.setScale(vec3(10.0,2.0,1.0)); wallFrontB.setPosition(vec3(0,0,-2.5)); Model wallBackB(&cube, &green); wallBackB.setScale(vec3(10.0,2.0,1.0)); wallBackB.setPosition(vec3(0,0,2.5)); Model wallLeftB(&cube, &red); wallLeftB.setScale(vec3(1.0,2.0,5.0)); wallLeftB.setPosition(vec3(-5.0,0,0)); Model wallRightB(&cube, &yellow); wallRightB.setScale(vec3(1.0,2.0,5.0)); wallRightB.setPosition(vec3(5.0,0,0)); Model floorModelB(&cube, &blue); floorModelB.setScale(vec3(10,1,5)); floorModelB.setPosition(vec3(0,-1.5,0)); Model cubeModelB(&cube, &yellow); cubeModelB.setPosition(vec3(2,0,0)); Portal portalB(1.5f, 2.0f); portalB.setPosition(vec3(-4.49,0,1.0)); portalB.rotateY(90.0f); Portal portalB2(1.5f, 2.0f); portalB2.setPosition(vec3(-4.49,0,-1.0)); portalB2.rotateY(90.0f); Module moduleB; moduleB.addGameObject(&wallFrontB); moduleB.addGameObject(&wallBackB); moduleB.addGameObject(&wallLeftB); moduleB.addGameObject(&wallRightB); moduleB.addGameObject(&floorModelB); //moduleB.addGameObject(&cubeModelB); //moduleB.addGameObject(&portalB); moduleB.addGameObject(&portalB2); moduleB.addGameObject(&portalB); // Set targets portalA.setTargetPortal(&portalB); portalB.setTargetPortal(&portalA); portalB2.setTargetPortal(&portalA); //portalA2.setTargetPortal(&portalB2); Camera camera; camera.translate(vec3(0, 0, 0)); camera.setupProjection(800,600); // Add camera to moduleA moduleB.addGameObject(&camera); vec4 v(0.5,0.5,-0.1,1); mat4 proj = glm::perspective(60.0f, 4.0f/3.0f, 0.1f, 100.0f); proj[2][2] = 1.0f; //proj[2][3] = 0.0f; proj[3][2] = 0.0f; //proj[3][3] = 1.0f; v = proj * v; v = v / v.w; printf("matrix : \n"); for(int i=0; i<4; ++i) { printf("%f, %f, %f, %f \n", proj[0][i], proj[1][i], proj[2][i], proj[3][i]); } printf("vector! ( %f, %f, %f, %f ) \n", v.x, v.y, v.z, v.w); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glfwSwapInterval(1); while(true) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); handleCamera(&camera); camera.render(); glfwSwapBuffers(); if(glfwGetKey(GLFW_KEY_ESC)) break; } Portal::cleanup(); cleanup(); return 0; }
int main(void) { _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); int width = 800, height = 600; GLFWwindow* window; glfwSetErrorCallback(error_callback); if (!glfwInit()) exit(EXIT_FAILURE); window = glfwCreateWindow(width, height, "cpu-voxels", NULL, NULL); if (!window) { glfwTerminate(); return 1; } glfwMakeContextCurrent(window); glfwSwapInterval(0); glfwSetKeyCallback(window, key_callback); glfwSetMouseButtonCallback(window, mouse_button_callback); glfwSetCursorPosCallback(window, mouse_move_callback); glfwSetKeyCallback(window, key_callback); vec3 eye = vec3_create(0.0f, 0.0f, VOXEL_BRICK_SIZE * 4); vec3 center = vec3f(0.0f); vec3 up = vec3_create(0.0, 1.0, 0.0 ); orbit_camera_init(eye, center, up); // TODO: handle resize int dw, dh; glfwGetFramebufferSize(window, &dw, &dh); int stride = 3; int total = dw*dh*stride; uint8_t *data = malloc(total); vec3 ro; //, rd; mat4 m4inverted, view; mat4 projection; mat4_perspective( projection, M_PI/4.0, (float)width/(float)height, 0.1, 1000.0 ); GLuint texture[1]; #ifdef ENABLE_THREADS screen_area areas[TOTAL_THREADS]; threadpool thpool = thpool_init(TOTAL_THREADS); #else screen_area areas[1]; #endif glGenTextures(1, texture); float start = glfwGetTime(); int fps = 0; voxel_brick my_first_brick = voxel_brick_create(); // TODO: make this work when the brick lb corner is not oriented at 0,0,0 voxel_brick_position(my_first_brick, vec3f(0.0f)); voxel_brick_fill(my_first_brick, &brick_fill); while (!glfwWindowShouldClose(window)) { if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) { orbit_camera_rotate(0, 0, -.1, 0); } if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) { orbit_camera_rotate(0, 0, .1, 0); } if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) { orbit_camera_rotate(0, 0, 0, .1); } if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) { orbit_camera_rotate(0, 0, 0, -.1); } glfwGetFramebufferSize(window, &width, &height); float now = glfwGetTime(); if (now - start > 1) { unsigned long long total_rays = (fps * width * height); printf("fps: %i (%f Mrays/s)@%ix%i - %i threads\n", fps, total_rays/1000000.0, width, height, TOTAL_THREADS); start = now; fps = 0; } fps++; orbit_camera_view(view); ro = mat4_get_eye(view); mat4_mul(m4inverted, projection, view); mat4_invert(m4inverted, m4inverted); // compute 3 points so that we can interpolate instead of unprojecting // on every point vec3 rda, rdb, planeYPosition, dcol, drow; vec3 t0 = vec3_create(0, 0, 0), tx = vec3_create(1, 0, 0), ty = vec3_create(0, 1, 0); vec4 viewport = { 0, 0, width, height }; rda = orbit_camera_unproject(t0, viewport, m4inverted); rdb = orbit_camera_unproject(tx, viewport, m4inverted); planeYPosition = orbit_camera_unproject(ty, viewport, m4inverted); dcol = planeYPosition - rda; drow = rdb - rda; int i=0, bh = height; #ifdef ENABLE_THREADS bh = (height/TOTAL_THREADS); for (i; i<TOTAL_THREADS; i++) { #endif areas[i].dcol = dcol; areas[i].drow = drow; areas[i].pos = planeYPosition; areas[i].ro = ro; areas[i].x = 0; areas[i].y = i*bh; areas[i].width = width; areas[i].height = areas[i].y + (int)(bh); areas[i].screen_height = (int)(height); areas[i].stride = stride; areas[i].data = data; areas[i].render_id = i; areas[i].brick = my_first_brick; #ifdef ENABLE_THREADS thpool_add_work(thpool, (void *)render_screen_area, (void *)(&areas[i])); } thpool_wait(thpool); #else render_screen_area((void *)(&areas[i])); #endif #ifdef RENDER glViewport(0, 0, width, height); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDisable(GL_CULL_FACE); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glScalef(1.0f, -1.0f, 1.0f); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture[0]); glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex2f( -1, -1); glTexCoord2f(1.0f, 0.0f); glVertex2f( 1, -1); glTexCoord2f(1.0f, 1.0f); glVertex2f( 1, 1); glTexCoord2f(0.0f, 1.0f); glVertex2f( -1, 1); glEnd(); glfwSwapBuffers(window); glDeleteTextures(1, &texture[0]); #endif glfwPollEvents(); } glfwDestroyWindow(window); glfwTerminate(); exit(EXIT_SUCCESS); }
void gameDialog::Update() { static int wheel = 0; static bool inWater = false; static bool inAir = false; unsigned char bl; // Detect usage of the mouse wheel int newWheel = glfwGetMouseWheel(); if (newWheel != wheel) { if (gMode.Get() == GameMode::CONSTRUCT) { fBuildingBlocks->UpdateSelection(newWheel); } else if (fDrawMap) { float fact = 1.0f + (wheel-newWheel)/10.0f; fMapWidth = fMapWidth * fact; if (fMapWidth < 100) fMapWidth = 100; } else { this->fRequestedCameraDistance += wheel-newWheel; if (this->fRequestedCameraDistance < 0.0f) this->fRequestedCameraDistance = 0.0f; if (this->fRequestedCameraDistance > 20.0f) this->fRequestedCameraDistance = 20.0f; // Don't allow unlimited third person view distance } wheel = newWheel; } if (gMode.Get() == GameMode::CONSTRUCT && (glfwGetKey(GLFW_KEY_DEL) == GLFW_PRESS || glfwGetKey('V') == GLFW_PRESS) && glfwGetMouseButton(GLFW_MOUSE_BUTTON_1) == GLFW_PRESS) { int x, y; glfwGetMousePos(&x, &y); this->ClickOnBlock(x, y); } gMonsters.Cleanup(); gOtherPlayers.Cleanup(); while (ListenForServerMessages()) continue; // Determine if player head is under water bl = chunk::GetChunkAndBlock(gPlayer.x, gPlayer.y, gPlayer.z); if (bl == BT_Air && fUnderWater) { gSoundControl.SetSoundFxStatus(SoundControl::SEnvironmentUnderWater,false); fUnderWater = false; } if ((bl == BT_Water || bl == BT_BrownWater) && !fUnderWater) { gSoundControl.SetSoundFxStatus(SoundControl::SEnvironmentUnderWater,true); fUnderWater = true; // Not in water when under water gSoundControl.SetSoundFxStatus(SoundControl::SPlayerFeetInWater,false); inWater = false; } // Determine if feet are wet // TODO: Change "magic number" for player height! bl = chunk::GetChunkAndBlock(gPlayer.x, gPlayer.y, gPlayer.z-350); if ((bl != BT_Water && bl != BT_BrownWater) && inWater && !fUnderWater) { gSoundControl.SetSoundFxStatus(SoundControl::SPlayerFeetInWater,false); inWater = false; } if ((bl == BT_Water || bl == BT_BrownWater) && !inWater && !fUnderWater) { gSoundControl.SetSoundFxStatus(SoundControl::SPlayerFeetInWater,true); inWater = true; } // TODO: Change "magic number" for player height! bl = chunk::GetChunkAndBlock(gPlayer.x, gPlayer.y, gPlayer.z-400); if (bl != BT_Air && inAir) { gSoundControl.SetSoundFxStatus(SoundControl::SPlayerInAir,false); inAir = false; } if (bl == BT_Air && !inAir) { gSoundControl.SetSoundFxStatus(SoundControl::SPlayerInAir,true); inAir = true; } this->UpdateCameraPosition(); gGameDialog.UpdateRunningStatus(false); if (Options::fgOptions.fFullScreen) { // Full screen, which means mouse is usually disabled. But there are cases when it is needed. bool showMouseFullscreen = false; static bool wasShowingMouse = false; if ((fShowMainDialog && !fHideDialog) || gMode.Get() == GameMode::CONSTRUCT || fShowInventory) showMouseFullscreen = true; if (wasShowingMouse && !showMouseFullscreen) { glfwDisable(GLFW_MOUSE_CURSOR); wasShowingMouse = false; } if (!wasShowingMouse && showMouseFullscreen) { glfwEnable(GLFW_MOUSE_CURSOR); wasShowingMouse = true; } } this->UpdateEffect(); gChunkProcess.Poll(); // Update all results }
//----------------------------------------------------------------------------- bool SYS_KeyPressed(int key) { return glfwGetKey(key); }
int main( void ) { int width, height, x; double t; // Initialise GLFW if( !glfwInit() ) { fprintf( stderr, "Failed to initialize GLFW\n" ); exit( EXIT_FAILURE ); } // Open a window and create its OpenGL context if( !glfwOpenWindow( 640, 480, 0,0,0,0, 0,0, GLFW_WINDOW ) ) { fprintf( stderr, "Failed to open GLFW window\n" ); glfwTerminate(); exit( EXIT_FAILURE ); } glfwSetWindowTitle( "Spinning Triangle" ); // Ensure we can capture the escape key being pressed below glfwEnable( GLFW_STICKY_KEYS ); // Enable vertical sync (on cards that support it) glfwSwapInterval( 1 ); do { t = glfwGetTime(); glfwGetMousePos( &x, NULL ); // Get window size (may be different than the requested size) glfwGetWindowSize( &width, &height ); // Special case: avoid division by zero below height = height > 0 ? height : 1; glViewport( 0, 0, width, height ); // Clear color buffer to black glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); glClear( GL_COLOR_BUFFER_BIT ); // Select and setup the projection matrix glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective( 65.0f, (GLfloat)width/(GLfloat)height, 1.0f, 100.0f ); // Select and setup the modelview matrix glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); gluLookAt( 0.0f, 1.0f, 0.0f, // Eye-position 0.0f, 20.0f, 0.0f, // View-point 0.0f, 0.0f, 1.0f ); // Up-vector // Draw a rotating colorful triangle glTranslatef( 0.0f, 14.0f, 0.0f ); glRotatef( 0.3f*(GLfloat)x + (GLfloat)t*100.0f, 0.0f, 0.0f, 1.0f ); glBegin( GL_TRIANGLES ); glColor3f( 1.0f, 0.0f, 0.0f ); glVertex3f( -5.0f, 0.0f, -4.0f ); glColor3f( 0.0f, 1.0f, 0.0f ); glVertex3f( 5.0f, 0.0f, -4.0f ); glColor3f( 0.0f, 0.0f, 1.0f ); glVertex3f( 0.0f, 0.0f, 6.0f ); glEnd(); // Swap buffers glfwSwapBuffers(); } // Check if the ESC key was pressed or the window was closed while( glfwGetKey( GLFW_KEY_ESC ) != GLFW_PRESS && glfwGetWindowParam( GLFW_OPENED ) ); // Close OpenGL window and terminate GLFW glfwTerminate(); exit( EXIT_SUCCESS ); }
bool CApplication::IsAltDown() { return glfwGetKey(GLFW_KEY_LALT) || glfwGetKey(GLFW_KEY_RALT); }
int main() { int width = 512; int height = 512; if(glfwInit() == GL_FALSE) { std::cerr << "failed to init GLFW" << std::endl; return 1; } // select opengl version glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 4); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2); // create a window if(glfwOpenWindow(width, height, 0, 0, 0, 8, 24, 8, GLFW_WINDOW) == GL_FALSE) { std::cerr << "failed to open window" << std::endl; glfwTerminate(); return 1; } // setup windows close callback glfwSetWindowCloseCallback(closedWindow); if (gl3wInit()) { std::cerr << "failed to init GL3W" << std::endl; glfwCloseWindow(); glfwTerminate(); return 1; } glfwSwapInterval(1); // shader source code // shared vertex shader std::string vertex_source = "#version 420\n" "layout(location = 0) in vec4 vposition;\n" "void main() {\n" " gl_Position = vposition;\n" "}\n"; // the first fragment shader doesn't output anything since it only // updates the image in place std::string fragment1_source = "#version 420\n" "uniform float dt;\n" "uniform ivec2 image_size;\n" "uniform layout(rgba32f) image2D image;\n" "layout(location = 0) out vec4 FragColor;\n" "void main() {\n" " ivec2 coords = ivec2(gl_FragCoord.xy);\n" " vec4 HE = imageLoad(image, coords);\n" " float Ezdx = HE.z-imageLoad(image, coords-ivec2(1, 0)).z;\n" " float Ezdy = HE.z-imageLoad(image, coords-ivec2(0, 1)).z;\n" " HE.xy += dt*vec2(-Ezdy, Ezdx);\n" " imageStore(image, coords, HE);\n" "}\n"; // the second fragment shader also outputs the frag color for display // purposes std::string fragment2_source = "#version 420\n" "uniform float t;\n" "uniform float dt;\n" "uniform ivec2 image_size;\n" "uniform layout(rgba32f) image2D image;\n" "layout(location = 0) out vec4 FragColor;\n" "void main() {\n" " ivec2 coords = ivec2(gl_FragCoord.xy);\n" " float e = 1;\n" " vec4 HE = imageLoad(image, coords);\n" " float r = HE.w;\n" " float Hydx = imageLoad(image, coords+ivec2(1, 0)).y\n" " -HE.y;\n" " float Hxdy = imageLoad(image, coords+ivec2(0, 1)).x\n" " -HE.x;\n" " float Eout = dt*(Hydx-Hxdy)/(e);\n" " HE.z = HE.z*(1-dt*r/e) + Eout;\n" // add source at image center " if(coords.x == image_size.x/2 && coords.y == image_size.y/2) {\n" " HE.z += 30*sin(15*t)*exp(-10*(t-2)*(t-2));\n" " }\n" " imageStore(image, coords, HE);\n" " FragColor = vec4(HE.z, HE.w, -HE.z, 1);\n" "}\n"; // program and shader handles GLuint shader1_program, shader2_program, vertex_shader, fragment1_shader, fragment2_shader; // we need these to properly pass the strings const char *source; int length; // create and compiler vertex shader vertex_shader = glCreateShader(GL_VERTEX_SHADER); source = vertex_source.c_str(); length = vertex_source.size(); glShaderSource(vertex_shader, 1, &source, &length); glCompileShader(vertex_shader); if(!check_shader_compile_status(vertex_shader)) { return 1; } // create and compiler fragment shader fragment1_shader = glCreateShader(GL_FRAGMENT_SHADER); source = fragment1_source.c_str(); length = fragment1_source.size(); glShaderSource(fragment1_shader, 1, &source, &length); glCompileShader(fragment1_shader); if(!check_shader_compile_status(fragment1_shader)) { return 1; } // create and compiler fragment shader fragment2_shader = glCreateShader(GL_FRAGMENT_SHADER); source = fragment2_source.c_str(); length = fragment2_source.size(); glShaderSource(fragment2_shader, 1, &source, &length); glCompileShader(fragment2_shader); if(!check_shader_compile_status(fragment2_shader)) { return 1; } // create program shader1_program = glCreateProgram(); // attach shaders glAttachShader(shader1_program, vertex_shader); glAttachShader(shader1_program, fragment1_shader); // link the program and check for errors glLinkProgram(shader1_program); check_program_link_status(shader1_program); // get texture uniform location GLint image_size_location1 = glGetUniformLocation(shader1_program, "image_size"); GLint image_location1 = glGetUniformLocation(shader1_program, "image"); GLint dt_location1 = glGetUniformLocation(shader1_program, "dt"); // create program shader2_program = glCreateProgram(); // attach shaders glAttachShader(shader2_program, vertex_shader); glAttachShader(shader2_program, fragment2_shader); // link the program and check for errors glLinkProgram(shader2_program); check_program_link_status(shader2_program); // get texture uniform location GLint image_size_location2 = glGetUniformLocation(shader2_program, "image_size"); GLint image_location2 = glGetUniformLocation(shader2_program, "image"); GLint t_location2 = glGetUniformLocation(shader2_program, "t"); GLint dt_location2 = glGetUniformLocation(shader2_program, "dt"); // vao and vbo handle GLuint vao, vbo, ibo; // generate and bind the vao glGenVertexArrays(1, &vao); glBindVertexArray(vao); // generate and bind the vertex buffer object glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); // data for a fullscreen quad GLfloat vertexData[] = { // X Y Z 1.0f, 1.0f, 0.0f, // vertex 0 -1.0f, 1.0f, 0.0f, // vertex 1 1.0f,-1.0f, 0.0f, // vertex 2 -1.0f,-1.0f, 0.0f, // vertex 3 }; // 4 vertices with 3 components (floats) each // fill with data glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*4*3, vertexData, GL_STATIC_DRAW); // set up generic attrib pointers glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), (char*)0 + 0*sizeof(GLfloat)); // generate and bind the index buffer object glGenBuffers(1, &ibo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); GLuint indexData[] = { 0,1,2, // first triangle 2,1,3, // second triangle }; // fill with data glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*2*3, indexData, GL_STATIC_DRAW); // "unbind" vao glBindVertexArray(0); // texture handle GLuint texture; // generate texture glGenTextures(1, &texture); // bind the texture glBindTexture(GL_TEXTURE_2D, texture); // create some image data std::vector<GLfloat> image(4*width*height); for(int j = 0;j<height;++j) for(int i = 0;i<width;++i) { size_t index = j*width + i; image[4*index + 0] = 0.0f; image[4*index + 1] = 0.0f; image[4*index + 2] = 0.0f; image[4*index + 3] = 20.0f*glm::clamp(glm::perlin(0.008f*glm::vec2(i,j+70)),0.0f,0.1f); } // set texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); // set texture content glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, &image[0]); float t = 0; float dt = 1.0f/60.0f; running = true; while(running) { t += dt; // reset time every 10 seconds to repeat the sequence if(t>10) t -= 10; // terminate on escape if(glfwGetKey(GLFW_KEY_ESC)) { running = false; } // clear first glClear(GL_COLOR_BUFFER_BIT); glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); // bind the vao glBindVertexArray(vao); int substeps = 5; glUseProgram(shader1_program); glUniform2i(image_size_location1, width, height); glUniform1i(image_location1, 0); glUniform1f(dt_location1, 50*dt/substeps); glUseProgram(shader2_program); glUniform2i(image_size_location2, width, height); glUniform1i(image_location2, 0); glUniform1f(dt_location2, 50*dt/substeps); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); int i = 0; for(;i<substeps-1;++i) { glUseProgram(shader1_program); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glUseProgram(shader2_program); glUniform1f(t_location2, t+i*dt/substeps); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); } glUseProgram(shader1_program); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glUseProgram(shader2_program); glUniform1f(t_location2, t+i*dt/substeps); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); // check for errors GLenum error = glGetError(); if(error != GL_NO_ERROR) { std::cerr << gluErrorString(error); running = false; } // finally swap buffers glfwSwapBuffers(); } // delete the created objects glDeleteTextures(1, &texture); glDeleteVertexArrays(1, &vao); glDeleteBuffers(1, &vbo); glDeleteBuffers(1, &ibo); glDetachShader(shader1_program, vertex_shader); glDetachShader(shader1_program, fragment1_shader); glDetachShader(shader2_program, vertex_shader); glDetachShader(shader2_program, fragment2_shader); glDeleteShader(vertex_shader); glDeleteShader(fragment1_shader); glDeleteProgram(shader1_program); glDeleteShader(fragment2_shader); glDeleteProgram(shader2_program); glfwCloseWindow(); glfwTerminate(); return 0; }
bool CApplication::IsShiftDown() { return glfwGetKey(GLFW_KEY_LSHIFT) || glfwGetKey(GLFW_KEY_RSHIFT); }
void CameraMovement::updateSmoothMovement() { /* Acceleration/Decceleration */ if(glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) { velocity += deltaTime * ACCELERATION_CONSTANT; velocity = CLAMP<float>(velocity, 0, 0.6); } else if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) { velocity *= 0.9f; } else { velocity *= 0.95f; } if(std::abs(velocity) < 0.001f) { velocity = 0.0f; } this->currentCurveT += this->deltaTime * this->velocity; /* Turning */ if(glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS && !hasRegisteredTurnKey) { turningAmount = 1.f; hasRegisteredTurnKey = true; shouldCalculateCurve = true; } else if(glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS && !hasRegisteredTurnKey) { turningAmount = -1.f; hasRegisteredTurnKey = true; shouldCalculateCurve = true; } else if (glfwGetKey(window, GLFW_KEY_A) == GLFW_RELEASE && glfwGetKey(window, GLFW_KEY_D) == GLFW_RELEASE) { turningAmount = 0.0f; hasRegisteredTurnKey = false; } glm::vec3 deltaMovement; // If within the curve, get new position if(this->currentCurveT <= 1.0f) { this->position = glm::vec3(curve.getPosition(currentCurveT)); deltaMovement = position - lastPosition; } else { // Otherwise create new curve and start from beginning this->curve.startPoint = this->curve.getPosition(currentCurveT); this->curve.controlPoint = this->curve.startPoint + glm::normalize(lookatDirection) * 3.f; this->curve.endPoint = this->curve.startPoint + glm::normalize(lookatDirection) * 6.f; currentCurveT = 0.0f; } // Update lookatDirection to match travel direction if(glm::length(deltaMovement) > 0.0f) { this->lookatDirection = deltaMovement; // If turning, create new bezier curve if(std::abs(turningAmount) > 0.0f && shouldCalculateCurve) { this->curve.startPoint = this->curve.getPosition(currentCurveT); this->curve.controlPoint = this->curve.startPoint + glm::normalize(lookatDirection) * 3.f; glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), turningAmount * 60.f, glm::vec3(0.0f,1.0f, 0.0f)); glm::vec3 rotatedPoint = glm::vec3(rotation * glm::vec4(glm::normalize(lookatDirection), 1.0)); this->curve.endPoint = this->curve.startPoint + rotatedPoint * 6.f; shouldCalculateCurve = false; currentCurveT = 0.0f; } } this->lastPosition = this->position; }
void InputService::update() { if(_infoSlot == NULL) { _isTerminationPending = true; _terminationMessage = "Missing InfoHandle"; } else { int mousePositionX, mousePositionY; glfwGetMousePos(&mousePositionX, &mousePositionY); _inputHandle->setMousePosition(mousePositionX, mousePositionY); _inputHandle->resetKeys(); if(glfwGetKey(GLFW_KEY_ESC) == GLFW_PRESS) { //std::cout << "Pressed ESC" << std::endl; _inputHandle->toggleKey(InputHandle::KEY_ESC); } if(glfwGetKey(167) == GLFW_PRESS && glfwGetKey(167) == GLFW_RELEASE) { //std::cout << "PRESSED 167" << std::endl; _audio->play(3); if (_state == INGAME) { setState(CONSOLE); _inputHandle->setState(_state); } else if (_state == CONSOLE) { setState(INGAME); _inputHandle->setState(_state); } _console->clearCommand(); _console->updateText(); resetKeys(); } // Legacy :) Still needed though if(_state == INGAME) { if(glfwGetKey('A') == GLFW_PRESS) { //std::cout << "Pressed A" << std::endl; if(!_infoSlot->getIsJumping()) _audio->play(0); _inputHandle->toggleKey(InputHandle::KEY_A); } if(glfwGetKey('S') == GLFW_PRESS) { //std::cout << "Pressed S" << std::endl; if(!_infoSlot->getIsJumping()) _audio->play(0); _inputHandle->toggleKey(InputHandle::KEY_S); } if(glfwGetKey('D') == GLFW_PRESS) { //std::cout << "Pressed D" << std::endl; if(!_infoSlot->getIsJumping()) _audio->play(0); _inputHandle->toggleKey(InputHandle::KEY_D); } if(glfwGetKey('W') == GLFW_PRESS) { //std::cout << "Pressed W" << std::endl; if(!_infoSlot->getIsJumping()) _audio->play(0); _inputHandle->toggleKey(InputHandle::KEY_W); } if(glfwGetKey(GLFW_KEY_SPACE) == GLFW_PRESS) { _audio->play(4); _inputHandle->toggleKey(InputHandle::KEY_SPACE); } if(glfwGetMouseButton(GLFW_MOUSE_BUTTON_1) == GLFW_PRESS) { //std::cout << "Mouse 1" << std::endl; _audio->play(1); } if(glfwGetMouseButton(GLFW_MOUSE_BUTTON_2) == GLFW_PRESS) { //std::cout << "Mouse 1" << std::endl; _audio->play(2); } } /*if(glfwGetKey(GLFW_KEY_ESC) == GLFW_PRESS || !glfwGetWindowParam(GLFW_OPENED)) { _isTerminationPending = true; _terminationMessage = "Termination by user input"; }*/ } }
int main( int argc, char** argv ) { std::cout << "Starting..\n"; std::vector<std::string> file_names; parse_args(argc, argv, file_names); file_names.push_back(std::string("b0e0.hgt")); InitGraphics(); glfwSetWindowTitle( "p7" ); // Ensure we can capture the escape key being pressed below glfwEnable( GLFW_STICKY_KEYS ); // Dark blue background glClearColor(0.7f, 0.7f, 0.7f, 0.0f); // Enable depth test glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); // Accept fragment if it closer to the camera than the former one glDepthFunc(GL_LESS); // glFrontFace(GL_CCW); // Create and compile our GLSL program from the shaders GLuint programIDs[2] = { LoadShaders( "tvs.vertexshader", "cfs.fragmentshader" ), LoadShaders( "tvs2.vertexshader", "cfs.fragmentshader" )}; std::cout << "Linked shaders..\n"; // Get a handle for our "MVP" uniform GLuint MatrixIDs[2] = {glGetUniformLocation(programIDs[0], "MVP"), glGetUniformLocation(programIDs[1], "MVP")}; GLuint EdgexIDs[2] = {glGetUniformLocation(programIDs[0], "Edgex"), glGetUniformLocation(programIDs[1], "Edgex")}; GLuint EdgeyIDs[2] = {glGetUniformLocation(programIDs[0], "Edgey"), glGetUniformLocation(programIDs[1], "Edgey")}; GLuint HeightIDs[2] = {glGetUniformLocation(programIDs[0], "height"), glGetUniformLocation(programIDs[1], "height")}; GLuint TextureIDs[2] = {glGetUniformLocation(programIDs[0], "tex2d"), glGetUniformLocation(programIDs[1], "tex2d")}; GLuint TimeIDs[2] = {glGetUniformLocation(programIDs[0], "time"), glGetUniformLocation(programIDs[1], "time")}; GLuint AlphaIDs[2] = {glGetUniformLocation(programIDs[0], "alpha"), glGetUniformLocation(programIDs[1], "alpha")}; std::cout << "Got uniforms..\n"; std::cout << glGetString(GL_VERSION) << std::endl; std::cout << "Loadin textures...\n"; char texName[] = "texture3.jpg"; std::cout << texName << std::endl; int t1x,t1y,t1comp; FILE* t1f = fopen(texName, "rb"); unsigned char* tex1data = stbi_load_from_file(t1f, &t1x, &t1y, &t1comp,0); unsigned int tex_2d; glGenTextures(1, &tex_2d); glBindTexture(GL_TEXTURE_2D, tex_2d); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, t1x, t1y, 0, GL_RGB, GL_UNSIGNED_BYTE, tex1data); /* char texNameCl[] = "textureClouds3.png"; std::cout << texNameCl << std::endl; int t2x,t2y,t2comp; FILE* t2f = fopen(texNameCl, "rb"); unsigned char* tex2data = stbi_load_from_file (t2f, &t2x, &t2y, &t2comp,0); unsigned int tex_cl; glGenTextures(1, &tex_cl); glBindTexture(GL_TEXTURE_2D, tex_cl); //--> glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, t2x, t2y, 0, GL_RGB, GL_UNSIGNED_BYTE, tex2data); */ std::cout << "Done!\n"; const int side(1201); const int vBOsize(file_names.size()); //Vertices: short piece_map[360][181]; for(int i=0; i<360; i++) for(int y=0; y<=180; y++) piece_map[i][y] = -1; unsigned int numberOfVertices=side*side; GLuint vaoObjects[vBOsize+1], vertexBufferObject, vBOs[vBOsize+1]; std::vector<std::pair<int, int> > edges(vBOsize+1); // --> std::cout << "Generating arrays...\n"; glGenVertexArrays(vBOsize, vaoObjects); std::cout << "Done\n"; glGenBuffers(vBOsize, vBOs); int height; // <--- for(short i=0; i< vBOsize; i++) { std::vector< int > vertexPositionsVec(3*numberOfVertices); int* vertexPositions = &vertexPositionsVec[0]; loadVertices(file_names[i], vertexPositionsVec, true, side, edges[i], height); glBindVertexArray(vaoObjects[i]); glBindBuffer(GL_ARRAY_BUFFER, vBOs[i]); glVertexAttribPointer( 0, // attribute. No particular reason for 0, but must match the layout in the shader. 3, // size GL_INT, // type GL_FALSE, // normalized? 0, // stride (void*)0 // array buffer offset ); glBufferData(GL_ARRAY_BUFFER, sizeof(int)*3*numberOfVertices, vertexPositions, GL_STATIC_DRAW); if(i<vBOsize-1) { piece_map[edges[i].second+180][edges[i].first+90]=i; std::cout << edges[i].second+180 << " " << edges[i].first+90 << std::endl; } } //Indices:: GLuint indexBufferObject, iBOs[maxLoD], numberOfIndices; std::vector<GLuint> nOIs(maxLoD); glGenBuffers(maxLoD, iBOs); for(unsigned int density=1, i=0; i<maxLoD; i++, density*=2) { std::cout << "Entering for with i: " << i << "\n"; nOIs[i]=(side-1)/density; if((side-1)%density!=0) nOIs[i]+=1; nOIs[i]=6*(nOIs[i]*(nOIs[i])); std::cout << "Allocating memory...\n"; GLuint* indices = new GLuint [nOIs[i]]; std::cout << "Done.\n"; glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iBOs[i]); std::cout << "Density: " << density << " Number of indices: " << nOIs[i] << std::endl; genIndices(indices, side, density); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*nOIs[i], indices, GL_STATIC_DRAW); std::cout << "Leaving for with i: " << i << "\n"; } // Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units glm::mat4 Projection = // glm::mat4(1.0f); glm::perspective(45.0f, 4.0f / 3.0f, 100.f, 30000.0f); // Camera matrix // int xVw = edges[0].first*side, yVw = edges[0].second*side; int xVw = 6000, yVw = -6000; height = 3000; glm::mat4 View = glm::lookAt( glm::vec3(xVw,yVw,2*height), // Camera is at (4,3,-3), in World Space glm::vec3(xVw,yVw,0), // and looks at the origin glm::vec3(0,1,0) // Head is up (set to 0,-1,0 to look upside-down) ); // Model matrix : an identity matrix (model will be at the origin) glm::mat4 Model = glm::mat4(1.0f); // Our ModelViewProjection : multiplication of our 3 matrices glm::mat4 MVP = Projection * View * Model; // Remember, matrix multiplication is the other way around std::cout << "Init done.\n"; glfwSetKeyCallback(Key_Callback); double last_time = glfwGetTime(), last_reset=last_time; int FPScounter=0; x = edges[0].second*12010; startx=x; y = edges[0].first*12010; starty=y; std::cout << edges[0].first << " " << edges[0].second << std::endl; do { int ex = x/12010+180; int ey = y/12010+90; //time statistics: FPScounter++; double cur_time = glfwGetTime(); if(cur_time-last_reset>=2) { double FPS = (float)FPScounter/(cur_time-last_reset); std::cout << "FPS: " << FPS << " lod: " << iBOindex << std::endl; std::cout << ex << " " << ey << " " << alpha << std::endl; if(autolod && abs(FPS-optfps)>4) { if(FPS<optfps && iBOindex<maxLoD) iBOindex++; if(FPS>4*optfps && iBOindex > 0) iBOindex--; } FPScounter=0; last_reset=cur_time; } last_time=cur_time; // Clear the screen glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Use our shader glUseProgram(programIDs[ball]); glm::mat4 Vw; // Send our transformation to the currently bound shader, // in the "MVP" uniform Vw=MVP * glm::translate( mat4(1.0),vec3((-x + 6000)*ball,(-y - 6000)*ball,(z - 12000)*ball)) * glm::rotate(mat4(1.0), oz, glm::vec3(0,1,0)) * glm::rotate(mat4(1.0), ox, glm::vec3(1,0,0)) * glm::rotate(mat4(1.0), oy, glm::vec3(0,0,1)) * glm::translate( mat4(1.0), vec3(-x*(1-ball), -y*(1-ball), z*(1-ball))); glUniformMatrix4fv(MatrixIDs[ball], 1, GL_FALSE, &Vw[0][0]); glUniform1i(HeightIDs[ball], 0); glUniform1f(TimeIDs[ball], glfwGetTime()); glUniform1f(AlphaIDs[ball], (float)alpha*0.1); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex_2d); glUniform1i(TextureIDs[ball], /*GL_TEXTURE0+*/0); indexBufferObject=iBOs[iBOindex]; numberOfIndices=nOIs[iBOindex]; // std::cout << ex << " " << ey << std::endl; if(ball==0) { glCullFace(GL_FRONT); for(int i = max(ex-3,0); i<= min(ex+3,360) ; i++) for(int j=max(ey-3,0); j<= min(ey+3,180); j++) { glUniform1i(EdgexIDs[ball], (i-180)); glUniform1i(EdgeyIDs[ball], (j-90)); int point; if(piece_map[i][j]==-1) { point=vBOsize-1; draw(vaoObjects[point], vBOs[point], iBOs[maxLoD-1], nOIs[maxLoD-1]); } else { point = piece_map[i][j]; draw(vaoObjects[point], vBOs[point], indexBufferObject, numberOfIndices); } // std::cout << "Drawing " << file_names[point] << "with mods " << i-180 << " " << j-90 << std::endl // << i << " " << ex << " " << j << " " << ey << std::endl; } } else { glCullFace(GL_FRONT); for(int i=/*edges[0].second+180+*/0; i</*edges[0].second+18*/360; i++) for(int j=/*edges[0].first+90+*/0; j<=/*edges[0].first+90*/180; j++) { glUniform1i(EdgexIDs[ball], (i-180)); glUniform1i(EdgeyIDs[ball], (j-90)); int point; if(piece_map[i][j]==-1) { point=vBOsize-1; draw(vaoObjects[point], vBOs[point], iBOs[maxLoD-1], nOIs[maxLoD-1]); } else { point = piece_map[i][j]; draw(vaoObjects[point], vBOs[point], indexBufferObject, numberOfIndices); } } } //CLOUDS /* Vw=MVP * glm::translate( mat4(1.0),vec3((-x + 6000)*ball,(-y - 6000)*ball,(z - 12000)*ball)) * glm::rotate(mat4(1.0), oz+(float)glfwGetTime(), glm::vec3(0,1,0)) * glm::rotate(mat4(1.0), ox, glm::vec3(1,0,0)) * glm::rotate(mat4(1.0), oy, glm::vec3(0,0,1)) * glm::translate( mat4(1.0), vec3(-x*(1-ball), -y*(1-ball), z*(1-ball))); glUniformMatrix4fv(MatrixIDs[ball], 1, GL_FALSE, &Vw[0][0]); glUniform1i(HeightIDs[ball], 100); glUniform1f(TimeIDs[ball], glfwGetTime()); glUniform1f(AlphaIDs[ball], 0.25); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex_cl); glUniform1i(TextureIDs[ball], 0); indexBufferObject=iBOs[iBOindex]; numberOfIndices=nOIs[iBOindex]; // std::cout << ex << " " << ey << std::endl; if(ball==0) { glCullFace(GL_FRONT); for(int i = max(ex-3,0); i<= min(ex+3,360) ;i++) for(int j=max(ey-3,0); j<= min(ey+3,180); j++) { glUniform1i(EdgexIDs[ball], (i-180)); glUniform1i(EdgeyIDs[ball], (j-90)); int point; { point=vBOsize-1; draw(vaoObjects[point], vBOs[point], iBOs[maxLoD-1], nOIs[maxLoD-1]); } } } else { glCullFace(GL_FRONT); for(int i=0; i<360;i++) for(int j=0; j<=180;j++) { glUniform1i(EdgexIDs[ball], (i-180)); glUniform1i(EdgeyIDs[ball], (j-90)); int point; { point=vBOsize-1; draw(vaoObjects[point], vBOs[point], iBOs[maxLoD-1], nOIs[maxLoD-1]); } } }*/ // Swap buffers glfwSwapBuffers(); } // Check if the ESC key was pressed or the window was closed while( glfwGetKey( GLFW_KEY_ESC ) != GLFW_PRESS && glfwGetWindowParam( GLFW_OPENED ) ); // Cleanup VBO and shader glDeleteProgram(programIDs[0]); glDeleteProgram(programIDs[1]); // CleanVBOs(vaoObjects, vBOs, vBOsize+1, iBOs, tex_2d); std::cout << "Cleaning done, terminating..\n"; // Close OpenGL window and terminate GLFW glfwTerminate(); return 0; }
int main() { int width = 640; int height = 480; if(glfwInit() == GL_FALSE) { std::cerr << "failed to init GLFW" << std::endl; return 1; } // select opengl version glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 3); // create a window if(glfwOpenWindow(width, height, 0, 0, 0, 8, 24, 8, GLFW_WINDOW) == GL_FALSE) { std::cerr << "failed to open window" << std::endl; glfwTerminate(); return 1; } // setup windows close callback glfwSetWindowCloseCallback(closedWindow); // this time we disable the mouse cursor since we want differential // mouse input glfwDisable(GLFW_MOUSE_CURSOR); if (gl3wInit()) { std::cerr << "failed to init GL3W" << std::endl; glfwCloseWindow(); glfwTerminate(); return 1; } // draw shader std::string vertex_source = "#version 330\n" "uniform mat4 ViewProjection;\n" "layout(location = 0) in vec4 vposition;\n" "layout(location = 1) in vec3 normal;\n" "out vec4 fcolor;\n" "void main() {\n" " float brightness = dot(normal,normalize(vec3(1,2,3)));\n" " brightness = 0.3+((brightness>0)?0.7*brightness:0.3*brightness);\n" " fcolor = vec4(brightness,brightness,brightness,1);\n" " gl_Position = ViewProjection*vposition;\n" "}\n"; std::string fragment_source = "#version 330\n" "in vec4 fcolor;\n" "layout(location = 0) out vec4 FragColor;\n" "void main() {\n" " FragColor = abs(fcolor);\n" "}\n"; // program and shader handles GLuint shader_program, vertex_shader, fragment_shader; // we need these to properly pass the strings const char *source; int length; // create and compiler vertex shader vertex_shader = glCreateShader(GL_VERTEX_SHADER); source = vertex_source.c_str(); length = vertex_source.size(); glShaderSource(vertex_shader, 1, &source, &length); glCompileShader(vertex_shader); if(!check_shader_compile_status(vertex_shader)) { return 1; } // create and compiler fragment shader fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); source = fragment_source.c_str(); length = fragment_source.size(); glShaderSource(fragment_shader, 1, &source, &length); glCompileShader(fragment_shader); if(!check_shader_compile_status(fragment_shader)) { return 1; } // create program shader_program = glCreateProgram(); // attach shaders glAttachShader(shader_program, vertex_shader); glAttachShader(shader_program, fragment_shader); // link the program and check for errors glLinkProgram(shader_program); check_program_link_status(shader_program); // obtain location of projection uniform GLint DrawViewProjection_location = glGetUniformLocation(shader_program, "ViewProjection"); // trivial shader for occlusion queries std::string query_vertex_source = "#version 330\n" "uniform mat4 ViewProjection;\n" "layout(location = 0) in vec4 vposition;\n" "void main() {\n" " gl_Position = ViewProjection*vposition;\n" "}\n"; std::string query_fragment_source = "#version 330\n" "void main() {\n" "}\n"; // program and shader handles GLuint query_shader_program, query_vertex_shader, query_fragment_shader; // create and compiler vertex shader query_vertex_shader = glCreateShader(GL_VERTEX_SHADER); source = query_vertex_source.c_str(); length = query_vertex_source.size(); glShaderSource(query_vertex_shader, 1, &source, &length); glCompileShader(query_vertex_shader); if(!check_shader_compile_status(query_vertex_shader)) { return 1; } // create and compiler fragment shader query_fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); source = query_fragment_source.c_str(); length = query_fragment_source.size(); glShaderSource(query_fragment_shader, 1, &source, &length); glCompileShader(query_fragment_shader); if(!check_shader_compile_status(query_fragment_shader)) { return 1; } // create program query_shader_program = glCreateProgram(); // attach shaders glAttachShader(query_shader_program, query_vertex_shader); glAttachShader(query_shader_program, query_fragment_shader); // link the program and check for errors glLinkProgram(query_shader_program); check_program_link_status(query_shader_program); // obtain location of projection uniform GLint QueryViewProjection_location = glGetUniformLocation(query_shader_program, "ViewProjection"); // chunk container and chunk parameters std::vector<Chunk> chunks; int chunkrange = 4; int chunksize = 32; // chunk extraction std::cout << "generating chunks, this may take a while." << std::endl; // iterate over all chunks we want to extract for(int i = -chunkrange;i<chunkrange;++i) for(int j = -chunkrange;j<chunkrange;++j) for(int k = -chunkrange;k<chunkrange;++k) { Chunk chunk; // chunk data // generate and bind the vao glGenVertexArrays(1, &chunk.vao); glBindVertexArray(chunk.vao); // generate and bind the vertex buffer object glGenBuffers(1, &chunk.vbo); glBindBuffer(GL_ARRAY_BUFFER, chunk.vbo); std::vector<glm::vec3> vertexData; glm::vec3 offset = static_cast<float>(chunksize) * glm::vec3(i,j,k); float threshold = 0.0f; // iterate over all blocks within the chunk for(int x = 0;x<chunksize;++x) for(int y = 0;y<chunksize;++y) for(int z = 0;z<chunksize;++z) { glm::vec3 pos = glm::vec3(x,y,z) + offset; // insert quads if current block is solid and neighbors are not if(world_function(pos)<threshold) { if(world_function(pos+glm::vec3(1,0,0))>=threshold) { vertexData.push_back(pos+0.5f*glm::vec3( 1, 1, 1)); vertexData.push_back(glm::vec3( 1, 0, 0)); vertexData.push_back(pos+0.5f*glm::vec3( 1,-1, 1)); vertexData.push_back(glm::vec3( 1, 0, 0)); vertexData.push_back(pos+0.5f*glm::vec3( 1, 1,-1)); vertexData.push_back(glm::vec3( 1, 0, 0)); vertexData.push_back(pos+0.5f*glm::vec3( 1,-1,-1)); vertexData.push_back(glm::vec3( 1, 0, 0)); } if(world_function(pos+glm::vec3(0,1,0))>=threshold) { vertexData.push_back(pos+0.5f*glm::vec3( 1, 1, 1)); vertexData.push_back(glm::vec3( 0, 1, 0)); vertexData.push_back(pos+0.5f*glm::vec3( 1, 1,-1)); vertexData.push_back(glm::vec3( 0, 1, 0)); vertexData.push_back(pos+0.5f*glm::vec3(-1, 1, 1)); vertexData.push_back(glm::vec3( 0, 1, 0)); vertexData.push_back(pos+0.5f*glm::vec3(-1, 1,-1)); vertexData.push_back(glm::vec3( 0, 1, 0)); } if(world_function(pos+glm::vec3(0,0,1))>=threshold) { vertexData.push_back(pos+0.5f*glm::vec3( 1, 1, 1)); vertexData.push_back(glm::vec3( 0, 0, 1)); vertexData.push_back(pos+0.5f*glm::vec3(-1, 1, 1)); vertexData.push_back(glm::vec3( 0, 0, 1)); vertexData.push_back(pos+0.5f*glm::vec3( 1,-1, 1)); vertexData.push_back(glm::vec3( 0, 0, 1)); vertexData.push_back(pos+0.5f*glm::vec3(-1,-1, 1)); vertexData.push_back(glm::vec3( 0, 0, 1)); } if(world_function(pos-glm::vec3(1,0,0))>=threshold) { vertexData.push_back(pos+0.5f*glm::vec3(-1, 1, 1)); vertexData.push_back(glm::vec3(-1, 0, 0)); vertexData.push_back(pos+0.5f*glm::vec3(-1, 1,-1)); vertexData.push_back(glm::vec3(-1, 0, 0)); vertexData.push_back(pos+0.5f*glm::vec3(-1,-1, 1)); vertexData.push_back(glm::vec3(-1, 0, 0)); vertexData.push_back(pos+0.5f*glm::vec3(-1,-1,-1)); vertexData.push_back(glm::vec3(-1, 0, 0)); } if(world_function(pos-glm::vec3(0,1,0))>=threshold) { vertexData.push_back(pos+0.5f*glm::vec3( 1,-1, 1)); vertexData.push_back(glm::vec3( 0,-1, 0)); vertexData.push_back(pos+0.5f*glm::vec3(-1,-1, 1)); vertexData.push_back(glm::vec3( 0,-1, 0)); vertexData.push_back(pos+0.5f*glm::vec3( 1,-1,-1)); vertexData.push_back(glm::vec3( 0,-1, 0)); vertexData.push_back(pos+0.5f*glm::vec3(-1,-1,-1)); vertexData.push_back(glm::vec3( 0,-1, 0)); } if(world_function(pos-glm::vec3(0,0,1))>=threshold) { vertexData.push_back(pos+0.5f*glm::vec3( 1, 1,-1)); vertexData.push_back(glm::vec3( 0, 0,-1)); vertexData.push_back(pos+0.5f*glm::vec3( 1,-1,-1)); vertexData.push_back(glm::vec3( 0, 0,-1)); vertexData.push_back(pos+0.5f*glm::vec3(-1, 1,-1)); vertexData.push_back(glm::vec3( 0, 0,-1)); vertexData.push_back(pos+0.5f*glm::vec3(-1,-1,-1)); vertexData.push_back(glm::vec3( 0, 0,-1)); } } } // upload glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3)*vertexData.size(), &vertexData[0], GL_STATIC_DRAW); // set up generic attrib pointers glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), (char*)0 + 0*sizeof(GLfloat)); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), (char*)0 + 3*sizeof(GLfloat)); // generate and bind the index buffer object glGenBuffers(1, &chunk.ibo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, chunk.ibo); chunk.quadcount = vertexData.size()/8; std::vector<GLuint> indexData(6*chunk.quadcount); for(int i = 0;i<chunk.quadcount;++i) { indexData[6*i + 0] = 4*i + 0; indexData[6*i + 1] = 4*i + 1; indexData[6*i + 2] = 4*i + 2; indexData[6*i + 3] = 4*i + 2; indexData[6*i + 4] = 4*i + 1; indexData[6*i + 5] = 4*i + 3; } // upload glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*indexData.size(), &indexData[0], GL_STATIC_DRAW); // chunk bounding box // generate and bind the vao glGenVertexArrays(1, &chunk.bounding_vao); glBindVertexArray(chunk.bounding_vao); // generate and bind the vertex buffer object glGenBuffers(1, &chunk.bounding_vbo); glBindBuffer(GL_ARRAY_BUFFER, chunk.bounding_vbo); // data for the bounding cube GLfloat boundingVertexData[] = { // X Y Z // face 0: offset.x+chunksize-0.5f, offset.y+chunksize-0.5f, offset.z+chunksize-0.5f, offset.x-0.5f, offset.y+chunksize-0.5f, offset.z+chunksize-0.5f, offset.x+chunksize-0.5f, offset.y-0.5f, offset.z+chunksize-0.5f, offset.x-0.5f, offset.y-0.5f, offset.z+chunksize-0.5f, // face 1: offset.x+chunksize-0.5f, offset.y+chunksize-0.5f, offset.z+chunksize-0.5f, offset.x+chunksize-0.5f, offset.y-0.5f, offset.z+chunksize-0.5f, offset.x+chunksize-0.5f, offset.y+chunksize-0.5f, offset.z-0.5f, offset.x+chunksize-0.5f, offset.y-0.5f, offset.z-0.5f, // face 2: offset.x+chunksize-0.5f, offset.y+chunksize-0.5f, offset.z+chunksize-0.5f, offset.x+chunksize-0.5f, offset.y+chunksize-0.5f, offset.z-0.5f, offset.x-0.5f, offset.y+chunksize-0.5f, offset.z+chunksize-0.5f, offset.x-0.5f, offset.y+chunksize-0.5f, offset.z-0.5f, // face 3: offset.x+chunksize-0.5f, offset.y+chunksize-0.5f, offset.z-0.5f, offset.x+chunksize-0.5f, offset.y-0.5f, offset.z-0.5f, offset.x-0.5f, offset.y+chunksize-0.5f, offset.z-0.5f, offset.x-0.5f, offset.y-0.5f, offset.z-0.5f, // face 4: offset.x-0.5f, offset.y+chunksize-0.5f, offset.z+chunksize-0.5f, offset.x-0.5f, offset.y+chunksize-0.5f, offset.z-0.5f, offset.x-0.5f, offset.y-0.5f, offset.z+chunksize-0.5f, offset.x-0.5f, offset.y-0.5f, offset.z-0.5f, // face 5: offset.x+chunksize-0.5f, offset.y-0.5f, offset.z+chunksize-0.5f, offset.x-0.5f, offset.y-0.5f, offset.z+chunksize-0.5f, offset.x+chunksize-0.5f, offset.y-0.5f, offset.z-0.5f, offset.x-0.5f, offset.y-0.5f, offset.z-0.5f, }; // 6 faces with 4 vertices with 6 components (floats) // fill with data glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*6*4*3, boundingVertexData, GL_STATIC_DRAW); // set up generic attrib pointers glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), (char*)0 + 0*sizeof(GLfloat)); // generate and bind the index buffer object glGenBuffers(1, &chunk.bounding_ibo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, chunk.bounding_ibo); GLuint boundingIndexData[] = { 0, 1, 2, 2, 1, 3, 4, 5, 6, 6, 5, 7, 8, 9,10,10, 9,11, 12,13,14,14,13,15,16,17,18,18,17,19,20,21,22,22,21,23, }; // fill with data glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*6*2*3, boundingIndexData, GL_STATIC_DRAW); // generate the query object for the occlusion query glGenQueries(1, &chunk.query); // set the center location of the chunk chunk.center = offset + 0.5f*chunksize; // add to container chunks.push_back(chunk); } // "unbind" vao glBindVertexArray(0); // timer query setup // use multiple queries to avoid stalling on getting the results const int querycount = 5; GLuint queries[querycount]; int current_query = 0; glGenQueries(querycount, queries); // we are drawing 3d objects so we want depth testing glEnable(GL_DEPTH_TEST); // camera position and orientation glm::vec3 position; glm::mat4 rotation = glm::mat4(1.0f); running = true; float t = glfwGetTime(); bool occlusion_cull = true; bool space_down = false; // mouse position int mousex, mousey; glfwGetMousePos(&mousex, &mousey); while(running) { // calculate timestep float new_t = glfwGetTime(); float dt = new_t - t; t = new_t; // update mouse differential int tmpx, tmpy; glfwGetMousePos(&tmpx, &tmpy); glm::vec2 mousediff(tmpx-mousex, tmpy-mousey); mousex = tmpx; mousey = tmpy; // find up, forward and right vector glm::mat3 rotation3(rotation); glm::vec3 up = glm::transpose(rotation3)*glm::vec3(0.0f, 1.0f, 0.0f); glm::vec3 right = glm::transpose(rotation3)*glm::vec3(1.0f, 0.0f, 0.0f); glm::vec3 forward = glm::transpose(rotation3)*glm::vec3(0.0f, 0.0f,-1.0f); // apply mouse rotation rotation = glm::rotate(rotation, 0.2f*mousediff.x, up); rotation = glm::rotate(rotation, 0.2f*mousediff.y, right); // roll if(glfwGetKey('Q')) { rotation = glm::rotate(rotation, 180.0f*dt, forward); } if(glfwGetKey('E')) { rotation = glm::rotate(rotation,-180.0f*dt, forward); } // movement if(glfwGetKey('W')) { position += 10.0f*dt*forward; } if(glfwGetKey('S')) { position -= 10.0f*dt*forward; } if(glfwGetKey('D')) { position += 10.0f*dt*right; } if(glfwGetKey('A')) { position -= 10.0f*dt*right; } // toggle occlusion culling if(glfwGetKey(GLFW_KEY_SPACE) && !space_down) { occlusion_cull = !occlusion_cull; } space_down = glfwGetKey(GLFW_KEY_SPACE); // terminate on escape if(glfwGetKey(GLFW_KEY_ESC)) { running = false; } // calculate ViewProjection matrix glm::mat4 Projection = glm::perspective(90.0f, 4.0f / 3.0f, 0.1f, 200.f); glm::mat4 View = rotation*glm::translate(glm::mat4(1.0f), -position); glm::mat4 ViewProjection = Projection*View; // set matrices for both shaders glUseProgram(query_shader_program); glUniformMatrix4fv(QueryViewProjection_location, 1, GL_FALSE, glm::value_ptr(ViewProjection)); glUseProgram(shader_program); glUniformMatrix4fv(DrawViewProjection_location, 1, GL_FALSE, glm::value_ptr(ViewProjection)); // set clear color to sky blue glClearColor(0.5f,0.8f,1.0f,1.0f); // clear glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // sort chunks by distance std::sort(chunks.begin(), chunks.end(), DistancePred(position)); size_t i = 0; float maxdist = chunksize; // start timer query glBeginQuery(GL_TIME_ELAPSED, queries[current_query]); // peel chunks while(i!=chunks.size()) { size_t j = i; if(occlusion_cull) { // start occlusion queries and render for the current slice glDisable(GL_CULL_FACE); // we don't want the queries to actually render something glDepthMask(GL_FALSE); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glUseProgram(query_shader_program); for(;j<chunks.size() && glm::distance(chunks[j].center, position)<maxdist;++j) { // frustum culling glm::vec4 projected = ViewProjection*glm::vec4(chunks[j].center,1); if( (glm::distance(chunks[j].center,position) > chunksize) && (std::max(std::abs(projected.x), std::abs(projected.y)) > projected.w+chunksize)) continue; // begin occlusion query glBeginQuery(GL_ANY_SAMPLES_PASSED, chunks[j].query); // draw bounding box glBindVertexArray(chunks[j].bounding_vao); glDrawElements(GL_TRIANGLES, 6*6, GL_UNSIGNED_INT, 0); // end occlusion query glEndQuery(GL_ANY_SAMPLES_PASSED); } j = i; } // render the current slice glEnable(GL_CULL_FACE); // turn rendering back on glDepthMask(GL_TRUE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glUseProgram(shader_program); for(;j<chunks.size() && glm::distance(chunks[j].center, position)<maxdist;++j) { // frustum culling glm::vec4 projected = ViewProjection*glm::vec4(chunks[j].center,1); if( (glm::distance(chunks[j].center,position) > chunksize) && (std::max(std::abs(projected.x), std::abs(projected.y)) > projected.w+chunksize)) continue; // begin conditional render if(occlusion_cull) glBeginConditionalRender(chunks[j].query, GL_QUERY_BY_REGION_WAIT); // draw chunk glBindVertexArray(chunks[j].vao); glDrawElements(GL_TRIANGLES, 6*chunks[j].quadcount, GL_UNSIGNED_INT, 0); // end conditional render if(occlusion_cull) glEndConditionalRender(); } i = j; maxdist += 2*chunksize; } // end timer query glEndQuery(GL_TIME_ELAPSED); // display timer query results from querycount frames before if(GL_TRUE == glIsQuery(queries[(current_query+1)%querycount])) { GLuint64 result; glGetQueryObjectui64v(queries[(current_query+1)%querycount], GL_QUERY_RESULT, &result); std::cout << result*1.e-6 << " ms/frame" << std::endl; } // advance query counter current_query = (current_query + 1)%querycount; // check for errors GLenum error = glGetError(); if(error != GL_NO_ERROR) { std::cerr << gluErrorString(error); running = false; } // finally swap buffers glfwSwapBuffers(); } // delete the created objects for(size_t i = 0;i<chunks.size();++i) { glDeleteVertexArrays(1, &chunks[i].vao); glDeleteBuffers(1, &chunks[i].vbo); glDeleteBuffers(1, &chunks[i].ibo); glDeleteVertexArrays(1, &chunks[i].bounding_vao); glDeleteBuffers(1, &chunks[i].bounding_vbo); glDeleteBuffers(1, &chunks[i].bounding_ibo); glDeleteQueries(1, &chunks[i].query); } glDeleteQueries(querycount, queries); glDetachShader(shader_program, vertex_shader); glDetachShader(shader_program, fragment_shader); glDeleteShader(vertex_shader); glDeleteShader(fragment_shader); glDeleteProgram(shader_program); glDetachShader(query_shader_program, query_vertex_shader); glDetachShader(query_shader_program, query_fragment_shader); glDeleteShader(query_vertex_shader); glDeleteShader(query_fragment_shader); glDeleteProgram(query_shader_program); glfwCloseWindow(); glfwTerminate(); return 0; }
int main() { init_glfw(); GLFWwindow* window = create_window(800, 600, "OpenGL"); init_glew(); GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); GLuint vbo; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); GLuint ebo; glGenBuffers(1, &ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW); GLuint vertexShader = compile_shader(GL_VERTEX_SHADER, vertexSource); GLuint fragmentShader = compile_shader(GL_FRAGMENT_SHADER, fragSource); GLuint program = link_program(vertexShader, fragmentShader); glUseProgram(program); GLint posAttrib = glGetAttribLocation(program, "position"); glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 7 * sizeof(float), 0); glEnableVertexAttribArray(posAttrib); GLint colorAttrib = glGetAttribLocation(program, "color"); glVertexAttribPointer(colorAttrib, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)(2 * sizeof(float))); glEnableVertexAttribArray(colorAttrib); GLint texAttrib = glGetAttribLocation(program, "texcoord"); glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)(5 * sizeof(float))); glEnableVertexAttribArray(texAttrib); GLuint tex; glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); int width, height; unsigned char* 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); 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); } // Clear the screen to black glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glUniform1f(glGetUniformLocation(program, "time"), glfwGetTime()); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); } glDeleteTextures(1, &tex); glDeleteProgram(program); glDeleteShader(fragmentShader); glDeleteShader(vertexShader); glDeleteBuffers(1, &vbo); glDeleteBuffers(1, &ebo); glDeleteVertexArrays(1, &vao); glfwTerminate(); }
int main () { assert (restart_gl_log ()); assert (start_gl ()); init_ss_quad (); /* set up framebuffer with texture attachment */ assert (init_fb ()); /* load the post-processing effect shaders */ GLuint post_sp = create_programme_from_files (POST_VS, POST_FS); /* load a mesh to draw in the main scene */ load_sphere (); GLuint sphere_sp = create_programme_from_files (SPHERE_VS, SPHERE_FS); GLint sphere_P_loc = glGetUniformLocation (sphere_sp, "P"); GLint sphere_V_loc = glGetUniformLocation (sphere_sp, "V"); assert (sphere_P_loc > -1); assert (sphere_V_loc > -1); /* set up view and projection matrices for sphere shader */ mat4 P = perspective ( 67.0f, (float)g_gl_width / (float)g_gl_height, 0.1f, 100.0f); mat4 V = look_at ( vec3 (0.0f, 0.0f, 5.0f), vec3 (0.0f, 0.0f, 0.0f), vec3 (0.0f, 1.0f, 0.0f)); glUseProgram (sphere_sp); glUniformMatrix4fv (sphere_P_loc, 1, GL_FALSE, P.m); glUniformMatrix4fv (sphere_V_loc, 1, GL_FALSE, V.m); glViewport (0, 0, g_gl_width, g_gl_height); while (!glfwWindowShouldClose (g_window)) { _update_fps_counter (g_window); /* bind the 'render to a texture' framebuffer for main scene */ glBindFramebuffer (GL_FRAMEBUFFER, g_fb); /* clear the framebuffer's colour and depth buffers */ glClearColor (0.2, 0.2, 0.2, 1.0); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // render an obj or something glUseProgram (sphere_sp); glBindVertexArray (g_sphere_vao); glDrawArrays (GL_TRIANGLES, 0, g_sphere_point_count); /* bind default framebuffer for post-processing effects. sample texture from previous pass */ glBindFramebuffer (GL_FRAMEBUFFER, 0); // clear the framebuffer's colour and depth buffers //glClearColor (0.0, 0.0, 0.0, 1.0); //glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // use our post-processing shader for the screen-space quad glUseProgram (post_sp); // bind the quad's VAO glBindVertexArray (g_ss_quad_vao); // activate the first texture slot and put texture from previous pass in it glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, g_fb_tex); // draw the quad that covers the screen area glDrawArrays (GL_TRIANGLES, 0, 6); // flip drawn framebuffer onto the display glfwSwapBuffers (g_window); glfwPollEvents (); if (GLFW_PRESS == glfwGetKey (g_window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (g_window, 1); } } return 0; }
int main(int argc, char **argv) { srand(time(NULL)); rand(); if (argc == 2 || argc == 3) { char *hostname = argv[1]; int port = DEFAULT_PORT; if (argc == 3) { port = atoi(argv[2]); } db_disable(); client_enable(); client_connect(hostname, port); client_start(); } if (!glfwInit()) { return -1; } create_window(); if (!window) { glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glfwSwapInterval(VSYNC); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwSetKeyCallback(window, on_key); glfwSetCharCallback(window, on_char); glfwSetMouseButtonCallback(window, on_mouse_button); glfwSetScrollCallback(window, on_scroll); #ifndef __APPLE__ if (glewInit() != GLEW_OK) { return -1; } #endif if (db_init()) { return -1; } glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glEnable(GL_LINE_SMOOTH); glLogicOp(GL_INVERT); glClearColor(0.53, 0.81, 0.92, 1.00); GLuint texture; glGenTextures(1, &texture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); load_png_texture("texture.png"); GLuint font; glGenTextures(1, &font); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, font); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); load_png_texture("font.png"); GLuint block_program = load_program( "shaders/block_vertex.glsl", "shaders/block_fragment.glsl"); GLuint matrix_loc = glGetUniformLocation(block_program, "matrix"); GLuint camera_loc = glGetUniformLocation(block_program, "camera"); GLuint sampler_loc = glGetUniformLocation(block_program, "sampler"); GLuint timer_loc = glGetUniformLocation(block_program, "timer"); GLuint position_loc = glGetAttribLocation(block_program, "position"); GLuint normal_loc = glGetAttribLocation(block_program, "normal"); GLuint uv_loc = glGetAttribLocation(block_program, "uv"); GLuint line_program = load_program( "shaders/line_vertex.glsl", "shaders/line_fragment.glsl"); GLuint line_matrix_loc = glGetUniformLocation(line_program, "matrix"); GLuint line_position_loc = glGetAttribLocation(line_program, "position"); GLuint text_program = load_program( "shaders/text_vertex.glsl", "shaders/text_fragment.glsl"); GLuint text_matrix_loc = glGetUniformLocation(text_program, "matrix"); GLuint text_sampler_loc = glGetUniformLocation(text_program, "sampler"); GLuint text_position_loc = glGetAttribLocation(text_program, "position"); GLuint text_uv_loc = glGetAttribLocation(text_program, "uv"); GLuint item_position_buffer = 0; GLuint item_normal_buffer = 0; GLuint item_uv_buffer = 0; int previous_block_type = 0; char messages[MAX_MESSAGES][TEXT_BUFFER_SIZE] = {0}; int message_index = 0; Chunk chunks[MAX_CHUNKS]; int chunk_count = 0; Player players[MAX_PLAYERS]; int player_count = 0; FPS fps = {0, 0}; float matrix[16]; float x = (rand_double() - 0.5) * 10000; float z = (rand_double() - 0.5) * 10000; float y = 0; float dy = 0; float rx = 0; float ry = 0; double px = 0; double py = 0; int loaded = db_load_state(&x, &y, &z, &rx, &ry); ensure_chunks(chunks, &chunk_count, x, y, z, 1); if (!loaded) { y = highest_block(chunks, chunk_count, x, z) + 2; } glfwGetCursorPos(window, &px, &py); double previous = glfwGetTime(); while (!glfwWindowShouldClose(window)) { int width, height; glfwGetFramebufferSize(window, &width, &height); glViewport(0, 0, width, height); update_fps(&fps, SHOW_FPS); double now = glfwGetTime(); double dt = MIN(now - previous, 0.2); previous = now; if (exclusive && (px || py)) { double mx, my; glfwGetCursorPos(window, &mx, &my); float m = 0.0025; rx += (mx - px) * m; ry -= (my - py) * m; if (rx < 0) { rx += RADIANS(360); } if (rx >= RADIANS(360)){ rx -= RADIANS(360); } ry = MAX(ry, -RADIANS(90)); ry = MIN(ry, RADIANS(90)); px = mx; py = my; } else { glfwGetCursorPos(window, &px, &py); } int sz = 0; int sx = 0; if (!typing) { float m = dt * 1.0; ortho = glfwGetKey(window, CRAFT_KEY_ORTHO); fov = glfwGetKey(window, CRAFT_KEY_ZOOM) ? 15.0 : 65.0; if (glfwGetKey(window, CRAFT_KEY_QUIT)) break; if (glfwGetKey(window, CRAFT_KEY_FORWARD)) sz--; if (glfwGetKey(window, CRAFT_KEY_BACKWARD)) sz++; if (glfwGetKey(window, CRAFT_KEY_LEFT)) sx--; if (glfwGetKey(window, CRAFT_KEY_RIGHT)) sx++; if (glfwGetKey(window, GLFW_KEY_LEFT)) rx -= m; if (glfwGetKey(window, GLFW_KEY_RIGHT)) rx += m; if (glfwGetKey(window, GLFW_KEY_UP)) ry += m; if (glfwGetKey(window, GLFW_KEY_DOWN)) ry -= m; } float vx, vy, vz; get_motion_vector(flying, sz, sx, rx, ry, &vx, &vy, &vz); if (!typing) { if (glfwGetKey(window, CRAFT_KEY_JUMP)) { if (flying) { vy = 1; } else if (dy == 0) { dy = 8; } } if (glfwGetKey(window, CRAFT_KEY_XM)) { vx = -1; vy = 0; vz = 0; } if (glfwGetKey(window, CRAFT_KEY_XP)) { vx = 1; vy = 0; vz = 0; } if (glfwGetKey(window, CRAFT_KEY_YM)) { vx = 0; vy = -1; vz = 0; } if (glfwGetKey(window, CRAFT_KEY_YP)) { vx = 0; vy = 1; vz = 0; } if (glfwGetKey(window, CRAFT_KEY_ZM)) { vx = 0; vy = 0; vz = -1; } if (glfwGetKey(window, CRAFT_KEY_ZP)) { vx = 0; vy = 0; vz = 1; } } float speed = flying ? 20 : 5; int step = 8; float ut = dt / step; vx = vx * ut * speed; vy = vy * ut * speed; vz = vz * ut * speed; for (int i = 0; i < step; i++) { if (flying) { dy = 0; } else { dy -= ut * 25; dy = MAX(dy, -250); } x += vx; y += vy + dy * ut; z += vz; if (collide(chunks, chunk_count, 2, &x, &y, &z)) { dy = 0; } } if (y < 0) { y = highest_block(chunks, chunk_count, x, z) + 2; } if (left_click) { left_click = 0; int hx, hy, hz; int hw = hit_test(chunks, chunk_count, 0, x, y, z, rx, ry, &hx, &hy, &hz); if (hy > 0 && is_destructable(hw)) { set_block(chunks, chunk_count, hx, hy, hz, 0); int above = get_block(chunks, chunk_count, hx, hy + 1, hz); if (is_plant(above)) { set_block(chunks, chunk_count, hx, hy + 1, hz, 0); } } } if (right_click) { right_click = 0; int hx, hy, hz; int hw = hit_test(chunks, chunk_count, 1, x, y, z, rx, ry, &hx, &hy, &hz); if (is_obstacle(hw)) { if (!player_intersects_block(2, x, y, z, hx, hy, hz)) { set_block(chunks, chunk_count, hx, hy, hz, block_type); } } } if (middle_click) { middle_click = 0; int hx, hy, hz; int hw = hit_test(chunks, chunk_count, 0, x, y, z, rx, ry, &hx, &hy, &hz); if (is_selectable(hw)) { block_type = hw; } } if (teleport) { teleport = 0; if (player_count) { int index = rand_int(player_count); Player *player = players + index; x = player->x; y = player->y; z = player->z; rx = player->rx; ry = player->ry; ensure_chunks(chunks, &chunk_count, x, y, z, 1); } } client_position(x, y, z, rx, ry); char buffer[RECV_BUFFER_SIZE]; while (client_recv(buffer, RECV_BUFFER_SIZE)) { float ux, uy, uz, urx, ury; if (sscanf(buffer, "U,%*d,%f,%f,%f,%f,%f", &ux, &uy, &uz, &urx, &ury) == 5) { x = ux; y = uy; z = uz; rx = urx; ry = ury; ensure_chunks(chunks, &chunk_count, x, y, z, 1); y = highest_block(chunks, chunk_count, x, z) + 2; } int bp, bq, bx, by, bz, bw; if (sscanf(buffer, "B,%d,%d,%d,%d,%d,%d", &bp, &bq, &bx, &by, &bz, &bw) == 6) { _set_block(chunks, chunk_count, bp, bq, bx, by, bz, bw); if (player_intersects_block(2, x, y, z, bx, by, bz)) { y = highest_block(chunks, chunk_count, x, z) + 2; } } int pid; float px, py, pz, prx, pry; if (sscanf(buffer, "P,%d,%f,%f,%f,%f,%f", &pid, &px, &py, &pz, &prx, &pry) == 6) { Player *player = find_player(players, player_count, pid); if (!player && player_count < MAX_PLAYERS) { player = players + player_count; player_count++; player->id = pid; player->position_buffer = 0; player->normal_buffer = 0; player->uv_buffer = 0; } if (player) { update_player(player, px, py, pz, prx, pry); } } if (sscanf(buffer, "D,%d", &pid) == 1) { delete_player(players, &player_count, pid); } if (buffer[0] == 'T' && buffer[1] == ',') { char *text = buffer + 2; printf("%s\n", text); snprintf( messages[message_index], TEXT_BUFFER_SIZE, "%s", text); message_index = (message_index + 1) % MAX_MESSAGES; } } int p = chunked(x); int q = chunked(z); ensure_chunks(chunks, &chunk_count, x, y, z, 0); // RENDER 3-D SCENE // glClear(GL_COLOR_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT); set_matrix_3d(matrix, width, height, x, y, z, rx, ry, fov, ortho); // render chunks glUseProgram(block_program); glUniformMatrix4fv(matrix_loc, 1, GL_FALSE, matrix); glUniform3f(camera_loc, x, y, z); glUniform1i(sampler_loc, 0); glUniform1f(timer_loc, glfwGetTime()); for (int i = 0; i < chunk_count; i++) { Chunk *chunk = chunks + i; if (chunk_distance(chunk, p, q) > RENDER_CHUNK_RADIUS) { continue; } if (y < 100 && !chunk_visible(chunk, matrix)) { continue; } draw_chunk(chunk, position_loc, normal_loc, uv_loc); } // render players for (int i = 0; i < player_count; i++) { Player *player = players + i; draw_player(player, position_loc, normal_loc, uv_loc); } // render focused block wireframe int hx, hy, hz; int hw = hit_test( chunks, chunk_count, 0, x, y, z, rx, ry, &hx, &hy, &hz); if (is_obstacle(hw)) { glUseProgram(line_program); glLineWidth(1); glEnable(GL_COLOR_LOGIC_OP); glUniformMatrix4fv(line_matrix_loc, 1, GL_FALSE, matrix); GLuint wireframe_buffer = gen_wireframe_buffer(hx, hy, hz, 0.51); draw_lines(wireframe_buffer, line_position_loc, 3, 48); glDeleteBuffers(1, &wireframe_buffer); glDisable(GL_COLOR_LOGIC_OP); } // RENDER 2-D HUD PARTS // glClear(GL_DEPTH_BUFFER_BIT); set_matrix_2d(matrix, width, height); // render crosshairs glUseProgram(line_program); glLineWidth(4); glEnable(GL_COLOR_LOGIC_OP); glUniformMatrix4fv(line_matrix_loc, 1, GL_FALSE, matrix); GLuint crosshair_buffer = gen_crosshair_buffer(width, height); draw_lines(crosshair_buffer, line_position_loc, 2, 4); glDeleteBuffers(1, &crosshair_buffer); glDisable(GL_COLOR_LOGIC_OP); // render text glUseProgram(text_program); glUniformMatrix4fv(text_matrix_loc, 1, GL_FALSE, matrix); glUniform1i(text_sampler_loc, 1); char text_buffer[1024]; float ts = 12; float tx = ts / 2; float ty = height - ts; snprintf( text_buffer, 1024, "%d, %d, %.2f, %.2f, %.2f [%d, %d]", p, q, x, y, z, player_count, chunk_count); print( text_position_loc, text_uv_loc, tx, ty, ts, text_buffer); for (int i = 0; i < MAX_MESSAGES; i++) { int index = (message_index + i) % MAX_MESSAGES; if (strlen(messages[index])) { ty -= ts * 2; print( text_position_loc, text_uv_loc, tx, ty, ts, messages[index]); } } if (typing) { ty -= ts * 2; snprintf(text_buffer, 1024, "> %s", typing_buffer); print( text_position_loc, text_uv_loc, tx, ty, ts, text_buffer); } // RENDER 3-D HUD PARTS // set_matrix_item(matrix, width, height); // render selected item if (block_type != previous_block_type) { previous_block_type = block_type; if (is_plant(block_type)) { gen_plant_buffers( &item_position_buffer, &item_normal_buffer, &item_uv_buffer, 0, 0, 0, 0.5, block_type); } else { gen_cube_buffers( &item_position_buffer, &item_normal_buffer, &item_uv_buffer, 0, 0, 0, 0.5, block_type); } } glUseProgram(block_program); glUniformMatrix4fv(matrix_loc, 1, GL_FALSE, matrix); glUniform3f(camera_loc, 0, 0, 5); glUniform1i(sampler_loc, 0); glUniform1f(timer_loc, glfwGetTime()); if (is_plant(block_type)) { draw_plant( item_position_buffer, item_normal_buffer, item_uv_buffer, position_loc, normal_loc, uv_loc); } else { draw_cube( item_position_buffer, item_normal_buffer, item_uv_buffer, position_loc, normal_loc, uv_loc); } // swap buffers glfwSwapBuffers(window); glfwPollEvents(); } client_stop(); db_save_state(x, y, z, rx, ry); db_close(); glfwTerminate(); return 0; }
int main(int argc, char** argv){ #ifdef __APPLE__ // Needed in OSX to force use of OpenGL3.2 glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2); glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); #endif // Set up pathtracer stuff bool loadedScene = false; finishedRender = false; targetFrame = 0; singleFrameMode = false; // Load scene file for(int i=1; i<argc; i++){ string header; string data; istringstream liness(argv[i]); getline(liness, header, '='); getline(liness, data, '='); if(strcmp(header.c_str(), "scene")==0){ renderScene = new scene(data); loadedScene = true; }else if(strcmp(header.c_str(), "frame")==0){ targetFrame = atoi(data.c_str()); singleFrameMode = true; } } if(!loadedScene){ cout << "Error: scene file needed!" << endl; return 0; } // Set up camera stuff from loaded pathtracer settings iterations = 0; renderCam = &renderScene->renderCam; width = renderCam->resolution[0]; height = renderCam->resolution[1]; if(targetFrame>=renderCam->frames){ cout << "Warning: Specified target frame is out of range, defaulting to frame 0." << endl; targetFrame = 0; } // Launch CUDA/GL #ifdef __APPLE__ init(); #else init(argc, argv); #endif initCuda(); initVAO(); initTextures(); GLuint passthroughProgram; passthroughProgram = initShader("shaders/passthroughVS.glsl", "shaders/passthroughFS.glsl"); glUseProgram(passthroughProgram); glActiveTexture(GL_TEXTURE0); #ifdef __APPLE__ // send into GLFW main loop while(1){ display(); if (glfwGetKey(GLFW_KEY_ESC) == GLFW_PRESS || !glfwGetWindowParam( GLFW_OPENED )){ exit(0); } } glfwTerminate(); #else glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutMainLoop(); #endif return 0; }
// the program starts here void AppMain() { // initialise GLFW glfwSetErrorCallback(OnError); if(!glfwInit()) throw std::runtime_error("glfwInit failed"); // open a window with GLFW glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); gWindow = glfwCreateWindow((int)SCREEN_SIZE.x, (int)SCREEN_SIZE.y, "OpenGL Tutorial", NULL, NULL); if(!gWindow) throw std::runtime_error("glfwCreateWindow failed. Can your hardware handle OpenGL 3.2?"); // GLFW settings glfwSetCursorPos(gWindow, 0, 0); glfwMakeContextCurrent(gWindow); glfwSetKeyCallback(gWindow, key_callback); // initialise GLEW glewExperimental = GL_TRUE; //stops glew crashing on OSX :-/ if(glewInit() != GLEW_OK) throw std::runtime_error("glewInit failed"); // GLEW throws some errors, so discard all the errors so far while(glGetError() != GL_NO_ERROR) {} // print out some info about the graphics drivers std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl; std::cout << "GLSL version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl; std::cout << "Vendor: " << glGetString(GL_VENDOR) << std::endl; std::cout << "Renderer: " << glGetString(GL_RENDERER) << std::endl; // make sure OpenGL version 3.2 API is available if(!GLEW_VERSION_3_2) throw std::runtime_error("OpenGL 3.2 API is not available."); // OpenGL settings glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // initialise the gBox asset LoadBoxAsset(); // create all the instances in the 3D scene based on the gBox asset CreateInstances(); // setup gCamera gCamera.setViewportAspectRatio(SCREEN_SIZE.x / SCREEN_SIZE.y); // run while the window is open double lastTime = glfwGetTime(); while(!glfwWindowShouldClose(gWindow)){ // process pending events glfwPollEvents(); // update the scene based on the time elapsed since last update double thisTime = glfwGetTime(); Update((float)(thisTime - lastTime)); lastTime = thisTime; // draw one frame Render(); // check for errors GLenum error = glGetError(); if(error != GL_NO_ERROR) std::cerr << "OpenGL Error " << error << std::endl; //exit program if escape key is pressed if(glfwGetKey(gWindow, GLFW_KEY_ESCAPE)) glfwSetWindowShouldClose(gWindow, GL_TRUE); } // clean up and exit glfwTerminate(); }
int main() { int width = 640; int height = 480; if(glfwInit() == GL_FALSE) { std::cerr << "failed to init GLFW" << std::endl; return 1; } // select opengl version glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 3); // create a window if(glfwOpenWindow(width, height, 0, 0, 0, 8, 24, 8, GLFW_WINDOW) == GL_FALSE) { std::cerr << "failed to open window" << std::endl; glfwTerminate(); return 1; } // setup windows close callback glfwSetWindowCloseCallback(closedWindow); if (gl3wInit()) { std::cerr << "failed to init GL3W" << std::endl; glfwCloseWindow(); glfwTerminate(); return 1; } // shader source code // the vertex shader simply passes through data std::string vertex_source = "#version 330\n" "layout(location = 0) in vec4 vposition;\n" "void main() {\n" " gl_Position = vposition;\n" "}\n"; // the geometry shader creates the billboard quads std::string geometry_source = "#version 330\n" "uniform mat4 View;\n" "uniform mat4 Projection;\n" "layout (points) in;\n" "layout (triangle_strip, max_vertices = 4) out;\n" "out vec2 txcoord;\n" "void main() {\n" " vec4 pos = View*gl_in[0].gl_Position;\n" " txcoord = vec2(-1,-1);\n" " gl_Position = Projection*(pos+0.2*vec4(txcoord,0,0));\n" " EmitVertex();\n" " txcoord = vec2( 1,-1);\n" " gl_Position = Projection*(pos+0.2*vec4(txcoord,0,0));\n" " EmitVertex();\n" " txcoord = vec2(-1, 1);\n" " gl_Position = Projection*(pos+0.2*vec4(txcoord,0,0));\n" " EmitVertex();\n" " txcoord = vec2( 1, 1);\n" " gl_Position = Projection*(pos+0.2*vec4(txcoord,0,0));\n" " EmitVertex();\n" "}\n"; // the fragment shader creates a bell like radial color distribution std::string fragment_source = "#version 330\n" "in vec2 txcoord;\n" "layout(location = 0) out vec4 FragColor;\n" "void main() {\n" " float s = 0.2*(1/(1+15.*dot(txcoord, txcoord))-1/16.);\n" " FragColor = s*vec4(0.3,0.3,1.0,1);\n" "}\n"; // program and shader handles GLuint shader_program, vertex_shader, geometry_shader, fragment_shader; // we need these to properly pass the strings const char *source; int length; // create and compiler vertex shader vertex_shader = glCreateShader(GL_VERTEX_SHADER); source = vertex_source.c_str(); length = vertex_source.size(); glShaderSource(vertex_shader, 1, &source, &length); glCompileShader(vertex_shader); if(!check_shader_compile_status(vertex_shader)) { return 1; } // create and compiler geometry shader geometry_shader = glCreateShader(GL_GEOMETRY_SHADER); source = geometry_source.c_str(); length = geometry_source.size(); glShaderSource(geometry_shader, 1, &source, &length); glCompileShader(geometry_shader); if(!check_shader_compile_status(geometry_shader)) { return 1; } // create and compiler fragment shader fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); source = fragment_source.c_str(); length = fragment_source.size(); glShaderSource(fragment_shader, 1, &source, &length); glCompileShader(fragment_shader); if(!check_shader_compile_status(fragment_shader)) { return 1; } // create program shader_program = glCreateProgram(); // attach shaders glAttachShader(shader_program, vertex_shader); glAttachShader(shader_program, geometry_shader); glAttachShader(shader_program, fragment_shader); // link the program and check for errors glLinkProgram(shader_program); check_program_link_status(shader_program); // obtain location of projection uniform GLint View_location = glGetUniformLocation(shader_program, "View"); GLint Projection_location = glGetUniformLocation(shader_program, "Projection"); const int particles = 128*1024; // randomly place particles in a cube std::vector<glm::vec3> vertexData(particles); std::vector<glm::vec3> velocity(particles); for(int i = 0; i<particles; ++i) { vertexData[i] = glm::vec3(0.5f-float(std::rand())/RAND_MAX, 0.5f-float(std::rand())/RAND_MAX, 0.5f-float(std::rand())/RAND_MAX); vertexData[i] = glm::vec3(0.0f,20.0f,0.0f) + 5.0f*vertexData[i]; } int buffercount = 3; // generate vbos and vaos GLuint vao[buffercount], vbo[buffercount]; glGenVertexArrays(buffercount, vao); glGenBuffers(buffercount, vbo); for(int i = 0; i<buffercount; ++i) { glBindVertexArray(vao[i]); glBindBuffer(GL_ARRAY_BUFFER, vbo[i]); // fill with initial data glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3)*vertexData.size(), &vertexData[0], GL_DYNAMIC_DRAW); // set up generic attrib pointers glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), (char*)0 + 0*sizeof(GLfloat)); } // "unbind" vao glBindVertexArray(0); // we are blending so no depth testing glDisable(GL_DEPTH_TEST); // enable blending glEnable(GL_BLEND); // and set the blend function to result = 1*source + 1*destination glBlendFunc(GL_ONE, GL_ONE); // define spheres for the particles to bounce off const int spheres = 3; glm::vec3 center[spheres]; float radius[spheres]; center[0] = glm::vec3(0,12,1); radius[0] = 3; center[1] = glm::vec3(-3,0,0); radius[1] = 7; center[2] = glm::vec3(5,-10,0); radius[2] = 12; // physical parameters float dt = 1.0f/60.0f; glm::vec3 g(0.0f, -9.81f, 0.0f); float bounce = 1.2f; // inelastic: 1.0f, elastic: 2.0f int current_buffer=0; running = true; while(running) { // get the time in seconds float t = glfwGetTime(); // terminate on escape if(glfwGetKey(GLFW_KEY_ESC)) { running = false; } // update physics for(int i = 0; i<particles; ++i) { // resolve sphere collisions for(int j = 0; j<spheres; ++j) { glm::vec3 diff = vertexData[i]-center[j]; float dist = glm::length(diff); if(dist<radius[j] && glm::dot(diff, velocity[i])<0.0f) velocity[i] -= bounce*diff/(dist*dist)*glm::dot(diff, velocity[i]); } // euler iteration velocity[i] += dt*g; vertexData[i] += dt*velocity[i]; // reset particles that fall out to a starting position if(vertexData[i].y<-30.0) { vertexData[i] = glm::vec3( 0.5f-float(std::rand())/RAND_MAX, 0.5f-float(std::rand())/RAND_MAX, 0.5f-float(std::rand())/RAND_MAX ); vertexData[i] = glm::vec3(0.0f,20.0f,0.0f) + 5.0f*vertexData[i]; velocity[i] = glm::vec3(0,0,0); } } // bind a buffer to upload to glBindBuffer(GL_ARRAY_BUFFER, vbo[(current_buffer+buffercount-1)%buffercount]); // explicitly invalidate the buffer glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3)*vertexData.size(), 0, GL_DYNAMIC_DRAW); // map the buffer glm::vec3 *mapped = reinterpret_cast<glm::vec3*>( glMapBufferRange(GL_ARRAY_BUFFER, 0, sizeof(glm::vec3)*vertexData.size(), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT ) ); // copy data into the mapped memory std::copy(vertexData.begin(), vertexData.end(), mapped); // unmap the buffer glUnmapBuffer(GL_ARRAY_BUFFER); // clear first glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // use the shader program glUseProgram(shader_program); // calculate ViewProjection matrix glm::mat4 Projection = glm::perspective(90.0f, 4.0f / 3.0f, 0.1f, 100.f); // translate the world/view position glm::mat4 View = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -30.0f)); // make the camera rotate around the origin View = glm::rotate(View, 30.0f, glm::vec3(1.0f, 0.0f, 0.0f)); View = glm::rotate(View, -22.5f*t, glm::vec3(0.0f, 1.0f, 0.0f)); // set the uniform glUniformMatrix4fv(View_location, 1, GL_FALSE, glm::value_ptr(View)); glUniformMatrix4fv(Projection_location, 1, GL_FALSE, glm::value_ptr(Projection)); // bind the current vao glBindVertexArray(vao[current_buffer]); // draw glDrawArrays(GL_POINTS, 0, particles); // check for errors GLenum error = glGetError(); if(error != GL_NO_ERROR) { std::cerr << gluErrorString(error); running = false; } // finally swap buffers glfwSwapBuffers(); // advance buffer index current_buffer = (current_buffer + 1) % buffercount; } // delete the created objects glDeleteVertexArrays(buffercount, vao); glDeleteBuffers(buffercount, vbo); glDetachShader(shader_program, vertex_shader); glDetachShader(shader_program, geometry_shader); glDetachShader(shader_program, fragment_shader); glDeleteShader(vertex_shader); glDeleteShader(geometry_shader); glDeleteShader(fragment_shader); glDeleteProgram(shader_program); glfwCloseWindow(); glfwTerminate(); return 0; }
int main( int argc, char **argv ) { int width = 1024, height=768; float widthf = (float) width, heightf = (float) height; double t; float fps = 0.f; // Initialise GLFW if( !glfwInit() ) { fprintf( stderr, "Failed to initialize GLFW\n" ); exit( EXIT_FAILURE ); } // Force core profile on Mac OSX #ifdef __APPLE__ glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2); glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); #endif // Open a window and create its OpenGL context if( !glfwOpenWindow( width, height, 0,0,0,0, 24, 0, GLFW_WINDOW ) ) { fprintf( stderr, "Failed to open GLFW window\n" ); glfwTerminate(); exit( EXIT_FAILURE ); } glfwSetWindowTitle( "002_forward_a" ); // Core profile is flagged as experimental in glew #ifdef __APPLE__ glewExperimental = GL_TRUE; #endif GLenum err = glewInit(); if (GLEW_OK != err) { /* Problem: glewInit failed, something is seriously wrong. */ fprintf(stderr, "Error: %s\n", glewGetErrorString(err)); exit( EXIT_FAILURE ); } // Ensure we can capture the escape key being pressed below glfwEnable( GLFW_STICKY_KEYS ); // Enable vertical sync (on cards that support it) glfwSwapInterval( 1 ); GLenum glerr = GL_NO_ERROR; glerr = glGetError(); if (!imguiRenderGLInit(DroidSans_ttf, DroidSans_ttf_len)) { fprintf(stderr, "Could not init GUI renderer.\n"); exit(EXIT_FAILURE); } // Init viewer structures Camera camera; camera_defaults(camera); GUIStates guiStates; init_gui_states(guiStates); // GUI float numLights = 10.f; // Load images and upload textures GLuint textures[3]; glGenTextures(3, textures); int x; int y; int comp; unsigned char * diffuse = stbi_load("textures/spnza_bricks_a_diff.tga", &x, &y, &comp, 3); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textures[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, x, y, 0, GL_RGB, GL_UNSIGNED_BYTE, diffuse); 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); fprintf(stderr, "Diffuse %dx%d:%d\n", x, y, comp); unsigned char * spec = stbi_load("textures/spnza_bricks_a_spec.tga", &x, &y, &comp, 1); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textures[1]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, x, y, 0, GL_RED, GL_UNSIGNED_BYTE, spec); 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); fprintf(stderr, "Spec %dx%d:%d\n", x, y, comp); // Try to load and compile shader int status; ShaderGLSL gbuffer_shader; const char * shaderFileGBuffer = "002/2_gbuffera.glsl"; //int status = load_shader_from_file(gbuffer_shader, shaderFileGBuffer, ShaderGLSL::VERTEX_SHADER | ShaderGLSL::FRAGMENT_SHADER | ShaderGLSL::GEOMETRY_SHADER); status = load_shader_from_file(gbuffer_shader, shaderFileGBuffer, ShaderGLSL::VERTEX_SHADER | ShaderGLSL::FRAGMENT_SHADER); if ( status == -1 ) { fprintf(stderr, "Error on loading %s\n", shaderFileGBuffer); exit( EXIT_FAILURE ); } // Compute locations for gbuffer_shader GLuint gbuffer_projectionLocation = glGetUniformLocation(gbuffer_shader.program, "Projection"); GLuint gbuffer_viewLocation = glGetUniformLocation(gbuffer_shader.program, "View"); GLuint gbuffer_objectLocation = glGetUniformLocation(gbuffer_shader.program, "Object"); GLuint gbuffer_timeLocation = glGetUniformLocation(gbuffer_shader.program, "Time"); GLuint gbuffer_diffuseLocation = glGetUniformLocation(gbuffer_shader.program, "Diffuse"); GLuint gbuffer_specLocation = glGetUniformLocation(gbuffer_shader.program, "Spec"); // Load Blit shader ShaderGLSL blit_shader; const char * shaderFileBlit = "002/2_blita.glsl"; //int status = load_shader_from_file(blit_shader, shaderFileBlit, ShaderGLSL::VERTEX_SHADER | ShaderGLSL::FRAGMENT_SHADER | ShaderGLSL::GEOMETRY_SHADER); status = load_shader_from_file(blit_shader, shaderFileBlit, ShaderGLSL::VERTEX_SHADER | ShaderGLSL::FRAGMENT_SHADER); if ( status == -1 ) { fprintf(stderr, "Error on loading %s\n", shaderFileBlit); exit( EXIT_FAILURE ); } // Compute locations for blit_shader GLuint blit_tex1Location = glGetUniformLocation(blit_shader.program, "Texture1"); // Load light accumulation shader ShaderGLSL lighting_shader; const char * shaderFileLighting = "002/2_lighta.glsl"; //int status = load_shader_from_file(lighting_shader, shaderFileLighting, ShaderGLSL::VERTEX_SHADER | ShaderGLSL::FRAGMENT_SHADER | ShaderGLSL::GEOMETRY_SHADER); status = load_shader_from_file(lighting_shader, shaderFileLighting, ShaderGLSL::VERTEX_SHADER | ShaderGLSL::FRAGMENT_SHADER); if ( status == -1 ) { fprintf(stderr, "Error on loading %s\n", shaderFileLighting); exit( EXIT_FAILURE ); } // Compute locations for lighting_shader GLuint lighting_materialLocation = glGetUniformLocation(lighting_shader.program, "Material"); GLuint lighting_normalLocation = glGetUniformLocation(lighting_shader.program, "Normal"); GLuint lighting_depthLocation = glGetUniformLocation(lighting_shader.program, "Depth"); GLuint lighting_inverseViewProjectionLocation = glGetUniformLocation(lighting_shader.program, "InverseViewProjection"); GLuint lighting_cameraPositionLocation = glGetUniformLocation(lighting_shader.program, "CameraPosition"); GLuint lighting_lightPositionLocation = glGetUniformLocation(lighting_shader.program, "LightPosition"); GLuint lighting_lightColorLocation = glGetUniformLocation(lighting_shader.program, "LightColor"); GLuint lighting_lightIntensityLocation = glGetUniformLocation(lighting_shader.program, "LightIntensity"); // Load geometry int cube_triangleCount = 12; int cube_triangleList[] = {0, 1, 2, 2, 1, 3, 4, 5, 6, 6, 5, 7, 8, 9, 10, 10, 9, 11, 12, 13, 14, 14, 13, 15, 16, 17, 18, 19, 17, 20, 21, 22, 23, 24, 25, 26, }; float cube_uvs[] = {0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f, 1.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f, 1.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f, 1.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f, 1.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f, 0.f, 1.f, 1.f, 0.f, 1.f, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 1.f, 1.f, 0.f, }; float cube_vertices[] = {-0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5 }; float cube_normals[] = {0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, }; int plane_triangleCount = 2; int plane_triangleList[] = {0, 1, 2, 2, 1, 3}; float plane_uvs[] = {0.f, 0.f, 0.f, 10.f, 10.f, 0.f, 10.f, 10.f}; float plane_vertices[] = {-50.0, -1.0, 50.0, 50.0, -1.0, 50.0, -50.0, -1.0, -50.0, 50.0, -1.0, -50.0}; float plane_normals[] = {0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0}; int quad_triangleCount = 2; int quad_triangleList[] = {0, 1, 2, 2, 1, 3}; float quad_vertices[] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0}; // Vertex Array Object GLuint vao[3]; glGenVertexArrays(3, vao); // Vertex Buffer Objects GLuint vbo[12]; glGenBuffers(12, vbo); // Cube glBindVertexArray(vao[0]); // Bind indices and upload data glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[0]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cube_triangleList), cube_triangleList, GL_STATIC_DRAW); // Bind vertices and upload data glBindBuffer(GL_ARRAY_BUFFER, vbo[1]); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*3, (void*)0); glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices), cube_vertices, GL_STATIC_DRAW); // Bind normals and upload data glBindBuffer(GL_ARRAY_BUFFER, vbo[2]); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*3, (void*)0); glBufferData(GL_ARRAY_BUFFER, sizeof(cube_normals), cube_normals, GL_STATIC_DRAW); // Bind uv coords and upload data glBindBuffer(GL_ARRAY_BUFFER, vbo[3]); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*2, (void*)0); glBufferData(GL_ARRAY_BUFFER, sizeof(cube_uvs), cube_uvs, GL_STATIC_DRAW); // Plane glBindVertexArray(vao[1]); // Bind indices and upload data glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[4]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(plane_triangleList), plane_triangleList, GL_STATIC_DRAW); // Bind vertices and upload data glBindBuffer(GL_ARRAY_BUFFER, vbo[5]); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*3, (void*)0); glBufferData(GL_ARRAY_BUFFER, sizeof(plane_vertices), plane_vertices, GL_STATIC_DRAW); // Bind normals and upload data glBindBuffer(GL_ARRAY_BUFFER, vbo[6]); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*3, (void*)0); glBufferData(GL_ARRAY_BUFFER, sizeof(plane_normals), plane_normals, GL_STATIC_DRAW); // Bind uv coords and upload data glBindBuffer(GL_ARRAY_BUFFER, vbo[7]); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*2, (void*)0); glBufferData(GL_ARRAY_BUFFER, sizeof(plane_uvs), plane_uvs, GL_STATIC_DRAW); // Quad glBindVertexArray(vao[2]); // Bind indices and upload data glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[8]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quad_triangleList), quad_triangleList, GL_STATIC_DRAW); // Bind vertices and upload data glBindBuffer(GL_ARRAY_BUFFER, vbo[9]); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*2, (void*)0); glBufferData(GL_ARRAY_BUFFER, sizeof(quad_vertices), quad_vertices, GL_STATIC_DRAW); // Unbind everything. Potentially illegal on some implementations glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); // Init frame buffers GLuint gbufferFbo; GLuint gbufferTextures[3]; GLuint gbufferDrawBuffers[2]; glGenTextures(3, gbufferTextures); // Create color texture glBindTexture(GL_TEXTURE_2D, gbufferTextures[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, 0); //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Create normal texture glBindTexture(GL_TEXTURE_2D, gbufferTextures[1]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, 0); //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Create depth texture glBindTexture(GL_TEXTURE_2D, gbufferTextures[2]); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Create Framebuffer Object glGenFramebuffers(1, &gbufferFbo); glBindFramebuffer(GL_FRAMEBUFFER, gbufferFbo); // Attach textures to framebuffer glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 , GL_TEXTURE_2D, gbufferTextures[0], 0); gbufferDrawBuffers[0] = GL_COLOR_ATTACHMENT0; glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1 , GL_TEXTURE_2D, gbufferTextures[1], 0); gbufferDrawBuffers[1] = GL_COLOR_ATTACHMENT1; glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, gbufferTextures[2], 0); if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { fprintf(stderr, "Error on building framebuffer\n"); exit( EXIT_FAILURE ); } glBindFramebuffer(GL_FRAMEBUFFER, 0); do { t = glfwGetTime(); // Mouse states int leftButton = glfwGetMouseButton( GLFW_MOUSE_BUTTON_LEFT ); int rightButton = glfwGetMouseButton( GLFW_MOUSE_BUTTON_RIGHT ); int middleButton = glfwGetMouseButton( GLFW_MOUSE_BUTTON_MIDDLE ); if( leftButton == GLFW_PRESS ) guiStates.turnLock = true; else guiStates.turnLock = false; if( rightButton == GLFW_PRESS ) guiStates.zoomLock = true; else guiStates.zoomLock = false; if( middleButton == GLFW_PRESS ) guiStates.panLock = true; else guiStates.panLock = false; // Camera movements int altPressed = glfwGetKey(GLFW_KEY_LSHIFT); if (!altPressed && (leftButton == GLFW_PRESS || rightButton == GLFW_PRESS || middleButton == GLFW_PRESS)) { int x; int y; glfwGetMousePos(&x, &y); guiStates.lockPositionX = x; guiStates.lockPositionY = y; } if (altPressed == GLFW_PRESS) { int mousex; int mousey; glfwGetMousePos(&mousex, &mousey); int diffLockPositionX = mousex - guiStates.lockPositionX; int diffLockPositionY = mousey - guiStates.lockPositionY; if (guiStates.zoomLock) { float zoomDir = 0.0; if (diffLockPositionX > 0) zoomDir = -1.f; else if (diffLockPositionX < 0 ) zoomDir = 1.f; camera_zoom(camera, zoomDir * GUIStates::MOUSE_ZOOM_SPEED); } else if (guiStates.turnLock) { camera_turn(camera, diffLockPositionY * GUIStates::MOUSE_TURN_SPEED, diffLockPositionX * GUIStates::MOUSE_TURN_SPEED); } else if (guiStates.panLock) { camera_pan(camera, diffLockPositionX * GUIStates::MOUSE_PAN_SPEED, diffLockPositionY * GUIStates::MOUSE_PAN_SPEED); } guiStates.lockPositionX = mousex; guiStates.lockPositionY = mousey; } // Get camera matrices glm::mat4 projection = glm::perspective(45.0f, widthf / heightf, 0.1f, 100.f); glm::mat4 worldToView = glm::lookAt(camera.eye, camera.o, camera.up); glm::mat4 objectToWorld; glm::mat4 worldToScreen = projection * worldToView; glm::mat4 screenToWorld = glm::transpose(glm::inverse(worldToScreen)); glBindFramebuffer(GL_FRAMEBUFFER, gbufferFbo); glDrawBuffers(2, gbufferDrawBuffers); // Viewport glViewport( 0, 0, width, height ); // Default states glEnable(GL_DEPTH_TEST); // Clear the front buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Bind gbuffer shader glUseProgram(gbuffer_shader.program); // Upload uniforms glUniformMatrix4fv(gbuffer_projectionLocation, 1, 0, glm::value_ptr(projection)); glUniformMatrix4fv(gbuffer_viewLocation, 1, 0, glm::value_ptr(worldToView)); glUniformMatrix4fv(gbuffer_objectLocation, 1, 0, glm::value_ptr(objectToWorld)); glUniform1f(gbuffer_timeLocation, t); glUniform1i(gbuffer_diffuseLocation, 0); glUniform1i(gbuffer_specLocation, 1); // Bind textures glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textures[0]); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textures[1]); // Render vaos glBindVertexArray(vao[0]); glDrawElementsInstanced(GL_TRIANGLES, cube_triangleCount * 3, GL_UNSIGNED_INT, (void*)0, 4); glBindVertexArray(vao[1]); glDrawElements(GL_TRIANGLES, plane_triangleCount * 3, GL_UNSIGNED_INT, (void*)0); // Unbind framebuffer glBindFramebuffer(GL_FRAMEBUFFER, 0); // Viewport glViewport( 0, 0, width, height ); // Clear the front buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Bind lighting shader glUseProgram(lighting_shader.program); // Upload uniforms glUniform1i(lighting_materialLocation, 0); glUniform1i(lighting_normalLocation, 1); glUniform1i(lighting_depthLocation, 2); glUniform3fv(lighting_cameraPositionLocation, 1, glm::value_ptr(camera.eye)); glUniformMatrix4fv(lighting_inverseViewProjectionLocation, 1, 0, glm::value_ptr(screenToWorld)); // Bind color to unit 0 glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, gbufferTextures[0]); // Bind normal to unit 1 glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, gbufferTextures[1]); // Bind depth to unit 2 glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, gbufferTextures[2]); // Blit above the rest glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); for (int i = 0; i < (int) numLights; ++i) { float tl = t * i; //Update light uniforms float lightPosition[3] = { sinf(tl) * 10.f, -0.5f, cosf(tl) * 10.f}; float lightColor[3] = {sinf(tl) * 1.f, 1.f - cosf(tl), -sinf(tl)}; float lightIntensity = 10.0; glUniform3fv(lighting_lightPositionLocation, 1, lightPosition); glUniform3fv(lighting_lightColorLocation, 1, lightColor); glUniform1f(lighting_lightIntensityLocation, lightIntensity); // Draw quad glBindVertexArray(vao[2]); glDrawElements(GL_TRIANGLES, quad_triangleCount * 3, GL_UNSIGNED_INT, (void*)0); } glDisable(GL_BLEND); // Bind blit shader glUseProgram(blit_shader.program); // Upload uniforms glUniform1i(blit_tex1Location, 0); // use only unit 0 glActiveTexture(GL_TEXTURE0); // Viewport glViewport( 0, 0, width/3, height/4 ); // Bind texture glBindTexture(GL_TEXTURE_2D, gbufferTextures[0]); // Draw quad glBindVertexArray(vao[2]); glDrawElements(GL_TRIANGLES, quad_triangleCount * 3, GL_UNSIGNED_INT, (void*)0); // Viewport glViewport( width/3, 0, width/3, height/4 ); // Bind texture glBindTexture(GL_TEXTURE_2D, gbufferTextures[1]); // Draw quad glBindVertexArray(vao[2]); glDrawElements(GL_TRIANGLES, quad_triangleCount * 3, GL_UNSIGNED_INT, (void*)0); // Viewport glViewport( width/3 * 2, 0, width/3, height/4 ); // Bind texture glBindTexture(GL_TEXTURE_2D, gbufferTextures[2]); // Draw quad glBindVertexArray(vao[2]); glDrawElements(GL_TRIANGLES, quad_triangleCount * 3, GL_UNSIGNED_INT, (void*)0); #if 1 // Draw UI glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glViewport(0, 0, width, height); unsigned char mbut = 0; int mscroll = 0; int mousex; int mousey; glfwGetMousePos(&mousex, &mousey); mousey = height - mousey; if( leftButton == GLFW_PRESS ) mbut |= IMGUI_MBUT_LEFT; imguiBeginFrame(mousex, mousey, mbut, mscroll); int logScroll = 0; char lineBuffer[512]; imguiBeginScrollArea("001", width - 210, height - 310, 200, 300, &logScroll); sprintf(lineBuffer, "FPS %f", fps); imguiLabel(lineBuffer); imguiSlider("Lights", &numLights, 0.0, 100.0, 1.0); imguiEndScrollArea(); imguiEndFrame(); imguiRenderGLDraw(width, height); glDisable(GL_BLEND); #endif // Check for errors GLenum err = glGetError(); if(err != GL_NO_ERROR) { fprintf(stderr, "OpenGL Error : %s\n", gluErrorString(err)); } // Swap buffers glfwSwapBuffers(); } // Check if the ESC key was pressed or the window was closed while( glfwGetKey( GLFW_KEY_ESC ) != GLFW_PRESS && glfwGetWindowParam( GLFW_OPENED ) ); // Clean UI imguiRenderGLDestroy(); // Close OpenGL window and terminate GLFW glfwTerminate(); exit( EXIT_SUCCESS ); }
bool GLFW_App::checkRunning() { return running() && !glfwGetKey(m_windows.back()->handle(), GLFW_KEY_ESCAPE ) && !glfwWindowShouldClose(m_windows.back()->handle()); }