Textures_练习四
使用一个uniform变量作为mix函数的第三个参数来改变两个纹理可见度,使用上和下键来改变箱子或笑脸的可见度
fs.in
1 #version 330 core 2 out vec4 FragColor; 3 4 in vec3 ourColor; 5 in vec2 TexCoord; 6 7 // texture samplers 8 uniform sampler2D texture1; 9 uniform sampler2D texture2; 10 uniform float rate; 11 12 void main() 13 { 14 // linearly interpolate between both textures (80% container, 20% awesomeface) 15 FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), rate); 16 }
main函数
1 #include <glad/glad.h> 2 #include <GLFW/glfw3.h> 3 #define STB_IMAGE_IMPLEMENTATION 4 #include <stb/stb_image.h> 5 6 #include <Shader/shader.h> 7 8 #include <iostream> 9 10 void framebuffer_size_callback(GLFWwindow* window, int width, int height); 11 void processInput(GLFWwindow *window); 12 13 // settings 14 const unsigned int SCR_WIDTH = 800; 15 const unsigned int SCR_HEIGHT = 600; 16 17 float rate = 0.2f; 18 19 int main() 20 { 21 // glfw: initialize and configure 22 // ------------------------------ 23 glfwInit(); 24 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 25 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 26 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 27 28 #ifdef __APPLE__ 29 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X 30 #endif 31 32 // glfw window creation 33 // -------------------- 34 GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL); 35 if (window == NULL) 36 { 37 std::cout << "Failed to create GLFW window" << std::endl; 38 glfwTerminate(); 39 return -1; 40 } 41 glfwMakeContextCurrent(window); 42 glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); 43 44 // glad: load all OpenGL function pointers 45 // --------------------------------------- 46 if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) 47 { 48 std::cout << "Failed to initialize GLAD" << std::endl; 49 return -1; 50 } 51 52 // build and compile our shader zprogram 53 // ------------------------------------ 54 Shader ourShader("vs.in", "fs.in"); 55 56 // set up vertex data (and buffer(s)) and configure vertex attributes 57 // ------------------------------------------------------------------ 58 float vertices[] = { 59 // positions // colors // texture coords 60 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right 61 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right 62 -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom left 63 -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left 64 }; 65 unsigned int indices[] = { 66 0, 1, 3, // first triangle 67 1, 2, 3 // second triangle 68 }; 69 unsigned int VBO, VAO, EBO; 70 glGenVertexArrays(1, &VAO); 71 glGenBuffers(1, &VBO); 72 glGenBuffers(1, &EBO); 73 74 glBindVertexArray(VAO); 75 76 glBindBuffer(GL_ARRAY_BUFFER, VBO); 77 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 78 79 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); 80 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); 81 82 // position attribute 83 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0); 84 glEnableVertexAttribArray(0); 85 // color attribute 86 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float))); 87 glEnableVertexAttribArray(1); 88 // texture coord attribute 89 glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float))); 90 glEnableVertexAttribArray(2); 91 92 93 // load and create a texture 94 // ------------------------- 95 unsigned int texture1, texture2; 96 // texture 1 97 // --------- 98 glGenTextures(1, &texture1); 99 glBindTexture(GL_TEXTURE_2D, texture1); 100 // set the texture wrapping parameters 101 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method) 102 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 103 // set texture filtering parameters 104 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 105 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 106 // load image, create texture and generate mipmaps 107 int width, height, nrChannels; 108 stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis. 109 // The FileSystem::getPath(...) is part of the GitHub repository so we can find files on any IDE/platform; replace it with your own image path. 110 unsigned char *data = stbi_load("container.jpg", &width, &height, &nrChannels, 0); 111 if (data) 112 { 113 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); 114 glGenerateMipmap(GL_TEXTURE_2D); 115 } 116 else 117 { 118 std::cout << "Failed to load texture" << std::endl; 119 } 120 stbi_image_free(data); 121 // texture 2 122 // --------- 123 glGenTextures(1, &texture2); 124 glBindTexture(GL_TEXTURE_2D, texture2); 125 // set the texture wrapping parameters 126 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method) 127 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 128 // set texture filtering parameters 129 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 130 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 131 // load image, create texture and generate mipmaps 132 data = stbi_load("awesomeface.png", &width, &height, &nrChannels, 0); 133 if (data) 134 { 135 // note that the awesomeface.png has transparency and thus an alpha channel, so make sure to tell OpenGL the data type is of GL_RGBA 136 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); 137 glGenerateMipmap(GL_TEXTURE_2D); 138 } 139 else 140 { 141 std::cout << "Failed to load texture" << std::endl; 142 } 143 stbi_image_free(data); 144 145 // tell opengl for each sampler to which texture unit it belongs to (only has to be done once) 146 // ------------------------------------------------------------------------------------------- 147 ourShader.use(); // don't forget to activate/use the shader before setting uniforms! 148 // either set it manually like so: 149 glUniform1i(glGetUniformLocation(ourShader.ID, "texture1"), 0); 150 // or set it via the texture class 151 ourShader.setInt("texture2", 1); 152 153 154 155 // render loop 156 // ----------- 157 while (!glfwWindowShouldClose(window)) 158 { 159 // input 160 // ----- 161 processInput(window); 162 163 // render 164 // ------ 165 glClearColor(0.2f, 0.3f, 0.3f, 1.0f); 166 glClear(GL_COLOR_BUFFER_BIT); 167 168 // bind textures on corresponding texture units 169 glActiveTexture(GL_TEXTURE0); 170 glBindTexture(GL_TEXTURE_2D, texture1); 171 glActiveTexture(GL_TEXTURE1); 172 glBindTexture(GL_TEXTURE_2D, texture2); 173 174 // render container 175 ourShader.use(); 176 ourShader.setFloat("rate", rate); 177 glBindVertexArray(VAO); 178 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); 179 180 // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.) 181 // ------------------------------------------------------------------------------- 182 glfwSwapBuffers(window); 183 glfwPollEvents(); 184 } 185 186 // optional: de-allocate all resources once they've outlived their purpose: 187 // ------------------------------------------------------------------------ 188 glDeleteVertexArrays(1, &VAO); 189 glDeleteBuffers(1, &VBO); 190 glDeleteBuffers(1, &EBO); 191 192 // glfw: terminate, clearing all previously allocated GLFW resources. 193 // ------------------------------------------------------------------ 194 glfwTerminate(); 195 return 0; 196 } 197 198 // process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly 199 // --------------------------------------------------------------------------------------------------------- 200 void processInput(GLFWwindow *window) 201 { 202 if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) 203 glfwSetWindowShouldClose(window, true); 204 if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS){ 205 rate += 0.001f; 206 if (rate > 1.0f)rate = 1.0f; 207 } 208 if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS){ 209 rate -= 0.001f; 210 if (rate < 0.0f)rate = 0.0f; 211 } 212 } 213 214 // glfw: whenever the window size changed (by OS or user resize) this callback function executes 215 // --------------------------------------------------------------------------------------------- 216 void framebuffer_size_callback(GLFWwindow* window, int width, int height) 217 { 218 // make sure the viewport matches the new window dimensions; note that width and 219 // height will be significantly larger than specified on retina displays. 220 glViewport(0, 0, width, height); 221 }
2019/11/27