#include<glad/glad.h>#include<glfw3.h>#include<iostream>#include"Shader.h"#include"Camera.h"#define STB_IMAGE_IMPLEMENTATION#include<stb_image.h>#include<glm/glm.hpp>#include<glm/gtc/matrix_transform.hpp>#include<glm/gtc/type_ptr.hpp>voidframebuffer_size_callback(GLFWwindow* window,int width,int height);voidmouse_callback(GLFWwindow* window,double xpos,double ypos);voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset);voidprocessInput(GLFWwindow *window);unsignedintloadTexture(constchar*path);// settingsconstunsignedint SCR_WIDTH =800;constunsignedint SCR_HEIGHT =600;// camera
Camera camera(glm::vec3(0.0f,0.0f,3.0f));float lastX =(float)SCR_WIDTH /2.0;float lastY =(float)SCR_HEIGHT /2.0;bool firstMouse =true;// timingfloat deltaTime =0.0f;float lastFrame =0.0f;intmain(){// 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;}// configure global opengl state// -----------------------------glEnable(GL_DEPTH_TEST);glDepthFunc(GL_ALWAYS);// always pass the depth test (same effect as glDisable(GL_DEPTH_TEST))// build and compile shaders// -------------------------
Shader shader("/Users/apathetically/CLionProjects/RenderTest/shader_file/1.1.depth_testing.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/1.1.depth_testing.fs");// set up vertex data (and buffer(s)) and configure vertex attributes// ------------------------------------------------------------------float cubeVertices[]={// positions // texture Coords-0.5f,-0.5f,-0.5f,0.0f,0.0f,0.5f,-0.5f,-0.5f,1.0f,0.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,-0.5f,0.5f,-0.5f,0.0f,1.0f,-0.5f,-0.5f,-0.5f,0.0f,0.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,0.5f,-0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,0.5f,1.0f,1.0f,0.5f,0.5f,0.5f,1.0f,1.0f,-0.5f,0.5f,0.5f,0.0f,1.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,-0.5f,0.5f,0.5f,1.0f,0.0f,-0.5f,0.5f,-0.5f,1.0f,1.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,-0.5f,0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,0.5f,-0.5f,-0.5f,0.0f,1.0f,0.5f,-0.5f,-0.5f,0.0f,1.0f,0.5f,-0.5f,0.5f,0.0f,0.0f,0.5f,0.5f,0.5f,1.0f,0.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,0.5f,-0.5f,-0.5f,1.0f,1.0f,0.5f,-0.5f,0.5f,1.0f,0.0f,0.5f,-0.5f,0.5f,1.0f,0.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,-0.5f,0.5f,-0.5f,0.0f,1.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,0.5f,0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,0.5f,1.0f,0.0f,-0.5f,0.5f,0.5f,0.0f,0.0f,-0.5f,0.5f,-0.5f,0.0f,1.0f};float planeVertices[]={// positions // texture Coords (note we set these higher than 1 (together with GL_REPEAT as texture wrapping mode). this will cause the floor texture to repeat)5.0f,-0.5f,5.0f,2.0f,0.0f,-5.0f,-0.5f,5.0f,0.0f,0.0f,-5.0f,-0.5f,-5.0f,0.0f,2.0f,5.0f,-0.5f,5.0f,2.0f,0.0f,-5.0f,-0.5f,-5.0f,0.0f,2.0f,5.0f,-0.5f,-5.0f,2.0f,2.0f};// cube VAOunsignedint cubeVAO, cubeVBO;glGenVertexArrays(1,&cubeVAO);glGenBuffers(1,&cubeVBO);glBindVertexArray(cubeVAO);glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);glBufferData(GL_ARRAY_BUFFER,sizeof(cubeVertices),&cubeVertices, 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(0);// plane VAOunsignedint planeVAO, planeVBO;glGenVertexArrays(1,&planeVAO);glGenBuffers(1,&planeVBO);glBindVertexArray(planeVAO);glBindBuffer(GL_ARRAY_BUFFER, planeVBO);glBufferData(GL_ARRAY_BUFFER,sizeof(planeVertices),&planeVertices, 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(0);// load textures// -------------unsignedint cubeTexture =loadTexture("/Users/apathetically/CLionProjects/RenderTest/resources/textures/marble.jpg");unsignedint floorTexture =loadTexture("/Users/apathetically/CLionProjects/RenderTest/resources/textures/metal.png");// shader configuration// --------------------
shader.use();
shader.setInt("texture1",0);// render loop// -----------while(!glfwWindowShouldClose(window)){// per-frame time logic// --------------------float currentFrame =glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;// input// -----processInput(window);// render// ------glClearColor(0.1f,0.1f,0.1f,1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shader.use();
glm::mat4 model = glm::mat4(1.0f);
glm::mat4 view = camera.GetViewMatrix();
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom),(float)SCR_WIDTH /(float)SCR_HEIGHT,0.1f,100.0f);
shader.setMat4("view", view);
shader.setMat4("projection", projection);// cubesglBindVertexArray(cubeVAO);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, cubeTexture);
model = glm::translate(model, glm::vec3(-1.0f,0.0f,-1.0f));
shader.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,36);
model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(2.0f,0.0f,0.0f));
shader.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,36);// floorglBindVertexArray(planeVAO);glBindTexture(GL_TEXTURE_2D, floorTexture);
shader.setMat4("model", glm::mat4(1.0f));glDrawArrays(GL_TRIANGLES,0,6);glBindVertexArray(0);// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)// -------------------------------------------------------------------------------glfwSwapBuffers(window);glfwPollEvents();}// optional: de-allocate all resources once they've outlived their purpose:// ------------------------------------------------------------------------glDeleteVertexArrays(1,&cubeVAO);glDeleteVertexArrays(1,&planeVAO);glDeleteBuffers(1,&cubeVBO);glDeleteBuffers(1,&planeVBO);glfwTerminate();return0;}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly// ---------------------------------------------------------------------------------------------------------voidprocessInput(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_A)== GLFW_PRESS)
camera.ProcessKeyboard(LEFT, deltaTime);if(glfwGetKey(window, GLFW_KEY_S)== GLFW_PRESS)
camera.ProcessKeyboard(BACKWARD, deltaTime);if(glfwGetKey(window, GLFW_KEY_D)== GLFW_PRESS)
camera.ProcessKeyboard(RIGHT, deltaTime);if(glfwGetKey(window, GLFW_KEY_E)== GLFW_PRESS)
camera.ProcessKeyboard(UP, deltaTime);if(glfwGetKey(window, GLFW_KEY_Q)== GLFW_PRESS)
camera.ProcessKeyboard(DOWN, deltaTime);}// glfw: whenever the window size changed (by OS or user resize) this callback function executes// ---------------------------------------------------------------------------------------------voidframebuffer_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// -------------------------------------------------------voidmouse_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 top
lastX = xpos;
lastY = ypos;
camera.ProcessMouseMovement(xoffset, yoffset);}// glfw: whenever the mouse scroll wheel scrolls, this callback is called// ----------------------------------------------------------------------voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset){
camera.ProcessMouseScroll(yoffset);}// utility function for loading a 2D texture from file// ---------------------------------------------------unsignedintloadTexture(charconst*path){unsignedint textureID;glGenTextures(1,&textureID);int width, height, nrComponents;unsignedchar*data =stbi_load(path,&width,&height,&nrComponents,0);if(data){
GLenum format;if(nrComponents ==1)
format = GL_RED;elseif(nrComponents ==3)
format = GL_RGB;elseif(nrComponents ==4)
format = GL_RGBA;glBindTexture(GL_TEXTURE_2D, textureID);glTexImage2D(GL_TEXTURE_2D,0, format, width, height,0, format, 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;}
模板测试
#include<glad/glad.h>#include<glfw3.h>#include<iostream>#include"Shader.h"#include"Camera.h"#define STB_IMAGE_IMPLEMENTATION#include<stb_image.h>#include<glm/glm.hpp>#include<glm/gtc/matrix_transform.hpp>#include<glm/gtc/type_ptr.hpp>voidframebuffer_size_callback(GLFWwindow* window,int width,int height);voidmouse_callback(GLFWwindow* window,double xpos,double ypos);voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset);voidprocessInput(GLFWwindow *window);unsignedintloadTexture(constchar*path);// settingsconstunsignedint SCR_WIDTH =800;constunsignedint SCR_HEIGHT =600;// camera
Camera camera(glm::vec3(0.0f,0.0f,3.0f));float lastX =(float)SCR_WIDTH /2.0;float lastY =(float)SCR_HEIGHT /2.0;bool firstMouse =true;// timingfloat deltaTime =0.0f;float lastFrame =0.0f;intmain(){// 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;}// configure global opengl state// -----------------------------glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LESS);// always pass the depth test (same effect as glDisable(GL_DEPTH_TEST))glEnable(GL_STENCIL_TEST);glStencilFunc(GL_NOTEQUAL,1,0xFF);glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);// build and compile shaders// -------------------------
Shader shader("/Users/apathetically/CLionProjects/RenderTest/shader_file/2.stencil_testing.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/2.stencil_testing.fs");
Shader shaderSingleColor("/Users/apathetically/CLionProjects/RenderTest/shader_file/2.stencil_testing.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/2.stencil_single_color.fs");// set up vertex data (and buffer(s)) and configure vertex attributes// ------------------------------------------------------------------float cubeVertices[]={// positions // texture Coords-0.5f,-0.5f,-0.5f,0.0f,0.0f,0.5f,-0.5f,-0.5f,1.0f,0.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,-0.5f,0.5f,-0.5f,0.0f,1.0f,-0.5f,-0.5f,-0.5f,0.0f,0.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,0.5f,-0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,0.5f,1.0f,1.0f,0.5f,0.5f,0.5f,1.0f,1.0f,-0.5f,0.5f,0.5f,0.0f,1.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,-0.5f,0.5f,0.5f,1.0f,0.0f,-0.5f,0.5f,-0.5f,1.0f,1.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,-0.5f,0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,0.5f,-0.5f,-0.5f,0.0f,1.0f,0.5f,-0.5f,-0.5f,0.0f,1.0f,0.5f,-0.5f,0.5f,0.0f,0.0f,0.5f,0.5f,0.5f,1.0f,0.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,0.5f,-0.5f,-0.5f,1.0f,1.0f,0.5f,-0.5f,0.5f,1.0f,0.0f,0.5f,-0.5f,0.5f,1.0f,0.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,-0.5f,0.5f,-0.5f,0.0f,1.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,0.5f,0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,0.5f,1.0f,0.0f,-0.5f,0.5f,0.5f,0.0f,0.0f,-0.5f,0.5f,-0.5f,0.0f,1.0f};float planeVertices[]={// positions // texture Coords (note we set these higher than 1 (together with GL_REPEAT as texture wrapping mode). this will cause the floor texture to repeat)5.0f,-0.5f,5.0f,2.0f,0.0f,-5.0f,-0.5f,5.0f,0.0f,0.0f,-5.0f,-0.5f,-5.0f,0.0f,2.0f,5.0f,-0.5f,5.0f,2.0f,0.0f,-5.0f,-0.5f,-5.0f,0.0f,2.0f,5.0f,-0.5f,-5.0f,2.0f,2.0f};// cube VAOunsignedint cubeVAO, cubeVBO;glGenVertexArrays(1,&cubeVAO);glGenBuffers(1,&cubeVBO);glBindVertexArray(cubeVAO);glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);glBufferData(GL_ARRAY_BUFFER,sizeof(cubeVertices),&cubeVertices, 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(0);// plane VAOunsignedint planeVAO, planeVBO;glGenVertexArrays(1,&planeVAO);glGenBuffers(1,&planeVBO);glBindVertexArray(planeVAO);glBindBuffer(GL_ARRAY_BUFFER, planeVBO);glBufferData(GL_ARRAY_BUFFER,sizeof(planeVertices),&planeVertices, 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(0);// load textures// -------------unsignedint cubeTexture =loadTexture("/Users/apathetically/CLionProjects/RenderTest/resources/textures/marble.jpg");unsignedint floorTexture =loadTexture("/Users/apathetically/CLionProjects/RenderTest/resources/textures/metal.png");// shader configuration// --------------------
shader.use();
shader.setInt("texture1",0);// render loop// -----------while(!glfwWindowShouldClose(window)){// per-frame time logic// --------------------float currentFrame =glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;// input// -----processInput(window);// render// ------glClearColor(0.1f,0.1f,0.1f,1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);// set uniforms
shaderSingleColor.use();
glm::mat4 model = glm::mat4(1.0f);
glm::mat4 view = camera.GetViewMatrix();
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom),(float)SCR_WIDTH /(float)SCR_HEIGHT,0.1f,100.0f);
shaderSingleColor.setMat4("view", view);
shaderSingleColor.setMat4("projection", projection);
shader.use();
shader.setMat4("view", view);
shader.setMat4("projection", projection);// draw floor as normal, but don't write the floor to the stencil buffer, we only care about the containers.// We set its mask to 0x00 to not write to the stencil buffer.glStencilMask(0x00);// floorglBindVertexArray(planeVAO);glBindTexture(GL_TEXTURE_2D, floorTexture);
shader.setMat4("model", glm::mat4(1.0f));glDrawArrays(GL_TRIANGLES,0,6);glBindVertexArray(0);// 1st. render pass, draw objects as normal, writing to the stencil bufferglStencilFunc(GL_ALWAYS,1,0xFF);glStencilMask(0xFF);// cubesglBindVertexArray(cubeVAO);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, cubeTexture);
model = glm::translate(model, glm::vec3(-1.0,0.0f,-1.0f));
shader.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,36);
model = glm::mat4(1.0);
model = glm::translate(model, glm::vec3(2.0f,0.0f,0.0f));
shader.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,36);// 2nd. render pass: now draw slightly scaled versions of the objects, this time disabling stencil writing.// Because the stencil buffer is now filled with several 1s. The parts of the buffer that are 1 are not drawn,// thus only drawing the objects' size differences, making it look like borders.glStencilFunc(GL_NOTEQUAL,1,0xFF);glStencilMask(0x00);glDisable(GL_DEPTH_TEST);
shaderSingleColor.use();float scale =1.1;// cubesglBindVertexArray(cubeVAO);glBindTexture(GL_TEXTURE_2D, cubeTexture);
model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(-1.0f,0.0f,-1.0f));
model = glm::scale(model, glm::vec3(scale, scale, scale));
shaderSingleColor.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,36);
model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(2.0f,0.0f,0.0f));
model = glm::scale(model, glm::vec3(scale, scale, scale));
shaderSingleColor.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,36);glBindVertexArray(0);glStencilMask(0xFF);glStencilFunc(GL_ALWAYS,0,0xFF);glEnable(GL_DEPTH_TEST);// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)glfwSwapBuffers(window);glfwPollEvents();}// optional: de-allocate all resources once they've outlived their purpose:// ------------------------------------------------------------------------glDeleteVertexArrays(1,&cubeVAO);glDeleteVertexArrays(1,&planeVAO);glDeleteBuffers(1,&cubeVBO);glDeleteBuffers(1,&planeVBO);glfwTerminate();return0;}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly// ---------------------------------------------------------------------------------------------------------voidprocessInput(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_A)== GLFW_PRESS)
camera.ProcessKeyboard(LEFT, deltaTime);if(glfwGetKey(window, GLFW_KEY_S)== GLFW_PRESS)
camera.ProcessKeyboard(BACKWARD, deltaTime);if(glfwGetKey(window, GLFW_KEY_D)== GLFW_PRESS)
camera.ProcessKeyboard(RIGHT, deltaTime);if(glfwGetKey(window, GLFW_KEY_E)== GLFW_PRESS)
camera.ProcessKeyboard(UP, deltaTime);if(glfwGetKey(window, GLFW_KEY_Q)== GLFW_PRESS)
camera.ProcessKeyboard(DOWN, deltaTime);}// glfw: whenever the window size changed (by OS or user resize) this callback function executes// ---------------------------------------------------------------------------------------------voidframebuffer_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// -------------------------------------------------------voidmouse_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 top
lastX = xpos;
lastY = ypos;
camera.ProcessMouseMovement(xoffset, yoffset);}// glfw: whenever the mouse scroll wheel scrolls, this callback is called// ----------------------------------------------------------------------voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset){
camera.ProcessMouseScroll(yoffset);}// utility function for loading a 2D texture from file// ---------------------------------------------------unsignedintloadTexture(charconst*path){unsignedint textureID;glGenTextures(1,&textureID);int width, height, nrComponents;unsignedchar*data =stbi_load(path,&width,&height,&nrComponents,0);if(data){
GLenum format;if(nrComponents ==1)
format = GL_RED;elseif(nrComponents ==3)
format = GL_RGB;elseif(nrComponents ==4)
format = GL_RGBA;glBindTexture(GL_TEXTURE_2D, textureID);glTexImage2D(GL_TEXTURE_2D,0, format, width, height,0, format, 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;}
混合草
#include<glad/glad.h>#include<glfw3.h>#include<iostream>#include"Shader.h"#include"Camera.h"#define STB_IMAGE_IMPLEMENTATION#include<stb_image.h>#include<glm/glm.hpp>#include<glm/gtc/matrix_transform.hpp>#include<glm/gtc/type_ptr.hpp>voidframebuffer_size_callback(GLFWwindow* window,int width,int height);voidmouse_callback(GLFWwindow* window,double xpos,double ypos);voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset);voidprocessInput(GLFWwindow *window);unsignedintloadTexture(constchar*path);// settingsconstunsignedint SCR_WIDTH =800;constunsignedint SCR_HEIGHT =600;// camera
Camera camera(glm::vec3(0.0f,0.0f,3.0f));float lastX =(float)SCR_WIDTH /2.0;float lastY =(float)SCR_HEIGHT /2.0;bool firstMouse =true;// timingfloat deltaTime =0.0f;float lastFrame =0.0f;intmain(){// 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;}// configure global opengl state// -----------------------------glEnable(GL_DEPTH_TEST);// build and compile shaders// -------------------------
Shader shader("/Users/apathetically/CLionProjects/RenderTest/shader_file/3.1.blending.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/3.1.blending.fs");// set up vertex data (and buffer(s)) and configure vertex attributes// ------------------------------------------------------------------float cubeVertices[]={// positions // texture Coords-0.5f,-0.5f,-0.5f,0.0f,0.0f,0.5f,-0.5f,-0.5f,1.0f,0.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,-0.5f,0.5f,-0.5f,0.0f,1.0f,-0.5f,-0.5f,-0.5f,0.0f,0.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,0.5f,-0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,0.5f,1.0f,1.0f,0.5f,0.5f,0.5f,1.0f,1.0f,-0.5f,0.5f,0.5f,0.0f,1.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,-0.5f,0.5f,0.5f,1.0f,0.0f,-0.5f,0.5f,-0.5f,1.0f,1.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,-0.5f,0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,0.5f,-0.5f,-0.5f,0.0f,1.0f,0.5f,-0.5f,-0.5f,0.0f,1.0f,0.5f,-0.5f,0.5f,0.0f,0.0f,0.5f,0.5f,0.5f,1.0f,0.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,0.5f,-0.5f,-0.5f,1.0f,1.0f,0.5f,-0.5f,0.5f,1.0f,0.0f,0.5f,-0.5f,0.5f,1.0f,0.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,-0.5f,0.5f,-0.5f,0.0f,1.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,0.5f,0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,0.5f,1.0f,0.0f,-0.5f,0.5f,0.5f,0.0f,0.0f,-0.5f,0.5f,-0.5f,0.0f,1.0f};float planeVertices[]={// positions // texture Coords (note we set these higher than 1 (together with GL_REPEAT as texture wrapping mode). this will cause the floor texture to repeat)5.0f,-0.5f,5.0f,2.0f,0.0f,-5.0f,-0.5f,5.0f,0.0f,0.0f,-5.0f,-0.5f,-5.0f,0.0f,2.0f,5.0f,-0.5f,5.0f,2.0f,0.0f,-5.0f,-0.5f,-5.0f,0.0f,2.0f,5.0f,-0.5f,-5.0f,2.0f,2.0f};float transparentVertices[]={// positions // texture Coords (swapped y coordinates because texture is flipped upside down)0.0f,0.5f,0.0f,0.0f,0.0f,0.0f,-0.5f,0.0f,0.0f,1.0f,1.0f,-0.5f,0.0f,1.0f,1.0f,0.0f,0.5f,0.0f,0.0f,0.0f,1.0f,-0.5f,0.0f,1.0f,1.0f,1.0f,0.5f,0.0f,1.0f,0.0f};// cube VAOunsignedint cubeVAO, cubeVBO;glGenVertexArrays(1,&cubeVAO);glGenBuffers(1,&cubeVBO);glBindVertexArray(cubeVAO);glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);glBufferData(GL_ARRAY_BUFFER,sizeof(cubeVertices),&cubeVertices, 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)));// plane VAOunsignedint planeVAO, planeVBO;glGenVertexArrays(1,&planeVAO);glGenBuffers(1,&planeVBO);glBindVertexArray(planeVAO);glBindBuffer(GL_ARRAY_BUFFER, planeVBO);glBufferData(GL_ARRAY_BUFFER,sizeof(planeVertices),&planeVertices, 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(0);// transparent VAOunsignedint transparentVAO, transparentVBO;glGenVertexArrays(1,&transparentVAO);glGenBuffers(1,&transparentVBO);glBindVertexArray(transparentVAO);glBindBuffer(GL_ARRAY_BUFFER, transparentVBO);glBufferData(GL_ARRAY_BUFFER,sizeof(transparentVertices),&transparentVertices, 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(0);// load textures// -------------unsignedint cubeTexture =loadTexture("/Users/apathetically/CLionProjects/RenderTest/resources/textures/marble.jpg");unsignedint floorTexture =loadTexture("/Users/apathetically/CLionProjects/RenderTest/resources/textures/metal.png");unsignedint transparentTexture =loadTexture("/Users/apathetically/CLionProjects/RenderTest/resources/textures/grass.png");// transparent vegetation locations// --------------------
std::vector<glm::vec3> vegetation {
glm::vec3(-1.5f,0.0f,-0.48f),
glm::vec3(1.5f,0.0f,0.51f),
glm::vec3(0.0f,0.0f,0.7f),
glm::vec3(-0.3f,0.0f,-2.3f),
glm::vec3(0.5f,0.0f,-0.6f)};// shader configuration// --------------------
shader.use();
shader.setInt("texture1",0);// render loop// -----------while(!glfwWindowShouldClose(window)){// per-frame time logic// --------------------float currentFrame =glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;// input// -----processInput(window);// render// ------glClearColor(0.1f,0.1f,0.1f,1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// draw objects
shader.use();
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom),(float)SCR_WIDTH /(float)SCR_HEIGHT,0.1f,100.0f);
glm::mat4 view = camera.GetViewMatrix();
glm::mat4 model = glm::mat4(1.0f);
shader.setMat4("projection", projection);
shader.setMat4("view", view);// cubesglBindVertexArray(cubeVAO);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, cubeTexture);
model = glm::translate(model, glm::vec3(-1.0f,0.0f,-1.0f));
shader.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,36);
model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(2.0f,0.0f,0.0f));
shader.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,36);// floorglBindVertexArray(planeVAO);glBindTexture(GL_TEXTURE_2D, floorTexture);
model = glm::mat4(1.0f);
shader.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,6);// vegetationglBindVertexArray(transparentVAO);glBindTexture(GL_TEXTURE_2D, transparentTexture);for(unsignedint i =0;i < vegetation.size();i ++){
model = glm::mat4(1.0f);
model = glm::translate(model, vegetation[i]);
shader.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,6);}// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)glfwSwapBuffers(window);glfwPollEvents();}// optional: de-allocate all resources once they've outlived their purpose:// ------------------------------------------------------------------------glDeleteVertexArrays(1,&cubeVAO);glDeleteVertexArrays(1,&planeVAO);glDeleteBuffers(1,&cubeVBO);glDeleteBuffers(1,&planeVBO);glfwTerminate();return0;}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly// ---------------------------------------------------------------------------------------------------------voidprocessInput(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_A)== GLFW_PRESS)
camera.ProcessKeyboard(LEFT, deltaTime);if(glfwGetKey(window, GLFW_KEY_S)== GLFW_PRESS)
camera.ProcessKeyboard(BACKWARD, deltaTime);if(glfwGetKey(window, GLFW_KEY_D)== GLFW_PRESS)
camera.ProcessKeyboard(RIGHT, deltaTime);if(glfwGetKey(window, GLFW_KEY_E)== GLFW_PRESS)
camera.ProcessKeyboard(UP, deltaTime);if(glfwGetKey(window, GLFW_KEY_Q)== GLFW_PRESS)
camera.ProcessKeyboard(DOWN, deltaTime);}// glfw: whenever the window size changed (by OS or user resize) this callback function executes// ---------------------------------------------------------------------------------------------voidframebuffer_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// -------------------------------------------------------voidmouse_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 top
lastX = xpos;
lastY = ypos;
camera.ProcessMouseMovement(xoffset, yoffset);}// glfw: whenever the mouse scroll wheel scrolls, this callback is called// ----------------------------------------------------------------------voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset){
camera.ProcessMouseScroll(yoffset);}// utility function for loading a 2D texture from file// ---------------------------------------------------unsignedintloadTexture(charconst*path){unsignedint textureID;glGenTextures(1,&textureID);int width, height, nrComponents;unsignedchar*data =stbi_load(path,&width,&height,&nrComponents,0);if(data){
GLenum format;if(nrComponents ==1)
format = GL_RED;elseif(nrComponents ==3)
format = GL_RGB;elseif(nrComponents ==4)
format = GL_RGBA;glBindTexture(GL_TEXTURE_2D, textureID);glTexImage2D(GL_TEXTURE_2D,0, format, width, height,0, format, GL_UNSIGNED_BYTE, data);glGenerateMipmap(GL_TEXTURE_2D);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);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;}
窗户混合
#include<glad/glad.h>#include<glfw3.h>#include<iostream>#include"Shader.h"#include"Camera.h"#define STB_IMAGE_IMPLEMENTATION#include<stb_image.h>#include<glm/glm.hpp>#include<glm/gtc/matrix_transform.hpp>#include<glm/gtc/type_ptr.hpp>#include<map>voidframebuffer_size_callback(GLFWwindow* window,int width,int height);voidmouse_callback(GLFWwindow* window,double xpos,double ypos);voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset);voidprocessInput(GLFWwindow *window);unsignedintloadTexture(constchar*path);// settingsconstunsignedint SCR_WIDTH =800;constunsignedint SCR_HEIGHT =600;// camera
Camera camera(glm::vec3(0.0f,0.0f,3.0f));float lastX =(float)SCR_WIDTH /2.0;float lastY =(float)SCR_HEIGHT /2.0;bool firstMouse =true;// timingfloat deltaTime =0.0f;float lastFrame =0.0f;intmain(){// 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;}// configure global opengl state// -----------------------------glEnable(GL_DEPTH_TEST);glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);// build and compile shaders// -------------------------
Shader shader("/Users/apathetically/CLionProjects/RenderTest/shader_file/3.2.blending.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/3.2.blending.fs");// set up vertex data (and buffer(s)) and configure vertex attributes// ------------------------------------------------------------------float cubeVertices[]={// positions // texture Coords-0.5f,-0.5f,-0.5f,0.0f,0.0f,0.5f,-0.5f,-0.5f,1.0f,0.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,-0.5f,0.5f,-0.5f,0.0f,1.0f,-0.5f,-0.5f,-0.5f,0.0f,0.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,0.5f,-0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,0.5f,1.0f,1.0f,0.5f,0.5f,0.5f,1.0f,1.0f,-0.5f,0.5f,0.5f,0.0f,1.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,-0.5f,0.5f,0.5f,1.0f,0.0f,-0.5f,0.5f,-0.5f,1.0f,1.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,-0.5f,0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,0.5f,-0.5f,-0.5f,0.0f,1.0f,0.5f,-0.5f,-0.5f,0.0f,1.0f,0.5f,-0.5f,0.5f,0.0f,0.0f,0.5f,0.5f,0.5f,1.0f,0.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,0.5f,-0.5f,-0.5f,1.0f,1.0f,0.5f,-0.5f,0.5f,1.0f,0.0f,0.5f,-0.5f,0.5f,1.0f,0.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,-0.5f,0.5f,-0.5f,0.0f,1.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,0.5f,0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,0.5f,1.0f,0.0f,-0.5f,0.5f,0.5f,0.0f,0.0f,-0.5f,0.5f,-0.5f,0.0f,1.0f};float planeVertices[]={// positions // texture Coords (note we set these higher than 1 (together with GL_REPEAT as texture wrapping mode). this will cause the floor texture to repeat)5.0f,-0.5f,5.0f,2.0f,0.0f,-5.0f,-0.5f,5.0f,0.0f,0.0f,-5.0f,-0.5f,-5.0f,0.0f,2.0f,5.0f,-0.5f,5.0f,2.0f,0.0f,-5.0f,-0.5f,-5.0f,0.0f,2.0f,5.0f,-0.5f,-5.0f,2.0f,2.0f};float transparentVertices[]={// positions // texture Coords (swapped y coordinates because texture is flipped upside down)0.0f,0.5f,0.0f,0.0f,0.0f,0.0f,-0.5f,0.0f,0.0f,1.0f,1.0f,-0.5f,0.0f,1.0f,1.0f,0.0f,0.5f,0.0f,0.0f,0.0f,1.0f,-0.5f,0.0f,1.0f,1.0f,1.0f,0.5f,0.0f,1.0f,0.0f};// cube VAOunsignedint cubeVAO, cubeVBO;glGenVertexArrays(1,&cubeVAO);glGenBuffers(1,&cubeVBO);glBindVertexArray(cubeVAO);glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);glBufferData(GL_ARRAY_BUFFER,sizeof(cubeVertices),&cubeVertices, 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)));// plane VAOunsignedint planeVAO, planeVBO;glGenVertexArrays(1,&planeVAO);glGenBuffers(1,&planeVBO);glBindVertexArray(planeVAO);glBindBuffer(GL_ARRAY_BUFFER, planeVBO);glBufferData(GL_ARRAY_BUFFER,sizeof(planeVertices),&planeVertices, 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(0);// transparent VAOunsignedint transparentVAO, transparentVBO;glGenVertexArrays(1,&transparentVAO);glGenBuffers(1,&transparentVBO);glBindVertexArray(transparentVAO);glBindBuffer(GL_ARRAY_BUFFER, transparentVBO);glBufferData(GL_ARRAY_BUFFER,sizeof(transparentVertices),&transparentVertices, 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(0);// load textures// -------------unsignedint cubeTexture =loadTexture("/Users/apathetically/CLionProjects/RenderTest/resources/textures/marble.jpg");unsignedint floorTexture =loadTexture("/Users/apathetically/CLionProjects/RenderTest/resources/textures/metal.png");unsignedint transparentTexture =loadTexture("/Users/apathetically/CLionProjects/RenderTest/resources/textures/blending_transparent_window.png");// transparent vegetation locations// --------------------
std::vector<glm::vec3> windows {
glm::vec3(-1.5f,0.0f,-0.48f),
glm::vec3(1.5f,0.0f,0.51f),
glm::vec3(0.0f,0.0f,0.7f),
glm::vec3(-0.3f,0.0f,-2.3f),
glm::vec3(0.5f,0.0f,-0.6f)};// shader configuration// --------------------
shader.use();
shader.setInt("texture1",0);// render loop// -----------while(!glfwWindowShouldClose(window)){// per-frame time logic// --------------------float currentFrame =glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;// input// -----processInput(window);// sort the transparent windows before rendering// ---------------------------------------------
std::map<float, glm::vec3> sorted;for(unsignedint i =0;i < windows.size();i ++){float distance = glm::length(camera.Position - windows[i]);
sorted[distance]= windows[i];}// render// ------glClearColor(0.1f,0.1f,0.1f,1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// draw objects
shader.use();
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom),(float)SCR_WIDTH /(float)SCR_HEIGHT,0.1f,100.0f);
glm::mat4 view = camera.GetViewMatrix();
glm::mat4 model = glm::mat4(1.0f);
shader.setMat4("projection", projection);
shader.setMat4("view", view);// cubesglBindVertexArray(cubeVAO);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, cubeTexture);
model = glm::translate(model, glm::vec3(-1.0f,0.0f,-1.0f));
shader.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,36);
model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(2.0f,0.0f,0.0f));
shader.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,36);// floorglBindVertexArray(planeVAO);glBindTexture(GL_TEXTURE_2D, floorTexture);
model = glm::mat4(1.0f);
shader.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,6);// windows (from furthest to nearest)glBindVertexArray(transparentVAO);glBindTexture(GL_TEXTURE_2D, transparentTexture);for(std::map<float, glm::vec3>::reverse_iterator it = sorted.rbegin();it != sorted.rend();++it){
model = glm::mat4(1.0f);
model = glm::translate(model, it->second);
shader.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,6);}// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)glfwSwapBuffers(window);glfwPollEvents();}// optional: de-allocate all resources once they've outlived their purpose:// ------------------------------------------------------------------------glDeleteVertexArrays(1,&cubeVAO);glDeleteVertexArrays(1,&planeVAO);glDeleteBuffers(1,&cubeVBO);glDeleteBuffers(1,&planeVBO);glfwTerminate();return0;}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly// ---------------------------------------------------------------------------------------------------------voidprocessInput(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_A)== GLFW_PRESS)
camera.ProcessKeyboard(LEFT, deltaTime);if(glfwGetKey(window, GLFW_KEY_S)== GLFW_PRESS)
camera.ProcessKeyboard(BACKWARD, deltaTime);if(glfwGetKey(window, GLFW_KEY_D)== GLFW_PRESS)
camera.ProcessKeyboard(RIGHT, deltaTime);if(glfwGetKey(window, GLFW_KEY_E)== GLFW_PRESS)
camera.ProcessKeyboard(UP, deltaTime);if(glfwGetKey(window, GLFW_KEY_Q)== GLFW_PRESS)
camera.ProcessKeyboard(DOWN, deltaTime);}// glfw: whenever the window size changed (by OS or user resize) this callback function executes// ---------------------------------------------------------------------------------------------voidframebuffer_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// -------------------------------------------------------voidmouse_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 top
lastX = xpos;
lastY = ypos;
camera.ProcessMouseMovement(xoffset, yoffset);}// glfw: whenever the mouse scroll wheel scrolls, this callback is called// ----------------------------------------------------------------------voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset){
camera.ProcessMouseScroll(yoffset);}// utility function for loading a 2D texture from file// ---------------------------------------------------unsignedintloadTexture(charconst*path){unsignedint textureID;glGenTextures(1,&textureID);int width, height, nrComponents;unsignedchar*data =stbi_load(path,&width,&height,&nrComponents,0);if(data){
GLenum format;if(nrComponents ==1)
format = GL_RED;elseif(nrComponents ==3)
format = GL_RGB;elseif(nrComponents ==4)
format = GL_RGBA;glBindTexture(GL_TEXTURE_2D, textureID);glTexImage2D(GL_TEXTURE_2D,0, format, width, height,0, format, 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;}
面剔除
#include<glad/glad.h>#include<glfw3.h>#include<iostream>#include"Shader.h"#include"Camera.h"#define STB_IMAGE_IMPLEMENTATION#include<stb_image.h>#include<glm/glm.hpp>#include<glm/gtc/matrix_transform.hpp>#include<glm/gtc/type_ptr.hpp>#include<map>voidframebuffer_size_callback(GLFWwindow* window,int width,int height);voidmouse_callback(GLFWwindow* window,double xpos,double ypos);voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset);voidprocessInput(GLFWwindow *window);unsignedintloadTexture(constchar*path);// settingsconstunsignedint SCR_WIDTH =800;constunsignedint SCR_HEIGHT =600;// camera
Camera camera(glm::vec3(0.0f,0.0f,3.0f));float lastX =(float)SCR_WIDTH /2.0;float lastY =(float)SCR_HEIGHT /2.0;bool firstMouse =true;// timingfloat deltaTime =0.0f;float lastFrame =0.0f;intmain(){// 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;}// configure global opengl state// -----------------------------glEnable(GL_DEPTH_TEST);glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glEnable(GL_CULL_FACE);glCullFace(GL_BACK);glFrontFace(GL_CCW);// build and compile shaders// -------------------------
Shader shader("/Users/apathetically/CLionProjects/RenderTest/shader_file/3.2.blending.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/3.2.blending.fs");// set up vertex data (and buffer(s)) and configure vertex attributes// ------------------------------------------------------------------/*
Remember: to specify vertices in a counter-clockwise winding order you need to visualize the triangle
as if you're in front of the triangle and from that point of view, is where you set their order.
To define the order of a triangle on the right side of the cube for example, you'd imagine yourself looking
straight at the right side of the cube, and then visualize the triangle and make sure their order is specified
in a counter-clockwise order. This takes some practice, but try visualizing this yourself and see that this
is correct.
*/float cubeVertices[]={// Back face-0.5f,-0.5f,-0.5f,0.0f,0.0f,// Bottom-left0.5f,0.5f,-0.5f,1.0f,1.0f,// top-right0.5f,-0.5f,-0.5f,1.0f,0.0f,// bottom-right0.5f,0.5f,-0.5f,1.0f,1.0f,// top-right-0.5f,-0.5f,-0.5f,0.0f,0.0f,// bottom-left-0.5f,0.5f,-0.5f,0.0f,1.0f,// top-left// Front face-0.5f,-0.5f,0.5f,0.0f,0.0f,// bottom-left0.5f,-0.5f,0.5f,1.0f,0.0f,// bottom-right0.5f,0.5f,0.5f,1.0f,1.0f,// top-right0.5f,0.5f,0.5f,1.0f,1.0f,// top-right-0.5f,0.5f,0.5f,0.0f,1.0f,// top-left-0.5f,-0.5f,0.5f,0.0f,0.0f,// bottom-left// Left face-0.5f,0.5f,0.5f,1.0f,0.0f,// top-right-0.5f,0.5f,-0.5f,1.0f,1.0f,// top-left-0.5f,-0.5f,-0.5f,0.0f,1.0f,// bottom-left-0.5f,-0.5f,-0.5f,0.0f,1.0f,// bottom-left-0.5f,-0.5f,0.5f,0.0f,0.0f,// bottom-right-0.5f,0.5f,0.5f,1.0f,0.0f,// top-right// Right face0.5f,0.5f,0.5f,1.0f,0.0f,// top-left0.5f,-0.5f,-0.5f,0.0f,1.0f,// bottom-right0.5f,0.5f,-0.5f,1.0f,1.0f,// top-right0.5f,-0.5f,-0.5f,0.0f,1.0f,// bottom-right0.5f,0.5f,0.5f,1.0f,0.0f,// top-left0.5f,-0.5f,0.5f,0.0f,0.0f,// bottom-left// Bottom face-0.5f,-0.5f,-0.5f,0.0f,1.0f,// top-right0.5f,-0.5f,-0.5f,1.0f,1.0f,// top-left0.5f,-0.5f,0.5f,1.0f,0.0f,// bottom-left0.5f,-0.5f,0.5f,1.0f,0.0f,// bottom-left-0.5f,-0.5f,0.5f,0.0f,0.0f,// bottom-right-0.5f,-0.5f,-0.5f,0.0f,1.0f,// top-right// Top face-0.5f,0.5f,-0.5f,0.0f,1.0f,// top-left0.5f,0.5f,0.5f,1.0f,0.0f,// bottom-right0.5f,0.5f,-0.5f,1.0f,1.0f,// top-right0.5f,0.5f,0.5f,1.0f,0.0f,// bottom-right-0.5f,0.5f,-0.5f,0.0f,1.0f,// top-left-0.5f,0.5f,0.5f,0.0f,0.0f// bottom-left};float planeVertices[]={// positions // texture Coords (note we set these higher than 1 (together with GL_REPEAT as texture wrapping mode). this will cause the floor texture to repeat)5.0f,-0.5f,5.0f,2.0f,0.0f,-5.0f,-0.5f,5.0f,0.0f,0.0f,-5.0f,-0.5f,-5.0f,0.0f,2.0f,5.0f,-0.5f,5.0f,2.0f,0.0f,-5.0f,-0.5f,-5.0f,0.0f,2.0f,5.0f,-0.5f,-5.0f,2.0f,2.0f};float transparentVertices[]={// positions // texture Coords (swapped y coordinates because texture is flipped upside down)0.0f,0.5f,0.0f,0.0f,0.0f,0.0f,-0.5f,0.0f,0.0f,1.0f,1.0f,-0.5f,0.0f,1.0f,1.0f,0.0f,0.5f,0.0f,0.0f,0.0f,1.0f,-0.5f,0.0f,1.0f,1.0f,1.0f,0.5f,0.0f,1.0f,0.0f};// cube VAOunsignedint cubeVAO, cubeVBO;glGenVertexArrays(1,&cubeVAO);glGenBuffers(1,&cubeVBO);glBindVertexArray(cubeVAO);glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);glBufferData(GL_ARRAY_BUFFER,sizeof(cubeVertices),&cubeVertices, 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)));// plane VAOunsignedint planeVAO, planeVBO;glGenVertexArrays(1,&planeVAO);glGenBuffers(1,&planeVBO);glBindVertexArray(planeVAO);glBindBuffer(GL_ARRAY_BUFFER, planeVBO);glBufferData(GL_ARRAY_BUFFER,sizeof(planeVertices),&planeVertices, 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(0);// transparent VAOunsignedint transparentVAO, transparentVBO;glGenVertexArrays(1,&transparentVAO);glGenBuffers(1,&transparentVBO);glBindVertexArray(transparentVAO);glBindBuffer(GL_ARRAY_BUFFER, transparentVBO);glBufferData(GL_ARRAY_BUFFER,sizeof(transparentVertices),&transparentVertices, 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(0);// load textures// -------------unsignedint cubeTexture =loadTexture("/Users/apathetically/CLionProjects/RenderTest/resources/textures/marble.jpg");unsignedint floorTexture =loadTexture("/Users/apathetically/CLionProjects/RenderTest/resources/textures/metal.png");unsignedint transparentTexture =loadTexture("/Users/apathetically/CLionProjects/RenderTest/resources/textures/blending_transparent_window.png");// transparent vegetation locations// --------------------
std::vector<glm::vec3> windows {
glm::vec3(-1.5f,0.0f,-0.48f),
glm::vec3(1.5f,0.0f,0.51f),
glm::vec3(0.0f,0.0f,0.7f),
glm::vec3(-0.3f,0.0f,-2.3f),
glm::vec3(0.5f,0.0f,-0.6f)};// shader configuration// --------------------
shader.use();
shader.setInt("texture1",0);// render loop// -----------while(!glfwWindowShouldClose(window)){// per-frame time logic// --------------------float currentFrame =glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;// input// -----processInput(window);// sort the transparent windows before rendering// ---------------------------------------------
std::map<float, glm::vec3> sorted;for(unsignedint i =0;i < windows.size();i ++){float distance = glm::length(camera.Position - windows[i]);
sorted[distance]= windows[i];}// render// ------glClearColor(0.1f,0.1f,0.1f,1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// draw objects
shader.use();
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom),(float)SCR_WIDTH /(float)SCR_HEIGHT,0.1f,100.0f);
glm::mat4 view = camera.GetViewMatrix();
glm::mat4 model = glm::mat4(1.0f);
shader.setMat4("projection", projection);
shader.setMat4("view", view);// cubesglBindVertexArray(cubeVAO);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, cubeTexture);
model = glm::translate(model, glm::vec3(-1.0f,0.0f,-1.0f));
shader.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,36);
model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(2.0f,0.0f,0.0f));
shader.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,36);// floorglBindVertexArray(planeVAO);glBindTexture(GL_TEXTURE_2D, floorTexture);
model = glm::mat4(1.0f);
shader.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,6);// windows (from furthest to nearest)glBindVertexArray(transparentVAO);glBindTexture(GL_TEXTURE_2D, transparentTexture);for(std::map<float, glm::vec3>::reverse_iterator it = sorted.rbegin();it != sorted.rend();++it){
model = glm::mat4(1.0f);
model = glm::translate(model, it->second);
shader.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,6);}// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)glfwSwapBuffers(window);glfwPollEvents();}// optional: de-allocate all resources once they've outlived their purpose:// ------------------------------------------------------------------------glDeleteVertexArrays(1,&cubeVAO);glDeleteVertexArrays(1,&planeVAO);glDeleteBuffers(1,&cubeVBO);glDeleteBuffers(1,&planeVBO);glfwTerminate();return0;}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly// ---------------------------------------------------------------------------------------------------------voidprocessInput(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_A)== GLFW_PRESS)
camera.ProcessKeyboard(LEFT, deltaTime);if(glfwGetKey(window, GLFW_KEY_S)== GLFW_PRESS)
camera.ProcessKeyboard(BACKWARD, deltaTime);if(glfwGetKey(window, GLFW_KEY_D)== GLFW_PRESS)
camera.ProcessKeyboard(RIGHT, deltaTime);if(glfwGetKey(window, GLFW_KEY_E)== GLFW_PRESS)
camera.ProcessKeyboard(UP, deltaTime);if(glfwGetKey(window, GLFW_KEY_Q)== GLFW_PRESS)
camera.ProcessKeyboard(DOWN, deltaTime);}// glfw: whenever the window size changed (by OS or user resize) this callback function executes// ---------------------------------------------------------------------------------------------voidframebuffer_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// -------------------------------------------------------voidmouse_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 top
lastX = xpos;
lastY = ypos;
camera.ProcessMouseMovement(xoffset, yoffset);}// glfw: whenever the mouse scroll wheel scrolls, this callback is called// ----------------------------------------------------------------------voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset){
camera.ProcessMouseScroll(yoffset);}// utility function for loading a 2D texture from file// ---------------------------------------------------unsignedintloadTexture(charconst*path){unsignedint textureID;glGenTextures(1,&textureID);int width, height, nrComponents;unsignedchar*data =stbi_load(path,&width,&height,&nrComponents,0);if(data){
GLenum format;if(nrComponents ==1)
format = GL_RED;elseif(nrComponents ==3)
format = GL_RGB;elseif(nrComponents ==4)
format = GL_RGBA;glBindTexture(GL_TEXTURE_2D, textureID);glTexImage2D(GL_TEXTURE_2D,0, format, width, height,0, format, 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;}
帧缓冲
#include<glad/glad.h>#include<glfw3.h>#include<iostream>#include"Shader.h"#include"Camera.h"#define STB_IMAGE_IMPLEMENTATION#include<stb_image.h>#include<glm/glm.hpp>#include<glm/gtc/matrix_transform.hpp>#include<glm/gtc/type_ptr.hpp>voidframebuffer_size_callback(GLFWwindow* window,int width,int height);voidmouse_callback(GLFWwindow* window,double xpos,double ypos);voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset);voidprocessInput(GLFWwindow *window);unsignedintloadTexture(constchar*path);// settingsconstunsignedint SCR_WIDTH =800;constunsignedint SCR_HEIGHT =600;// camera
Camera camera(glm::vec3(0.0f,0.0f,3.0f));float lastX =(float)SCR_WIDTH /2.0;float lastY =(float)SCR_HEIGHT /2.0;bool firstMouse =true;// timingfloat deltaTime =0.0f;float lastFrame =0.0f;intmain(){// 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;}// configure global opengl state// -----------------------------glEnable(GL_DEPTH_TEST);// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);// build and compile shaders// -------------------------
Shader shader("/Users/apathetically/CLionProjects/RenderTest/shader_file/5.1.framebuffers.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/5.1.framebuffers.fs");
Shader screenShader("/Users/apathetically/CLionProjects/RenderTest/shader_file/5.1.framebuffers_screen.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/5.1.framebuffers_screen.fs");// set up vertex data (and buffer(s)) and configure vertex attributes// ------------------------------------------------------------------float cubeVertices[]={// positions // texture Coords-0.5f,-0.5f,-0.5f,0.0f,0.0f,0.5f,-0.5f,-0.5f,1.0f,0.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,-0.5f,0.5f,-0.5f,0.0f,1.0f,-0.5f,-0.5f,-0.5f,0.0f,0.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,0.5f,-0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,0.5f,1.0f,1.0f,0.5f,0.5f,0.5f,1.0f,1.0f,-0.5f,0.5f,0.5f,0.0f,1.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,-0.5f,0.5f,0.5f,1.0f,0.0f,-0.5f,0.5f,-0.5f,1.0f,1.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,-0.5f,0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,0.5f,-0.5f,-0.5f,0.0f,1.0f,0.5f,-0.5f,-0.5f,0.0f,1.0f,0.5f,-0.5f,0.5f,0.0f,0.0f,0.5f,0.5f,0.5f,1.0f,0.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,0.5f,-0.5f,-0.5f,1.0f,1.0f,0.5f,-0.5f,0.5f,1.0f,0.0f,0.5f,-0.5f,0.5f,1.0f,0.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,-0.5f,0.5f,-0.5f,0.0f,1.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,0.5f,0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,0.5f,1.0f,0.0f,-0.5f,0.5f,0.5f,0.0f,0.0f,-0.5f,0.5f,-0.5f,0.0f,1.0f};float planeVertices[]={// positions // texture Coords5.0f,-0.5f,5.0f,2.0f,0.0f,-5.0f,-0.5f,5.0f,0.0f,0.0f,-5.0f,-0.5f,-5.0f,0.0f,2.0f,5.0f,-0.5f,5.0f,2.0f,0.0f,-5.0f,-0.5f,-5.0f,0.0f,2.0f,5.0f,-0.5f,-5.0f,2.0f,2.0f};float quadVertices[]={// vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates.// positions // texCoords-1.0f,1.0f,0.0f,1.0f,-1.0f,-1.0f,0.0f,0.0f,1.0f,-1.0f,1.0f,0.0f,-1.0f,1.0f,0.0f,1.0f,1.0f,-1.0f,1.0f,0.0f,1.0f,1.0f,1.0f,1.0f};// cube VAOunsignedint cubeVAO, cubeVBO;glGenVertexArrays(1,&cubeVAO);glGenBuffers(1,&cubeVBO);glBindVertexArray(cubeVAO);glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);glBufferData(GL_ARRAY_BUFFER,sizeof(cubeVertices),&cubeVertices, 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)));// plane VAOunsignedint planeVAO, planeVBO;glGenVertexArrays(1,&planeVAO);glGenBuffers(1,&planeVBO);glBindVertexArray(planeVAO);glBindBuffer(GL_ARRAY_BUFFER, planeVBO);glBufferData(GL_ARRAY_BUFFER,sizeof(planeVertices),&planeVertices, 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)));// screen quad VAOunsignedint quadVAO, quadVBO;glGenVertexArrays(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,2, GL_FLOAT, GL_FALSE,4*sizeof(float),(void*)0);glEnableVertexAttribArray(1);glVertexAttribPointer(1,2, GL_FLOAT, GL_FALSE,4*sizeof(float),(void*)(2*sizeof(float)));// load textures// -------------unsignedint cubeTexture =loadTexture("/Users/apathetically/CLionProjects/RenderTest/resources/textures/marble.jpg");unsignedint floorTexture =loadTexture("/Users/apathetically/CLionProjects/RenderTest/resources/textures/metal.png");// shader configuration// --------------------
shader.use();
shader.setInt("texture1",0);
screenShader.use();
screenShader.setInt("screenTexture",0);// framebuffer configuration// -------------------------unsignedint framebuffer;glGenFramebuffers(1,&framebuffer);glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);// create a color attachment textureunsignedint textureColorbuffer;glGenTextures(1,&textureColorbuffer);glBindTexture(GL_TEXTURE_2D, textureColorbuffer);glTexImage2D(GL_TEXTURE_2D,0, GL_RGB, SCR_WIDTH, SCR_HEIGHT,0, GL_RGB, GL_UNSIGNED_BYTE,NULL);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureColorbuffer,0);// create a renderbuffer object for depth and stencil attachment (we won't be sampling these)unsignedint rbo;glGenRenderbuffers(1,&rbo);glBindRenderbuffer(GL_RENDERBUFFER, rbo);// use a single renderbuffer object for both a depth AND stencil buffer.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, SCR_WIDTH, SCR_HEIGHT);glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);// now that we actually created the framebuffer and added all attachment we want to check if it is actually complete nowif(glCheckFramebufferStatus(GL_FRAMEBUFFER)!= GL_FRAMEBUFFER_COMPLETE)
std::cout <<"ERROR::FRAMEBUFFER:: Framebuffer is not complete!"<< std::endl;glBindFramebuffer(GL_FRAMEBUFFER,0);// draw as wireframe// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);// render loop// -----------while(!glfwWindowShouldClose(window)){// per-frame time logic// --------------------float currentFrame =glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;// input// -----processInput(window);// render// ------// bind to framebuffer and draw scene as we normally would to color textureglBindFramebuffer(GL_FRAMEBUFFER, framebuffer);glEnable(GL_DEPTH_TEST);// enable depth testing (is disabled for rendering screen-space quad)// make sure we clear the framebuffer's contentglClearColor(0.1f,0.1f,0.1f,1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// draw objects
shader.use();
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom),(float)SCR_WIDTH /(float)SCR_HEIGHT,0.1f,100.0f);
glm::mat4 view = camera.GetViewMatrix();
glm::mat4 model = glm::mat4(1.0f);
shader.setMat4("projection", projection);
shader.setMat4("view", view);// cubesglBindVertexArray(cubeVAO);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, cubeTexture);
model = glm::translate(model, glm::vec3(-1.0f,0.0f,-1.0f));
shader.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,36);
model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(2.0f,0.0f,0.0f));
shader.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,36);// floorglBindVertexArray(planeVAO);glBindTexture(GL_TEXTURE_2D, floorTexture);
model = glm::mat4(1.0f);
shader.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,6);glBindVertexArray(0);// now bind back to default framebuffer and draw a quad plane with the attached framebuffer color textureglBindFramebuffer(GL_FRAMEBUFFER,0);glDisable(GL_DEPTH_TEST);// disable depth test so screen-space quad isn't discarded due to depth test.// clear all relevant buffersglClearColor(1.0f,1.0f,1.0f,1.0f);// set clear color to white (not really necessary actually, since we won't// be able to see behind the quad anyways)glClear(GL_COLOR_BUFFER_BIT);
screenShader.use();glBindVertexArray(quadVAO);glBindTexture(GL_TEXTURE_2D, textureColorbuffer);// use the color attachment texture as the texture of the quad planeglDrawArrays(GL_TRIANGLES,0,6);// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)glfwSwapBuffers(window);glfwPollEvents();}// optional: de-allocate all resources once they've outlived their purpose:// ------------------------------------------------------------------------glDeleteVertexArrays(1,&cubeVAO);glDeleteVertexArrays(1,&planeVAO);glDeleteVertexArrays(1,&quadVAO);glDeleteBuffers(1,&cubeVBO);glDeleteBuffers(1,&planeVBO);glDeleteBuffers(1,&quadVBO);glfwTerminate();return0;}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly// ---------------------------------------------------------------------------------------------------------voidprocessInput(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_A)== GLFW_PRESS)
camera.ProcessKeyboard(LEFT, deltaTime);if(glfwGetKey(window, GLFW_KEY_S)== GLFW_PRESS)
camera.ProcessKeyboard(BACKWARD, deltaTime);if(glfwGetKey(window, GLFW_KEY_D)== GLFW_PRESS)
camera.ProcessKeyboard(RIGHT, deltaTime);if(glfwGetKey(window, GLFW_KEY_E)== GLFW_PRESS)
camera.ProcessKeyboard(UP, deltaTime);if(glfwGetKey(window, GLFW_KEY_Q)== GLFW_PRESS)
camera.ProcessKeyboard(DOWN, deltaTime);}// glfw: whenever the window size changed (by OS or user resize) this callback function executes// ---------------------------------------------------------------------------------------------voidframebuffer_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// -------------------------------------------------------voidmouse_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 top
lastX = xpos;
lastY = ypos;
camera.ProcessMouseMovement(xoffset, yoffset);}// glfw: whenever the mouse scroll wheel scrolls, this callback is called// ----------------------------------------------------------------------voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset){
camera.ProcessMouseScroll(yoffset);}// utility function for loading a 2D texture from file// ---------------------------------------------------unsignedintloadTexture(charconst*path){unsignedint textureID;glGenTextures(1,&textureID);int width, height, nrComponents;unsignedchar*data =stbi_load(path,&width,&height,&nrComponents,0);if(data){
GLenum format;if(nrComponents ==1)
format = GL_RED;elseif(nrComponents ==3)
format = GL_RGB;elseif(nrComponents ==4)
format = GL_RGBA;glBindTexture(GL_TEXTURE_2D, textureID);glTexImage2D(GL_TEXTURE_2D,0, format, width, height,0, format, 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;}
立方体贴图
#include<glad/glad.h>#include<glfw3.h>#include<iostream>#include"Shader.h"#include"Camera.h"#define STB_IMAGE_IMPLEMENTATION#include<stb_image.h>#include<glm/glm.hpp>#include<glm/gtc/matrix_transform.hpp>#include<glm/gtc/type_ptr.hpp>voidframebuffer_size_callback(GLFWwindow* window,int width,int height);voidmouse_callback(GLFWwindow* window,double xpos,double ypos);voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset);voidprocessInput(GLFWwindow *window);unsignedintloadTexture(constchar*path);unsignedintloadCubemap(std::vector<std::string> faces);// settingsconstunsignedint SCR_WIDTH =800;constunsignedint SCR_HEIGHT =600;// camera
Camera camera(glm::vec3(0.0f,0.0f,3.0f));float lastX =(float)SCR_WIDTH /2.0;float lastY =(float)SCR_HEIGHT /2.0;bool firstMouse =true;// timingfloat deltaTime =0.0f;float lastFrame =0.0f;intmain(){// 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;}// configure global opengl state// -----------------------------glEnable(GL_DEPTH_TEST);// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//// build and compile shaders// -------------------------
Shader shader("/Users/apathetically/CLionProjects/RenderTest/shader_file/6.1.cubemaps.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/6.1.cubemaps.fs");
Shader skyboxShader("/Users/apathetically/CLionProjects/RenderTest/shader_file/6.1.skybox.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/6.1.skybox.fs");// set up vertex data (and buffer(s)) and configure vertex attributes// ------------------------------------------------------------------float cubeVertices[]={// positions // texture Coords-0.5f,-0.5f,-0.5f,0.0f,0.0f,0.5f,-0.5f,-0.5f,1.0f,0.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,-0.5f,0.5f,-0.5f,0.0f,1.0f,-0.5f,-0.5f,-0.5f,0.0f,0.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,0.5f,-0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,0.5f,1.0f,1.0f,0.5f,0.5f,0.5f,1.0f,1.0f,-0.5f,0.5f,0.5f,0.0f,1.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,-0.5f,0.5f,0.5f,1.0f,0.0f,-0.5f,0.5f,-0.5f,1.0f,1.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,-0.5f,0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,0.5f,-0.5f,-0.5f,0.0f,1.0f,0.5f,-0.5f,-0.5f,0.0f,1.0f,0.5f,-0.5f,0.5f,0.0f,0.0f,0.5f,0.5f,0.5f,1.0f,0.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,0.5f,-0.5f,-0.5f,1.0f,1.0f,0.5f,-0.5f,0.5f,1.0f,0.0f,0.5f,-0.5f,0.5f,1.0f,0.0f,-0.5f,-0.5f,0.5f,0.0f,0.0f,-0.5f,-0.5f,-0.5f,0.0f,1.0f,-0.5f,0.5f,-0.5f,0.0f,1.0f,0.5f,0.5f,-0.5f,1.0f,1.0f,0.5f,0.5f,0.5f,1.0f,0.0f,0.5f,0.5f,0.5f,1.0f,0.0f,-0.5f,0.5f,0.5f,0.0f,0.0f,-0.5f,0.5f,-0.5f,0.0f,1.0f};float skyboxVertices[]={// positions-1.0f,1.0f,-1.0f,-1.0f,-1.0f,-1.0f,1.0f,-1.0f,-1.0f,1.0f,-1.0f,-1.0f,1.0f,1.0f,-1.0f,-1.0f,1.0f,-1.0f,-1.0f,-1.0f,1.0f,-1.0f,-1.0f,-1.0f,-1.0f,1.0f,-1.0f,-1.0f,1.0f,-1.0f,-1.0f,1.0f,1.0f,-1.0f,-1.0f,1.0f,1.0f,-1.0f,-1.0f,1.0f,-1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,-1.0f,1.0f,-1.0f,-1.0f,-1.0f,-1.0f,1.0f,-1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,-1.0f,1.0f,-1.0f,-1.0f,1.0f,-1.0f,1.0f,-1.0f,1.0f,1.0f,-1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,-1.0f,1.0f,1.0f,-1.0f,1.0f,-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,1.0f,1.0f,-1.0f,-1.0f,1.0f,-1.0f,-1.0f,-1.0f,-1.0f,1.0f,1.0f,-1.0f,1.0f};// cube VAOunsignedint cubeVAO, cubeVBO;glGenVertexArrays(1,&cubeVAO);glGenBuffers(1,&cubeVBO);glBindVertexArray(cubeVAO);glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);glBufferData(GL_ARRAY_BUFFER,sizeof(cubeVertices),&cubeVertices, 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)));// skybox VAOunsignedint skyboxVAO, skyboxVBO;glGenVertexArrays(1,&skyboxVAO);glGenBuffers(1,&skyboxVBO);glBindVertexArray(skyboxVAO);glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO);glBufferData(GL_ARRAY_BUFFER,sizeof(skyboxVertices),&skyboxVertices, GL_STATIC_DRAW);glEnableVertexAttribArray(0);glVertexAttribPointer(0,3, GL_FLOAT, GL_FALSE,3*sizeof(float),(void*)0);// load textures// -------------unsignedint cubeTexture =loadTexture("/Users/apathetically/CLionProjects/RenderTest/resources/textures/container.jpg");
std::vector<std::string> faces{"/Users/apathetically/CLionProjects/RenderTest/resources/textures/skybox/right.jpg","/Users/apathetically/CLionProjects/RenderTest/resources/textures/skybox/left.jpg","/Users/apathetically/CLionProjects/RenderTest/resources/textures/skybox/top.jpg","/Users/apathetically/CLionProjects/RenderTest/resources/textures/skybox/bottom.jpg","/Users/apathetically/CLionProjects/RenderTest/resources/textures/skybox/front.jpg","/Users/apathetically/CLionProjects/RenderTest/resources/textures/skybox/back.jpg",};unsignedint cubemapTexture =loadCubemap(faces);// shader configuration// --------------------
shader.use();
shader.setInt("texture1",0);
skyboxShader.use();
skyboxShader.setInt("screenTexture",0);// render loop// -----------while(!glfwWindowShouldClose(window)){// per-frame time logic// --------------------float currentFrame =glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;// input// -----processInput(window);// render// ------glClearColor(0.1f,0.1f,0.1f,1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// draw scene as normal
shader.use();
glm::mat4 model = glm::mat4(1.0f);
glm::mat4 view = camera.GetViewMatrix();
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom),(float)SCR_WIDTH/(float)SCR_HEIGHT,0.1f,100.0f);
shader.setMat4("model", model);
shader.setMat4("view", view);
shader.setMat4("projection", projection);// cubesglBindVertexArray(cubeVAO);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, cubeTexture);glDrawArrays(GL_TRIANGLES,0,36);glBindVertexArray(0);// draw skybox as lastglDepthFunc(GL_LEQUAL);// change depth function so depth test passes when values are equal to depth buffer's content
skyboxShader.use();
view = glm::mat4(glm::mat3(camera.GetViewMatrix()));
skyboxShader.setMat4("view", view);
skyboxShader.setMat4("projection", projection);// skybox cubeglBindVertexArray(skyboxVAO);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);glDrawArrays(GL_TRIANGLES,0,36);glBindVertexArray(0);glDepthFunc(GL_LESS);// set depth function back to default// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)// -------------------------------------------------------------------------------glfwSwapBuffers(window);glfwPollEvents();}// optional: de-allocate all resources once they've outlived their purpose:// ------------------------------------------------------------------------glDeleteVertexArrays(1,&cubeVAO);glDeleteVertexArrays(1,&skyboxVAO);glDeleteBuffers(1,&cubeVBO);glDeleteBuffers(1,&skyboxVAO);glfwTerminate();return0;}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly// ---------------------------------------------------------------------------------------------------------voidprocessInput(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_A)== GLFW_PRESS)
camera.ProcessKeyboard(LEFT, deltaTime);if(glfwGetKey(window, GLFW_KEY_S)== GLFW_PRESS)
camera.ProcessKeyboard(BACKWARD, deltaTime);if(glfwGetKey(window, GLFW_KEY_D)== GLFW_PRESS)
camera.ProcessKeyboard(RIGHT, deltaTime);if(glfwGetKey(window, GLFW_KEY_E)== GLFW_PRESS)
camera.ProcessKeyboard(UP, deltaTime);if(glfwGetKey(window, GLFW_KEY_Q)== GLFW_PRESS)
camera.ProcessKeyboard(DOWN, deltaTime);}// glfw: whenever the window size changed (by OS or user resize) this callback function executes// ---------------------------------------------------------------------------------------------voidframebuffer_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// -------------------------------------------------------voidmouse_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 top
lastX = xpos;
lastY = ypos;
camera.ProcessMouseMovement(xoffset, yoffset);}// glfw: whenever the mouse scroll wheel scrolls, this callback is called// ----------------------------------------------------------------------voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset){
camera.ProcessMouseScroll(yoffset);}// utility function for loading a 2D texture from file// ---------------------------------------------------unsignedintloadTexture(charconst*path){unsignedint textureID;glGenTextures(1,&textureID);int width, height, nrComponents;unsignedchar*data =stbi_load(path,&width,&height,&nrComponents,0);if(data){
GLenum format;if(nrComponents ==1)
format = GL_RED;elseif(nrComponents ==3)
format = GL_RGB;elseif(nrComponents ==4)
format = GL_RGBA;glBindTexture(GL_TEXTURE_2D, textureID);glTexImage2D(GL_TEXTURE_2D,0, format, width, height,0, format, 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;}// loads a cubemap texture from 6 individual texture faces// order:// +X (right)// -X (left)// +Y (top)// -Y (bottom)// +Z (front)// -Z (back)// -------------------------------------------------------unsignedintloadCubemap(std::vector<std::string> faces){unsignedint textureID;glGenTextures(1,&textureID);glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);int width, height, nrChannels;for(unsignedint i =0;i < faces.size();i ++){unsignedchar*data =stbi_load(faces[i].c_str(),&width,&height,&nrChannels,0);if(data){glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,0, GL_RGB, width, height,0, GL_RGB, GL_UNSIGNED_BYTE, data);stbi_image_free(data);}else{
std::cout <<"Cubemap texture failed to load at path: "<< faces[i]<< std::endl;stbi_image_free(data);}}glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);return textureID;}
环境映射-反射-折射
#include<glad/glad.h>#include<glfw3.h>#include<iostream>#include"Shader.h"#include"Camera.h"#define STB_IMAGE_IMPLEMENTATION#include<stb_image.h>#include<glm/glm.hpp>#include<glm/gtc/matrix_transform.hpp>#include<glm/gtc/type_ptr.hpp>voidframebuffer_size_callback(GLFWwindow* window,int width,int height);voidmouse_callback(GLFWwindow* window,double xpos,double ypos);voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset);voidprocessInput(GLFWwindow *window);unsignedintloadTexture(constchar*path);unsignedintloadCubemap(std::vector<std::string> faces);// settingsconstunsignedint SCR_WIDTH =800;constunsignedint SCR_HEIGHT =600;// camera
Camera camera(glm::vec3(0.0f,0.0f,3.0f));float lastX =(float)SCR_WIDTH /2.0;float lastY =(float)SCR_HEIGHT /2.0;bool firstMouse =true;// timingfloat deltaTime =0.0f;float lastFrame =0.0f;intmain(){// 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;}// configure global opengl state// -----------------------------glEnable(GL_DEPTH_TEST);// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//// build and compile shaders// -------------------------
Shader shader("/Users/apathetically/CLionProjects/RenderTest/shader_file/6.2.cubemaps.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/6.2.cubemaps.fs");
Shader skyboxShader("/Users/apathetically/CLionProjects/RenderTest/shader_file/6.1.skybox.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/6.1.skybox.fs");// set up vertex data (and buffer(s)) and configure vertex attributes// ------------------------------------------------------------------float cubeVertices[]={// positions // normals-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};float skyboxVertices[]={// positions-1.0f,1.0f,-1.0f,-1.0f,-1.0f,-1.0f,1.0f,-1.0f,-1.0f,1.0f,-1.0f,-1.0f,1.0f,1.0f,-1.0f,-1.0f,1.0f,-1.0f,-1.0f,-1.0f,1.0f,-1.0f,-1.0f,-1.0f,-1.0f,1.0f,-1.0f,-1.0f,1.0f,-1.0f,-1.0f,1.0f,1.0f,-1.0f,-1.0f,1.0f,1.0f,-1.0f,-1.0f,1.0f,-1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,-1.0f,1.0f,-1.0f,-1.0f,-1.0f,-1.0f,1.0f,-1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,-1.0f,1.0f,-1.0f,-1.0f,1.0f,-1.0f,1.0f,-1.0f,1.0f,1.0f,-1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,-1.0f,1.0f,1.0f,-1.0f,1.0f,-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,1.0f,1.0f,-1.0f,-1.0f,1.0f,-1.0f,-1.0f,-1.0f,-1.0f,1.0f,1.0f,-1.0f,1.0f};// cube VAOunsignedint cubeVAO, cubeVBO;glGenVertexArrays(1,&cubeVAO);glGenBuffers(1,&cubeVBO);glBindVertexArray(cubeVAO);glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);glBufferData(GL_ARRAY_BUFFER,sizeof(cubeVertices),&cubeVertices, GL_STATIC_DRAW);glEnableVertexAttribArray(0);glVertexAttribPointer(0,3, GL_FLOAT, GL_FALSE,6*sizeof(float),(void*)0);glEnableVertexAttribArray(1);glVertexAttribPointer(1,3, GL_FLOAT, GL_FALSE,6*sizeof(float),(void*)(3*sizeof(float)));// skybox VAOunsignedint skyboxVAO, skyboxVBO;glGenVertexArrays(1,&skyboxVAO);glGenBuffers(1,&skyboxVBO);glBindVertexArray(skyboxVAO);glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO);glBufferData(GL_ARRAY_BUFFER,sizeof(skyboxVertices),&skyboxVertices, GL_STATIC_DRAW);glEnableVertexAttribArray(0);glVertexAttribPointer(0,3, GL_FLOAT, GL_FALSE,3*sizeof(float),(void*)0);// load textures// -------------unsignedint cubeTexture =loadTexture("/Users/apathetically/CLionProjects/RenderTest/resources/textures/container.jpg");
std::vector<std::string> faces{"/Users/apathetically/CLionProjects/RenderTest/resources/textures/skybox/right.jpg","/Users/apathetically/CLionProjects/RenderTest/resources/textures/skybox/left.jpg","/Users/apathetically/CLionProjects/RenderTest/resources/textures/skybox/top.jpg","/Users/apathetically/CLionProjects/RenderTest/resources/textures/skybox/bottom.jpg","/Users/apathetically/CLionProjects/RenderTest/resources/textures/skybox/front.jpg","/Users/apathetically/CLionProjects/RenderTest/resources/textures/skybox/back.jpg",};unsignedint cubemapTexture =loadCubemap(faces);// shader configuration// --------------------
shader.use();
shader.setInt("texture1",0);
skyboxShader.use();
skyboxShader.setInt("screenTexture",0);// render loop// -----------while(!glfwWindowShouldClose(window)){// per-frame time logic// --------------------float currentFrame =glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;// input// -----processInput(window);// render// ------glClearColor(0.1f,0.1f,0.1f,1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// draw scene as normal
shader.use();
glm::mat4 model = glm::mat4(1.0f);
glm::mat4 view = camera.GetViewMatrix();
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom),(float)SCR_WIDTH/(float)SCR_HEIGHT,0.1f,100.0f);
shader.setMat4("model", model);
shader.setMat4("view", view);
shader.setMat4("projection", projection);
shader.setVec3("cameraPos", camera.Position);// cubesglBindVertexArray(cubeVAO);glActiveTexture(GL_TEXTURE0);// glBindTexture(GL_TEXTURE_2D, cubeTexture);glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);glDrawArrays(GL_TRIANGLES,0,36);glBindVertexArray(0);// draw skybox as lastglDepthFunc(GL_LEQUAL);// change depth function so depth test passes when values are equal to depth buffer's content
skyboxShader.use();
view = glm::mat4(glm::mat3(camera.GetViewMatrix()));
skyboxShader.setMat4("view", view);
skyboxShader.setMat4("projection", projection);// skybox cubeglBindVertexArray(skyboxVAO);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);glDrawArrays(GL_TRIANGLES,0,36);glBindVertexArray(0);glDepthFunc(GL_LESS);// set depth function back to default// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)// -------------------------------------------------------------------------------glfwSwapBuffers(window);glfwPollEvents();}// optional: de-allocate all resources once they've outlived their purpose:// ------------------------------------------------------------------------glDeleteVertexArrays(1,&cubeVAO);glDeleteVertexArrays(1,&skyboxVAO);glDeleteBuffers(1,&cubeVBO);glDeleteBuffers(1,&skyboxVAO);glfwTerminate();return0;}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly// ---------------------------------------------------------------------------------------------------------voidprocessInput(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_A)== GLFW_PRESS)
camera.ProcessKeyboard(LEFT, deltaTime);if(glfwGetKey(window, GLFW_KEY_S)== GLFW_PRESS)
camera.ProcessKeyboard(BACKWARD, deltaTime);if(glfwGetKey(window, GLFW_KEY_D)== GLFW_PRESS)
camera.ProcessKeyboard(RIGHT, deltaTime);if(glfwGetKey(window, GLFW_KEY_E)== GLFW_PRESS)
camera.ProcessKeyboard(UP, deltaTime);if(glfwGetKey(window, GLFW_KEY_Q)== GLFW_PRESS)
camera.ProcessKeyboard(DOWN, deltaTime);}// glfw: whenever the window size changed (by OS or user resize) this callback function executes// ---------------------------------------------------------------------------------------------voidframebuffer_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// -------------------------------------------------------voidmouse_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 top
lastX = xpos;
lastY = ypos;
camera.ProcessMouseMovement(xoffset, yoffset);}// glfw: whenever the mouse scroll wheel scrolls, this callback is called// ----------------------------------------------------------------------voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset){
camera.ProcessMouseScroll(yoffset);}// utility function for loading a 2D texture from file// ---------------------------------------------------unsignedintloadTexture(charconst*path){unsignedint textureID;glGenTextures(1,&textureID);int width, height, nrComponents;unsignedchar*data =stbi_load(path,&width,&height,&nrComponents,0);if(data){
GLenum format;if(nrComponents ==1)
format = GL_RED;elseif(nrComponents ==3)
format = GL_RGB;elseif(nrComponents ==4)
format = GL_RGBA;glBindTexture(GL_TEXTURE_2D, textureID);glTexImage2D(GL_TEXTURE_2D,0, format, width, height,0, format, 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;}// loads a cubemap texture from 6 individual texture faces// order:// +X (right)// -X (left)// +Y (top)// -Y (bottom)// +Z (front)// -Z (back)// -------------------------------------------------------unsignedintloadCubemap(std::vector<std::string> faces){unsignedint textureID;glGenTextures(1,&textureID);glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);int width, height, nrChannels;for(unsignedint i =0;i < faces.size();i ++){unsignedchar*data =stbi_load(faces[i].c_str(),&width,&height,&nrChannels,0);if(data){glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,0, GL_RGB, width, height,0, GL_RGB, GL_UNSIGNED_BYTE, data);stbi_image_free(data);}else{
std::cout <<"Cubemap texture failed to load at path: "<< faces[i]<< std::endl;stbi_image_free(data);}}glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);return textureID;}
几何着色器-画房子
#include<glad/glad.h>#include<glfw3.h>#include<iostream>#include"Shader.h"#include"Camera.h"#define STB_IMAGE_IMPLEMENTATION#include<stb_image.h>#include<glm/glm.hpp>#include<glm/gtc/matrix_transform.hpp>#include<glm/gtc/type_ptr.hpp>voidframebuffer_size_callback(GLFWwindow* window,int width,int height);voidmouse_callback(GLFWwindow* window,double xpos,double ypos);voidprocessInput(GLFWwindow *window);// settingsconstunsignedint SCR_WIDTH =800;constunsignedint SCR_HEIGHT =600;// camera
Camera camera(glm::vec3(0.0f,0.0f,3.0f));float lastX =(float)SCR_WIDTH /2.0;float lastY =(float)SCR_HEIGHT /2.0;bool firstMouse =true;// timingfloat deltaTime =0.0f;float lastFrame =0.0f;intmain(){// 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,"RenderTest",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);// 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;}// configure global opengl state// -----------------------------glEnable(GL_DEPTH_TEST);// build and compile shaders// -------------------------
Shader shaderRed("/Users/apathetically/CLionProjects/RenderTest/shader_file/8.advanced_glsl.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/8.red.fs");
Shader shaderGreen("/Users/apathetically/CLionProjects/RenderTest/shader_file/8.advanced_glsl.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/8.green.fs");
Shader shaderBlue("/Users/apathetically/CLionProjects/RenderTest/shader_file/8.advanced_glsl.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/8.blue.fs");
Shader shaderYellow("/Users/apathetically/CLionProjects/RenderTest/shader_file/8.advanced_glsl.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/8.yellow.fs");// set up vertex data (and buffer(s)) and configure vertex attributes// ------------------------------------------------------------------float cubeVertices[]={// positions-0.5f,-0.5f,-0.5f,0.5f,-0.5f,-0.5f,0.5f,0.5f,-0.5f,0.5f,0.5f,-0.5f,-0.5f,0.5f,-0.5f,-0.5f,-0.5f,-0.5f,-0.5f,-0.5f,0.5f,0.5f,-0.5f,0.5f,0.5f,0.5f,0.5f,0.5f,0.5f,0.5f,-0.5f,0.5f,0.5f,-0.5f,-0.5f,0.5f,-0.5f,0.5f,0.5f,-0.5f,0.5f,-0.5f,-0.5f,-0.5f,-0.5f,-0.5f,-0.5f,-0.5f,-0.5f,-0.5f,0.5f,-0.5f,0.5f,0.5f,0.5f,0.5f,0.5f,0.5f,0.5f,-0.5f,0.5f,-0.5f,-0.5f,0.5f,-0.5f,-0.5f,0.5f,-0.5f,0.5f,0.5f,0.5f,0.5f,-0.5f,-0.5f,-0.5f,0.5f,-0.5f,-0.5f,0.5f,-0.5f,0.5f,0.5f,-0.5f,0.5f,-0.5f,-0.5f,0.5f,-0.5f,-0.5f,-0.5f,-0.5f,0.5f,-0.5f,0.5f,0.5f,-0.5f,0.5f,0.5f,0.5f,0.5f,0.5f,0.5f,-0.5f,0.5f,0.5f,-0.5f,0.5f,-0.5f,};// cube VAOunsignedint cubeVAO, cubeVBO;glGenVertexArrays(1,&cubeVAO);glGenBuffers(1,&cubeVBO);glBindVertexArray(cubeVAO);glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);glBufferData(GL_ARRAY_BUFFER,sizeof(cubeVertices),&cubeVertices, GL_STATIC_DRAW);glEnableVertexAttribArray(0);glVertexAttribPointer(0,3, GL_FLOAT, GL_FALSE,3*sizeof(float),(void*)0);// configure a uniform buffer object// ---------------------------------// first. We get the relevant block indicesunsignedint uniformBlockIndexRed =glGetUniformBlockIndex(shaderRed.ID,"Matrices");unsignedint uniformBlockIndexGreen =glGetUniformBlockIndex(shaderGreen.ID,"Matrices");unsignedint uniformBlockIndexBlue =glGetUniformBlockIndex(shaderBlue.ID,"Matrices");unsignedint uniformBlockIndexYellow =glGetUniformBlockIndex(shaderYellow.ID,"Matrices");// then we link each shader's uniform block to this uniform binding pointglUniformBlockBinding(shaderRed.ID, uniformBlockIndexRed,0);glUniformBlockBinding(shaderGreen.ID, uniformBlockIndexGreen,0);glUniformBlockBinding(shaderBlue.ID, uniformBlockIndexBlue,0);glUniformBlockBinding(shaderYellow.ID, uniformBlockIndexYellow,0);// Now actually create the bufferunsignedint uboMatrices;glGenBuffers(1,&uboMatrices);glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);glBufferData(GL_UNIFORM_BUFFER,2*sizeof(glm::mat4),NULL, GL_STATIC_DRAW);glBindBuffer(GL_UNIFORM_BUFFER,0);// define the range of the buffer that links to a uniform binding pointglBindBufferRange(GL_UNIFORM_BUFFER,0, uboMatrices,0,2*sizeof(glm::mat4));// store the projection matrix (we only do this once now) (note: we're not using zoom anymore by changing the FoV)
glm::mat4 projection = glm::perspective(45.0f,(float)SCR_WIDTH /(float)SCR_HEIGHT,0.1f,100.0f);glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);glBufferSubData(GL_UNIFORM_BUFFER,0,sizeof(glm::mat4), glm::value_ptr(projection));glBindBuffer(GL_UNIFORM_BUFFER,0);// render loop// -----------while(!glfwWindowShouldClose(window)){// pre-frame time logic// --------------------float currentFrame =glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;// input// -----processInput(window);// render// ------glClearColor(0.1f,0.1f,0.1f,1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// set the view and projection matrix in the uniform block - we only have to do this once per loop iteration;
glm::mat4 view = camera.GetViewMatrix();glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);glBufferSubData(GL_UNIFORM_BUFFER,sizeof(glm::mat4),sizeof(glm::mat4), glm::value_ptr(view));glBindBuffer(GL_UNIFORM_BUFFER,0);// draw 4 cubes// REDglBindVertexArray(cubeVAO);
shaderRed.use();
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(-0.75f,0.75f,0.0f));// move top-left
shaderRed.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,36);// GREEN
shaderGreen.use();
model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(0.75f,0.75f,0.0f));// move top-right
shaderGreen.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,36);// YELLOW
shaderYellow.use();
model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(-0.75f,-0.75f,0.0f));// move bottom-left
shaderYellow.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,36);// BLUE
shaderBlue.use();
model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(0.75f,-0.75f,0.0f));// move bottom-right
shaderBlue.setMat4("model", model);glDrawArrays(GL_TRIANGLES,0,36);// glfw: swap buffers and poll IO events (keys pressed/released mouse moved etc.)// ------------------------------------------------------------------------------glfwSwapBuffers(window);glfwPollEvents();}// optional: de-allocate all resources once they've outlived their purpose:// ------------------------------------------------------------------------glDeleteVertexArrays(1,&cubeVAO);glDeleteBuffers(1,&cubeVBO);glfwTerminate();return0;}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly// ---------------------------------------------------------------------------------------------------------voidprocessInput(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_A)== GLFW_PRESS)
camera.ProcessKeyboard(LEFT, deltaTime);if(glfwGetKey(window, GLFW_KEY_S)== GLFW_PRESS)
camera.ProcessKeyboard(BACKWARD, deltaTime);if(glfwGetKey(window, GLFW_KEY_D)== GLFW_PRESS)
camera.ProcessKeyboard(RIGHT, deltaTime);if(glfwGetKey(window, GLFW_KEY_E)== GLFW_PRESS)
camera.ProcessKeyboard(UP, deltaTime);if(glfwGetKey(window, GLFW_KEY_Q)== GLFW_PRESS)
camera.ProcessKeyboard(DOWN, deltaTime);}// glfw: whenever the window size changed (by OS or user resize) this callback function executes// ---------------------------------------------------------------------------------------------voidframebuffer_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// -------------------------------------------------------voidmouse_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 top
lastX = xpos;
lastY = ypos;
camera.ProcessMouseMovement(xoffset, yoffset);}
几何着色器-爆炸效果
#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"Camera.h"#include"Model.h"#include<iostream>voidframebuffer_size_callback(GLFWwindow* window,int width,int height);voidmouse_callback(GLFWwindow* window,double xpos,double ypos);voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset);voidprocessInput(GLFWwindow *window);// settingsconstunsignedint SCR_WIDTH =800;constunsignedint SCR_HEIGHT =600;// camera
Camera camera(glm::vec3(0.0f,0.0f,3.0f));float lastX = SCR_WIDTH /2.0f;float lastY = SCR_HEIGHT /2.0f;bool firstMouse =true;// timingfloat deltaTime =0.0f;float lastFrame =0.0f;intmain(){// 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);glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);// 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;}// tell stb_image.h to flip loaded texture's on the y-axis (before loading model).// stbi_set_flip_vertically_on_load(true);// configure global opengl state// -----------------------------glEnable(GL_DEPTH_TEST);// build and compile shaders// -------------------------
Shader shader("/Users/apathetically/CLionProjects/RenderTest/shader_file/9.2.geometry_shader.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/9.2.geometry_shader.fs","/Users/apathetically/CLionProjects/RenderTest/shader_file/9.2.geometry_shader.gs");// load models// -----------
Model nanosuit("/Users/apathetically/CLionProjects/RenderTest/resources/model/nanosuit/nanosuit.obj");// draw in wireframe//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);// render loop// -----------while(!glfwWindowShouldClose(window)){// per-frame time logic// --------------------float currentFrame =glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;// input// -----processInput(window);// render// ------glClearColor(0.1f,0.1f,0.1f,1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// configure transformation matrices
glm::mat4 projection = glm::perspective(glm::radians(45.0f),(float)SCR_WIDTH /(float)SCR_HEIGHT,1.0f,100.0f);
glm::mat4 view = camera.GetViewMatrix();
glm::mat4 model = glm::mat4(1.0f);// don't forget to enable shader before setting uniforms
shader.use();
shader.setMat4("projection", projection);
shader.setMat4("view", view);
shader.setMat4("model", model);// add time component to geometry shader in the form of a uniform
shader.setFloat("time",glfwGetTime());// draw model
nanosuit.Draw(shader);// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)// -------------------------------------------------------------------------------glfwSwapBuffers(window);glfwPollEvents();}// glfw: terminate, clearing all previously allocated GLFW resources.// ------------------------------------------------------------------glfwTerminate();return0;}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly// ---------------------------------------------------------------------------------------------------------voidprocessInput(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_A)== GLFW_PRESS)
camera.ProcessKeyboard(LEFT, deltaTime);if(glfwGetKey(window, GLFW_KEY_S)== GLFW_PRESS)
camera.ProcessKeyboard(BACKWARD, deltaTime);if(glfwGetKey(window, GLFW_KEY_D)== GLFW_PRESS)
camera.ProcessKeyboard(RIGHT, deltaTime);if(glfwGetKey(window, GLFW_KEY_E)== GLFW_PRESS)
camera.ProcessKeyboard(UP, deltaTime);if(glfwGetKey(window, GLFW_KEY_Q)== GLFW_PRESS)
camera.ProcessKeyboard(DOWN, deltaTime);}// glfw: whenever the window size changed (by OS or user resize) this callback function executes// ---------------------------------------------------------------------------------------------voidframebuffer_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// -------------------------------------------------------voidmouse_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 top
lastX = xpos;
lastY = ypos;
camera.ProcessMouseMovement(xoffset, yoffset);}// glfw: whenever the mouse scroll wheel scrolls, this callback is called// ----------------------------------------------------------------------voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset){
camera.ProcessMouseScroll(yoffset);}
几何着色器-毛发效果
#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"Camera.h"#include"Model.h"#include<iostream>voidframebuffer_size_callback(GLFWwindow* window,int width,int height);voidmouse_callback(GLFWwindow* window,double xpos,double ypos);voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset);voidprocessInput(GLFWwindow *window);// settingsconstunsignedint SCR_WIDTH =800;constunsignedint SCR_HEIGHT =600;// camera
Camera camera(glm::vec3(0.0f,0.0f,3.0f));float lastX = SCR_WIDTH /2.0f;float lastY = SCR_HEIGHT /2.0f;bool firstMouse =true;// timingfloat deltaTime =0.0f;float lastFrame =0.0f;intmain(){// 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);glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);// 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;}// tell stb_image.h to flip loaded texture's on the y-axis (before loading model).// stbi_set_flip_vertically_on_load(true);// configure global opengl state// -----------------------------glEnable(GL_DEPTH_TEST);// build and compile shaders// -------------------------
Shader shader("/Users/apathetically/CLionProjects/RenderTest/shader_file/9.3.default.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/9.3.default.fs");
Shader normalShader("/Users/apathetically/CLionProjects/RenderTest/shader_file/9.3.normal_visualization.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/9.3.normal_visualization.fs","/Users/apathetically/CLionProjects/RenderTest/shader_file/9.3.normal_visualization.gs");// load models// -----------
Model backpack("/Users/apathetically/CLionProjects/RenderTest/resources/model/nanosuit/nanosuit.obj");// draw in wireframe//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);// render loop// -----------while(!glfwWindowShouldClose(window)){// per-frame time logic// --------------------float currentFrame =glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;// input// -----processInput(window);// render// ------glClearColor(0.1f,0.1f,0.1f,1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// configure transformation matrices
glm::mat4 projection = glm::perspective(glm::radians(45.0f),(float)SCR_WIDTH /(float)SCR_HEIGHT,1.0f,100.0f);
glm::mat4 view = camera.GetViewMatrix();
glm::mat4 model = glm::mat4(1.0f);// don't forget to enable shader before setting uniforms
shader.use();
shader.setMat4("projection", projection);
shader.setMat4("view", view);
shader.setMat4("model", model);// draw model as usual
backpack.Draw(shader);// then draw model with normal visualizing geometry shader
normalShader.use();
normalShader.setMat4("projection", projection);
normalShader.setMat4("view", view);
normalShader.setMat4("model", model);
backpack.Draw(normalShader);// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)// -------------------------------------------------------------------------------glfwSwapBuffers(window);glfwPollEvents();}// glfw: terminate, clearing all previously allocated GLFW resources.// ------------------------------------------------------------------glfwTerminate();return0;}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly// ---------------------------------------------------------------------------------------------------------voidprocessInput(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_A)== GLFW_PRESS)
camera.ProcessKeyboard(LEFT, deltaTime);if(glfwGetKey(window, GLFW_KEY_S)== GLFW_PRESS)
camera.ProcessKeyboard(BACKWARD, deltaTime);if(glfwGetKey(window, GLFW_KEY_D)== GLFW_PRESS)
camera.ProcessKeyboard(RIGHT, deltaTime);if(glfwGetKey(window, GLFW_KEY_E)== GLFW_PRESS)
camera.ProcessKeyboard(UP, deltaTime);if(glfwGetKey(window, GLFW_KEY_Q)== GLFW_PRESS)
camera.ProcessKeyboard(DOWN, deltaTime);}// glfw: whenever the window size changed (by OS or user resize) this callback function executes// ---------------------------------------------------------------------------------------------voidframebuffer_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// -------------------------------------------------------voidmouse_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 top
lastX = xpos;
lastY = ypos;
camera.ProcessMouseMovement(xoffset, yoffset);}// glfw: whenever the mouse scroll wheel scrolls, this callback is called// ----------------------------------------------------------------------voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset){
camera.ProcessMouseScroll(yoffset);}
实例化四边形
#include<glad/glad.h>#include<GLFW/glfw3.h>#include"Shader.h"#include<iostream>voidframebuffer_size_callback(GLFWwindow* window,int width,int height);// settingsconstunsignedint SCR_WIDTH =800;constunsignedint SCR_HEIGHT =600;intmain(){// 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,"RenderTest",NULL,NULL);if(window ==NULL){
std::cout <<"Failed to create GLFW window"<< std::endl;glfwTerminate();return-1;}glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);// glad: load all OpenGL function pointers// ---------------------------------------if(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){
std::cout <<"Failed to initialize GLAD"<< std::endl;return-1;}// configure global opengl state// -----------------------------glEnable(GL_DEPTH_TEST);// build and compile shaders// -------------------------
Shader shader("/Users/apathetically/CLionProjects/RenderTest/shader_file/10.1.instancing.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/10.1.instancing.fs");// generate a list of 100 quad locations/translation-vectors// ---------------------------------------------------------
glm::vec2 translations[100];int index =0;float offset =0.1f;for(int y =-10;y <10;y +=2){for(int x =-10;x <10;x +=2){
glm::vec2 translation;
translation.x =(float)x /10.0f+ offset;
translation.y =(float)y /10.0f+ offset;
translations[index ++]= translation;}}// store instance data in an array buffer// --------------------------------------unsignedint instanceVBO;glGenBuffers(1,&instanceVBO);glBindBuffer(GL_ARRAY_BUFFER, instanceVBO);glBufferData(GL_ARRAY_BUFFER,sizeof(glm::vec2)*100,&translations[0], GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER,0);// set up vertex data (and buffer(s)) and configure vertex attributes// ------------------------------------------------------------------float quadVertices[]={// positions // colors-0.05f,0.05f,1.0f,0.0f,0.0f,0.05f,-0.05f,0.0f,1.0f,0.0f,-0.05f,-0.05f,0.0f,0.0f,1.0f,-0.05f,0.05f,1.0f,0.0f,0.0f,0.05f,-0.05f,0.0f,1.0f,0.0f,0.05f,0.05f,0.0f,1.0f,1.0f};unsignedint quadVAO, quadVBO;glGenVertexArrays(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,2, GL_FLOAT, GL_FALSE,5*sizeof(float),(void*)0);glEnableVertexAttribArray(1);glVertexAttribPointer(1,3, GL_FLOAT, GL_FALSE,5*sizeof(float),(void*)(2*sizeof(float)));// also set instance dataglEnableVertexAttribArray(2);glBindBuffer(GL_ARRAY_BUFFER, instanceVBO);// this attribute comes from a different vertex bufferglVertexAttribPointer(2,2, GL_FLOAT, GL_FALSE,2*sizeof(float),(void*)0);glBindBuffer(GL_ARRAY_BUFFER,0);glVertexAttribDivisor(2,1);// tell OpenGL this is an instanced vertex attribute.// render loop// -----------while(!glfwWindowShouldClose(window)){// render// ------glClearColor(0.1f,0.1f,0.1f,1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// draw 100 instanced quads
shader.use();glBindVertexArray(quadVAO);glDrawArraysInstanced(GL_TRIANGLES,0,6,100);// 100 triangles of 6 vertices each;glBindVertexArray(0);// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)// -------------------------------------------------------------------------------glfwSwapBuffers(window);glfwPollEvents();}// optional: de-allocate all resources once they've outlived their purpose:// ------------------------------------------------------------------------glDeleteVertexArrays(1,&quadVAO);glDeleteBuffers(1,&quadVBO);glfwTerminate();return0;}// glfw: whenever the window size changed (by OS or user resize) this callback function executes// ---------------------------------------------------------------------------------------------voidframebuffer_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);}
陨石带-未实例化
#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"Camera.h"#include"Model.h"#include<iostream>voidframebuffer_size_callback(GLFWwindow* window,int width,int height);voidmouse_callback(GLFWwindow* window,double xpos,double ypos);voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset);voidprocessInput(GLFWwindow *window);// settingsconstunsignedint SCR_WIDTH =800;constunsignedint SCR_HEIGHT =600;// camera
Camera camera(glm::vec3(0.0f,0.0f,55.0f));float lastX = SCR_WIDTH /2.0f;float lastY = SCR_HEIGHT /2.0f;bool firstMouse =true;// timingfloat deltaTime =0.0f;float lastFrame =0.0f;intmain(){// 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);glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);// 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;}// configure global opengl state// -----------------------------glEnable(GL_DEPTH_TEST);// build and compile shaders// -------------------------
Shader shader("/Users/apathetically/CLionProjects/RenderTest/shader_file/10.2.instancing.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/10.2.instancing.fs");// load models// -----------
Model planet("/Users/apathetically/CLionProjects/RenderTest/resources/model/planet/planet.obj");
Model rock("/Users/apathetically/CLionProjects/RenderTest/resources/model/rock/rock.obj");// generate a large list of semi-random model transformation matrices// ------------------------------------------------------------------unsignedint amount =1000;
glm::mat4* modelMatrices;
modelMatrices =new glm::mat4[amount];srand(glfwGetTime());// initialize random seedfloat radius =50.0;float offset =2.5f;for(unsignedint i =0; i < amount; i++){
glm::mat4 model = glm::mat4(1.0f);// 1. translation: displace along circle with 'radius' in range [-offset, offset]float angle =(float)i /(float)amount *360.0f;float displacement =(rand()%(int)(2* offset *100))/100.0f- offset;float x =sin(angle)* radius + displacement;
displacement =(rand()%(int)(2* offset *100))/100.0f- offset;float y = displacement *0.4f;// keep height of asteroid field smaller compared to width of x and z
displacement =(rand()%(int)(2* offset *100))/100.0f- offset;float z =cos(angle)* radius + displacement;
model = glm::translate(model, glm::vec3(x, y, z));// 2. scale: Scale between 0.05 and 0.25ffloat scale =(rand()%20)/100.0f+0.05;
model = glm::scale(model, glm::vec3(scale));// 3. rotation: add random rotation around a (semi)randomly picked rotation axis vectorfloat rotAngle =(rand()%360);
model = glm::rotate(model, rotAngle, glm::vec3(0.4f,0.6f,0.8f));// 4. now add to list of matrices
modelMatrices[i]= model;}// render loop// -----------while(!glfwWindowShouldClose(window)){// per-frame time logic// --------------------float currentFrame =glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;// input// -----processInput(window);// render// ------glClearColor(0.1f,0.1f,0.1f,1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// configure transformation matrices
glm::mat4 projection = glm::perspective(glm::radians(45.0f),(float)SCR_WIDTH /(float)SCR_HEIGHT,0.1f,1000.0f);
glm::mat4 view = camera.GetViewMatrix();
shader.use();
shader.setMat4("projection", projection);
shader.setMat4("view", view);// draw planet
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(0.0f,-3.0f,0.0f));
model = glm::scale(model, glm::vec3(4.0f,4.0f,4.0f));
shader.setMat4("model", model);
planet.Draw(shader);// draw meteoritesfor(unsignedint i =0; i < amount; i++){
shader.setMat4("model", modelMatrices[i]);
rock.Draw(shader);}// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)// -------------------------------------------------------------------------------glfwSwapBuffers(window);glfwPollEvents();}// glfw: terminate, clearing all previously allocated GLFW resources.// ------------------------------------------------------------------glfwTerminate();return0;}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly// ---------------------------------------------------------------------------------------------------------voidprocessInput(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_A)== GLFW_PRESS)
camera.ProcessKeyboard(LEFT, deltaTime);if(glfwGetKey(window, GLFW_KEY_S)== GLFW_PRESS)
camera.ProcessKeyboard(BACKWARD, deltaTime);if(glfwGetKey(window, GLFW_KEY_D)== GLFW_PRESS)
camera.ProcessKeyboard(RIGHT, deltaTime);if(glfwGetKey(window, GLFW_KEY_E)== GLFW_PRESS)
camera.ProcessKeyboard(UP, deltaTime);if(glfwGetKey(window, GLFW_KEY_Q)== GLFW_PRESS)
camera.ProcessKeyboard(DOWN, deltaTime);}// glfw: whenever the window size changed (by OS or user resize) this callback function executes// ---------------------------------------------------------------------------------------------voidframebuffer_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// -------------------------------------------------------voidmouse_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 top
lastX = xpos;
lastY = ypos;
camera.ProcessMouseMovement(xoffset, yoffset);}// glfw: whenever the mouse scroll wheel scrolls, this callback is called// ----------------------------------------------------------------------voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset){
camera.ProcessMouseScroll(yoffset);}
陨石带-实例化 (本机测试比非实例化还慢)
#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"Camera.h"#include"Model.h"#include<iostream>voidframebuffer_size_callback(GLFWwindow* window,int width,int height);voidmouse_callback(GLFWwindow* window,double xpos,double ypos);voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset);voidprocessInput(GLFWwindow *window);// settingsconstunsignedint SCR_WIDTH =800;constunsignedint SCR_HEIGHT =600;// camera
Camera camera(glm::vec3(0.0f,0.0f,55.0f));float lastX = SCR_WIDTH /2.0f;float lastY = SCR_HEIGHT /2.0f;bool firstMouse =true;// timingfloat deltaTime =0.0f;float lastFrame =0.0f;intmain(){// 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);glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);// 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;}// configure global opengl state// -----------------------------glEnable(GL_DEPTH_TEST);// build and compile shaders// -------------------------
Shader planetShader("/Users/apathetically/CLionProjects/RenderTest/shader_file/10.2.instancing.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/10.2.instancing.fs");
Shader asteroidShader("/Users/apathetically/CLionProjects/RenderTest/shader_file/10.3.asteroids.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/10.3.asteroids.fs");// load models// -----------
Model planet("/Users/apathetically/CLionProjects/RenderTest/resources/model/planet/planet.obj");
Model rock("/Users/apathetically/CLionProjects/RenderTest/resources/model/rock/rock.obj");// generate a large list of semi-random model transformation matrices// ------------------------------------------------------------------unsignedint amount =10000;
glm::mat4* modelMatrices;
modelMatrices =new glm::mat4[amount];srand(glfwGetTime());// initialize random seedfloat radius =150.0;float offset =25f;for(unsignedint i =0; i < amount; i++){
glm::mat4 model = glm::mat4(1.0f);// 1. translation: displace along circle with 'radius' in range [-offset, offset]float angle =(float)i /(float)amount *360.0f;float displacement =(rand()%(int)(2* offset *100))/100.0f- offset;float x =sin(angle)* radius + displacement;
displacement =(rand()%(int)(2* offset *100))/100.0f- offset;float y = displacement *0.4f;// keep height of asteroid field smaller compared to width of x and z
displacement =(rand()%(int)(2* offset *100))/100.0f- offset;float z =cos(angle)* radius + displacement;
model = glm::translate(model, glm::vec3(x, y, z));// 2. scale: Scale between 0.05 and 0.25ffloat scale =(rand()%20)/100.0f+0.05;
model = glm::scale(model, glm::vec3(scale));// 3. rotation: add random rotation around a (semi)randomly picked rotation axis vectorfloat rotAngle =(rand()%360);
model = glm::rotate(model, rotAngle, glm::vec3(0.4f,0.6f,0.8f));// 4. now add to list of matrices
modelMatrices[i]= model;}// configure instanced array// -------------------------unsignedint buffer;glGenBuffers(1,&buffer);glBindBuffer(GL_ARRAY_BUFFER, buffer);glBufferData(GL_ARRAY_BUFFER, amount *sizeof(glm::mat4),&modelMatrices[0], GL_STATIC_DRAW);// set transformation matrices as an instance vertex attribute (with divisor 1)// note: we're cheating a little by taking the, now publicly declared, VAO of the model's mesh(es) and adding new vertexAttribPointers// normally you'd want to do this in a more organized fashion, but for learning purposes this will do.// -----------------------------------------------------------------------------------------------------------------------------------for(unsignedint i =0; i < rock.meshes.size(); i++){unsignedint VAO = rock.meshes[i].VAO;glBindVertexArray(VAO);// set attribute pointers for matrix (4 times vec4)glEnableVertexAttribArray(3);glVertexAttribPointer(3,4, GL_FLOAT, GL_FALSE,sizeof(glm::mat4),(void*)0);glEnableVertexAttribArray(4);glVertexAttribPointer(4,4, GL_FLOAT, GL_FALSE,sizeof(glm::mat4),(void*)(sizeof(glm::vec4)));glEnableVertexAttribArray(5);glVertexAttribPointer(5,4, GL_FLOAT, GL_FALSE,sizeof(glm::mat4),(void*)(2*sizeof(glm::vec4)));glEnableVertexAttribArray(6);glVertexAttribPointer(6,4, GL_FLOAT, GL_FALSE,sizeof(glm::mat4),(void*)(3*sizeof(glm::vec4)));glVertexAttribDivisor(3,1);glVertexAttribDivisor(4,1);glVertexAttribDivisor(5,1);glVertexAttribDivisor(6,1);glBindVertexArray(0);}// render loop// -----------while(!glfwWindowShouldClose(window)){// per-frame time logic// --------------------float currentFrame =glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;// input// -----processInput(window);// render// ------glClearColor(0.1f,0.1f,0.1f,1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// configure transformation matrices
glm::mat4 projection = glm::perspective(glm::radians(45.0f),(float)SCR_WIDTH /(float)SCR_HEIGHT,0.1f,1000.0f);
glm::mat4 view = camera.GetViewMatrix();
asteroidShader.use();
asteroidShader.setMat4("projection", projection);
asteroidShader.setMat4("view", view);
planetShader.use();
planetShader.setMat4("projection", projection);
planetShader.setMat4("view", view);// draw planet
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(0.0f,-3.0f,0.0f));
model = glm::scale(model, glm::vec3(4.0f,4.0f,4.0f));
planetShader.setMat4("model", model);
planet.Draw(planetShader);// draw meteorites
asteroidShader.use();
asteroidShader.setInt("texture_diffuse1",0);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, rock.textures_loaded[0].id);// note: we also made the textures_loaded vector public (instead of private) from the model class.for(unsignedint i =0; i < rock.meshes.size(); i++){glBindVertexArray(rock.meshes[i].VAO);glDrawElementsInstanced(GL_TRIANGLES, rock.meshes[i].indices.size(), GL_UNSIGNED_INT,0, amount);glBindVertexArray(0);}// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)// -------------------------------------------------------------------------------glfwSwapBuffers(window);glfwPollEvents();}// glfw: terminate, clearing all previously allocated GLFW resources.// ------------------------------------------------------------------glfwTerminate();return0;}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly// ---------------------------------------------------------------------------------------------------------voidprocessInput(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_A)== GLFW_PRESS)
camera.ProcessKeyboard(LEFT, deltaTime);if(glfwGetKey(window, GLFW_KEY_S)== GLFW_PRESS)
camera.ProcessKeyboard(BACKWARD, deltaTime);if(glfwGetKey(window, GLFW_KEY_D)== GLFW_PRESS)
camera.ProcessKeyboard(RIGHT, deltaTime);if(glfwGetKey(window, GLFW_KEY_E)== GLFW_PRESS)
camera.ProcessKeyboard(UP, deltaTime);if(glfwGetKey(window, GLFW_KEY_Q)== GLFW_PRESS)
camera.ProcessKeyboard(DOWN, deltaTime);}// glfw: whenever the window size changed (by OS or user resize) this callback function executes// ---------------------------------------------------------------------------------------------voidframebuffer_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// -------------------------------------------------------voidmouse_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 top
lastX = xpos;
lastY = ypos;
camera.ProcessMouseMovement(xoffset, yoffset);}// glfw: whenever the mouse scroll wheel scrolls, this callback is called// ----------------------------------------------------------------------voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset){
camera.ProcessMouseScroll(yoffset);}
抗锯齿
#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"Camera.h"#include"Model.h"#include<iostream>voidframebuffer_size_callback(GLFWwindow* window,int width,int height);voidmouse_callback(GLFWwindow* window,double xpos,double ypos);voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset);voidprocessInput(GLFWwindow *window);// settingsconstunsignedint SCR_WIDTH =800;constunsignedint SCR_HEIGHT =600;// camera
Camera camera(glm::vec3(0.0f,0.0f,55.0f));float lastX = SCR_WIDTH /2.0f;float lastY = SCR_HEIGHT /2.0f;bool firstMouse =true;// timingfloat deltaTime =0.0f;float lastFrame =0.0f;intmain(){// 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);glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);glfwWindowHint(GLFW_SAMPLES,4);// 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;}// configure global opengl state// -----------------------------glEnable(GL_DEPTH_TEST);glEnable(GL_MULTISAMPLE);// build and compile shaders// -------------------------
Shader shader("/Users/apathetically/CLionProjects/RenderTest/shader_file/10.2.instancing.vs","/Users/apathetically/CLionProjects/RenderTest/shader_file/10.2.instancing.fs");// load models// -----------
Model planet("/Users/apathetically/CLionProjects/RenderTest/resources/model/planet/planet.obj");
Model rock("/Users/apathetically/CLionProjects/RenderTest/resources/model/rock/rock.obj");// generate a large list of semi-random model transformation matrices// ------------------------------------------------------------------unsignedint amount =10000;
glm::mat4* modelMatrices;
modelMatrices =new glm::mat4[amount];srand(glfwGetTime());// initialize random seedfloat radius =150.0;float offset =25.0f;for(unsignedint i =0; i < amount; i++){
glm::mat4 model = glm::mat4(1.0f);// 1. translation: displace along circle with 'radius' in range [-offset, offset]float angle =(float)i /(float)amount *360.0f;float displacement =(rand()%(int)(2* offset *100))/100.0f- offset;float x =sin(angle)* radius + displacement;
displacement =(rand()%(int)(2* offset *100))/100.0f- offset;float y = displacement *0.4f;// keep height of asteroid field smaller compared to width of x and z
displacement =(rand()%(int)(2* offset *100))/100.0f- offset;float z =cos(angle)* radius + displacement;
model = glm::translate(model, glm::vec3(x, y, z));// 2. scale: Scale between 0.05 and 0.25ffloat scale =(rand()%20)/100.0f+0.05;
model = glm::scale(model, glm::vec3(scale));// 3. rotation: add random rotation around a (semi)randomly picked rotation axis vectorfloat rotAngle =(rand()%360);
model = glm::rotate(model, rotAngle, glm::vec3(0.4f,0.6f,0.8f));// 4. now add to list of matrices
modelMatrices[i]= model;}// render loop// -----------while(!glfwWindowShouldClose(window)){// per-frame time logic// --------------------float currentFrame =glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;// input// -----processInput(window);// render// ------glClearColor(0.1f,0.1f,0.1f,1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// configure transformation matrices
glm::mat4 projection = glm::perspective(glm::radians(45.0f),(float)SCR_WIDTH /(float)SCR_HEIGHT,0.1f,1000.0f);
glm::mat4 view = camera.GetViewMatrix();
shader.use();
shader.setMat4("projection", projection);
shader.setMat4("view", view);// draw planet
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(0.0f,-3.0f,0.0f));
model = glm::scale(model, glm::vec3(4.0f,4.0f,4.0f));
shader.setMat4("model", model);
planet.Draw(shader);// draw meteoritesfor(unsignedint i =0; i < amount; i++){
shader.setMat4("model", modelMatrices[i]);
rock.Draw(shader);}// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)// -------------------------------------------------------------------------------glfwSwapBuffers(window);glfwPollEvents();}// glfw: terminate, clearing all previously allocated GLFW resources.// ------------------------------------------------------------------glfwTerminate();return0;}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly// ---------------------------------------------------------------------------------------------------------voidprocessInput(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_A)== GLFW_PRESS)
camera.ProcessKeyboard(LEFT, deltaTime);if(glfwGetKey(window, GLFW_KEY_S)== GLFW_PRESS)
camera.ProcessKeyboard(BACKWARD, deltaTime);if(glfwGetKey(window, GLFW_KEY_D)== GLFW_PRESS)
camera.ProcessKeyboard(RIGHT, deltaTime);if(glfwGetKey(window, GLFW_KEY_E)== GLFW_PRESS)
camera.ProcessKeyboard(UP, deltaTime);if(glfwGetKey(window, GLFW_KEY_Q)== GLFW_PRESS)
camera.ProcessKeyboard(DOWN, deltaTime);}// glfw: whenever the window size changed (by OS or user resize) this callback function executes// ---------------------------------------------------------------------------------------------voidframebuffer_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// -------------------------------------------------------voidmouse_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 top
lastX = xpos;
lastY = ypos;
camera.ProcessMouseMovement(xoffset, yoffset);}// glfw: whenever the mouse scroll wheel scrolls, this callback is called// ----------------------------------------------------------------------voidscroll_callback(GLFWwindow* window,double xoffset,double yoffset){
camera.ProcessMouseScroll(yoffset);}