当前位置:   article > 正文

OpenGL之纹理数组和无绑定纹理_opengl纹理数组

opengl纹理数组

最近要学习纹理数组,网上查了下资料并不多,可能是本身用到就比较少吧,正好学习了下也算补充下笔记了。

首先,纹理数组有两种:

目录

sampler2DArray textures

sampler2D textures[16]


1.sampler2DArray textures

从网上搜索的结果来看,第一种用的可能是更多的。sampler2DArray也是个类型,和普通单张纹理不一样的地方可能这是一个纹理集合体吧。所以,它在绑定纹理时也只需要一个纹理ID,使用时也是一个纹理单元,和普通单张纹理绑定和使用是一样的,只是在创建加载纹理时有些差别,具体从代码里看:

  1. //生成纹理
  2. glGenTextures(1, &textureID);
  3. //绑定纹理
  4. glBindTexture(GL_TEXTURE_2D_ARRAY, textureID); //绑定时选择纹理数组类型
  5. //设置如何从数据缓冲区去读取图像数据
  6. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  7. //设置纹理过滤的参数
  8. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
  9. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
  10. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  11. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  12. //接下来就是不同的地方了--
  13. //两种分配方式都可以,glTexImage3D好像是老版本的方式
  14. glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 1000, 1000, 2);
  15. //glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 1000, 1000, 2, 0,GL_RGB, GL_UNSIGNED_BYTE, NULL);
  16. const char* path[2] = { "D:\\My Document\\1213.jpg","D:\\My Document\\R-C.jpg" };
  17. //加载图片
  18. for (int i = 0; i < 2; i++) {
  19. unsigned char* pBits;
  20. int nWidth, nHeight, nComponents;
  21. // Read the texture bits 读取纹理数据
  22. stbi_set_flip_vertically_on_load(true); //告诉stb_image.h在y轴上翻转加载的纹理。
  23. pBits = stbi_load(path, &nWidth, &nHeight, &nComponents, 0);
  24. //更新纹理 这里把深度进行了修改,下面的i就代表深度
  25. glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, i, nWidth, nHeight, 1, GL_RGB, GL_UNSIGNED_BYTE, pBits);
  26. stbi_image_free(pBits);
  27. }

纹理使用时:

  1. glActiveTexture(GL_TEXTURE2);
  2. glBindTexture(GL_TEXTURE_2D_ARRAY, textureID);
  3. glUniform1i(glGetUniformLocation(programObject[0], "TextureArray"), 2);//纹理传入binding=2

着色器纹理使用:

  1. #version 430 core
  2. out vec4 FragColor;
  3. in vec2 vTexPosition1;
  4. layout(binding = 2) uniform sampler2DArray TextureArray;
  5. void main()
  6. {
  7. FragColor = texture(TextureArray, vec3(vTexPosition1,1));//纹理坐标第三位为纹理序号索引
  8. }

经过加载不同纹理发现,如果尺寸大于设置的尺寸,纹理就加载不出来了,尺寸小了也会出现填不满的现象,所以个人以为,这种方式可能只适合加载统一尺寸的多张纹理。

2.sampler2D textures[16]

这一种就是真正意义的纹理数组了,起初我以为可以像传入普通数组一样传入纹理,并用glUniform1iv去传入,但是我不知道此刻应该先绑定哪一个纹理ID,尝试下来都没有成功加载。之后又通过UBO的方式将纹理ID数组传入,依然没有加载出纹理。之后学习无绑定纹理,才了解到纹理与着色器的联系并不是通过纹理ID,所以索性通过无绑定的方式加载纹理数组。

  1. GLuint textureArray[3]; //纹理数组
  2. //此处省略纹理创建过程
  3. //.....
  4. //
  5. GLuint64 handles[3]; //纹理句柄
  6. for (int i = 0; i < 3; i++)
  7. {
  8. glBindTexture(GL_TEXTURE_2D, textureArray[i]);
  9. handles[i] = glGetTextureHandleARB(textureArray[i]);
  10. glMakeTextureHandleResidentARB(handles[i]);
  11. }

使用纹理时有两种,我都尝试了:

  1. //第一种--单独的纹理数组--uniform sampler2D textArray[3];
  2. glUniformHandleui64vARB(glGetUniformLocation(programObject[0], "textArray"), 3,handles);
  3. //第二种--被UBO包裹的纹理数组
  4. //glBindBuffer(GL_UNIFORM_BUFFER, UBO);
  5. //glBufferSubData(GL_UNIFORM_BUFFER, 0, 3*sizeof(GLuint64), &handles);

着色器里写法:

  1. #version 430 core
  2. #extension GL_ARB_bindless_texture : require //无绑定纹理必须要有的
  3. out vec4 FragColor;
  4. in vec2 vTexPosition1;
  5. //第一种--单独的纹理数组
  6. //uniform sampler2D textArray[3];
  7. //第二种--被UBO包裹的纹理数组
  8. layout(binding = 0) uniform UBO_data
  9. {
  10. sampler2D textArray[3];
  11. };
  12. void main()
  13. {
  14. //纹理采样
  15. FragColor = texture(textArray[0], vTexPosition1);//以数组成员方式采样
  16. }

经过试验发现,这种方式加载的纹理尺寸可以不受限制了,而且加载出来都可以自适应窗口。

之后想尝试绑定的方式加载,如果有大佬有办法,看到的话希望可以指点一下。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/509889
推荐阅读
相关标签
  

闽ICP备14008679号