微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么我的 sampler2D 数组总是使用纹理单元 0? 纹理标题纹理来源

如何解决为什么我的 sampler2D 数组总是使用纹理单元 0? 纹理标题纹理来源

纹理标题

class texture
{
public:
    texture(int tex_unit,const std::string& filename);

    gluint get_texture() { return tex; }
    GLint get_tex_unit() { return unit; }
    std::string get_filename() { return filename; }

private:
    gluint tex;
    GLint unit; 
    std::string filename;
};

纹理来源

texture::texture(int _unit,const std::string& _filename)
    : unit(_unit),filename(_filename)
{
    int width,height,channels;
    uint8_t* data = stbi_load(filename.c_str(),&width,&height,&channels,3);
    if (!data)
        throw std::runtime_error("texture: " + std::string(stbi_failure_reason()));

    glGenTextures(1,&tex);
    glActiveTexture(GL_TEXTURE0 + unit);
    glBindTexture(GL_TEXTURE_2D,tex);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D,GL_RGBA,width,GL_RGB,GL_UNSIGNED_BYTE,data);

    glBindTexture(GL_TEXTURE_2D,0);

    stbi_image_free(data);
}

创建了两个纹理,texture::unit 设置为 0 和 1。

scene_textures["background"] = std::make_shared<texture>(0,"data/milkyway.bmp");
scene_textures["earth"] = std::make_shared<texture>(1,"data/earth.bmp");

然后在我运行(计算)着色器之前,我将纹理绑定到正确的纹理单元(为了清晰起见进行了简化)。

auto background = scene_textures["background"];
auto earth = scene_textures["earth"];

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,background->get_texture());
gluniform1i(rt_shader->get_uniform("textures[0]"),0);

glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_2D,scene_textures["earth"]->get_texture());
gluniform1i(rt_shader->get_uniform("textures[1]"),1);

在着色器中有一个包含 8 个 sampler2D 的数组,我使用纹理函数来查找纹素,例如

uniform sampler2D textures[8];
texture(textures[0],uv)
texture(textures[1],uv)

问题是着色器总是使用纹理单元 0(背景纹理),无论我使用纹理 [0] 还是纹理 [1]。我不确定我在这里做错了什么。我会尝试使用 sampler2DArray,但我想先知道这里的问题是什么。

更新: 为了索引 sample2D 数组,我使用了一个存储在 SSBO (scene_objects.mat.texture) 中的变量。访问 scene_objects 的其余着色器代码按预期工作。

struct physics
{
    float attraction;
};

struct material
{
    float diffuse_color[3];
    float specular_exponent;
    int texture;
};

struct scene_object
{
    int type;
    float position[3];

    // sphere
    float radius;

    material mat;
    physics phys;
};

layout (std430,binding = 1) buffer scene_objects
{
    int obj_cnt;
    scene_object objects[];
};

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。