1.  

1.当片段着色器处理完一个片段之后,模板测试(stencil test)会开始执行,和深度测试一样,它也可能会丢弃片段,接下来,被保留的片段会进入深度测试
2.每个窗口库都需要为你配置一个模板缓冲,但是GLFW这个窗口库会自动做这件事,所以不用告诉GLFW来创建一个模板缓冲
3.场景中的片段将只会在片段的模板值为1的时候被渲染,其他的都被丢弃了
启用模板缓冲的写入
渲染物体,更新模板缓冲的内容
禁用模板缓冲的写入
渲染其他物体,这次根据模板缓冲的内容丢弃特定的片段

  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

  1.  

但是glStencilFunc只描述了OpenGL应该对模板缓冲内容做什么,而不是我们应该如何更新缓冲,所以就需要glStencilOp这个函数了
glStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass)一共包含三个选项,我们能够设置每个选项应该采取的行为
sfail:模板测试失败是采取的行为
dpfail:模板测试通过,但深度测试失败采取的行为
dppass:模板测试和深度测试都通过时采取的行为

  1.  
  2. 1 /**
  3. * glBlendFunc混合两种颜色的函数
  4. *glBlendFunc(GLenum sfactor, GLenum dfactor)函数接受两个参数,来设置源和目标因子
  5. *常数颜色向量Cconstan可以通过glBlendColor函数来另外设置*
  6. *glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  7. *也可以使用glBlendFuncSeparate为RGB和alpha通道分别设置不同的选项
  8. * glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_GL_ZERO);
  9. *glBlendEquation(GLenum mode)允许我们设置运算符
  10. *GL_FUNC_ADD:默认选项,将两个分量相加,Cr = S + D
  11. *GL_FUNC_SUBTRACT = S - D
  12. *GL_FUNC_REVERSE_SUBTRACT,将两个分量向减,但顺序相反*/
  13.  
  14. /**
  15. *当绘制一个有不透明和透明物体的场景的时候,大体的原则如下:
  16. *1.先绘制所有不透明的物体。
  17. *2.对所有透明的物体排序。
  18. *3.按顺序绘制所有透明的物体。**/
  19.  
  20. #include <iostream>
  21. #include <vector>
  22. #include <map>
  23.  
  24. using namespace std;
  25. #define GLEW_STATIC
  26.  
  27. #include <GL/glew.h>
  28. #include <GLFW/glfw3.h>
  29.  
  30. #include "stb_image.h"
  31.  
  32. #include <glm/glm.hpp>
  33. #include <glm/gtc/matrix_transform.hpp>
  34. #include <glm/gtc/type_ptr.hpp>
  35.  
  36. #include "Shader.h"
  37. #include "camera.h"
  38. //#include "Model.h"
  39.  
  40. void framebuffer_size_callback(GLFWwindow* window, int width, int height);
  41. void mouse_callback(GLFWwindow* window, double xpos, double ypos);
  42. void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
  43. void processInput(GLFWwindow* window);
  44. unsigned int loadTexture(const char *path);
  45.  
  46. //setting
  47. const unsigned int SCR_WIDTH = ;
  48. const unsigned int SCR_HEIGHT = ;
  49.  
  50. //camera
  51. Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
  52. float lastX = (float)SCR_WIDTH / ;
  53. float lastY = (float)SCR_HEIGHT / ;
  54. bool firstMouse = true;
  55.  
  56. //timing
  57. float deltaTime = 0.0f;
  58. float lastFrame = 0.0f;
  59.  
  60. int main()
  61. {
  62. glfwInit();
  63. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, );
  64. glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, );
  65. glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  66.  
  67. GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LEARNOPENGL", NULL, NULL);
  68. if (window == NULL)
  69. {
  70. std::cout << "Failed to create window!" << std::endl;
  71. glfwTerminate();
  72. return -;
  73. }
  74. glfwMakeContextCurrent(window);
  75. glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
  76. glfwSetCursorPosCallback(window, mouse_callback);
  77. glfwSetScrollCallback(window, scroll_callback);
  78.  
  79. //tell GLFW to capture our mouse
  80. glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
  81.  
  82. glewExperimental = GL_TRUE;
  83. if (glewInit() != GLEW_OK)
  84. {
  85. std::cout << "Failed to initialize GLEW!" << std::endl;
  86. return -;
  87. }
  88.  
  89. ////configure global opengl state
  90. //glEnable(GL_DEPTH_TEST); //启用深度测试,默认情况下是禁用的
  91. //glDepthFunc(GL_LESS); //always pass the depth test(same effect as glDisable(GL_DEPTH_TEST)//禁用深度测试,永远都通过深度测试
  92. ////glDepthMask(GL_FALSE); //深度掩码,可以禁用深度缓冲的写入
  93.  
  94. //glEnable(GL_STENCIL_TEST);
  95. ////glStencilMask(0x00); //位掩码, 每个模板值都为0, 每一位在写入模板缓冲时都会变成0(禁用写入)
  96. //glStencilMask(0xff); //每个模板值都为1,每一位写入模板缓冲时都保持原样
  97.  
  98. //glStencilFunc(GL_EQUAL, 1, 0xFF); //只要一个片段的模板值等于参考值1,片段将会通过测试并被绘制,否则会被被丢弃
  99. //glStencilOp(GL_INCR_WRAP, GL_INCR_WRAP, GL_INCR_WRAP);//默认情况下,glStencilOp是设置为这样的,所以不论任何测试的结果是如何,模板缓冲都会保留它的值
  100. ////默认的行为不会更新模板缓冲,所以如果你想写入模板缓冲的话,至少对其中一个选项设置不同的值
  101. glEnable(GL_DEPTH_TEST);
  102. glDepthFunc(GL_LESS);
  103. glEnable(GL_BLEND); //启用混合
  104. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  105.  
  106. //build and compile shaders
  107. Shader shader("E:\\C++\\HigherOpenGL\\1.2.1ver1.txt", "E:\\C++\\HigherOpenGL\\1.3.2Frag1.txt");
  108.  
  109. float cubeVertices[] = {
  110. //position //texture Coords
  111. -0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
  112. 0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
  113. 0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
  114. 0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
  115. -0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
  116. -0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
  117.  
  118. -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
  119. 0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
  120. 0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
  121. 0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
  122. -0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
  123. -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
  124.  
  125. -0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
  126. -0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
  127. -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
  128. -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
  129. -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
  130. -0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
  131.  
  132. 0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
  133. 0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
  134. 0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
  135. 0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
  136. 0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
  137. 0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
  138.  
  139. -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
  140. 0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
  141. 0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
  142. 0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
  143. -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
  144. -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
  145.  
  146. -0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
  147. 0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
  148. 0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
  149. 0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
  150. -0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
  151. -0.5f, 0.5f, -0.5f, 0.0f, 1.0f
  152. };
  153.  
  154. float floorVertices[] = {
  155. 5.0f, -0.5f, 5.0f, 2.0f, 0.0f,
  156. -5.0f, -0.5f, 5.0f, 0.0f, 0.0f,
  157. -5.0f, -0.5f, -5.0f, 0.0f, 2.0f,
  158.  
  159. 5.0f, -0.5f, 5.0f, 2.0f, 0.0f,
  160. -5.0f, -0.5f, -5.0f, 0.0f, 2.0f,
  161. 5.0f, -0.5f, -5.0f, 2.0f, 2.0f
  162. };
  163.  
  164. float grassVertices[] = {
  165. 1.0f, -0.5f, 0.0f, 1.0f, 0.0f,
  166. 0.0f, -0.5f, 0.0f, 0.0f, 0.0f,
  167. 0.0f, 0.5f, 0.0f, 0.0f, 1.0f,
  168. 1.0f, -0.5f, 0.0f, 1.0f, 0.0f,
  169. 0.0f, 0.5f, 0.0f, 0.0f, 1.0f,
  170. 1.0f, 0.5f, 0.0f, 1.0f, 1.0f
  171. };
  172.  
  173. vector<glm::vec3> vegetation;
  174. vegetation.push_back(glm::vec3(-1.5f, 0.0f, -0.48f));
  175. vegetation.push_back(glm::vec3(1.5f, 0.0f, 0.51f));
  176. vegetation.push_back(glm::vec3(0.0f, 0.0f, 0.7f));
  177. vegetation.push_back(glm::vec3(-0.3f, 0.0f, -2.3f));
  178. vegetation.push_back(glm::vec3(0.5f, 0.0f, -0.6f));
  179.  
  180. //cube VAO
  181. unsigned int cubeVAO, cubeVBO;
  182. glGenVertexArrays(, &cubeVAO);
  183. glGenBuffers(, &cubeVBO);
  184. glBindVertexArray(cubeVAO);
  185. glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
  186. glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW);
  187. glEnableVertexAttribArray();
  188. glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, * sizeof(float), (void*));
  189. glEnableVertexAttribArray();
  190. glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, * sizeof(float), (void*)( * sizeof(float)));
  191. glBindVertexArray();
  192.  
  193. //floor VAO
  194. unsigned int floorVAO, floorVBO;
  195. glGenVertexArrays(, &floorVAO);
  196. glGenBuffers(, &floorVBO);
  197. glBindVertexArray(floorVAO);
  198. glBindBuffer(GL_ARRAY_BUFFER, floorVBO);
  199. glBufferData(GL_ARRAY_BUFFER, sizeof(floorVertices), floorVertices, GL_STATIC_DRAW);
  200. glEnableVertexAttribArray();
  201. glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, * sizeof(float), (void*));
  202. glEnableVertexAttribArray();
  203. glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, * sizeof(float), (void*)( * sizeof(float)));
  204. glBindVertexArray();
  205.  
  206. unsigned grassVAO, grassVBO;
  207. glGenVertexArrays(, &grassVAO);
  208. glGenBuffers(, &grassVBO);
  209. glBindVertexArray(grassVAO);
  210. glBindBuffer(GL_ARRAY_BUFFER, grassVBO);
  211. glBufferData(GL_ARRAY_BUFFER, sizeof(grassVertices), grassVertices, GL_STATIC_DRAW);
  212. glEnableVertexAttribArray();
  213. glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, * sizeof(float), (void*));
  214. glEnableVertexAttribArray();
  215. glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, * sizeof(float), (void*)( * sizeof(float)));
  216.  
  217. //load textures
  218. stbi_set_flip_vertically_on_load(true);
  219. unsigned int cubeTexture = loadTexture("greenWall.jpg");
  220. unsigned int floorTexture = loadTexture("floor.jpg");
  221. unsigned int grassTexture = loadTexture("glass.png");
  222.  
  223. shader.use();
  224. glUniform1i(glGetUniformLocation(shader.ID, "texture1"), );
  225.  
  226. //render loop
  227. while (!glfwWindowShouldClose(window))
  228. {
  229. //per-frame time logic
  230. float currentFrame = glfwGetTime();
  231. deltaTime = currentFrame - lastFrame;
  232. lastFrame = currentFrame;
  233.  
  234. //input
  235. processInput(window);
  236.  
  237. //render
  238. glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
  239. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  240.  
  241. shader.use();
  242. glm::mat4 model;
  243. glm::mat4 view = camera.GetViewMatrix();
  244. glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
  245. shader.setMat4("view", view);
  246. glUniformMatrix4fv(glGetUniformLocation(shader.ID, "projection"), , GL_FALSE, glm::value_ptr(projection));
  247.  
  248. //floor
  249. glBindVertexArray(floorVAO);
  250. glActiveTexture(GL_TEXTURE0);
  251. glBindTexture(GL_TEXTURE_2D, floorTexture);
  252. shader.setMat4("model", glm::mat4());
  253. glDrawArrays(GL_TRIANGLES, , );
  254. //glBindVertexArray(0);
  255.  
  256. //cube
  257. glBindVertexArray(cubeVAO);
  258. glActiveTexture(GL_TEXTURE0);
  259. glBindTexture(GL_TEXTURE_2D, cubeTexture);
  260. model = glm::translate(model, glm::vec3(-1.0f, 0.0f, -1.0f));
  261. glUniformMatrix4fv(glGetUniformLocation(shader.ID, "model"), , GL_FALSE, glm::value_ptr(model));
  262. glDrawArrays(GL_TRIANGLES, , );
  263. model = glm::mat4();
  264. model = glm::translate(model, glm::vec3(2.0f, 0.0f, 0.0f)); //the second cube
  265. shader.setMat4("model", model);
  266. glDrawArrays(GL_TRIANGLES, , );
  267.  
  268. //我们把距离和它对应的位置向量存储到一个STL库的map数据结构中,map会自动根据健值(key)对它的值进行排序,
  269. //所以只要我们添加了所有的位置,并以他的距离作为键,它们就会自动根据距离值排序了
  270. std::map<float, glm::vec3> sorted;
  271. for (unsigned int i = ; i < vegetation.size(); i++)
  272. {
  273. float distance = glm::length(camera.Position - vegetation[i]);
  274. sorted[distance] = vegetation[i]; //一个距离对应一个位置
  275. }
  276. //结果就是一个排序后的容器对象,它根据distance健值从低到高存储了每个窗户的位置
  277.  
  278. //之后,这次在渲染的时候,我们将以逆序(从远到近)从map中获取值,之后以正确的顺序绘制对应的窗户
  279. /*glBindVertexArray(grassVAO);
  280. glBindTexture(GL_TEXTURE_2D, grassTexture);
  281. for (std::map<float, glm::vec3>::reverse_iterator it = sorted.rbegin(); it != sorted.rend(); it++)
  282. {
  283. model = glm::mat4();
  284. model = glm::translate(model, it->second);
  285. shader.setMat4("model", model);
  286. glDrawArrays(GL_TRIANGLES, 0, 6);
  287. }*/
  288.  
  289. glBindVertexArray(grassVAO);
  290. glBindTexture(GL_TEXTURE_2D, grassTexture);
  291. for (unsigned int i = ; i < vegetation.size(); i++)
  292. {
  293. model = glm::mat4();
  294. model = glm::translate(model, vegetation[i]);
  295. shader.setMat4("model", model);
  296. glDrawArrays(GL_TRIANGLES, , );
  297. }
  298.  
  299. //glfw: swap buffers and poll IO events (keys pressed / released, mouse moved etc.)
  300. glfwSwapBuffers(window);
  301. glfwPollEvents();
  302. }
  303.  
  304. //optional: de - allocate all resources once they've outlived their purpose;
  305. glDeleteVertexArrays(, &cubeVAO);
  306. glDeleteVertexArrays(, &floorVAO);
  307. glDeleteBuffers(, &cubeVBO);
  308. glDeleteBuffers(, &floorVBO);
  309.  
  310. glfwTerminate();
  311. return ;
  312. }
  313.  
  314. void processInput(GLFWwindow *window)
  315. {
  316. if (glfwGetKey(window, GLFW_KEY_ENTER) == GLFW_PRESS)
  317. glfwSetWindowShouldClose(window, true);
  318. if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
  319. camera.ProcessKeyboard(FORWARD, deltaTime);
  320. if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
  321. camera.ProcessKeyboard(BACKWARD, deltaTime);
  322. if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
  323. camera.ProcessKeyboard(LEFT, deltaTime);
  324. if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
  325. camera.ProcessKeyboard(RIGHT, deltaTime);
  326. }
  327.  
  328. void framebuffer_size_callback(GLFWwindow* window, int width, int height)
  329. {
  330. glViewport(, , width, height);
  331. }
  332.  
  333. void mouse_callback(GLFWwindow *window, double xpos, double ypos)
  334. {
  335. if (firstMouse)
  336. {
  337. lastX = xpos;
  338. lastY = ypos;
  339. firstMouse = false;
  340. }
  341.  
  342. float xoffset = xpos - lastX;
  343. float yoffset = lastY - ypos;
  344.  
  345. lastX = xpos;
  346. lastY = ypos;
  347.  
  348. camera.ProcessMouseMovement(xoffset, yoffset);
  349. }
  350.  
  351. void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
  352. {
  353. camera.ProcessMouseScroll(yoffset);
  354. }
  355.  
  356. unsigned int loadTexture(char const *path)
  357. {
  358. unsigned int textureID;
  359. glGenTextures(, &textureID);
  360.  
  361. int width, height, nrChannels;
  362. unsigned char *data = stbi_load(path, &width, &height, &nrChannels, );
  363. if (data)
  364. {
  365. GLenum format;
  366. if (nrChannels == )
  367. format = GL_RED;
  368. else if (nrChannels == )
  369. format = GL_RGB;
  370. else if (nrChannels == )
  371. format = GL_RGBA;
  372.  
  373. glBindTexture(GL_TEXTURE_2D, textureID);
  374. //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
  375. glTexImage2D(GL_TEXTURE_2D, , format, width, height, , format, GL_UNSIGNED_BYTE, data); //create a texture
  376. glGenerateMipmap(GL_TEXTURE_2D);
  377.  
  378. /*glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  379. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);*/
  380. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  381. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  382. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  383. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  384.  
  385. stbi_image_free(data);
  386. }
  387. else
  388. {
  389. std::cout << "Texture failed to load at path: " << path << std::endl;
  390. stbi_image_free(data);
  391. }
  392. return textureID;
  393.  
  394. }

