#define _USE_MATH_DEFINES #include #include #define GLEW_STATIC #include #include #define GLM_FORCE_RADIANS #include #include #include "GLSL.h" #include "MatrixStack.h" #include "Program.h" #include "Shape.h" using namespace std; GLFWwindow *window; // Main application window string RES_DIR = ""; // Where data files live shared_ptr prog; shared_ptr shape; static void error_callback(int error, const char *description) { cerr << description << endl; } static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) { if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { glfwSetWindowShouldClose(window, GL_TRUE); } } static void init() { GLSL::checkVersion(); // Set background color. glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Enable z-buffer test. glEnable(GL_DEPTH_TEST); // Initialize mesh. shape = make_shared(); shape->loadMesh(RES_DIR + "teapot.obj"); shape->init(); // Initialize the GLSL program. prog = make_shared(); prog->setVerbose(false); // Set this to true when debugging. prog->setShaderNames(RES_DIR + "simple_vert.glsl", RES_DIR + "simple_frag.glsl"); prog->init(); prog->addUniform("P"); prog->addUniform("MV"); prog->addAttribute("vertPos"); prog->addAttribute("vertNor"); // If there were any OpenGL errors, this will print something. // You can intersperse this line in your code to find the exact location // of your OpenGL error. GLSL::checkError(GET_FILE_LINE); } static void render() { // Get current frame buffer size. int width, height; glfwGetFramebufferSize(window, &width, &height); float aspect = width/(float)height; glViewport(0, 0, width, height); // Clear framebuffer. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Create matrix stacks. auto P = make_shared(); auto MV = make_shared(); // Apply projection. P->pushMatrix(); P->multMatrix(glm::perspective((float)(45.0*M_PI/180.0), aspect, 0.01f, 100.0f)); // Apply camera transform. MV->pushMatrix(); MV->translate(glm::vec3(0, -0.5, -3)); // Draw mesh using GLSL. prog->bind(); glUniformMatrix4fv(prog->getUniform("P"), 1, GL_FALSE, &P->topMatrix()[0][0]); glUniformMatrix4fv(prog->getUniform("MV"), 1, GL_FALSE, &MV->topMatrix()[0][0]); shape->draw(prog); prog->unbind(); // Pop matrix stacks. MV->popMatrix(); P->popMatrix(); GLSL::checkError(GET_FILE_LINE); } int main(int argc, char **argv) { if(argc < 2) { cout << "Please specify the resource directory." << endl; return 0; } RES_DIR = argv[1] + string("/"); // Set error callback. glfwSetErrorCallback(error_callback); // Initialize the library. if(!glfwInit()) { return -1; } // Create a windowed mode window and its OpenGL context. window = glfwCreateWindow(640, 480, "YOUR NAME", NULL, NULL); if(!window) { glfwTerminate(); return -1; } // Make the window's context current. glfwMakeContextCurrent(window); // Initialize GLEW. glewExperimental = true; if(glewInit() != GLEW_OK) { cerr << "Failed to initialize GLEW" << endl; return -1; } glGetError(); // A bug in glewInit() causes an error that we can safely ignore. cout << "OpenGL version: " << glGetString(GL_VERSION) << endl; cout << "GLSL version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << endl; // Set vsync. glfwSwapInterval(1); // Set keyboard callback. glfwSetKeyCallback(window, key_callback); // Initialize scene. init(); // Loop until the user closes the window. while(!glfwWindowShouldClose(window)) { // Render scene. render(); // Swap front and back buffers. glfwSwapBuffers(window); // Poll for and process events. glfwPollEvents(); } // Quit program. glfwDestroyWindow(window); glfwTerminate(); return 0; }