int main() { // 1.1 Initialize the GLFW glfwInit(); // 1.2 Set GLFW options 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); // 1.3 Create a GLFW window GLFWwindow* window = glfwCreateWindow(Width, Height, "LearnOpengl", nullptr, nullptr); if (window == nullptr) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } // 1.4 Link GLFW window glfwMakeContextCurrent(window); // 2.1 Set callback functions glfwSetKeyCallback(window, key_callback); glfwSetCursorPosCallback(window, mouse_callback); // 2.2 Capture the mouse glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); // 3.1 Set GLEW glewExperimental = GL_TRUE; if (glewInit() != GLEW_OK) { std::cout << "Failed to initialize GLEW" << std::endl; glfwTerminate(); return -1; } // 4. Set viewport glViewport(0, 0, Width, Height); // 5. Link shaders Shader objectShader("object.vert", "object.frag"); Shader lampShader("lamp.vert", "lamp.frag"); // 6. Create vertices GLfloat vertices[] = { // position // normal -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f }; // 7. Create and set object VAO and VBO GLuint objectVAO; glGenVertexArrays(1, &objectVAO); glBindVertexArray(objectVAO); GLuint VBO; glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6* sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(1); glBindVertexArray(0); // 8. Create and set light VAO GLuint lampVAO; glGenVertexArrays(1, &lampVAO); glBindVertexArray(lampVAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); glBindVertexArray(0); // 9. Enable depth test glEnable(GL_DEPTH_TEST); // 10. Game Loop GLfloat lastFrame = 0.0f; while (glfwWindowShouldClose(window) == GL_FALSE) { glfwPollEvents(); glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GLfloat currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; keyboard_movement(); // Make lamp spinning lampPosition.x = 2 * std::sin(1.2f * currentFrame); lampPosition.z = 0.2f + 2 * std::cos(1.2f * currentFrame); // object shader objectShader.use(); // vertex shader's variables GLint modelLocation = glGetUniformLocation(objectShader.getProgram(), "model"); GLint viewLocation = glGetUniformLocation(objectShader.getProgram(), "view"); GLint projectionLocation = glGetUniformLocation(objectShader.getProgram(), "projection"); GLint lampPositionLocation = glGetUniformLocation(objectShader.getProgram(), "lampPosition"); glm::mat4 model; model = glm::translate(model, glm::vec3(0.0f, -1.0f, 0.0f)); glm::mat4 view = glm::lookAt(cameraPosition, cameraPosition + cameraFront, cameraUp); glm::mat4 projection = glm::perspective(glm::radians(45.0f), (GLfloat)Width / (GLfloat)Height, 0.1f, 100.0f); glUniformMatrix4fv(modelLocation, 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(viewLocation, 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, glm::value_ptr(projection)); glUniform3f(lampPositionLocation, lampPosition.x, lampPosition.y, lampPosition.z); // fragment shader's variables GLint lampAmbientLocation = glGetUniformLocation(objectShader.getProgram(), "lamp.ambient"); GLint lampDiffuseLocation = glGetUniformLocation(objectShader.getProgram(), "lamp.diffuse"); GLint lampSpecularLocation = glGetUniformLocation(objectShader.getProgram(), "lamp.specular"); GLint materialAmbientLocation = glGetUniformLocation(objectShader.getProgram(), "material.ambient"); GLint materialDiffuseLocation = glGetUniformLocation(objectShader.getProgram(), "material.diffuse"); GLint materialSpecularLocation = glGetUniformLocation(objectShader.getProgram(), "material.specular"); GLint materialShininessLocation = glGetUniformLocation(objectShader.getProgram(), "material.shininess"); glUniform3f(lampAmbientLocation, 1.0f, 1.0f, 1.0f); glUniform3f(lampDiffuseLocation, 1.0f, 1.0f, 1.0f); glUniform3f(lampSpecularLocation, 1.0f, 1.0f, 1.0f); glUniform3f(materialAmbientLocation, 0.0215f, 0.1745f, 0.0215f); glUniform3f(materialDiffuseLocation, 0.07568f, 0.61424f, 0.07568f); glUniform3f(materialSpecularLocation, 0.633f, 0.727811f, 0.633f); glUniform1f(materialShininessLocation, 76.8f); // drawing glBindVertexArray(objectVAO); glDrawArrays(GL_TRIANGLES, 0, 36); glBindVertexArray(0); // lamp shader lampShader.use(); // vertex shader's variables modelLocation = glGetUniformLocation(lampShader.getProgram(), "model"); viewLocation = glGetUniformLocation(lampShader.getProgram(), "view"); projectionLocation = glGetUniformLocation(lampShader.getProgram(), "projection"); glm::mat4 lampModel; lampModel = glm::translate(lampModel, lampPosition); lampModel = glm::scale(lampModel, glm::vec3(0.2f)); glUniformMatrix4fv(modelLocation, 1, GL_FALSE, glm::value_ptr(lampModel)); glUniformMatrix4fv(viewLocation, 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, glm::value_ptr(projection)); // drawing glBindVertexArray(lampVAO); glDrawArrays(GL_TRIANGLES, 0, 36); glBindVertexArray(0); glfwSwapBuffers(window); } glDeleteVertexArrays(1, &objectVAO); glDeleteVertexArrays(1, &lampVAO); glDeleteBuffers(1, &VBO); glfwTerminate(); return 0; }
int main() { // 1.1 Initialize the GLFW glfwInit(); // 1.2 Set GLFW options 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); // 1.3 Create a GLFW window GLFWwindow* window = glfwCreateWindow(Width, Height, "LearnOpengl", nullptr, nullptr); if (window == nullptr) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } // 1.4 Link GLFW window glfwMakeContextCurrent(window); // 2.1 Set callback functions glfwSetKeyCallback(window, key_callback); glfwSetCursorPosCallback(window, mouse_callback); // 2.2 Capture the mouse glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); // 3.1 Set GLEW glewExperimental = GL_TRUE; if (glewInit() != GLEW_OK) { std::cout << "Failed to initialize GLEW" << std::endl; glfwTerminate(); return -1; } // 4. Set viewport glViewport(0, 0, Width, Height); // 5. Link shaders Shader objectShader("object.vert", "object.frag"); Shader lampShader("lamp.vert", "lamp.frag"); // 6. Create vertices GLfloat vertices[] = { // Positions // Normals // Texture Coordinates -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 }; glm::vec3 cubePositions[] = { glm::vec3( 0.0f, 0.0f, 0.0f), glm::vec3( 2.0f, 5.0f, -15.0f), glm::vec3(-1.5f, -2.2f, -2.5f), glm::vec3(-3.8f, -2.0f, -12.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) }; // 7. Create and set object VAO and VBO GLuint objectVAO; glGenVertexArrays(1, &objectVAO); glBindVertexArray(objectVAO); GLuint VBO; glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(1); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat))); glEnableVertexAttribArray(2); glBindVertexArray(0); // 8. Create and set light VAO GLuint lampVAO; glGenVertexArrays(1, &lampVAO); glBindVertexArray(lampVAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); glBindVertexArray(0); // 9. Create diffuse map and specular map GLuint diffuseMap; glGenTextures(1, &diffuseMap); glBindTexture(GL_TEXTURE_2D, diffuseMap); 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); int imageWidth, imageHeight; unsigned char* image = SOIL_load_image("img/box.png", &imageWidth, &imageHeight, 0, SOIL_LOAD_RGB); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imageWidth, imageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, image); glGenerateMipmap(GL_TEXTURE_2D); SOIL_free_image_data(image); glBindTexture(GL_TEXTURE_2D, 0); GLuint specularMap; glGenTextures(1, &specularMap); glBindTexture(GL_TEXTURE_2D, specularMap); 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); image = SOIL_load_image("img/boundary.png", &imageWidth, &imageHeight, 0, SOIL_LOAD_RGB); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imageWidth, imageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, image); glGenerateMipmap(GL_TEXTURE_2D); SOIL_free_image_data(image); glBindTexture(GL_TEXTURE_2D, 0); // 10. Enable depth test glEnable(GL_DEPTH_TEST); // 11. Game Loop GLfloat lastFrame = 0.0f; while (glfwWindowShouldClose(window) == GL_FALSE) { glfwPollEvents(); glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GLfloat currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; keyboard_movement(); // object shader objectShader.use(); // vertex shader's variables GLint modelLocation = glGetUniformLocation(objectShader.getProgram(), "model"); GLint viewLocation = glGetUniformLocation(objectShader.getProgram(), "view"); GLint projectionLocation = glGetUniformLocation(objectShader.getProgram(), "projection"); // glm::mat4 model; // model = glm::translate(model, glm::vec3(0.0f, -1.0f, 0.0f)); glm::mat4 view = glm::lookAt(cameraPosition, cameraPosition + cameraFront, cameraUp); glm::mat4 projection = glm::perspective(glm::radians(45.0f), (GLfloat)Width / (GLfloat)Height, 0.1f, 100.0f); // glUniformMatrix4fv(modelLocation, 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(viewLocation, 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, glm::value_ptr(projection)); // fragment shader's variables GLint lampDirectionLocation = glGetUniformLocation(objectShader.getProgram(), "lamp.direction"); GLint lampAmbientLocation = glGetUniformLocation(objectShader.getProgram(), "lamp.ambient"); GLint lampDiffuseLocation = glGetUniformLocation(objectShader.getProgram(), "lamp.diffuse"); GLint lampSpecularLocation = glGetUniformLocation(objectShader.getProgram(), "lamp.specular"); GLint materialDiffuseLocation = glGetUniformLocation(objectShader.getProgram(), "material.diffuse"); GLint materialSpecularLocation = glGetUniformLocation(objectShader.getProgram(), "material.specular"); GLint materialShininessLocation = glGetUniformLocation(objectShader.getProgram(), "material.shininess"); // w must be 0.0f: it's just a direction, we don't want translation works glm::vec4 lampDirectionInViewSpace = view * glm::vec4(lampDirection.x, lampDirection.y, lampDirection.z, 0.0f); glUniform3f(lampDirectionLocation, lampDirectionInViewSpace.x, lampDirectionInViewSpace.y, lampDirectionInViewSpace.z); glUniform3f(lampAmbientLocation, 0.2f, 0.2f, 0.2f); glUniform3f(lampDiffuseLocation, 0.5f, 0.5f, 0.5f); glUniform3f(lampSpecularLocation, 1.0f, 1.0f, 1.0f); glUniform1i(materialDiffuseLocation, 0); glUniform1i(materialSpecularLocation, 1); glUniform1f(materialShininessLocation, 64.0f); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, diffuseMap); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, specularMap); // drawing glBindVertexArray(objectVAO); for(GLuint i = 0; i < 10; i++) { glm::mat4 model; model = glm::translate(model, cubePositions[i]); GLfloat angle = 20.0f * i; model = glm::rotate(model, angle, glm::vec3(1.0f, 0.3f, 0.5f)); glUniformMatrix4fv(modelLocation, 1, GL_FALSE, glm::value_ptr(model)); glDrawArrays(GL_TRIANGLES, 0, 36); } glBindVertexArray(0); // // lamp shader // lampShader.use(); // // // vertex shader's variables // modelLocation = glGetUniformLocation(lampShader.getProgram(), "model"); // viewLocation = glGetUniformLocation(lampShader.getProgram(), "view"); // projectionLocation = glGetUniformLocation(lampShader.getProgram(), "projection"); // // glm::mat4 lampModel; // lampModel = glm::translate(lampModel, lampPosition); // lampModel = glm::scale(lampModel, glm::vec3(0.2f)); // glUniformMatrix4fv(modelLocation, 1, GL_FALSE, glm::value_ptr(lampModel)); // glUniformMatrix4fv(viewLocation, 1, GL_FALSE, glm::value_ptr(view)); // glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, glm::value_ptr(projection)); // // // drawing // glBindVertexArray(lampVAO); // glDrawArrays(GL_TRIANGLES, 0, 36); // glBindVertexArray(0); glfwSwapBuffers(window); } glDeleteVertexArrays(1, &objectVAO); glDeleteVertexArrays(1, &lampVAO); glDeleteBuffers(1, &VBO); glfwTerminate(); return 0; }
// The MAIN function, from here we start the application and run the game loop void basicLight() { // Init GLFW glfwInit(); // Set all the required options for GLFW 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); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Create a GLFWwindow object that we can use for GLFW's functions GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr); glfwMakeContextCurrent(window); // Set the required callback functions glfwSetKeyCallback(window, key_callback); glfwSetCursorPosCallback(window, mouse_callback); glfwSetScrollCallback(window, scroll_callback); // GLFW Options glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions glewExperimental = GL_TRUE; // Initialize GLEW to setup the OpenGL Function pointers glewInit(); // Define the viewport dimensions glViewport(0, 0, WIDTH, HEIGHT); // OpenGL options glEnable(GL_DEPTH_TEST); // Build and compile our shader program Shader lampShader(lightVertexObjectSS, lightFragmentSS); Shader objectShader(objectVertexObjectSS, objectFragmentSS); //Shader objectShader(gouraudObjectVertexObjectSS, gouraudObjectFragmentSS); // Set up vertex data (and buffer(s)) and attribute pointers GLfloat vertices[] = { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f }; // First, set the container's VAO (and VBO) GLuint VBO, containerVAO; glGenVertexArrays(1, &containerVAO); glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindVertexArray(containerVAO); // Position attribute glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); // Normal attribute glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(1); glBindVertexArray(0); // Then, we set the light's VAO (VBO stays the same. After all, the vertices are the same for the light object (also a 3D cube)) GLuint lightVAO; glGenVertexArrays(1, &lightVAO); glBindVertexArray(lightVAO); // We only need to bind to the VBO (to link it with glVertexAttribPointer), no need to fill it; the VBO's data already contains all we need. glBindBuffer(GL_ARRAY_BUFFER, VBO); // Set the vertex attributes (only position data for the lamp)) glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); glBindVertexArray(0); // Game loop while (!glfwWindowShouldClose(window)) { // Calculate deltatime of current frame GLfloat currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions glfwPollEvents(); do_movement(); // Clear the colorbuffer glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); ////////////////////////////////////////////////////////////////////// // Use cooresponding shader when setting uniforms/drawing objects objectShader.Use(); GLint objectColorLoc = glGetUniformLocation(objectShader.Program, "objectColor"); GLint lightColorLoc = glGetUniformLocation(objectShader.Program, "lightColor"); GLint lightPosLoc = glGetUniformLocation(objectShader.Program, "lightPos"); GLint viewPosLoc = glGetUniformLocation(objectShader.Program, "viewPos"); glUniform3f(objectColorLoc, 1.0f, 0.5f, 0.31f); glUniform3f(lightColorLoc, 1.0f, 1.0f, 1.0f); lightPos.x = sin(glfwGetTime()) * 1.5f; lightPos.y = cos(glfwGetTime()/2) * 1.0f; glUniform3f(lightPosLoc, lightPos.x, lightPos.y, lightPos.z); glUniform3f(viewPosLoc, camera.Position.x, camera.Position.y, camera.Position.z); // Create camera transformations glm::mat4 view; view = camera.GetViewMatrix(); glm::mat4 projection = glm::perspective(camera.Zoom, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f); // Get the uniform locations GLint modelLoc = glGetUniformLocation(objectShader.Program, "model"); GLint viewLoc = glGetUniformLocation(objectShader.Program, "view"); GLint projLoc = glGetUniformLocation(objectShader.Program, "projection"); // Pass the matrices to the shader glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection)); // Draw the container (using container's vertex attributes) glBindVertexArray(containerVAO); glm::mat4 model; GLfloat angle = glm::radians(glfwGetTime() * 45.0f); model = glm::rotate(model, angle, glm::vec3(1.0f, 0.5f, 0.0f)); glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); glDrawArrays(GL_TRIANGLES, 0, 36); glBindVertexArray(0); /////////////////////////////////////////////////////////////// // Also draw the lamp object, again binding the appropriate shader lampShader.Use(); // Get location objects for the matrices on the lamp shader (these could be different on a different shader) modelLoc = glGetUniformLocation(lampShader.Program, "model"); viewLoc = glGetUniformLocation(lampShader.Program, "view"); projLoc = glGetUniformLocation(lampShader.Program, "projection"); // Set matrices 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); // Swap the screen buffers glfwSwapBuffers(window); } // Terminate GLFW, clearing any resources allocated by GLFW. glfwTerminate(); }