高级openg 混合,一个完整程序

Posted 一个拿着底层薪资操着架构师的心的码农

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高级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 + D 10 *GL_FUNC_SUBTRACT = S - D 11 *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_STATIC 27 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 //setting 48 const unsigned int SCR_WIDTH = 800; 49 const unsigned int SCR_HEIGHT = 600; 50 51 //camera 52 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 //timing 58 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 mouse 81 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 state 91 //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以上是关于高级openg 混合,一个完整程序的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段——git命令操作一个完整流程

VSCode自定义代码片段15——git命令操作一个完整流程

VSCode自定义代码片段15——git命令操作一个完整流程

错误记录Flutter 混合开发获取 BinaryMessenger 报错 ( FlutterActivityAndFragmentDelegate.getFlutterEngine() )(代码片段

JavaScript笔试题(js高级代码片段)

FlutterFlutter 混合开发 ( Flutter 与 Native 通信 | 完整代码示例 )