Shader.h

  1. #ifndef SHADER_H_INCLUDE
  2. #define SHADER_H_INCLUDE
  3.  
  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 files
  31. vShaderFile.open(vertexPath);
  32. fShaderFile.open(fragmentPath);
  33.  
  34. std::stringstream vShaderStream, fShaderStream;
  35.  
  36. //read file's buffer contents into streams
  37. vShaderStream << vShaderFile.rdbuf();
  38. fShaderStream << fShaderFile.rdbuf();
  39.  
  40. //close file handlers
  41. vShaderFile.close();
  42. fShaderFile.close();
  43.  
  44. //convert stream into string
  45. 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 shaders
  56. unsigned int vertex, fragment;
  57. int success;
  58. char infoLog[];
  59.  
  60. //vertex shader
  61. vertex = glCreateShader(GL_VERTEX_SHADER);
  62. glShaderSource(vertex, , &vShaderCode, NULL);
  63. glCompileShader(vertex);
  64. glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
  65. if (!success)
  66. {
  67. glGetShaderInfoLog(vertex, , NULL, infoLog);
  68. std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED!" << std::endl;
  69. }
  70.  
  71. fragment = glCreateShader(GL_FRAGMENT_SHADER);
  72. glShaderSource(fragment, , &fShaderCode, NULL);
  73. glCompileShader(fragment);
  74. glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
  75. if (!success)
  76. {
  77. glGetShaderInfoLog(fragment, , 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, , 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 necessary
  93. glDeleteShader(vertex);
  94. glDeleteShader(fragment);
  95. }
  96.  
  97. //activate the shader
  98. 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()), , &value[]);
  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. void setMat4(const std::string &name, glm::mat4 &trans) const
  130. {
  131.  
  132. glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), , GL_FALSE, &trans[][]);
  133. }
  134.  
  135. /*void setMat4(const std::string &name, glm::mat4 trans) const
  136. {
  137.  
  138. //'trans': formal parameter with requested alignment of 16 won't be aligned,请求对齐的16的形式参数不会对齐
  139. glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, glm::value_ptr(trans));
  140. }*/
  141.  
  142. };
  143.  
  144. #endif

