diff --git a/OpenGL/lab2/src/ls.fs b/OpenGL/lab2/src/ls.fs new file mode 100644 index 0000000..9b39924 --- /dev/null +++ b/OpenGL/lab2/src/ls.fs @@ -0,0 +1,8 @@ +#version 330 core +out vec4 FragColor; + +void main() +{ + FragColor = vec4(1.0); // set all 4 vector values to 1.0 +} + diff --git a/OpenGL/lab2/src/ls.vs b/OpenGL/lab2/src/ls.vs new file mode 100644 index 0000000..af399bb --- /dev/null +++ b/OpenGL/lab2/src/ls.vs @@ -0,0 +1,12 @@ +#version 330 core +layout (location = 0) in vec3 aPos; + +uniform mat4 trans; +uniform mat4 view; +uniform mat4 projection; + +void main() +{ + gl_Position = projection * view * trans * vec4(aPos, 1.0); +} + diff --git a/OpenGL/lab2/src/main.cpp b/OpenGL/lab2/src/main.cpp index a0b84d4..08481db 100644 --- a/OpenGL/lab2/src/main.cpp +++ b/OpenGL/lab2/src/main.cpp @@ -13,14 +13,13 @@ const unsigned int SCR_WIDTH = 600; const unsigned int SCR_HEIGHT = 600; - // 四边形顶点 float vertices[] = { - // ---- 位置 ---- ---- 颜色 ---- - 纹理坐标 - - 0.2f, 0.4f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // 右上 - 0.2f, -0.4f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // 右下 + // ---- 位置 ---- -- 法向量-- - 纹理坐标 - + 0.2f, 0.4f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // 右上 + 0.2f, -0.4f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, // 右下 -0.2f, -0.4f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // 左下 - -0.2f, 0.4f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // 左上 + -0.2f, 0.4f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f // 左上 }; // 索引 @@ -32,6 +31,9 @@ unsigned int indices[] = { float deltaTime, lastTime; Camera camera = Camera(SCR_HEIGHT / 2.0f, SCR_HEIGHT / 2.0f); +// lighting +glm::vec3 lightPos(1.2f, 1.0f, 2.0f); + void framebuffer_size_callback(GLFWwindow *window, int width, int height); void processInput(GLFWwindow *window); void mouse_callback(GLFWwindow *window, double xpos, double ypos); @@ -44,7 +46,6 @@ int main() { glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - // glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 创建窗口 GLFWwindow *window = @@ -54,7 +55,12 @@ int main() { glfwTerminate(); return -1; } + glfwMakeContextCurrent(window); + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + glfwSetCursorPosCallback(window, mouse_callback); + glfwSetScrollCallback(window, scroll_callback); // 加载glad if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { @@ -62,12 +68,6 @@ int main() { return -1; } - // 设置视口 - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); - glfwSetCursorPosCallback(window, mouse_callback); - glfwSetScrollCallback(window, scroll_callback); - // 创建着色器程序 Shader shader = Shader("src/tex.vs", "src/tex.fs"); @@ -90,7 +90,7 @@ int main() { // 顶点属性 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)0); glEnableVertexAttribArray(0); - // 颜色属性 + // 法向量属性 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(3 * sizeof(float))); glEnableVertexAttribArray(1); @@ -133,6 +133,19 @@ int main() { shader.use(); // 绑定纹理 shader.setInt("tex", 0); + // // 直射光 + shader.setVec3("dirLight.direction", 2.0f, 0.0f, 0.0f); + shader.setVec3("dirLight.ambient", 0.2f, 0.2f, 0.2f); + shader.setVec3("dirLight.diffuse", 0.6f, 0.6f, 0.6f); + shader.setVec3("dirLight.specular", 0.7f, 0.7f, 0.7f); + // 点光源 + shader.setVec3("pointLighs.position", glm::vec3(-0.5f, -2.0f, -0.5f)); + shader.setVec3("pointLight.ambient", 0.2f, 0.2f, 0.2f); + shader.setVec3("pointLight.diffuse", 3.0f, 3.0f, 3.0f); + shader.setVec3("pointLight.specular", 3.0f, 3.0f, 3.0f); + shader.setFloat("pointLight.constant", 1.0f); + shader.setFloat("pointLight.linear", 0.00014f); + shader.setFloat("pointLight.quadratic", 0.0000007f); // 开启深度测试 glEnable(GL_DEPTH_TEST); @@ -165,23 +178,34 @@ int main() { shader.use(); glBindVertexArray(VAO); + shader.setVec3("viewPos", camera.Position); shader.setMat4("view", view); shader.setMat4("projection", projection); + // 设置材质 + shader.setVec3("material.ambient", 1.0f, 0.5f, 0.31f); + shader.setVec3("material.diffuse", 1.0f, 0.5f, 0.31f); + shader.setVec3("material.specular", 0.5f, 0.5f, 0.5f); + shader.setFloat("material.shininess", 4.0f); glm::mat4 trans(1.0f); + trans = glm::rotate(trans, glm::radians(-90.0f), glm::vec3(1.0, 0.0, 0.0)); trans = glm::rotate(trans, float(-sin((float)glfwGetTime())), glm::vec3(0.0, 1.0, 0.0)); trans = glm::translate(trans, glm::vec3(-0.2, 0.0, 0.0)); shader.setMat4("trans", trans); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + // 设置材质 + shader.setVec3("material.ambient", 1.0f, 0.5f, 0.31f); + shader.setVec3("material.diffuse", 0.75f, 0.6f, 0.23f); + shader.setVec3("material.specular", 0.62f, 0.55f, 0.37f); + shader.setFloat("material.shininess", 64.0f); trans = glm::mat4(1.0f); + trans = glm::rotate(trans, glm::radians(-90.0f), glm::vec3(1.0, 0.0, 0.0)); trans = glm::rotate(trans, float(sin((float)glfwGetTime())), glm::vec3(0.0, 1.0, 0.0)); trans = glm::translate(trans, glm::vec3(0.2, 0.0, 0.0)); trans = glm::rotate(trans, glm::radians(180.0f), glm::vec3(0.0, 1.0, 0.0)); - // trans = glm::rotate(trans, (float)glfwGetTime(), glm::vec3(0.0, 0.5, - // 0.5)); trans = glm::scale(trans, glm::vec3(0.5, 0.5, 0.5)); shader.setMat4("trans", trans); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); @@ -209,11 +233,8 @@ void processInput(GLFWwindow *window) { camera.ProcessKeyboard(RIGHT, deltaTime); if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) camera.ProcessKeyboard(UP, deltaTime); - if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) - camera.ProcessKeyboard(DOWN, deltaTime); } - // 窗口大小改变时回调该函数 void framebuffer_size_callback(GLFWwindow *window, int width, int height) { glViewport(0, 0, width, height); diff --git a/OpenGL/lab2/src/tex.fs b/OpenGL/lab2/src/tex.fs index 346818b..e7ffe0a 100644 --- a/OpenGL/lab2/src/tex.fs +++ b/OpenGL/lab2/src/tex.fs @@ -1,14 +1,140 @@ #version 330 core -out vec4 FragColor; -in vec3 ourColor; +struct Material { + vec3 ambient; + vec3 diffuse; + vec3 specular; + float shininess; +}; + +struct DirLight { + vec3 direction; + + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; + +struct PointLight { + vec3 position; + + float constant; + float linear; + float quadratic; + + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; + +struct SpotLight { + vec3 position; + vec3 direction; + float cutOff; + float outerCutOff; + + float constant; + float linear; + float quadratic; + + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; + +in vec3 FragPos; +in vec3 Normal; in vec2 TexCoord; - uniform sampler2D tex; +uniform vec3 viewPos; +//直射光 +uniform DirLight dirLight; +//点光源 +uniform PointLight pointLight; +//材质 +uniform Material material; + +out vec4 FragColor; + +vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir); +vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir); +vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir); + void main() { - // FragColor = texture(tex, TexCoord) * vec4(ourColor, 1.0); + + vec3 norm = normalize(Normal); + vec3 viewDir = normalize(viewPos - FragPos); + // 第一阶段:定向光照 + vec3 result = CalcDirLight(dirLight, norm, viewDir); + // 第二阶段:点光源 + result += CalcPointLight(pointLight, norm, FragPos, viewDir); + if (texture(tex, TexCoord).a < 0.7) discard; - FragColor = texture(tex, TexCoord); + FragColor = vec4(result,1.0) * texture(tex, TexCoord); +} + +// calculates the color when using a directional light. +vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir) +{ + vec3 lightDir = normalize(-light.direction); + // diffuse shading + float diff = max(dot(normal, lightDir), 0.0); + // specular shading + vec3 reflectDir = reflect(-lightDir, normal); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); + // combine results + vec3 ambient = light.ambient * material.ambient * vec3(texture(tex, TexCoord)); + vec3 diffuse = light.diffuse * diff *material.diffuse * vec3(texture(tex, TexCoord)); + vec3 specular = light.specular * spec * material.specular * vec3(texture(tex, TexCoord)); + return (ambient + diffuse + specular); +} + +// calculates the color when using a point light. +vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir) +{ + vec3 lightDir = normalize(light.position - fragPos); + // diffuse shading + float diff = max(dot(normal, lightDir), 0.0); + // specular shading + vec3 reflectDir = reflect(-lightDir, normal); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); + // attenuation + float distance = length(light.position - fragPos); + float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); + // combine results + vec3 ambient = light.ambient * material.ambient * vec3(texture(tex, TexCoord)); + vec3 diffuse = light.diffuse * diff *material.diffuse * vec3(texture(tex, TexCoord)); + vec3 specular = light.specular * spec * material.specular * vec3(texture(tex, TexCoord)); + ambient *= attenuation; + diffuse *= attenuation; + specular *= attenuation; + return (ambient + diffuse + specular); +} + +// calculates the color when using a spot light. +vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir) +{ + vec3 lightDir = normalize(light.position - fragPos); + // diffuse shading + float diff = max(dot(normal, lightDir), 0.0); + // specular shading + vec3 reflectDir = reflect(-lightDir, normal); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); + // attenuation + float distance = length(light.position - fragPos); + float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); + // spotlight intensity + float theta = dot(lightDir, normalize(-light.direction)); + float epsilon = light.cutOff - light.outerCutOff; + float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0); + // combine results + vec3 ambient = light.ambient * material.ambient * vec3(texture(tex, TexCoord)); + vec3 diffuse = light.diffuse * diff *material.diffuse * vec3(texture(tex, TexCoord)); + vec3 specular = light.specular * spec * material.specular * vec3(texture(tex, TexCoord)); + ambient *= attenuation * intensity; + diffuse *= attenuation * intensity; + specular *= attenuation * intensity; + return (ambient + diffuse + specular); } \ No newline at end of file diff --git a/OpenGL/lab2/src/tex.vs b/OpenGL/lab2/src/tex.vs index d2437c7..b21b368 100644 --- a/OpenGL/lab2/src/tex.vs +++ b/OpenGL/lab2/src/tex.vs @@ -1,19 +1,23 @@ #version 330 core -layout (location = 0) in vec3 aPos; -layout (location = 1) in vec3 aColor; -layout (location = 2) in vec2 aTexCoord; +layout(location = 0) in vec3 aPos; +layout(location = 1) in vec3 aNormal; +layout(location = 2) in vec2 aTexCoord; -out vec3 ourColor; out vec2 TexCoord; +out vec3 FragPos; +out vec3 Normal; +out vec2 TexCoords; uniform mat4 trans; -uniform mat4 view; +uniform mat4 view; uniform mat4 projection; -void main() -{ - gl_Position = projection * view * trans * vec4(aPos, 1.0); - // gl_Position = trans * vec4(aPos, 1.0); - ourColor = aColor; - TexCoord = aTexCoord; +void main() { + // 计算角度 + FragPos = vec3(trans * vec4(aPos, 1.0)); + // 计算法向量 + Normal = mat3(transpose(inverse(trans))) * aNormal; + + gl_Position = projection * view * trans * vec4(aPos, 1.0); + TexCoord = aTexCoord; }