你能像教程一开始那样,定义相应的材质来模拟现实世界的物体吗?
分享一个银材质的箱子:
1 // silver material 2 lightingShader.setVec3("material.ambient", 0.19225,0.19225,0.19225); 3 lightingShader.setVec3("material.diffuse", 0.50754 ,0.50754, 0.50754); 4 lightingShader.setVec3("material.specular", 0.508273, 0.508273 ,0.508273); 5 lightingShader.setFloat("material.shininess", 0.4 * 128);
完整代码:
1 #include <glad/glad.h> 2 #include <GLFW/glfw3.h> 3 #define STB_IMAGE_IMPLEMENTATION 4 #include <stb/stb_image.h> 5 6 #include <glm/glm.hpp> 7 #include <glm/gtc/matrix_transform.hpp> 8 #include <glm/gtc/type_ptr.hpp> 9 10 #include <Shader/shader.h> 11 #include <Camera/camera.h> 12 13 #include <iostream> 14 15 void framebuffer_size_callback(GLFWwindow* window, int width, int height); 16 void mouse_callback(GLFWwindow* window, double xpos, double ypos); 17 void scroll_callback(GLFWwindow* window, double xoffset, double yoffset); 18 void processInput(GLFWwindow *window); 19 20 // settings 21 const unsigned int SCR_WIDTH = 800; 22 const unsigned int SCR_HEIGHT = 600; 23 24 // camera 25 Camera camera(glm::vec3(0.0f, 0.0f, 3.0f)); 26 float lastX = SCR_WIDTH / 2.0f; 27 float lastY = SCR_HEIGHT / 2.0f; 28 bool firstMouse = true; 29 30 //timeing 31 float deltaTime = 0.0f; // 当前帧与上一帧的时间差 32 float lastFrame = 0.0f; // 上一帧的时间 33 34 // lighting 35 glm::vec3 lightPos(1.2f, 1.0f, 2.0f); 36 37 int main() 38 { 39 // glfw: initialize and configure 40 // ------------------------------ 41 glfwInit(); 42 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 43 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 44 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 45 46 #ifdef __APPLE__ 47 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X 48 #endif 49 50 // glfw window creation 51 // -------------------- 52 GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL); 53 if (window == NULL) 54 { 55 std::cout << "Failed to create GLFW window" << std::endl; 56 glfwTerminate(); 57 return -1; 58 } 59 glfwMakeContextCurrent(window); 60 glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); 61 glfwSetCursorPosCallback(window, mouse_callback); 62 glfwSetScrollCallback(window, scroll_callback); 63 64 // tell GLFW to capture our mouse 65 glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); 66 67 // glad: load all OpenGL function pointers 68 // --------------------------------------- 69 if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) 70 { 71 std::cout << "Failed to initialize GLAD" << std::endl; 72 return -1; 73 } 74 75 // configure global opengl state 76 // ----------------------------- 77 glEnable(GL_DEPTH_TEST); 78 79 // build and compile our shader zprogram 80 // ------------------------------------ 81 Shader lightingShader("colors.vs", "colors.fs"); 82 Shader lampShader("lamp.vs", "lamp.fs"); 83 84 // set up vertex data (and buffer(s)) and configure vertex attributes 85 // ------------------------------------------------------------------ 86 float vertices[] = { 87 -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 88 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 89 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 90 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 91 -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 92 -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 93 94 -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 95 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 96 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 97 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 98 -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 99 -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 100 101 -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 102 -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 103 -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 104 -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 105 -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 106 -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 107 108 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 109 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 110 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 111 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 112 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 113 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 114 115 -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 116 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 117 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 118 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 119 -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 120 -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 121 122 -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 123 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 124 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 125 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 126 -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 127 -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f 128 }; 129 130 unsigned int VBO, cubeVAO; 131 glGenVertexArrays(1, &cubeVAO); 132 glGenBuffers(1, &VBO); 133 134 glBindVertexArray(cubeVAO); 135 136 glBindBuffer(GL_ARRAY_BUFFER, VBO); 137 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 138 139 // position attribute 140 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); 141 glEnableVertexAttribArray(0); 142 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float))); 143 glEnableVertexAttribArray(1); 144 145 unsigned int lightVAO; 146 glGenVertexArrays(1, &lightVAO); 147 glBindVertexArray(lightVAO); 148 // 只需要绑定VBO不用再次设置VBO的数据,因为箱子的VBO数据中已经包含了正确的立方体顶点数据 149 glBindBuffer(GL_ARRAY_BUFFER, VBO); 150 // 设置灯立方体的顶点属性(对我们的灯来说仅仅只有位置数据) 151 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); 152 glEnableVertexAttribArray(0); 153 154 // pass projection matrix to shader (as projection matrix rarely changes there's no need to do this per frame) 155 // ----------------------------------------------------------------------------------------------------------- 156 //glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f); 157 //ourShader.setMat4("projection", projection); 158 159 // render loop 160 // ----------- 161 while (!glfwWindowShouldClose(window)) 162 { 163 float currentFrame = glfwGetTime(); 164 deltaTime = currentFrame - lastFrame; 165 lastFrame = currentFrame; 166 167 // input 168 // ----- 169 processInput(window); 170 171 // render 172 // ------ 173 glClearColor(0.1f, 0.1f, 0.1f, 1.0f); 174 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 175 176 // activate shader 177 lightingShader.use(); 178 lightingShader.setVec3("objectColor", 1.0f, 0.5f, 0.31f); 179 lightingShader.setVec3("lightColor", 1.0f, 1.0f, 1.0f); 180 lightingShader.setVec3("lightPos", lightPos); 181 lightingShader.setVec3("viewPos", camera.Position); 182 183 //lightingShader.setVec3("material.ambient", 1.0f, 0.5f, 0.31f); 184 //lightingShader.setVec3("material.diffuse", 1.0f, 0.5f, 0.31f); 185 //lightingShader.setVec3("material.specular", 0.5f, 0.5f, 0.5f); 186 //lightingShader.setFloat("material.shininess", 32.0f); 187 lightingShader.setVec3("material.ambient", 0.19225, 0.19225, 0.19225); 188 lightingShader.setVec3("material.diffuse", 0.50754, 0.50754, 0.50754); 189 lightingShader.setVec3("material.specular", 0.508273, 0.508273, 0.508273); 190 lightingShader.setFloat("material.shininess", 0.4 * 128); 191 192 lightingShader.setVec3("light.ambient", 0.2f, 0.2f, 0.2f); 193 lightingShader.setVec3("light.diffuse", 0.5f, 0.5f, 0.5f); // 将光照调暗了一些以搭配场景 194 /* 195 glm::vec3 lightColor; 196 lightColor.x = sin(glfwGetTime() * 2.0f); 197 lightColor.y = sin(glfwGetTime() * 0.7f); 198 lightColor.z = sin(glfwGetTime() * 1.3f); 199 200 glm::vec3 diffuseColor = lightColor * glm::vec3(0.5f); // 降低影响 201 glm::vec3 ambientColor = diffuseColor * glm::vec3(0.2f); // 很低的影响 202 203 lightingShader.setVec3("light.ambient", ambientColor); 204 lightingShader.setVec3("light.diffuse", diffuseColor); 205 */ 206 lightingShader.setVec3("light.specular", 1.0f, 1.0f, 1.0f); 207 208 // pass projection matrix to shader (note that in this case it could change every frame) 209 glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f); 210 lightingShader.setMat4("projection", projection); 211 212 // camera/view transformation 213 glm::mat4 view = camera.GetViewMatrix(); 214 lightingShader.setMat4("view", view); 215 216 glm::mat4 model = glm::mat4(1.0); 217 lightingShader.setMat4("model", model); 218 // render boxes 219 glBindVertexArray(cubeVAO); 220 glDrawArrays(GL_TRIANGLES, 0, 36); 221 222 lampShader.use(); 223 lampShader.setMat4("projection", projection); 224 lampShader.setMat4("view", view); 225 model = glm::mat4(1.0f); 226 float r = 5.0f; 227 float x = sin(glfwGetTime())*r; 228 float z = cos(glfwGetTime())*r; 229 lightPos.x = x; lightPos.z = z; 230 model = glm::translate(model, lightPos); 231 model = glm::scale(model, glm::vec3(0.2f)); 232 lampShader.setMat4("model", model); 233 234 glBindVertexArray(lightVAO); 235 glDrawArrays(GL_TRIANGLES, 0, 36); 236 237 // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.) 238 // ------------------------------------------------------------------------------- 239 glfwSwapBuffers(window); 240 glfwPollEvents(); 241 } 242 243 // optional: de-allocate all resources once they've outlived their purpose: 244 // ------------------------------------------------------------------------ 245 glDeleteVertexArrays(1, &cubeVAO); 246 glDeleteVertexArrays(1, &lightVAO); 247 glDeleteBuffers(1, &VBO); 248 249 // glfw: terminate, clearing all previously allocated GLFW resources. 250 // ------------------------------------------------------------------ 251 glfwTerminate(); 252 return 0; 253 } 254 255 // process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly 256 // --------------------------------------------------------------------------------------------------------- 257 void processInput(GLFWwindow *window) 258 { 259 if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) 260 glfwSetWindowShouldClose(window, true); 261 262 if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) 263 camera.ProcessKeyboard(FORWARD, deltaTime); 264 if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) 265 camera.ProcessKeyboard(BACKWARD, deltaTime); 266 if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) 267 camera.ProcessKeyboard(LEFT, deltaTime); 268 if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) 269 camera.ProcessKeyboard(RIGHT, deltaTime); 270 } 271 272 // glfw: whenever the window size changed (by OS or user resize) this callback function executes 273 // --------------------------------------------------------------------------------------------- 274 void framebuffer_size_callback(GLFWwindow* window, int width, int height) 275 { 276 // make sure the viewport matches the new window dimensions; note that width and 277 // height will be significantly larger than specified on retina displays. 278 glViewport(0, 0, width, height); 279 } 280 281 void mouse_callback(GLFWwindow* window, double xpos, double ypos){ 282 if (firstMouse) 283 { 284 lastX = xpos; 285 lastY = ypos; 286 firstMouse = false; 287 } 288 289 float xoffset = xpos - lastX; 290 float yoffset = lastY - ypos; 291 //std::cout << ypos << std::endl; 292 lastX = xpos; 293 lastY = ypos; 294 295 camera.ProcessMouseMovement(xoffset, yoffset); 296 } 297 298 // glfw: whenever the mouse scroll wheel scrolls, this callback is called 299 // ---------------------------------------------------------------------- 300 void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) 301 { 302 camera.ProcessMouseScroll(yoffset); 303 }
2019/11/30