camera.h

  1. #ifndef CAMERA_H
  2. #define CAMERA_H
  3.  
  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 methods
  11. enum Camera_Movement {
  12. FORWARD,
  13. BACKWARD,
  14. LEFT,
  15. RIGHT
  16. };
  17.  
  18. // Default camera values
  19. 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. // An abstract camera class that processes input and calculates the corresponding Euler Angles, Vectors and Matrices for use in OpenGL
  26. class Camera
  27. {
  28. public:
  29. // Camera Attributes
  30. glm::vec3 Position;
  31. glm::vec3 Front;
  32. glm::vec3 Up;
  33. glm::vec3 Right;
  34. glm::vec3 WorldUp;
  35. // Euler Angles
  36. float Yaw;
  37. float Pitch;
  38. // Camera options
  39. float MovementSpeed;
  40. float MouseSensitivity;
  41. float Zoom;
  42.  
  43. // Constructor with vectors
  44. 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)
  45. {
  46. Position = position;
  47. WorldUp = up;
  48. Yaw = yaw;
  49. Pitch = pitch;
  50. updateCameraVectors();
  51. }
  52. // Constructor with scalar values
  53. 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)
  54. {
  55. Position = glm::vec3(posX, posY, posZ);
  56. WorldUp = glm::vec3(upX, upY, upZ);
  57. Yaw = yaw;
  58. Pitch = pitch;
  59. updateCameraVectors();
  60. }
  61.  
  62. // Returns the view matrix calculated using Euler Angles and the LookAt Matrix
  63. glm::mat4 GetViewMatrix()
  64. {
  65. return glm::lookAt(Position, Position + Front, Up);
  66. }
  67.  
  68. // 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)
  69. void ProcessKeyboard(Camera_Movement direction, float deltaTime)
  70. {
  71. float velocity = MovementSpeed * deltaTime;
  72. if (direction == FORWARD)
  73. Position += Front * velocity;
  74. if (direction == BACKWARD)
  75. Position -= Front * velocity;
  76. if (direction == LEFT)
  77. Position -= Right * velocity;
  78. if (direction == RIGHT)
  79. Position += Right * velocity;
  80. }
  81.  
  82. // Processes input received from a mouse input system. Expects the offset value in both the x and y direction.
  83. void ProcessMouseMovement(float xoffset, float yoffset, GLboolean constrainPitch = true)
  84. {
  85. xoffset *= MouseSensitivity;
  86. yoffset *= MouseSensitivity;
  87.  
  88. Yaw += xoffset;
  89. Pitch += yoffset;
  90.  
  91. // Make sure that when pitch is out of bounds, screen doesn't get flipped
  92. if (constrainPitch)
  93. {
  94. if (Pitch > 89.0f)
  95. Pitch = 89.0f;
  96. if (Pitch < -89.0f)
  97. Pitch = -89.0f;
  98. }
  99.  
  100. // Update Front, Right and Up Vectors using the updated Euler angles
  101. updateCameraVectors();
  102. }
  103.  
  104. // Processes input received from a mouse scroll-wheel event. Only requires input on the vertical wheel-axis
  105. void ProcessMouseScroll(float yoffset)
  106. {
  107. if (Zoom >= 1.0f && Zoom <= 45.0f) //zoom缩放,就是视野
  108. Zoom -= yoffset;
  109. if (Zoom <= 1.0f)
  110. Zoom = 1.0f;
  111. if (Zoom >= 45.0f)
  112. Zoom = 45.0f;
  113. }
  114.  
  115. private:
  116. // Calculates the front vector from the Camera's (updated) Euler Angles
  117. void updateCameraVectors()
  118. {
  119. // Calculate the new Front vector
  120. glm::vec3 front;
  121. front.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch));
  122. front.y = sin(glm::radians(Pitch));
  123. front.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch));
  124. Front = glm::normalize(front);
  125. // Also re-calculate the Right and Up vector
  126. 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.
  127. Up = glm::normalize(glm::cross(Right, Front));
  128. }
  129. };
  130. #endif

