如何将多个纹理加载到片段着色器中

时间:2017-07-06 06:06:15

标签: c++ opengl textures texture2d

所以我试图在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);

1 个答案:

答案 0 :(得分:3)

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

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

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

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

    2.1使用glActiveTexture

    设置活动纹理单元

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

    2.3使用glTexImage2D

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

    2.4使用glTexParameteri

  4. 设置活动纹理单元的参数
  5. 为了同时使用多个纹理,请确保它们具有唯一的名称纹理单元

    3.1将活动纹理单位设置为0

    3.2将一个名为纹理的绑定到活动纹理单元

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

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

    3.5将另一个名为纹理的绑定到活动纹理单元

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

    ...

  6. 当你完成后,不要忘记用glDeleteTextures删除所有命名纹理
  7. 命令的顺序不是唯一可能的命令,命令集不是最小的 - 这只是典型的。

    原始答案:

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

     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
    }