// To compile on Windows // Install GLFW 3.3.8 // https://www.glfw.org/download.html // Install GLEW 2.2.0 // https://github.com/nigels-com/glew/releases/tag/glew-2.2.0 // // extract the downloaded .zip files to "C:/libs"; this is currently expected // by our CMakeLists.txt. // Install CMake // https://cmake.org/download // Add to PATH for all users // from project root: // mkdir build // cd build // cmake .. // cmake --build . // The last step compiles the executable - this can also be done from Visual // Studio // To run in VS // Set startup project in Solution Explorer // Press F5 to run // // To compile on Arch Linux // // Install dependencies // sudo pacman -S glfw mesa glew // // Build // cmake .. // cmake --build . #include #include #include #include #include #include #include std::string readFile(const std::string& filePath) { std::ifstream fileStream(filePath, std::ios::in); if (!fileStream.is_open()) { std::cerr << "Could not read file " << filePath << ". File does not exist." << std::endl; return ""; } std::stringstream sstr; sstr << fileStream.rdbuf(); fileStream.close(); return sstr.str(); } GLuint compileShader(const std::string& shaderPath, GLenum shaderType) { GLuint shader; GLint success; std::string shaderSource = readFile(shaderPath); const char* source = shaderSource.c_str(); shader = glCreateShader(shaderType); glShaderSource(shader, 1, &source, NULL); glCompileShader(shader); glGetShaderiv(shader, GL_COMPILE_STATUS, &success); if (!success) { GLchar infoLog[512]; glGetShaderInfoLog(shader, 512, NULL, infoLog); std::cerr << "shader compilation failed" << std::endl << infoLog << std::endl; } return shader; } std::chrono::steady_clock::time_point startTime = std::chrono::steady_clock::now(); float getTime() { std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); std::chrono::duration timeSpan = std::chrono::duration_cast>(now - startTime); return timeSpan.count(); } int main() { // Set up GLFW, OpenGL and GLEW. if (!glfwInit()) return -1; GLFWwindow* window = glfwCreateWindow(640, 480, "Hello Triangle", NULL, NULL); if (!window) { glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glewExperimental = GL_TRUE; if (glewInit() != GLEW_OK) { std::cerr << "Failed to initialize GLEW" << std::endl; return -1; } // VAO, VBO float vertices[] = { -0.5, -0.5, 0.0, // left 0.5, -0.5, 0.0, // right 0.0, 0.5, 0.0 // top }; GLuint VBO, VAO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); // Shaders GLuint vertShader = compileShader("./vert.glsl", GL_VERTEX_SHADER); GLuint fragShader = compileShader("./frag.glsl", GL_FRAGMENT_SHADER); GLuint shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertShader); glAttachShader(shaderProgram, fragShader); glLinkProgram(shaderProgram); GLint success; GLchar infoLog[512]; glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); std::cerr << "shader linking failed" << std::endl << infoLog << std::endl; } // We no longer need the individual shaders glDeleteShader(vertShader); glDeleteShader(fragShader); // Main loop while (!glfwWindowShouldClose(window)) { glClearColor(0.2, 0.3, 0.3, 1.0); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(shaderProgram); GLint timeLocation = glGetUniformLocation(shaderProgram, "_Time"); if (timeLocation == -1) { std::cerr << "Could not find uniform: _Time" << std::endl; } float timeValue = getTime(); glUniform1f(timeLocation, timeValue); glBindVertexArray(VAO); glDrawArrays(GL_TRIANGLES, 0, 3); glfwSwapBuffers(window); glfwPollEvents(); } glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); glfwTerminate(); return 0; }