stb_image.h下载

图片:

高级openg 混合,一个完整程序的更多相关文章

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

    yii2的高级模板分为backend和frontend,最开始用yii的时候并没怎么在意,就使用了两个域名分别解析前后台.今天无意间看见 可以使用一个域名指向前后台. 1.修改 advanced/ba ...

  2. python高级编程 编写一个包1

    #目的是:编写,发行python包可重复过程"""1:是缩短开始真正工作之前所需要的设置时间,也就是提供模板2:提供编写包的标准化方法3:简化测试驱动开发方法的使用4:为 ...

  3. Java高级特性--自定义一个StringBuilder的类

    案例讲解--自定义一个StringBuilder的类 一:案例设计介绍 自义一个M定yStringBuilder来实现StringBuilder的功能 二:案例设计 实现append()方法追加字符串 ...

  4. constraintLayout的一些高级用法 布局一个16:9的图片 以及GuideLine的使用

    <!-- "W,9:16" 同样的效果 --> <ImageView android:layout_width="0dp" android:l ...

  5. Java高级应用(一个)-文件夹监控服务

    最近.在研究一些比较成熟的框架.他们还发现,他们中的一些相当不错的文章.现在,对于一些在你们中间一个简单的翻译(版的英文文章,非常有帮助). 译:原文链接 你有没有发现,当你编辑一个文件.同一时候使用 ...

  6. Yii2 高级版新建一个 Api 应用

    原文地址:http://www.getyii.com/topic/28 先在项目的根目录下复制一份 backend 为 api: cp backend/ api -r 拷贝 api 环境 cp -a ...

  7. UNIX环境高级编程——初始化一个守护进程

    #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h&g ...

  8. yii2 高级版新建一个应用(api应用为例子)

    先在项目的根目录下复制一份 backend 为 api: cp backend/ api -r 拷贝 api 环境 cp -a environments/dev/frontend environmen ...

  9. webdriver高级应用- 改变一个页面对象的属性值

    适用于一些无法操作的元素,可以直接改他的属性从而操作,代码如下: #encoding=utf-8 from selenium import webdriver import unittest impo ...

