高级openg 混合,一个完整程序
1.当片段着色器处理完一个片段之后,模板测试(stencil test)会开始执行,和深度测试一样,它也可能会丢弃片段,接下来,被保留的片段会进入深度测试
2.每个窗口库都需要为你配置一个模板缓冲,但是GLFW这个窗口库会自动做这件事,所以不用告诉GLFW来创建一个模板缓冲
3.场景中的片段将只会在片段的模板值为1的时候被渲染,其他的都被丢弃了
启用模板缓冲的写入
渲染物体,更新模板缓冲的内容
禁用模板缓冲的写入
渲染其他物体,这次根据模板缓冲的内容丢弃特定的片段
用来配置模板缓冲的两个函数,glStencilFunc和glStencilOp
glStencilFunc(GLenum func, GLint ref, GLuint mash)一共包含三个参数:
func:设置模板测试函数(Stencil Test Function),这个测试函数将会应用到已存储的的模板值上和GLstenciFunc函数的ref值上,
可用的选项有:GL_NEVER/ GL_LESS/ GL_LEQUAL / GL_GREATER / GL_AEAUAL / GL_EQUAL / GL_NOTEQUAL和 GL_ALWAYS
ref:设置了模板测试的参考值(Reference Value), 模板缓冲的内容将会与这个值进行比较
mask:设置一个掩码,它将会与参考值和村初值在测试比较他们之前进行与(and)运算,初识情况下所有为都为1
但是glStencilFunc只描述了OpenGL应该对模板缓冲内容做什么,而不是我们应该如何更新缓冲,所以就需要glStencilOp这个函数了
glStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass)一共包含三个选项,我们能够设置每个选项应该采取的行为
sfail:模板测试失败是采取的行为
dpfail:模板测试通过,但深度测试失败采取的行为
dppass:模板测试和深度测试都通过时采取的行为
1 /**2 * glBlendFunc混合两种颜色的函数3 *glBlendFunc(GLenum sfactor, GLenum dfactor)函数接受两个参数,来设置源和目标因子4 *常数颜色向量Cconstan可以通过glBlendColor函数来另外设置*5 *glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);6 *也可以使用glBlendFuncSeparate为RGB和alpha通道分别设置不同的选项7 * glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_GL_ZERO);8 *glBlendEquation(GLenum mode)允许我们设置运算符9 *GL_FUNC_ADD:默认选项,将两个分量相加,Cr = S + D10 *GL_FUNC_SUBTRACT = S - D11 *GL_FUNC_REVERSE_SUBTRACT,将两个分量向减,但顺序相反*/12 13 /**14 *当绘制一个有不透明和透明物体的场景的时候,大体的原则如下:15 *1.先绘制所有不透明的物体。16 *2.对所有透明的物体排序。17 *3.按顺序绘制所有透明的物体。**/18 19 20 21 #include <iostream>22 #include <vector>23 #include <map>24 25 using namespace std;26 #define GLEW_STATIC27 28 #include <GL/glew.h>29 #include <GLFW/glfw3.h>30 31 #include "stb_image.h"32 33 #include <glm/glm.hpp>34 #include <glm/gtc/matrix_transform.hpp>35 #include <glm/gtc/type_ptr.hpp>36 37 #include "Shader.h"38 #include "camera.h"39 //#include "Model.h"40 41 void framebuffer_size_callback(GLFWwindow* window, int width, int height);42 void mouse_callback(GLFWwindow* window, double xpos, double ypos);43 void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);44 void processInput(GLFWwindow* window);45 unsigned int loadTexture(const char *path);46 47 //setting48 const unsigned int SCR_WIDTH = 800;49 const unsigned int SCR_HEIGHT = 600;50 51 //camera52 Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));53 float lastX = (float)SCR_WIDTH / 2;54 float lastY = (float)SCR_HEIGHT / 2;55 bool firstMouse = true;56 57 //timing58 float deltaTime = 0.0f;59 float lastFrame = 0.0f;60 61 int main()62 {63 glfwInit();64 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);65 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);66 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);67 68 GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LEARNOPENGL", NULL, NULL);69 if (window == NULL)70 {71 std::cout << "Failed to create window!" << std::endl;72 glfwTerminate();73 return -1;74 }75 glfwMakeContextCurrent(window);76 glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);77 glfwSetCursorPosCallback(window, mouse_callback);78 glfwSetScrollCallback(window, scroll_callback);79 80 //tell GLFW to capture our mouse81 glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);82 83 glewExperimental = GL_TRUE;84 if (glewInit() != GLEW_OK)85 {86 std::cout << "Failed to initialize GLEW!" << std::endl;87 return -1;88 }89 90 ////configure global opengl state91 //glEnable(GL_DEPTH_TEST); //启用深度测试,默认情况下是禁用的92 //glDepthFunc(GL_LESS); //always pass the depth test(same effect as glDisable(GL_DEPTH_TEST)//禁用深度测试,永远都通过深度测试93 ////glDepthMask(GL_FALSE); //深度掩码,可以禁用深度缓冲的写入94 95 //glEnable(GL_STENCIL_TEST);96 ////glStencilMask(0x00); //位掩码, 每个模板值都为0, 每一位在写入模板缓冲时都会变成0(禁用写入)97 //glStencilMask(0xff); //每个模板值都为1,每一位写入模板缓冲时都保持原样98 99 //glStencilFunc(GL_EQUAL, 1, 0xFF); //只要一个片段的模板值等于参考值1,片段将会通过测试并被绘制,否则会被被丢弃
100 //glStencilOp(GL_INCR_WRAP, GL_INCR_WRAP, GL_INCR_WRAP);//默认情况下,glStencilOp是设置为这样的,所以不论任何测试的结果是如何,模板缓冲都会保留它的值
101 ////默认的行为不会更新模板缓冲,所以如果你想写入模板缓冲的话,至少对其中一个选项设置不同的值
102 glEnable(GL_DEPTH_TEST);
103 glDepthFunc(GL_LESS);
104 glEnable(GL_BLEND); //启用混合
105 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
106
107 //build and compile shaders
108 Shader shader("E:\\C++\\HigherOpenGL\\1.2.1ver1.txt", "E:\\C++\\HigherOpenGL\\1.3.2Frag1.txt");
109
110 float cubeVertices[] = {
111 //position //texture Coords
112 -0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
113 0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
114 0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
115 0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
116 -0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
117 -0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
118
119 -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
120 0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
121 0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
122 0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
123 -0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
124 -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
125
126 -0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
127 -0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
128 -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
129 -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
130 -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
131 -0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
132
133 0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
134 0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
135 0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
136 0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
137 0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
138 0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
139
140 -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
141 0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
142 0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
143 0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
144 -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
145 -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
146
147 -0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
148 0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
149 0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
150 0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
151 -0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
152 -0.5f, 0.5f, -0.5f, 0.0f, 1.0f
153 };
154
155 float floorVertices[] = {
156 5.0f, -0.5f, 5.0f, 2.0f, 0.0f,
157 -5.0f, -0.5f, 5.0f, 0.0f, 0.0f,
158 -5.0f, -0.5f, -5.0f, 0.0f, 2.0f,
159
160 5.0f, -0.5f, 5.0f, 2.0f, 0.0f,
161 -5.0f, -0.5f, -5.0f, 0.0f, 2.0f,
162 5.0f, -0.5f, -5.0f, 2.0f, 2.0f
163 };
164
165 float grassVertices[] = {
166 1.0f, -0.5f, 0.0f, 1.0f, 0.0f,
167 0.0f, -0.5f, 0.0f, 0.0f, 0.0f,
168 0.0f, 0.5f, 0.0f, 0.0f, 1.0f,
169 1.0f, -0.5f, 0.0f, 1.0f, 0.0f,
170 0.0f, 0.5f, 0.0f, 0.0f, 1.0f,
171 1.0f, 0.5f, 0.0f, 1.0f, 1.0f
172 };
173
174 vector<glm::vec3> vegetation;
175 vegetation.push_back(glm::vec3(-1.5f, 0.0f, -0.48f));
176 vegetation.push_back(glm::vec3(1.5f, 0.0f, 0.51f));
177 vegetation.push_back(glm::vec3(0.0f, 0.0f, 0.7f));
178 vegetation.push_back(glm::vec3(-0.3f, 0.0f, -2.3f));
179 vegetation.push_back(glm::vec3(0.5f, 0.0f, -0.6f));
180
181 //cube VAO
182 unsigned int cubeVAO, cubeVBO;
183 glGenVertexArrays(1, &cubeVAO);
184 glGenBuffers(1, &cubeVBO);
185 glBindVertexArray(cubeVAO);
186 glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
187 glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW);
188 glEnableVertexAttribArray(0);
189 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
190 glEnableVertexAttribArray(1);
191 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
192 glBindVertexArray(0);
193
194 //floor VAO
195 unsigned int floorVAO, floorVBO;
196 glGenVertexArrays(1, &floorVAO);
197 glGenBuffers(1, &floorVBO);
198 glBindVertexArray(floorVAO);
199 glBindBuffer(GL_ARRAY_BUFFER, floorVBO);
200 glBufferData(GL_ARRAY_BUFFER, sizeof(floorVertices), floorVertices, GL_STATIC_DRAW);
201 glEnableVertexAttribArray(0);
202 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
203 glEnableVertexAttribArray(1);
204 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
205 glBindVertexArray(0);
206
207 unsigned grassVAO, grassVBO;
208 glGenVertexArrays(1, &grassVAO);
209 glGenBuffers(1, &grassVBO);
210 glBindVertexArray(grassVAO);
211 glBindBuffer(GL_ARRAY_BUFFER, grassVBO);
212 glBufferData(GL_ARRAY_BUFFER, sizeof(grassVertices), grassVertices, GL_STATIC_DRAW);
213 glEnableVertexAttribArray(0);
214 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
215 glEnableVertexAttribArray(1);
216 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
217
218
219 //load textures
220 stbi_set_flip_vertically_on_load(true);
221 unsigned int cubeTexture = loadTexture("greenWall.jpg");
222 unsigned int floorTexture = loadTexture("floor.jpg");
223 unsigned int grassTexture = loadTexture("glass.png");
224
225 shader.use();
226 glUniform1i(glGetUniformLocation(shader.ID, "texture1"), 0);
227
228
229
230 //render loop
231 while (!glfwWindowShouldClose(window))
232 {
233 //per-frame time logic
234 float currentFrame = glfwGetTime();
235 deltaTime = currentFrame - lastFrame;
236 lastFrame = currentFrame;
237
238 //input
239 processInput(window);
240
241 //render
242 glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
243 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
244
245 shader.use();
246 glm::mat4 model;
247 glm::mat4 view = camera.GetViewMatrix();
248 glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
249 shader.setMat4("view", view);
250 glUniformMatrix4fv(glGetUniformLocation(shader.ID, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
251
252
253
254 //floor
255 glBindVertexArray(floorVAO);
256 glActiveTexture(GL_TEXTURE0);
257 glBindTexture(GL_TEXTURE_2D, floorTexture);
258 shader.setMat4("model", glm::mat4());
259 glDrawArrays(GL_TRIANGLES, 0, 6);
260 //glBindVertexArray(0);
261
262 //cube
263 glBindVertexArray(cubeVAO);
264 glActiveTexture(GL_TEXTURE0);
265 glBindTexture(GL_TEXTURE_2D, cubeTexture);
266 model = glm::translate(model, glm::vec3(-1.0f, 0.0f, -1.0f));
267 glUniformMatrix4fv(glGetUniformLocation(shader.ID, "model"), 1, GL_FALSE, glm::value_ptr(model));
268 glDrawArrays(GL_TRIANGLES, 0, 36);
269 model = glm::mat4();
270 model = glm::translate(model, glm::vec3(2.0f, 0.0f, 0.0f)); //the second cube
271 shader.setMat4("model", model);
272 glDrawArrays(GL_TRIANGLES, 0, 36);
273
274 //我们把距离和它对应的位置向量存储到一个STL库的map数据结构中,map会自动根据健值(key)对它的值进行排序,
275 //所以只要我们添加了所有的位置,并以他的距离作为键,它们就会自动根据距离值排序了
276 std::map<float, glm::vec3> sorted;
277 for (unsigned int i = 0; i < vegetation.size(); i++)
278 {
279 float distance = glm::length(camera.Position - vegetation[i]);
280 sorted[distance] = vegetation[i]; //一个距离对应一个位置
281 }
282 //结果就是一个排序后的容器对象,它根据distance健值从低到高存储了每个窗户的位置
283
284 //之后,这次在渲染的时候,我们将以逆序(从远到近)从map中获取值,之后以正确的顺序绘制对应的窗户
285 /*glBindVertexArray(grassVAO);
286 glBindTexture(GL_TEXTURE_2D, grassTexture);
287 for (std::map<float, glm::vec3>::reverse_iterator it = sorted.rbegin(); it != sorted.rend(); it++)
288 {
289 model = glm::mat4();
290 model = glm::translate(model, it->second);
291 shader.setMat4("model", model);
292 glDrawArrays(GL_TRIANGLES, 0, 6);
293 }*/
294
295
296
297
298 glBindVertexArray(grassVAO);
299 glBindTexture(GL_TEXTURE_2D, grassTexture);
300 for (unsigned int i = 0; i < vegetation.size(); i++)
301 {
302 model = glm::mat4();
303 model = glm::translate(model, vegetation[i]);
304 shader.setMat4("model", model);
305 glDrawArrays(GL_TRIANGLES, 0, 6);
306 }
307
308 //glfw: swap buffers and poll IO events (keys pressed / released, mouse moved etc.)
309 glfwSwapBuffers(window);
310 glfwPollEvents();
311 }
312
313 //optional: de - allocate all resources once they've outlived their purpose;
314 glDeleteVertexArrays(1, &cubeVAO);
315 glDeleteVertexArrays(1, &floorVAO);
316 glDeleteBuffers(1, &cubeVBO);
317 glDeleteBuffers(1, &floorVBO);
318
319 glfwTerminate();
320 return 0;
321 }
322
323 void processInput(GLFWwindow *window)
324 {
325 if (glfwGetKey(window, GLFW_KEY_ENTER) == GLFW_PRESS)
326 glfwSetWindowShouldClose(window, true);
327 if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
328 camera.ProcessKeyboard(FORWARD, deltaTime);
329 if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
330 camera.ProcessKeyboard(BACKWARD, deltaTime);
331 if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
332 camera.ProcessKeyboard(LEFT, deltaTime);
333 if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
334 camera.ProcessKeyboard(RIGHT, deltaTime);
335 }
336
337 void framebuffer_size_callback(GLFWwindow* window, int width, int height)
338 {
339 glViewport(0, 0, width, height);
340 }
341
342 void mouse_callback(GLFWwindow *window, double xpos, double ypos)
343 {
344 if (firstMouse)
345 {
346 lastX = xpos;
347 lastY = ypos;
348 firstMouse = false;
349 }
350
351 float xoffset = xpos - lastX;
352 float yoffset = lastY - ypos;
353
354 lastX = xpos;
355 lastY = ypos;
356
357 camera.ProcessMouseMovement(xoffset, yoffset);
358 }
359
360 void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
361 {
362 camera.ProcessMouseScroll(yoffset);
363 }
364
365 unsigned int loadTexture(char const *path)
366 {
367 unsigned int textureID;
368 glGenTextures(1, &textureID);
369
370 int width, height, nrChannels;
371 unsigned char *data = stbi_load(path, &width, &height, &nrChannels, 0);
372 if (data)
373 {
374 GLenum format;
375 if (nrChannels == 1)
376 format = GL_RED;
377 else if (nrChannels == 3)
378 format = GL_RGB;
379 else if (nrChannels == 4)
380 format = GL_RGBA;
381
382 glBindTexture(GL_TEXTURE_2D, textureID);
383 //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
384 glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); //create a texture
385 glGenerateMipmap(GL_TEXTURE_2D);
386
387 /*glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
388 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);*/
389 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
390 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
391 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
392 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
393
394 stbi_image_free(data);
395 }
396 else
397 {
398 std::cout << "Texture failed to load at path: " << path << std::endl;
399 stbi_image_free(data);
400 }
401 return textureID;
402
403 }
Shader.h
1 #ifndef SHADER_H_INCLUDE2 #define SHADER_H_INCLUDE3 4 #include <iostream>5 #include <string>6 #include <sstream>7 #include <fstream>8 9 #include <GL/glew.h>10 #include <GLFW/glfw3.h>11 #include <glm/glm.hpp>12 #include <glm/gtc/matrix_transform.hpp>13 #include <glm/gtc/type_ptr.hpp>14 15 class Shader {16 public:17 unsigned int ID;18 19 Shader(const GLchar* vertexPath, const GLchar* fragmentPath)20 {21 std::string vertexCode;22 std::string fragmentCode;23 std::ifstream vShaderFile;24 std::ifstream fShaderFile;25 26 vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);27 fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);28 29 try {30 //open files31 vShaderFile.open(vertexPath);32 fShaderFile.open(fragmentPath);33 34 std::stringstream vShaderStream, fShaderStream;35 36 //read file's buffer contents into streams37 vShaderStream << vShaderFile.rdbuf();38 fShaderStream << fShaderFile.rdbuf();39 40 //close file handlers41 vShaderFile.close();42 fShaderFile.close();43 44 //convert stream into string45 vertexCode = vShaderStream.str();46 fragmentCode = fShaderStream.str();47 }48 catch (std::ifstream::failure e)49 {50 std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ" << std::endl;51 }52 const char* vShaderCode = vertexCode.c_str();53 const char* fShaderCode = fragmentCode.c_str();54 55 //2.compile shaders56 unsigned int vertex, fragment;57 int success;58 char infoLog[512];59 60 //vertex shader61 vertex = glCreateShader(GL_VERTEX_SHADER);62 glShaderSource(vertex, 1, &vShaderCode, NULL);63 glCompileShader(vertex);64 glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);65 if (!success)66 {67 glGetShaderInfoLog(vertex, 512, NULL, infoLog);68 std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED!" << std::endl;69 }70 71 fragment = glCreateShader(GL_FRAGMENT_SHADER);72 glShaderSource(fragment, 1, &fShaderCode, NULL);73 glCompileShader(fragment);74 glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);75 if (!success)76 {77 glGetShaderInfoLog(fragment, 512, NULL, infoLog);78 std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED!" << std::endl;79 }80 81 ID = glCreateProgram();82 glAttachShader(ID, vertex);83 glAttachShader(ID, fragment);84 glLinkProgram(ID);85 glGetProgramiv(ID, GL_LINK_STATUS, &success);86 if (!success)87 {88 glGetProgramInfoLog(ID, 512, NULL, infoLog);89 std::cout << "ERROR::SHADER::PROGRAM::LINKTING_FAILED!" << std::endl;90 }91 92 //delete the shaders sa they are linked into our program now and no long necessary93 glDeleteShader(vertex);94 glDeleteShader(fragment);95 }96 97 //activate the shader98 void use()99 {
100 glUseProgram(ID);
101 }
102
103 //utility uniform functions
104 void setBool(const std::string &name, bool value) const
105 {
106 glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
107 }
108
109 void setInt(const std::string &name, int value) const
110 {
111 glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
112 }
113
114 void setFloat(const std::string &name, float value) const
115 {
116 glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
117 }
118
119 void setVec3(const std::string &name, const glm::vec3 &value) const
120 {
121 glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
122 }
123
124 void setVec3(const std::string &name, float x, float y, float z) const
125 {
126 glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z);
127 }
128
129
130 void setMat4(const std::string &name, glm::mat4 &trans) const
131 {
132
133 glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &trans[0][0]);
134 }
135
136
137 /*void setMat4(const std::string &name, glm::mat4 trans) const
138 {
139
140 //'trans': formal parameter with requested alignment of 16 won't be aligned,请求对齐的16的形式参数不会对齐
141 glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, glm::value_ptr(trans));
142 }*/
143
144 };
145
146 #endif
camera.h
1 #ifndef CAMERA_H2 #define CAMERA_H3 4 #include <GL/glew.h>5 #include <glm/glm.hpp>6 #include <glm/gtc/matrix_transform.hpp>7 8 #include <vector>9 10 // Defines several possible options for camera movement. Used as abstraction to stay away from window-system specific input methods11 enum Camera_Movement {12 FORWARD,13 BACKWARD,14 LEFT,15 RIGHT16 };17 18 // Default camera values19 const float YAW = -90.0f;20 const float PITCH = 0.0f;21 const float SPEED = 2.5f;22 const float SENSITIVITY = 0.1f;23 const float ZOOM = 45.0f;24 25 26 // An abstract camera class that processes input and calculates the corresponding Euler Angles, Vectors and Matrices for use in OpenGL27 class Camera28 {29 public:30 // Camera Attributes31 glm::vec3 Position;32 glm::vec3 Front;33 glm::vec3 Up;34 glm::vec3 Right;35 glm::vec3 WorldUp;36 // Euler Angles37 float Yaw;38 float Pitch;39 // Camera options40 float MovementSpeed;41 float MouseSensitivity;42 float Zoom;43 44 // Constructor with vectors45 Camera(glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), float yaw = YAW, float pitch = PITCH) : Front(glm::vec3(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVITY), Zoom(ZOOM)46 {47 Position = position;48 WorldUp = up;49 Yaw = yaw;50 Pitch = pitch;51 updateCameraVectors();52 }53 // Constructor with scalar values54 Camera(float posX, float posY, float posZ, float upX, float upY, float upZ, float yaw, float pitch) : Front(glm::vec3(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVITY), Zoom(ZOOM)55 {56 Position = glm::vec3(posX, posY, posZ);57 WorldUp = glm::vec3(upX, upY, upZ);58 Yaw = yaw;59 Pitch = pitch;60 updateCameraVectors();61 }62 63 // Returns the view matrix calculated using Euler Angles and the LookAt Matrix64 glm::mat4 GetViewMatrix()65 {66 return glm::lookAt(Position, Position + Front, Up);67 }68 69 // Processes input received from any keyboard-like input system. Accepts input parameter in the form of camera defined ENUM (to abstract it from windowing systems)70 void ProcessKeyboard(Camera_Movement direction, float deltaTime)71 {72 float velocity = MovementSpeed * deltaTime;73 if (direction == FORWARD)74 Position += Front * velocity;75 if (direction == BACKWARD)76 Position -= Front * velocity;77 if (direction == LEFT)78 Position -= Right * velocity;79 if (direction == RIGHT)80 Position += Right * velocity;81 }82 83 // Processes input received from a mouse input system. Expects the offset value in both the x and y direction.84 void ProcessMouseMovement(float xoffset, float yoffset, GLboolean constrainPitch = true)85 {86 xoffset *= MouseSensitivity;87 yoffset *= MouseSensitivity;88 89 Yaw += xoffset;90 Pitch += yoffset;91 92 // Make sure that when pitch is out of bounds, screen doesn't get flipped93 if (constrainPitch)94 {95 if (Pitch > 89.0f)96 Pitch = 89.0f;97 if (Pitch < -89.0f)98 Pitch = -89.0f;99 }
100
101 // Update Front, Right and Up Vectors using the updated Euler angles
102 updateCameraVectors();
103 }
104
105 // Processes input received from a mouse scroll-wheel event. Only requires input on the vertical wheel-axis
106 void ProcessMouseScroll(float yoffset)
107 {
108 if (Zoom >= 1.0f && Zoom <= 45.0f) //zoom缩放,就是视野
109 Zoom -= yoffset;
110 if (Zoom <= 1.0f)
111 Zoom = 1.0f;
112 if (Zoom >= 45.0f)
113 Zoom = 45.0f;
114 }
115
116 private:
117 // Calculates the front vector from the Camera's (updated) Euler Angles
118 void updateCameraVectors()
119 {
120 // Calculate the new Front vector
121 glm::vec3 front;
122 front.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch));
123 front.y = sin(glm::radians(Pitch));
124 front.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch));
125 Front = glm::normalize(front);
126 // Also re-calculate the Right and Up vector
127 Right = glm::normalize(glm::cross(Front, WorldUp)); // Normalize the vectors, because their length gets closer to 0 the more you look up or down which results in slower movement.
128 Up = glm::normalize(glm::cross(Right, Front));
129 }
130 };
131 #endif
stb_image.h下载
图片:
高级openg 混合,一个完整程序相关推荐
- 每日一皮:实习生将他的代码交给高级开发人员,高级开发反手一个...
高级开发人员反手就是一个Code Review 往期推荐 每日一皮:QA一来,大家都要靠边站! 每日一皮:据说PM就是这样忍受你的! 每日一皮:代码出现Bug的三种表情! 每日一皮:举一反三,这么聪明 ...
- javascript高级程序设计pdf_一个老牌程序员推荐的JavaScript的书籍,看了真的不后悔!...
很多人问我怎么学前端?我的回答是:读书吧!相对于在网上学习,在项目中学习和跟着有经验的同事学习,书中有着相对完整的知识体系,每读一本好书都会带来一次全面的提高.而如果深一脚浅一脚的学习,写出代码的质量 ...
- 我,【MySQL】高级篇,一个让你的数据管家单车变摩托的 “关系型数据库”
相关数据库sql文件 链接:https://pan.baidu.com/s/1RynVEnBL2nak5aJf0rXYmA 提取码:11gz 文章目录 一.视图 视图介绍 视图的创建 视图的修改 视图 ...
- offlc计算机等级报一级还是二级,请问计算机二级MS Office 和MS Office高级应用是一个东西吗?...
是的,一样的,只不过换了个名称而已. 计算机二级MS OFFICE高级应用都有题bai型如下:计算机du基础知识二.Word的功能和zhi使dao用三.Excel功能和使用四.PowerPoint的功 ...
- 带你全面掌握高级知识点!一个本科渣渣是怎么逆袭从咸鱼到Offer收割机的?年薪50W
开头 在大厂,写得一手好文档是一个非常吃香的技能.这可不只是一个锦上添花的东西,而是很多工程师晋升,打造自己话语权的武器. 我这两年在组内的深刻体会就是,大部分厉害的高级工程师(不包括那些纯混日子靠资 ...
- yii2高级模板使用一个域名管理前后台
1.修改 advanced/backend/config/main.PHP 文件如下: return ['homeUrl' => '/admin','components' => ['re ...
- yii2高级模板使用一个域名管理前后台(url重写)
前台使用 advanced.com访问,后台使用 advanced.com/admin访问 1.修改 advanced/backend/config/main.php return [ 'homeUr ...
- 关于高级导数的一个不等式估计
from: http://math.fudan.edu.cn/gdsx/XXYD.HTM
- 手机浏览器网址_「效率集」自定义网址导航高级功能介绍
「效率集」是国内仅有的几家提供了个性自定义导航的网站,功能比hao123强,用户体验优于百度导航首页,且支持聚合搜索,方便用户从不同渠道(网页,微博,微信公众号,知乎,维基百科)获取信息:方便用户在网 ...
最新文章
- 信息太多,时间太少: 大脑如何区分重要和不重要的事?
- CLR Via C# 3rd 阅读摘要 -- Chapter 24 – Runtime Serialization
- 常见的排序算法(1)
- oracle 11g 从rman全备中恢复控制文件,拥有RMAN全备(缺少后增文件),丢失全部数据文件,控制文件的恢复...
- 本文可能是国内第一篇介绍C/4HANA Foundation的中文博客
- Memcached服务端自动启动(转载)
- C#LeetCode刷题之#48-旋转图像(Rotate Image)
- 织梦自定义html文本,织梦内容模型自定义字段及调用方法
- 【论文解读】UniLM:一种既能阅读又能自动生成的预训练模型
- list是否包含字符串_Python创建list
- 移植MotionDriver到RTT
- 路由器与无线网如何连接到服务器,两个路由器无线连接怎么设置_如何将两个路由器无线连接-192路由网...
- 怎样得到 显示器所有能支持的分辨率 (显示器分辨率范围)
- 这样做优化,实现 0.059s 启动一个SpringBoot项目!
- GDAL中的地理坐标系、投影坐标系及其相互转换
- 不定积分——类似1/(1+e^x)的积分
- CPU安装双核补丁的重要性和安装方法
- 苹果 Fitness+ Apple Watch“去散步”即将推出
- 使用VS Code 插件, 快速入门超账Fabric(一) : 知识回复
- c语言四舍五入保留小数