OPENGL光照漫反射練習
阿新 • • 發佈:2019-01-05
#include <glad\glad.h> #include <GLFW\glfw3.h> #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> #include "Shader.h" #include <iostream> using namespace std; const unsigned int SRC_WIDTH = 800; const unsigned int SRC_HEIGHT = 600; glm::vec3 cameraPosition = glm::vec3(0.0f,0.0f,3.0f); glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f); glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f); glm::vec3 lightPosition = glm::vec3(1.0f, 0.0f, 2.0f); glm::vec3 lightColor = glm::vec3(1.0f,1.0f,1.0f); glm::vec3 objectColor = glm::vec3(1.0f,0.5f,0.3f); bool firstMouseClick = true; float mouseSensortive = 0.1f; float zoom = 45.0f; float lastX = SRC_WIDTH / 2.0f; float lastY = SRC_HEIGHT / 2.0f; float yaw = -90.0f; float pitch = 0.0f; //座標 和 法向量 const char* cubeVertexShaderSource = "#version 330 core\n" "layout(location = 0) in vec3 aPos;\n" "layout(location = 1) in vec3 aNormal;\n" "out vec3 FragPos;\n" "out vec3 Normal;\n" "uniform mat4 model;\n" "uniform mat4 view;\n" "uniform mat4 projection;\n" "void main(){\n" "Normal = aNormal;\n" "FragPos = vec3(model * vec4(aPos,1.0));\n" //"gl_Position = projection * view * model * vec4(aPos,1.0);\n" "gl_Position = projection * view * vec4(FragPos, 1.0);\n" "}\n" ; //光照方向 = 光源向量減去碎片位置向量(世界座標系) //光照方向點積法向量就是漫反射效果 //漫反射效果 + 全反射效果 const char* cubeFragShaderSource = "#version 330 core\n" "out vec4 FragColor;\n" "in vec3 FragPos;\n" "in vec3 Normal;\n" "uniform vec3 lightPos;\n" "uniform vec3 lightColor;\n" "uniform vec3 objectColor;\n" "void main(){\n" "float ambientStrength = 0.1;\n" "vec3 ambient = ambientStrength * lightColor;\n" "vec3 norm = normalize(Normal);\n" "vec3 lightDir = normalize(lightPos - FragPos);\n" "float diff = max(dot(norm,lightDir),0.0);\n" "vec3 diffuse = diff * lightColor;\n" "vec3 result = (ambient + diffuse) * objectColor;\n" "FragColor = vec4(result,1.0);\n" "}\n" ; const char* lightVertexShaderSource = "#version 330 core\n" "layout(location = 0) in vec3 aPos;\n" "uniform mat4 model;\n" "uniform mat4 view;\n" "uniform mat4 projection;\n" "void main(){\n" "gl_Position = projection * view * model * vec4(aPos,1.0);\n" "}\n" ; const char* lightFragShaderSource = "#version 330 core\n" "out vec4 FragColor;\n" "void main(){\n" "FragColor = vec4(1.0);\n" "}\n" ; void framebuffer_size_callback(GLFWwindow* window, int width, int height); void mouse_callback(GLFWwindow* window, double xpos, double ypos); void processInput(GLFWwindow *window); int main() { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); #ifdef __APPLE__ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X #endif GLFWwindow* window = glfwCreateWindow(SRC_WIDTH, SRC_HEIGHT, "Zhongqi", NULL, NULL); if (window == NULL) { std::cout << "Create Window Failed" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); glfwSetCursorPosCallback(window, mouse_callback); if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { return -1; } glEnable(GL_DEPTH_TEST); Shader cubeShader(cubeVertexShaderSource, cubeFragShaderSource); Shader lightShader(lightVertexShaderSource,lightFragShaderSource); //頂點貼面的法向量 由於是正方體 就在頂點陣列給出 float 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 }; unsigned int cubeVAO, VBO; glGenVertexArrays(1, &cubeVAO); glGenBuffers(1, &VBO); glBindVertexArray(cubeVAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(0)); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1); unsigned int lightVAO; glGenVertexArrays(1, &lightVAO); glBindVertexArray(lightVAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(0)); glEnableVertexAttribArray(0); //渲染操作 while (!glfwWindowShouldClose(window)) { processInput(window); glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); cubeShader.use(); cubeShader.setVec3("lightPos", lightPosition); cubeShader.setVec3("lightColor", 1.0f, 1.0f, 1.0f); cubeShader.setVec3("objectColor", 1.0f, 0.5f, 0.31f); glm::mat4 model; glm::mat4 view; glm::mat4 projection; model = glm::rotate(model, glm::radians(45.0f), glm::vec3(1.0f,1.0f,1.0f)); projection = glm::perspective(glm::radians(zoom), (float)SRC_WIDTH / (float)SRC_HEIGHT, 0.1f, 100.0f); view = glm::lookAt(cameraPosition, cameraPosition + cameraFront, cameraUp); cubeShader.setMat4("model", model); cubeShader.setMat4("view", view); cubeShader.setMat4("projection", projection); glBindVertexArray(cubeVAO); glDrawArrays(GL_TRIANGLES, 0, 36); lightShader.use(); lightShader.setMat4("view", view); lightShader.setMat4("projection", projection); model = glm::mat4(); model = glm::translate(model, lightPosition); model = glm::scale(model, glm::vec3(0.2f)); lightShader.setMat4("model", model); glBindVertexArray(lightVAO); glDrawArrays(GL_TRIANGLES, 0, 36); glfwSwapBuffers(window); glfwPollEvents(); } glDeleteVertexArrays(1, &lightVAO); glDeleteVertexArrays(1, &cubeVAO); glDeleteBuffers(1, &VBO); glfwTerminate(); return 0; } void framebuffer_size_callback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); } void mouse_callback(GLFWwindow* window, double xpos, double ypos) { if (firstMouseClick) { lastX = xpos; lastY = ypos; firstMouseClick = false; } float xoffset = xpos - lastX; float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top lastX = xpos; lastY = ypos; xoffset *= mouseSensortive; yoffset *= mouseSensortive; yaw += xoffset; pitch += yoffset; if (pitch > 89.0f) pitch = 89.0f; if (pitch < -89.0f) pitch = -89.0f; glm::vec3 front; front.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch)); front.y = sin(glm::radians(pitch)); front.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch)); cameraFront = glm::normalize(front); } void processInput(GLFWwindow *window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); }
效果圖