sampler2DArray - 设置和使用

时间:2018-04-29 21:08:09

标签: opengl glsl jogl

我正在学习OpenGL,我不得不使用sampler2DArray。我整天都在受折磨 - 一切都无济于事。我有两个问题:

  1. 如何创建纹理列表?
  2. 如何在着色器中使用sampler2DArray?
  3. 以下是我尝试创建纹理列表的结果:

    // textures - ids loaded textures
    private int createTextureArray(GL2 gl, int[] textures, int width, int height) {
            int layerCount = textures.length;
            int mipLevelCount = 1;
            IntBuffer texture = IntBuffer.allocate(1);
            gl.glGenTextures(1, texture);
            gl.glActiveTexture(GL.GL_TEXTURE0);
            gl.glBindTexture(GL2.GL_TEXTURE_2D_ARRAY, texture.get(0));
            gl.glTexStorage3D(GL2.GL_TEXTURE_2D_ARRAY, mipLevelCount, GL2.GL_RGBA8, width, height, layerCount);
    
            for (int i = 0; i<textures.length; i++) {
                 gl.glTexSubImage3D(GL2.GL_TEXTURE_2D_ARRAY, i, // error here
                         0, 0, 0,
                         width, height, layerCount,
                         GL2.GL_RGBA, GL2.GL_UNSIGNED_BYTE,
                         textures[i]);
    
            }
    
            // Always set reasonable texture parameters
            gl.glTexParameteri(GL2.GL_TEXTURE_2D_ARRAY, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR);
            gl.glTexParameteri(GL2.GL_TEXTURE_2D_ARRAY, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);
            gl.glTexParameteri(GL2.GL_TEXTURE_2D_ARRAY, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_EDGE);
            gl.glTexParameteri(GL2.GL_TEXTURE_2D_ARRAY, GL2.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP_TO_EDGE);
    
            return texture.get(0);
        }
    

    Shader示例:

    #version 130
    uniform sampler2DArray textures;
    varying vec2 UV;
    ...
    void main() {
       ...
       int layer = 0;
       gl_FragColor = texture2DArray(textures, vec3(UV, layer));
    }
    

    我将非常感谢你的帮助。

2 个答案:

答案 0 :(得分:2)

array texture 不是“纹理列表”。数组纹理是单个OpenGL纹理,其中单独具有许多准独立层。虽然您可以在概念上将数组纹理的每个层视为单独的概念纹理,但在OpenGL(和GLSL)中,它是单个对象

鉴于此,函数中的接口不正确。它应该返回一个纹理对象,它应该作为参数,而不是int的数组(注意:OpenGL对象是无符号整数),但是一个整数:要在该纹理中创建的数组图层。

如何在GLSL中使用数组纹理很简单。您的采样器uniform使用数组纹理采样器类型(例如sampler2DArray用于2D数组纹理)。将数组纹理绑定到您指定为采样器均匀分区的相同纹理图像单元(就像对非数组2D纹理一样)。

你的GLSL遗漏了一件事。没有texture2DArray功能。正确使用的函数只是texture。后GL 3.0中的纹理类型仅由参数指定,而不是由函数的名称指定。

答案 1 :(得分:1)

除了@NicolBolas已经说过的内容:着色器代码存在许多问题,主要是由于版本130中已弃用的功能:

  • 任何标准glsl版本中都没有方法texture2DArray。 EXT_texture_array扩展中有一个,但是从未集成过,因为在glsl 130中,所有纹理查找函数(texture2D,texture3D,...)都被重载的texture命令所取代。如果您的目标是130而没有扩展程序,则应使用
    texture(textures, vec3(UV, layer))
  • glsl 130中不推荐使用varying关键字,应将其替换为in / out

  • gl_FragColor已弃用,应使用用户定义的输出(out)变量。

您可能希望查看GLSL 130 Spec的第1.2.1节,其中介绍了弃用以及如何处理这些弃用。总的来说,我鼓励大家今天不要使用130,除非有特殊原因。更好地转向OpenGL 3.3+核心配置文件和GLSL 330 +。