你能像教程一开始那样,定义相应的材质来模拟现实世界的物体吗?
分享一个银材质的箱子:

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
