OpenGL高级光照篇--SSAO-38

学习链接:中文 -------- 英语原文

这一节东西比较多,可以说对之前学过的内容的总结和练习。
多处使用帧缓冲,需要好好理解每个帧缓冲渲染的目的,渲染的结果存到哪了,输入是哪个帧缓冲的。
还是多看看代码和上面的文章。
文章底部还有其他的关于SSAO的介绍。

流程:
1.正常渲染GBuffer
2.渲染遮挡值
3.模糊遮挡值
4.应用遮挡到环境光上,其他光照正常计算(在观察空间)

源码:源码

自己跟着敲的一边代码:添加了部分注释

#include 
#include 
#include #include 
#include 
#include #include 
#include 
#include #include 
#include void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
void processInput(GLFWwindow* window);
unsigned int loadTexture(const char* path, bool gammaCorrection);
void renderQuad();
void renderCube();// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
bool bloom = true;
bool bloomKeyPressed = false;
float exposure = 1.0f;// camera
Camera camera(glm::vec3(0.0f, 0.0f, 5.0f));
float lastX = (float)SCR_WIDTH / 2.0;
float lastY = (float)SCR_HEIGHT / 2.0;
bool firstMouse = true;// timing
float deltaTime = 0.0f;
float lastFrame = 0.0f;float lerp(float a, float b, float t)
{return a + t * (b - a);
}int main()
{// glfw: initialize and configure// ------------------------------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);
#endif// glfw window creation// --------------------GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);if (window == NULL){std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);glfwSetCursorPosCallback(window, mouse_callback);glfwSetScrollCallback(window, scroll_callback);// tell GLFW to capture our mouseglfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);// glad: load all OpenGL function pointers// ---------------------------------------if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){std::cout << "Failed to initialize GLAD" << std::endl;return -1;}//stbi_set_flip_vertically_on_load(true);// configure global opengl state// -----------------------------glEnable(GL_DEPTH_TEST);//build and compile shadersShader shaderGeometryPass("Shaders/Learn38_SSAOGeometry.vs", "Shaders/Learn38_SSAOGeometry.fs");Shader shaderLightingPass("Shaders/Learn38_SSAO.vs", "Shaders/Learn38_SSAOLighting.fs");Shader shaderSSAO("Shaders/Learn38_SSAO.vs", "Shaders/Learn38_SSAO.fs");Shader shaderSSAOBlur("Shaders/Learn38_SSAO.vs", "Shaders/Learn38_SSAOBlur.fs");//load modelModel backpack("Models/backpack/backpack.obj");//configure gbuffer framebuffer;unsigned int gBuffer;glGenFramebuffers(1, &gBuffer);glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);unsigned int gPosition, gNormal, gAlbedo;//position color bufferglGenTextures(1, &gPosition);glBindTexture(GL_TEXTURE_2D, gPosition);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gPosition, 0);//normal color bufferglGenTextures(1, &gNormal);glBindTexture(GL_TEXTURE_2D, gNormal);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gNormal, 0);//color + specular color bufferglGenTextures(1, &gAlbedo);glBindTexture(GL_TEXTURE_2D, gAlbedo);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gAlbedo, 0);//tell opengl which color attachments we'll use(of this framebuffer) for renderingunsigned int attacments[3] = { GL_COLOR_ATTACHMENT0,GL_COLOR_ATTACHMENT1,GL_COLOR_ATTACHMENT2 };glDrawBuffers(3, attacments);//create and attach depth buffer(renderbuffer)unsigned int rboDepth;glGenRenderbuffers(1, &rboDepth);glBindRenderbuffer(GL_RENDERBUFFER, rboDepth);glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, SCR_WIDTH, SCR_HEIGHT);glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboDepth);//finally check if framebuffer is completeif (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){std::cout << "framebuffer not complete!" << std::endl;}glBindFramebuffer(GL_FRAMEBUFFER, 0);//also create framebuffer to hold SSAO processing stageunsigned int ssaoFBO, ssaoBlurFBO;glGenFramebuffers(1, &ssaoFBO);glGenFramebuffers(1, &ssaoBlurFBO);glBindFramebuffer(GL_FRAMEBUFFER, ssaoFBO);unsigned int ssaoColorBuffer, ssaoColorBufferBlur;//SSAO color bufferglGenTextures(1, &ssaoColorBuffer);glBindTexture(GL_TEXTURE_2D, ssaoColorBuffer);glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, SCR_WIDTH, SCR_HEIGHT, 0, GL_RED, GL_FLOAT, NULL);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ssaoColorBuffer, 0);if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){std::cout << "SSAO Framebuffer not complete!" << std::endl;}//and blur stageglBindFramebuffer(GL_FRAMEBUFFER, ssaoBlurFBO);glGenTextures(1, &ssaoColorBufferBlur);glBindTexture(GL_TEXTURE_2D, ssaoColorBufferBlur);glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, SCR_WIDTH, SCR_HEIGHT, 0, GL_RED, GL_FLOAT, NULL);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ssaoColorBufferBlur, 0);if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){std::cout << "SSAO blur framebuffer not complete!" << std::endl;}glBindFramebuffer(GL_FRAMEBUFFER, 0);//generate sample kernelstd::uniform_real_distribution<GLfloat> randomFloats(0.0, 1.0);std::default_random_engine generator;std::vector<glm::vec3> ssaoKernel;for (unsigned int i = 0; i < 64; i++){glm::vec3 sample(randomFloats(generator) * 2.0 - 1.0, randomFloats(generator) * 2.0 - 1.0, randomFloats(generator));sample = glm::normalize(sample);sample *= randomFloats(generator);float scale = float(i) / 64.0;//scale samples they're more aligned to center of kernelscale = lerp(0.1f, 1.0f, scale * scale);sample *= scale;ssaoKernel.push_back(sample);}//generate noise texturestd::vector<glm::vec3> ssaoNoise;for (unsigned int i = 0; i < 16; i++){glm::vec3 noise(randomFloats(generator) * 2.0 - 1.0, randomFloats(generator) * 2.0 - 1.0, 0.0f);ssaoNoise.push_back(noise);}unsigned int noiseTexture;glGenTextures(1, &noiseTexture);glBindTexture(GL_TEXTURE_2D, noiseTexture);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, 4, 4, 0, GL_RGB, GL_FLOAT, &ssaoNoise[0]);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);//lighting infoglm::vec3 lightPos = glm::vec3(2.0, 4.0, -2.0);glm::vec3 lightColor = glm::vec3(0.2, 0.2, 0.7);//shader configureshaderLightingPass.use();shaderLightingPass.setInt("gPosition", 0);shaderLightingPass.setInt("gNormal", 1);shaderLightingPass.setInt("gAlbedo", 2);shaderLightingPass.setInt("ssao", 3);shaderSSAO.use();shaderSSAO.setInt("gPosition", 0);shaderSSAO.setInt("gNormal", 1);shaderSSAO.setInt("texNoise", 2);shaderSSAOBlur.use();shaderSSAOBlur.setInt("ssaoInput", 0);// render loop	while (!glfwWindowShouldClose(window)){//per-frame time logicfloat currentFrame = glfwGetTime();deltaTime = currentFrame - lastFrame;lastFrame = currentFrame;//inputprocessInput(window);//renderglClearColor(0.0f, 0.0f, 0.0f, 1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//1.geometry pass :render scene's geometry/color data into gbufferglBindFramebuffer(GL_FRAMEBUFFER, gBuffer);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 50.0f);glm::mat4 view = camera.GetViewMatrix();glm::mat4 model = glm::mat4(1.0f);shaderGeometryPass.use();shaderGeometryPass.setMat4("projection", projection);shaderGeometryPass.setMat4("view", view);model = glm::mat4(1.0f);model = glm::translate(model, glm::vec3(0.0f, 7.0f, 0.0f));model = glm::scale(model, glm::vec3(7.5f, 7.5f, 7.5f));shaderGeometryPass.setMat4("model", model);shaderGeometryPass.setInt("invertedNormals", 1);renderCube();shaderGeometryPass.setInt("invertedNormals", 0);//backpack model on the floormodel = glm::mat4(1.0f);model = glm::translate(model, glm::vec3(0.0f, 0.5f, 0.0f));model = glm::rotate(model, glm::radians(-90.0f), glm::vec3(1.0f, 0.0f, 0.0f));model = glm::scale(model, glm::vec3(1.0f));shaderGeometryPass.setMat4("model", model);backpack.Draw(shaderGeometryPass);glBindFramebuffer(GL_FRAMEBUFFER, 0);//2.generate ssao textureglBindFramebuffer(GL_FRAMEBUFFER, ssaoFBO);glClear(GL_COLOR_BUFFER_BIT);shaderSSAO.use();//send kernel+rotationfor (unsigned int i = 0; i < 64; i++){shaderSSAO.setVec3("samples[" + std::to_string(i) + "]", ssaoKernel[i]);}shaderSSAO.setMat4("projection", projection);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, gPosition);glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D, gNormal);glActiveTexture(GL_TEXTURE2);glBindTexture(GL_TEXTURE_2D, noiseTexture);renderQuad();glBindFramebuffer(GL_FRAMEBUFFER, 0);		//3.blur ssao texture to remove noiseglBindFramebuffer(GL_FRAMEBUFFER, ssaoBlurFBO);glClear(GL_COLOR_BUFFER_BIT);shaderSSAOBlur.use();glActiveTexture(GL_TEXTURE0);//这里用的ssaoColorBuffer,是上面渲染好的数据,渲染到ssaoColorBufferBlurglBindTexture(GL_TEXTURE_2D, ssaoColorBuffer);renderQuad();glBindFramebuffer(GL_FRAMEBUFFER, 0);		//4.lighting pass:traditional deferred Blinn-Phong lighting with added screen-space ambient occlusionglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);shaderLightingPass.use();//send light relevant uniformsglm::vec3 lightPosView = glm::vec3(camera.GetViewMatrix() * glm::vec4(lightPos, 1.0f));shaderLightingPass.setVec3("light.Position", lightPosView);shaderLightingPass.setVec3("light.Color", lightColor);//update attenuaton parametersconst float linear = 0.09f;const float quadratic = 0.032f;shaderLightingPass.setFloat("light.Linear", linear);shaderLightingPass.setFloat("light.Quadratic", quadratic);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, gPosition);glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D, gNormal);glActiveTexture(GL_TEXTURE2);glBindTexture(GL_TEXTURE_2D, gAlbedo);glActiveTexture(GL_TEXTURE3);//这里输入是模糊好的buffer:ssaoColorBufferBlurglBindTexture(GL_TEXTURE_2D, ssaoColorBufferBlur);//finally render quadrenderQuad();glfwSwapBuffers(window);glfwPollEvents();}glfwTerminate();return 0;
}// renderCube() renders a 1x1 3D cube in NDC.
// -------------------------------------------------
unsigned int cubeVAO = 0;
unsigned int cubeVBO = 0;
void renderCube()
{// initialize (if necessary)if (cubeVAO == 0){float vertices[] = {// back face-1.0f, -1.0f, -1.0f,  0.0f,  0.0f, -1.0f, 0.0f, 0.0f, // bottom-left1.0f,  1.0f, -1.0f,  0.0f,  0.0f, -1.0f, 1.0f, 1.0f, // top-right1.0f, -1.0f, -1.0f,  0.0f,  0.0f, -1.0f, 1.0f, 0.0f, // bottom-right         1.0f,  1.0f, -1.0f,  0.0f,  0.0f, -1.0f, 1.0f, 1.0f, // top-right-1.0f, -1.0f, -1.0f,  0.0f,  0.0f, -1.0f, 0.0f, 0.0f, // bottom-left-1.0f,  1.0f, -1.0f,  0.0f,  0.0f, -1.0f, 0.0f, 1.0f, // top-left// front face-1.0f, -1.0f,  1.0f,  0.0f,  0.0f,  1.0f, 0.0f, 0.0f, // bottom-left1.0f, -1.0f,  1.0f,  0.0f,  0.0f,  1.0f, 1.0f, 0.0f, // bottom-right1.0f,  1.0f,  1.0f,  0.0f,  0.0f,  1.0f, 1.0f, 1.0f, // top-right1.0f,  1.0f,  1.0f,  0.0f,  0.0f,  1.0f, 1.0f, 1.0f, // top-right-1.0f,  1.0f,  1.0f,  0.0f,  0.0f,  1.0f, 0.0f, 1.0f, // top-left-1.0f, -1.0f,  1.0f,  0.0f,  0.0f,  1.0f, 0.0f, 0.0f, // bottom-left// left face-1.0f,  1.0f,  1.0f, -1.0f,  0.0f,  0.0f, 1.0f, 0.0f, // top-right-1.0f,  1.0f, -1.0f, -1.0f,  0.0f,  0.0f, 1.0f, 1.0f, // top-left-1.0f, -1.0f, -1.0f, -1.0f,  0.0f,  0.0f, 0.0f, 1.0f, // bottom-left-1.0f, -1.0f, -1.0f, -1.0f,  0.0f,  0.0f, 0.0f, 1.0f, // bottom-left-1.0f, -1.0f,  1.0f, -1.0f,  0.0f,  0.0f, 0.0f, 0.0f, // bottom-right-1.0f,  1.0f,  1.0f, -1.0f,  0.0f,  0.0f, 1.0f, 0.0f, // top-right// right face1.0f,  1.0f,  1.0f,  1.0f,  0.0f,  0.0f, 1.0f, 0.0f, // top-left1.0f, -1.0f, -1.0f,  1.0f,  0.0f,  0.0f, 0.0f, 1.0f, // bottom-right1.0f,  1.0f, -1.0f,  1.0f,  0.0f,  0.0f, 1.0f, 1.0f, // top-right         1.0f, -1.0f, -1.0f,  1.0f,  0.0f,  0.0f, 0.0f, 1.0f, // bottom-right1.0f,  1.0f,  1.0f,  1.0f,  0.0f,  0.0f, 1.0f, 0.0f, // top-left1.0f, -1.0f,  1.0f,  1.0f,  0.0f,  0.0f, 0.0f, 0.0f, // bottom-left     // bottom face-1.0f, -1.0f, -1.0f,  0.0f, -1.0f,  0.0f, 0.0f, 1.0f, // top-right1.0f, -1.0f, -1.0f,  0.0f, -1.0f,  0.0f, 1.0f, 1.0f, // top-left1.0f, -1.0f,  1.0f,  0.0f, -1.0f,  0.0f, 1.0f, 0.0f, // bottom-left1.0f, -1.0f,  1.0f,  0.0f, -1.0f,  0.0f, 1.0f, 0.0f, // bottom-left-1.0f, -1.0f,  1.0f,  0.0f, -1.0f,  0.0f, 0.0f, 0.0f, // bottom-right-1.0f, -1.0f, -1.0f,  0.0f, -1.0f,  0.0f, 0.0f, 1.0f, // top-right// top face-1.0f,  1.0f, -1.0f,  0.0f,  1.0f,  0.0f, 0.0f, 1.0f, // top-left1.0f,  1.0f , 1.0f,  0.0f,  1.0f,  0.0f, 1.0f, 0.0f, // bottom-right1.0f,  1.0f, -1.0f,  0.0f,  1.0f,  0.0f, 1.0f, 1.0f, // top-right     1.0f,  1.0f,  1.0f,  0.0f,  1.0f,  0.0f, 1.0f, 0.0f, // bottom-right-1.0f,  1.0f, -1.0f,  0.0f,  1.0f,  0.0f, 0.0f, 1.0f, // top-left-1.0f,  1.0f,  1.0f,  0.0f,  1.0f,  0.0f, 0.0f, 0.0f  // bottom-left        };glGenVertexArrays(1, &cubeVAO);glGenBuffers(1, &cubeVBO);// fill bufferglBindBuffer(GL_ARRAY_BUFFER, cubeVBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);// link vertex attributesglBindVertexArray(cubeVAO);glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));glEnableVertexAttribArray(2);glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));glBindBuffer(GL_ARRAY_BUFFER, 0);glBindVertexArray(0);}// render CubeglBindVertexArray(cubeVAO);glDrawArrays(GL_TRIANGLES, 0, 36);glBindVertexArray(0);
}// renderQuad() renders a 1x1 XY quad in NDC
// -----------------------------------------
unsigned int quadVAO = 0;
unsigned int quadVBO;
void renderQuad()
{if (quadVAO == 0){float quadVertices[] = {// positions        // texture Coords-1.0f,  1.0f, 0.0f, 0.0f, 1.0f,-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,1.0f,  1.0f, 0.0f, 1.0f, 1.0f,1.0f, -1.0f, 0.0f, 1.0f, 0.0f,};// setup plane VAOglGenVertexArrays(1, &quadVAO);glGenBuffers(1, &quadVBO);glBindVertexArray(quadVAO);glBindBuffer(GL_ARRAY_BUFFER, quadVBO);glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));}glBindVertexArray(quadVAO);glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);glBindVertexArray(0);
}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow* window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, true);if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)camera.ProcessKeyboard(FORWARD, deltaTime);if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)camera.ProcessKeyboard(BACKWARD, deltaTime);if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)camera.ProcessKeyboard(LEFT, deltaTime);if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)camera.ProcessKeyboard(RIGHT, deltaTime);if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS && !bloomKeyPressed){bloom = !bloom;bloomKeyPressed = true;}if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_RELEASE){bloomKeyPressed = false;}if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS){if (exposure > 0.0f)exposure -= 0.01f;elseexposure = 0.0f;}else if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS){exposure += 0.01f;}
}// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{// make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays.glViewport(0, 0, width, height);
}// glfw: whenever the mouse moves, this callback is called
// -------------------------------------------------------
void mouse_callback(GLFWwindow* window, double xpos, double ypos)
{if (firstMouse){lastX = xpos;lastY = ypos;firstMouse = false;}float xoffset = xpos - lastX;float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to toplastX = xpos;lastY = ypos;camera.ProcessMouseMovement(xoffset, yoffset);
}// glfw: whenever the mouse scroll wheel scrolls, this callback is called
// ----------------------------------------------------------------------
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{camera.ProcessMouseScroll(yoffset);
}// utility function for loading a 2D texture from file
// ---------------------------------------------------
unsigned int loadTexture(char const* path, bool gammaCorrection)
{unsigned int textureID;glGenTextures(1, &textureID);int width, height, nrComponents;unsigned char* data = stbi_load(path, &width, &height, &nrComponents, 0);if (data){GLenum internalFormat;GLenum dataFormat;if (nrComponents == 1){internalFormat = dataFormat = GL_RED;}else if (nrComponents == 3){internalFormat = gammaCorrection ? GL_SRGB : GL_RGB;dataFormat = GL_RGB;}else if (nrComponents == 4){internalFormat = gammaCorrection ? GL_SRGB_ALPHA : GL_RGBA;dataFormat = GL_RGBA;}glBindTexture(GL_TEXTURE_2D, textureID);glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, dataFormat, GL_UNSIGNED_BYTE, data);glGenerateMipmap(GL_TEXTURE_2D);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_MIPMAP_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);stbi_image_free(data);}else{std::cout << "Texture failed to load at path: " << path << std::endl;stbi_image_free(data);}return textureID;
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部