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 混合,一个完整程序相关推荐

  1. 每日一皮:实习生将他的代码交给高级开发人员,高级开发反手一个...

    高级开发人员反手就是一个Code Review 往期推荐 每日一皮:QA一来,大家都要靠边站! 每日一皮:据说PM就是这样忍受你的! 每日一皮:代码出现Bug的三种表情! 每日一皮:举一反三,这么聪明 ...

  2. javascript高级程序设计pdf_一个老牌程序员推荐的JavaScript的书籍,看了真的不后悔!...

    很多人问我怎么学前端?我的回答是:读书吧!相对于在网上学习,在项目中学习和跟着有经验的同事学习,书中有着相对完整的知识体系,每读一本好书都会带来一次全面的提高.而如果深一脚浅一脚的学习,写出代码的质量 ...

  3. 我,【MySQL】高级篇,一个让你的数据管家单车变摩托的 “关系型数据库”

    相关数据库sql文件 链接:https://pan.baidu.com/s/1RynVEnBL2nak5aJf0rXYmA 提取码:11gz 文章目录 一.视图 视图介绍 视图的创建 视图的修改 视图 ...

  4. offlc计算机等级报一级还是二级,请问计算机二级MS Office 和MS Office高级应用是一个东西吗?...

    是的,一样的,只不过换了个名称而已. 计算机二级MS OFFICE高级应用都有题bai型如下:计算机du基础知识二.Word的功能和zhi使dao用三.Excel功能和使用四.PowerPoint的功 ...

  5. 带你全面掌握高级知识点!一个本科渣渣是怎么逆袭从咸鱼到Offer收割机的?年薪50W

    开头 在大厂,写得一手好文档是一个非常吃香的技能.这可不只是一个锦上添花的东西,而是很多工程师晋升,打造自己话语权的武器. 我这两年在组内的深刻体会就是,大部分厉害的高级工程师(不包括那些纯混日子靠资 ...

  6. yii2高级模板使用一个域名管理前后台

    1.修改 advanced/backend/config/main.PHP 文件如下: return ['homeUrl' => '/admin','components' => ['re ...

  7. yii2高级模板使用一个域名管理前后台(url重写)

    前台使用 advanced.com访问,后台使用 advanced.com/admin访问 1.修改 advanced/backend/config/main.php return [ 'homeUr ...

  8. 关于高级导数的一个不等式估计

    from: http://math.fudan.edu.cn/gdsx/XXYD.HTM

  9. 手机浏览器网址_「效率集」自定义网址导航高级功能介绍

    「效率集」是国内仅有的几家提供了个性自定义导航的网站,功能比hao123强,用户体验优于百度导航首页,且支持聚合搜索,方便用户从不同渠道(网页,微博,微信公众号,知乎,维基百科)获取信息:方便用户在网 ...

最新文章

  1. 信息太多,时间太少: 大脑如何区分重要和不重要的事?
  2. CLR Via C# 3rd 阅读摘要 -- Chapter 24 – Runtime Serialization
  3. 常见的排序算法(1)
  4. oracle 11g 从rman全备中恢复控制文件,拥有RMAN全备(缺少后增文件),丢失全部数据文件,控制文件的恢复...
  5. 本文可能是国内第一篇介绍C/4HANA Foundation的中文博客
  6. Memcached服务端自动启动(转载)
  7. C#LeetCode刷题之#48-旋转图像(Rotate Image)
  8. 织梦自定义html文本,织梦内容模型自定义字段及调用方法
  9. 【论文解读】UniLM:一种既能阅读又能自动生成的预训练模型
  10. list是否包含字符串_Python创建list
  11. 移植MotionDriver到RTT
  12. 路由器与无线网如何连接到服务器,两个路由器无线连接怎么设置_如何将两个路由器无线连接-192路由网...
  13. 怎样得到 显示器所有能支持的分辨率 (显示器分辨率范围)
  14. 这样做优化,实现 0.059s 启动一个SpringBoot项目!
  15. GDAL中的地理坐标系、投影坐标系及其相互转换
  16. 不定积分——类似1/(1+e^x)的积分
  17. CPU安装双核补丁的重要性和安装方法
  18. 苹果 Fitness+ Apple Watch“去散步”即将推出
  19. 使用VS Code 插件, 快速入门超账Fabric(一) : 知识回复
  20. c语言四舍五入保留小数

热门文章

  1. word文档如何添加批注
  2. 【JAVA数据结构】双向链表的增删查改
  3. 网页一键分享到QQ空间、QQ好友、新浪微博、微信代码
  4. 好奇怪呀后面加什么标点_三年级语文提示语的标点练习(含答案)
  5. 海信java手机qq_内置QQ service 安卓手机海信E89可爱登场
  6. ubuntu 桌面卡死 解决方法
  7. (转)对VSAM的一些介绍
  8. oracle安装-无法在节点上执行物理内存检查的解决方案
  9. uncanny valley(恐怖谷)--学习笔记
  10. Python 循环结构