ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

OpenGL贴图、小图片叠加(10)

2022-06-27 01:31:44  阅读:225  来源: 互联网

标签:贴图 10 1.0 OpenGL 0.0 TEXTURE 纹理 2D GL


基于前边两篇博文:OpenGL多层纹理叠加_部分区域(九-2) - 邗影 - 博客园 (cnblogs.com)

OpenGL多层纹理叠加MIX(九-1) - 邗影 - 博客园 (cnblogs.com)

本篇文章效果类似,也是一个贴图,但是是一个完整小图贴到一张大图上;我们经常看视频的时候会有logo贴图的那种效果;或者像看电视,角落上有电视台小图;但是目前本博客的程序还做不到透明贴图(如图,彩虹中的透明部分是黑色的,而不是透明的)

 

 

 

 本博客仅展示个人实现效果(不代表真实原理、机制);通过使用多个VBO进行实现;

  1 #include "stdafx.h"
  2 #include<windows.h>
  3 #include <glad/glad.h>
  4 #include <GLFW/glfw3.h>
  5 #define STB_IMAGE_IMPLEMENTATION
  6 #include <stb_image.h>
  7 #include<string>
  8 #include<fstream>
  9 #include<sstream>
 10 #include<iostream>
 11 
 12 #include <stdio.h>
 13 
 14 // settings
 15 const unsigned int SCR_WIDTH = 800;
 16 const unsigned int SCR_HEIGHT = 600;
 17 unsigned int VBO = 0;
 18 unsigned int VBO2 = 0;
 19 unsigned int VAO = 0;
 20 unsigned int VAO2 = 0;
 21 unsigned int EBO = 0;
 22 unsigned int texturePIC = 0;
 23 unsigned int texturePIC2 = 0;
 24 int shaderProgram = 0;
 25 GLuint texId_bottom = 99;
 26 GLuint texId_top = 99;
 27 
 28 //本地文件夹下有个图片加载到项目上(注意参数列表中的引用表示变量本身,不要用变量的副本)
 29 void LoadPicture(unsigned int& textureIndex,unsigned int& textureIndex2)
 30 {
 31     //返回不同采样器的序号
 32     glUseProgram(shaderProgram);
 33     texId_bottom = glGetUniformLocation(shaderProgram, " ourTextureB");
 34     texId_top = glGetUniformLocation(shaderProgram, "ourTextureT");
 35 
 36     glGenTextures(1, &textureIndex);
 37     glActiveTexture(GL_TEXTURE0);
 38     glBindTexture(GL_TEXTURE_2D, textureIndex);
 39     
 40     //为bind的纹理设置环绕,过滤方式
 41     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 42     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 43     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 44     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 45 
 46     //加载图片生成纹理 :
 47     stbi_set_flip_vertically_on_load(true);
 48     //stbi是一个图片载入的开源组件,文件名,宽高,通道数,你期望的通道数(使用的是宽大于高的图片,如果是高>宽,程序需要改否则渲染异常)
 49     int W, H, channels_in_file, desired_channels = 3;
 50     unsigned char* data = stbi_load("./F.jpg ", &W, &H, &channels_in_file, desired_channels);
 51     if (channels_in_file == 3)
 52     {
 53         //数据生成纹理;根据指定的参数,把输入数据生成一张2D纹理
 54         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, W, H, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
 55         glUniform1i(texId_bottom,0);
 56         //生成mipmap数组
 57         glGenerateMipmap(GL_TEXTURE_2D);
 58     }
 59     stbi_image_free(data);
 60     data = nullptr;
 61 
 62     //加载图片2
 63     glGenTextures(1, &textureIndex2);
 64 
 65     glActiveTexture(GL_TEXTURE1);
 66     glBindTexture(GL_TEXTURE_2D, textureIndex2);
 67     //为bind的纹理设置环绕,过滤方式
 68     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 69     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 70     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 71     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 72     //加载图片生成纹理 :
 73     stbi_set_flip_vertically_on_load(true);
 74     //stbi是一个图片载入的开源组件,文件名,宽高,通道数,你期望的通道数
 75     int W2, H2, channels_in_file2, desired_channels2 = 3;
 76     unsigned char* data2 = stbi_load("./lyf.jpg", &W2, &H2, &channels_in_file2, desired_channels2);
 77     if (channels_in_file2 == 3)
 78     {
 79         //数据生成纹理;根据指定的参数,把输入数据生成一张2D纹理
 80         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, W2, H2, 0, GL_RGB, GL_UNSIGNED_BYTE, data2);
 81         glUniform1i(texId_top, 1);
 82         //生成mipmap数组
 83         glGenerateMipmap(GL_TEXTURE_2D);
 84     }
 85     stbi_image_free(data2);
 86     data2 = nullptr;
 87 
 88     glUseProgram(0);
 89 }
 90 
 91 
 92 void render()
 93 {
 94     
 95     glBindVertexArray(VAO);
 96     glUseProgram(shaderProgram);
 97     glUniform1i(glGetUniformLocation(shaderProgram, "mixValue"), 1);//要先启用着色器程序咋,再指定变量的值
 98     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
 99     glUseProgram(0);
100     glBindVertexArray(0);
101 
102     //不同的图片要画两次
103     
104     glBindVertexArray(VAO2);
105     glUseProgram(shaderProgram);
106     glUniform1i(glGetUniformLocation(shaderProgram, "mixValue"), 2);//为了给片元着色器区分采样
107     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
108     glUseProgram(0);
109     glBindVertexArray(0);
110 }
111 
112 void initmodule()
113 {
114     //做个一模型;正方形;映射了顶点坐标和纹理坐标的对应关系
115     float vertexs[] = {
116         //顶点坐标-------纹理坐标
117         1.0f,  1.0f, 0.0f,  1.0f, 1.0f,   // 右上
118         1.0f, -1.0f, 0.0f,  1.0f, 0.0f,   // 右下
119         -1.0f, -1.0f, 0.0f,  0.0f, 0.0f,   // 左下
120         -1.0f,  1.0f, 0.0f,  0.0f, 1.0f    // 左上
121 
122 
123     };
124 
125     float vertexs2[] = {
126         //顶点坐标-------纹理坐标
127         0.9f,  1.0f, 0.0f,  1.0f, 1.0f,   // 右上
128         0.9f, 0.5f, 0.0f,   1.0f, 0.0f,   // 右下
129         -0.1f, 0.5f, 0.0f,  0.0f, 0.0f,   // 左下
130         -0.1f,  1.0f, 0.0f,  0.0f, 1.0f    // 左上
131 
132 
133     };
134 
135 
136 
137     //一个正方形是由两个三角形得来的;记录顶点的索引顺序
138     unsigned int indexs[] = {
139         0,1,3,
140         1,2,3,
141     };
142 
143     
144     //加载纹理图片,生成纹理
145     LoadPicture(texturePIC, texturePIC2);
146 
147     //做VAO
148     glGenVertexArrays(1, &VAO);
149     glBindVertexArray(VAO);
150 
151     //做VBO
152 
153     glGenBuffers(1, &VBO);
154     glBindBuffer(GL_ARRAY_BUFFER, VBO);
155     //创建显存空间
156     glBufferData(GL_ARRAY_BUFFER, sizeof(vertexs), vertexs, GL_STATIC_DRAW);
157 
158     glGenBuffers(1, &EBO);
159     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
160     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexs), indexs, GL_STATIC_DRAW);
161 
162 
163     //设置第0个锚点,3个点,不需要归一化,跨度5个float可以读下一个点
164     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
165     //打开顶点
166     glEnableVertexAttribArray(0);
167     //纹理属性设置,纹理在第一个锚点上(指定顶点数据)你在顶点着色器程序中制定了锚点1的位置对应的是纹理坐标
168     glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
169     //打开纹理
170     glEnableVertexAttribArray(1);
171 
172     //解除绑定VBO
173     glBindBuffer(GL_ARRAY_BUFFER, 0);
174 
175     //解绑VAO
176     glBindVertexArray(0);
177 
178 
179     //叠图的VAO,VBO,EBO--------------注意不能用同一个VAO(VBO),
180     //对每个VAO可以使用同样的EBO,但是一定要在每个VAO下都写一次EBO以及glVertexAttribPointer
181     glGenVertexArrays(1, &VAO2);
182     glBindVertexArray(VAO2);
183 
184     glGenBuffers(1, &VBO2);
185     glBindBuffer(GL_ARRAY_BUFFER, VBO2);
186     //创建显存空间
187     glBufferData(GL_ARRAY_BUFFER, sizeof(vertexs2), vertexs2, GL_STATIC_DRAW);
188 
189 
190     //设置索引缓冲
191     glGenBuffers(1, &EBO);
192     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
193     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexs), indexs, GL_STATIC_DRAW);
194     
195     //绑定纹理,OpenGL至少保证有16个纹理单元供你使用,也就是说你可以激活从GL_TEXTURE0到GL_TEXTRUE15
196     
197     //设置第0个锚点,3个点,不需要归一化,跨度5个float可以读下一个点
198     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
199     //打开顶点
200     glEnableVertexAttribArray(0);
201     //纹理属性设置,纹理在第一个锚点上(指定顶点数据)你在顶点着色器程序中制定了锚点1的位置对应的是纹理坐标
202     glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
203     //打开纹理
204     glEnableVertexAttribArray(1);
205 
206     //解除绑定VBO
207     glBindBuffer(GL_ARRAY_BUFFER, 0);
208 
209     //解绑VAO
210     glBindVertexArray(0);
211 
212 }
213 
214 void initshader(const char* verpath, const char* fragpath)
215 {
216     //编译shader,并记录shaderID
217     std::string VerCode("");
218     std::string fregCode("");
219     //读文件
220     std::ifstream  vShaderFile;
221     std::ifstream  fShaderFile;
222 
223     vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
224     fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
225 
226     try
227     {
228         vShaderFile.open(verpath);
229         fShaderFile.open(fragpath);
230 
231         std::stringstream vsstream, fsstream;
232         vsstream << vShaderFile.rdbuf();
233         fsstream << fShaderFile.rdbuf();
234         VerCode = vsstream.str();
235         fregCode = fsstream.str();
236 
237     }
238     catch (const std::exception&)
239     {
240         std::cout << "read file error" << std::endl;
241     }
242 
243     const char* vshader = VerCode.c_str();
244     const char* fshader = fregCode.c_str();
245 
246     //shader 编译连接
247     unsigned int vertexID = 0, fragID = 0;
248     char infoLog[512];//存储错误信息
249     int  successflag = 0;
250     vertexID = glCreateShader(GL_VERTEX_SHADER);
251     glShaderSource(vertexID, 1, &vshader, NULL);
252     glCompileShader(vertexID);
253     //获取编译是否成功
254     glGetShaderiv(vertexID, GL_COMPILE_STATUS, &successflag);
255     if (!successflag)
256     {
257         glGetShaderInfoLog(vertexID, 512, NULL, infoLog);
258         std::string errstr(infoLog);
259         std::cout << "v shader err" << infoLog;
260     }
261     //frag
262     fragID = glCreateShader(GL_FRAGMENT_SHADER);
263     glShaderSource(fragID, 1, &fshader, NULL);
264     glCompileShader(fragID);
265     //获取编译是否成功
266     glGetShaderiv(fragID, GL_COMPILE_STATUS, &successflag);
267     if (!successflag)
268     {
269         glGetShaderInfoLog(fragID, 512, NULL, infoLog);
270         std::string errstr(infoLog);
271         std::cout << "f shader err" << infoLog;
272     }
273     //链接
274     shaderProgram = glCreateProgram();
275     glAttachShader(shaderProgram, vertexID);
276     glAttachShader(shaderProgram, fragID);
277     glLinkProgram(shaderProgram);
278     glGetProgramiv(shaderProgram, GL_LINK_STATUS, &successflag);
279     if (!successflag)
280     {
281         glGetShaderInfoLog(shaderProgram, 512, NULL, infoLog);
282         std::string errstr(infoLog);
283         std::cout << "link error";
284     }
285 
286     //编译完成后,可以把中间的步骤程序删除
287     glDeleteShader(vertexID);
288     glDeleteShader(fragID);
289 }
290 void processInput(GLFWwindow *window)
291 {
292     if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
293     {
294         //将窗口设置为关闭,跳出循环
295         glfwSetWindowShouldClose(window, true);
296     }
297 }
298 
299 void framebuffer_size_callback(GLFWwindow* window, int width, int height)
300 {
301     glViewport(0, 0, width, height);
302 }
303 
304 int main()
305 {
306     //glfw初始化
307     glfwInit();
308     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
309     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
310     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
311 
312     //glfw创建窗口
313     GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
314     if (window == NULL)
315     {
316         printf("创建窗口失败");
317         //终止
318         glfwTerminate();
319         return -1;
320     }
321     //显示窗口
322     glfwMakeContextCurrent(window);
323 
324     //设置回调,当窗口大小调整后将调用该回调函数
325     glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
326 
327     // glad初始化
328     if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
329     {
330         printf("加载失败");
331         return -1;
332     }
333     
334     initshader("vertexShader.glsl", "fragmentShader.glsl");
335     initmodule();
336     // 使用循环达到循环渲染效果
337     while (!glfwWindowShouldClose(window))
338     {
339         //自定义输入事件
340         processInput(window);
341         glEnable(GL_BLEND);
342         glClearColor(0.5f, 0.5f, 0.3f, 1.0f);
343         glClear(GL_COLOR_BUFFER_BIT);
344         render();
345         //交互缓冲区,否则显示空白
346         glfwSwapBuffers(window);
347         //输入输出事件,否则无法对窗口进行交互
348         glfwPollEvents();
349     }
350 
351     //终止渲染 关闭并清理glfw本地资源
352     glfwTerminate();
353     return 0;
354 }

片元着色器:

#version 330 core
out vec4 FragColor;
in vec2 TexCoord;
float alpha;

uniform int mixValue;
uniform sampler2D ourTextureB;
uniform sampler2D ourTextureT;
void main()
{
  
    if(mixValue == 1)
    {
        FragColor = texture(ourTextureB, TexCoord);
    }else{
      FragColor = texture(ourTextureT, TexCoord);
    }
   

};

顶点着色器:

#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec2 texCoord; 

out vec2 TexCoord;
void main()
{
   gl_Position = vec4(aPos.x,aPos.y,aPos.z,1.0);
   TexCoord = texCoord;
};

效果展示:

 

标签:贴图,10,1.0,OpenGL,0.0,TEXTURE,纹理,2D,GL
来源: https://www.cnblogs.com/8335IT/p/16414875.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有