【问题标题】:How to load multiple textures into the fragment shader如何将多个纹理加载到片段着色器中
【发布时间】:2017-12-09 23:47:43
【问题描述】:

因此,我尝试在 OpenGL 中对对象进行纹理处理,并且我有两个纹理要在片段着色器(rock.tga 和 Grass.tga)中混合在一起。我的片段着色器:

out vec3 color;

in vec2 uv;

uniform sampler2D grasstexture;
uniform sampler2D rocktexture;

要加载 sampler2D 纹理,这是我在 C++ 的头文件中所做的:

OpenGP::EigenImage<vec3> image;
OpenGP::imread("grass.tga", image);

glGenTextures(0, &_tex);
glBindTexture(GL_TEXTURE_2D, _tex);

check_error_gl();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
check_error_gl();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F,
             image.cols(), image.rows(), 0,
             GL_RGB, GL_FLOAT, image.data());
check_error_gl();
tex_id = glGetUniformLocation(_pid, "grasstexture");
glUniform1i(tex_id, 0);

这会将草纹理加载到我的片段着色器中。现在我想知道的是如何加载多个纹理。我不能将上面的代码复制两次,因为一个纹理总是被另一个覆盖。那么如何将多个纹理加载到片段着色器中呢?

编辑:这里是我的 _tex 声明的地方:

    class Mesh{
    protected:
        GLuint _tex;

        GLuint _vpoint;    ///< memory buffer
        GLuint _vnormal;   ///< memory buffer

    public:
        GLuint getProgramID(){ return _pid; }

        void init(){
//code for the textures goes in here

这是我的更新代码:

OpenGP::EigenImage<vec3> image;
glActiveTexture(GL_TEXTURE0);
OpenGP::imread("grass.tga", image);

//glGenTextures(1, &_tex);
glBindTexture(GL_TEXTURE_2D, _tex);

check_error_gl();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
check_error_gl();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F,
             image.cols(), image.rows(), 0,
             GL_RGB, GL_FLOAT, image.data());
check_error_gl();
tex_id = glGetUniformLocation(_pid, "grasstexture");
glUniform1i(tex_id, 0);

glActiveTexture(GL_TEXTURE1);
OpenGP::imread("rock.tga", image);

//glGenTextures(0, &_tex);

glBindTexture(GL_TEXTURE_2D, _tex);

check_error_gl();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
check_error_gl();
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB32F,
             image.cols(), image.rows(), 0,
             GL_RGB, GL_FLOAT, image.data());
check_error_gl();
tex_id = glGetUniformLocation(_pid, "rocktexture");
glUniform1i(tex_id, 1);

【问题讨论】:

    标签: c++ opengl textures texture2d


    【解决方案1】:

    Opengl 隐藏了很多上下文,因此您需要牢记这一点。你有纹理的三个部分:

    • 纹理名称 - 只是一个整数,传递它。
    • 活动纹理单元 - 上下文事物,设置为GL_TEXTURE0...
    • 纹理目标 - 对于初学者来说,GL_TEXTURE_2D 就是你所需要的。

    为了使 2d 纹理正常工作,您需要执行以下操作:

    1. 使用glGenTextures 创建opengl 纹理名称
    2. 使用以下操作设置纹理:

      2.1 用glActiveTexture设置活动纹理单元

      2.2 指定命名纹理绑定到的活动纹理单元的目标glBindTexture。为此,所有三个纹理部分都应该“在控制之下”。

      2.3 使用glTexImage2D

      为活动纹理单元指定一个二维纹理图像

      2.4 使用glTexParameteri为活动纹理单元设置参数

    3. 为了同时使用多个纹理,请确保它们具有唯一的名称和纹理单元:

      3.1 设置活动纹理unit为0

      3.2 将一个 named 纹理绑定到活动纹理 unit

      3.3 将纹理unit (0) 传递给着色器

      3.4 将活动纹理单元设置为 1

      3.5 将另一个 named 纹理绑定到活动纹理 unit

      3.6 将纹理unit (1) 传递给着色器

      ...

    4. 完成后不要忘记删除所有带有glDeleteTextures 的命名纹理

    命令的顺序不是唯一可能的,命令集也不是最少的——它只是典型的。


    原答案:

    您需要像这样设置下一个活动纹理:

     glActiveTexture(GL_TEXTURE1);
    

    在绑定之前绑定下一个纹理。 它也可以像这样工作:

    std::vector<std::string> textures = {"grass.tga", "rock.tga"};
    for(int i = 0; i < textures.size(); i++) {
        glActiveTexture(GL_TEXTURE0 + i);
        // create the texture
    }
    

    【讨论】:

    • 它不工作。我会用我最新的代码更新我的问题。基本上发生的事情是我的岩石纹理看起来非常白。我什至不确定它是岩石纹理还是我的草纹理的真正明亮版本。你知道我做错了什么吗?我还注释掉了我的 glGenTextures 行,因为由于某种原因,我的纹理根本不会出现。
    猜你喜欢
    • 2013-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-23
    • 1970-01-01
    相关资源
    最近更新 更多