随机推荐

  1. Oracle hint手动优化

    例子 select/*+FULL(fortest)*/ * from fortest where id = 2000000 //使用0.70s时间 select* from fortest where ...

  2. 从Oracle数据库中的本地命名文件tnsnames.ora来看服务别名、服务名和实例名的区别。

    tnsnames.ora的作用这里就不多述了,各位应该都知道. 首先先看两个例子: test1 = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCO ...

  3. git中工作区,缓存区,本地库,远程库的简要区别

    git中工作区,缓存区,本地库,远程库的简要区别 实际上前三个名词对应到实体,都是你从远程仓库克隆下来的那个项目目录!只不过工作区就是你实际看到的目录和目录里的内容,当你修改/添加/删除了从远程仓库c ...

  4. [转]JavaScript与元素间的抛物线轨迹运动

    在张鑫旭的博客看到这个抛物线的小动画,觉得很感兴趣,转载一下方便研究~ 原文地址:http://www.zhangxinxu.com/wordpress/?p=3855 在页面上添加元素的位移动画,除 ...

  5. react native 之 获取键盘高度

    多说不如多撸: /** * Created by shaotingzhou on 2017/2/23. *//** * Sample React Native App * https://github ...

  6. js--call( )/apply()/bind()--应用

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call funct ...

  7. MongDB篇,第四章:数据库知识4

    MongDB 数据库知识4 GridFS 大文件存储 文件的数据库存储 1,在数据库中以   字符串的方式  存储文件在本地的路径: 优点: 节省数据库空间 缺点: 当数据库或者文件位置发生变化时则无 ...

  8. SpringBoot 配置文件详解

    springboot采纳了建立生产就绪spring应用程序的观点. Spring Boot优先于配置的惯例,旨在让您尽快启动和运行.在一般情况下,我们不需要做太多的配置就能够让spring boot正 ...

  9. base标签对svg的影响

    页面地址:http://127.0.0.1:8080/fullLink_node.html?project_id=2 base:<base href="http://127.0.0.1 ...

  10. 利用selenium模拟登录webqq

    from selenium import webdriver import selenium.webdriver.support.ui as ui import time opt = webdrive ...