2025年OpenGL学习笔记(十六)混合和面剔除

OpenGL学习笔记(十六)混合和面剔除首先要做的就是通过根据贴图的 alpha 值渲染一些草在地面上 老样子还是先是顶点着色器 version 330 core out vec2 TextureCoord out vec4 vertexColor layout location 0 in vec3 aPos layout location 1 in vec3 aColor layout

大家好,我是讯享网,很高兴认识大家。
#version 330 core out vec2 TextureCoord; out vec4 vertexColor; layout (location=0) in vec3 aPos; layout (location=1) in vec3 aColor; layout (location=2) in vec2 aTextureCoord;//纹理坐标 uniform mat4 modelMat;//模型矩阵 uniform mat4 viewMat;//视角矩阵 uniform mat4 projMat;//投影 void main() { gl_Position=projMat*viewMat*modelMat*vec4(aPos.x,aPos.y,aPos.z,1.0f); vertexColor=vec4(aColor,1.0f); TextureCoord=aTextureCoord; } 

讯享网

片段着色器

讯享网#version 330 core out vec4 FragColor; in vec2 TextureCoord; uniform sampler2D ourTexture;//纹理 void main() { vec4 texColor = texture(ourTexture, TextureCoord); if(texColor.a < 0.1)//alpha值小于0.1就抛弃 discard; FragColor = texColor; } 

形状和位置的数组

float transparentVertices[] = { // positions // texture Coords (swapped y coordinates because texture is flipped upside down) 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, 1.0f, 1.0f, -0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, -0.5f, 0.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.0f, 1.0f, 0.0f }; glm::vec3 grass_pos[]= { glm::vec3(-1.5f, 0.0f, -0.48f), glm::vec3(1.5f, 0.0f, 0.51f), glm::vec3(0.0f, 0.0f, 0.7f), glm::vec3(-0.3f, 0.0f, -2.3f), glm::vec3(-1.0f, 0.0f, -0.314f), glm::vec3(1.0f, 0.0f, 0.51f), glm::vec3(2.23f, 0.0f, 0.7f), glm::vec3(-1.3f, 0.0f, -2.3f), glm::vec3(-0.5f, 0.0f, -0.48f), glm::vec3(2.5f, 0.0f, 1.1f), glm::vec3(1.0f, 0.0f, 0.78f), glm::vec3(-0.9f, 0.0f, -2.3f), glm::vec3(0.5f, 0.0f, -0.6f) }; 

然后是申请对应的VAO和VBO

讯享网 GLuint transparentVBO, transparentVAO; glGenVertexArrays(1, &transparentVAO); glGenBuffers(1, &transparentVBO); glBindVertexArray(transparentVAO); glBindBuffer(GL_ARRAY_BUFFER, transparentVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(transparentVertices), transparentVertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(0); glEnableVertexAttribArray(2); 

加载纹理图片

unsigned int texbufferC; texbufferC = Load_Texture("grass.png", GL_RGBA, GL_RGBA, 2); 

开始绘制

讯享网for (int i = 0; i < sizeof(grass_pos) / sizeof(grass_pos[0]); i++) { glBindVertexArray(transparentVAO);//应用透明VAO glm::mat4 modelMat; modelMat = glm::translate(modelMat,grass_pos[i]);//定义位置 glActiveTexture(GL_TEXTURE2);//加载和绑定纹理 glBindTexture(GL_TEXTURE_2D, texbufferC); shader.setInt("ourTexture", 2);//传输纹理号给片段着色器 shader.setMat4("modelMat", modelMat);//设置模型矩阵 glDrawArrays(GL_TRIANGLES,0,6);//根据模型行数决定这里的数值 } 

绘制结果:
在这里插入图片描述
讯享网
其中的

 glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, texbufferC); 

是可以去掉的,因为前面已经绑定过纹理编号了。

讯享网glEnable(GL_BLEND);//开始混合 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);//混合函数设置,源颜色向量的alpha做源因子,1-alpha做目标因子 

再使用vector装一下窗口位置。

vector<glm::vec3> windows_pos = { glm::vec3(-1.5f, 0.0f, -0.48f), glm::vec3(1.5f, 0.0f, 0.51f), glm::vec3(0.0f, 0.0f, 0.7f), glm::vec3(-0.3f, 0.0f, -2.3f), glm::vec3(0.5f, 0.0f, -0.6f) }; 

然后再用map做一个窗口与相机距离之间的排序。

讯享网std::map<float, glm::vec3>sorted;//map相当于字典 for (unsigned int i = 0; i < windows_pos.size(); i++) { float distance = glm::length(myCamera->Position - windows_pos[i]);//通过相机位置计算先后顺序 sorted[distance] = windows_pos[i]; } 

最后渲染这些窗口

glBindVertexArray(transparentVAO); for (std::map<float, glm::vec3>::reverse_iterator it = sorted.rbegin(); it != sorted.rend(); ++it) { modelMat = glm::mat4(1.0f); modelMat = glm::translate(modelMat, it->second); shader.setInt("ourTexture", 2); shader.setMat4("modelMat", modelMat); glDrawArrays(GL_TRIANGLES, 0, 6); } 

最后结果:
在这里插入图片描述
记住:

讯享网glEnable(GL_DEPTH_TEST);//开启深度测试 glEnable(GL_BLEND);//开始混合 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);//混合函数设置,源颜色向量的alpha做源因子,1-alpha做目标因子 

这些开启什么模式的东西,必须在 glfwMakeContextCurrent(window);之后,否则就相当于没有开启。

放在glfwMakeContextCurrent(window);之前的结果。
在这里插入图片描述

 glEnable(GL_CULL_FACE);//开启面剔除 glCullFace(GL_BACK);//只剔除后面的 
讯享网glDisable(GL_CULL_FACE);//关闭面剔除 

如果在渲染非闭合物体时,没有关闭面剔除,就会导致
在这里插入图片描述
渲染出来的箱子中空,地面消失了。

小讯
上一篇 2025-03-19 23:22
下一篇 2025-02-09 13:36

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/67438.html