2017-07-06 73 views
1

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

回答

3

Opengl的隐藏了许多它的上下文中,所以你需要记住它。你有质感的三个部分:

  • 纹理 - 只是一个整数,各地通过。
  • 活动纹理单元 - 方面的事情,与GL_TEXTURE0设置...
  • 纹理目标 - 对于初学者GL_TEXTURE_2D是你所需要的。

以下是你需要什么,以获得2D纹理的工作要做:

  1. glGenTextures
  2. 设置了以下行动设置了纹理创建的OpenGL纹理

    2.1集活性纹理单元glActiveTexture

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

    2.3指定与glTexImage2D

    2为活性纹理单元二维纹理图像。4个为活动纹理单元设置参数与glTexParameteri

  3. 为了同时使用多重纹理确保它们具有独特的纹理单元

    3.1设置活动纹理单元到0

    3.2绑定一个命名为纹理到活动纹理单位

    3.3通行证纹理单元(0)到着色器

    3.4设置活动纹理单元1

    3.5绑定另一个命名纹理活性纹理单元

    3.6通行证纹理单元(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 
} 
+0

它不工作。我会用我最新的代码更新我的问题。基本上发生的事情是,我的岩石纹理显得非常白。我甚至不确定这是岩石质地还是我草地纹理的非常明亮的版本。你知道我做错了什么吗?我也评论了我的glGenTextures系列,因为某些原因使我的纹理根本不出现。 –

+0

@SarahMacleod我已经更新了答案 – teivaz

相关问题