如何将多个纹理加载到片段着色器中
How to load multiple textures into the fragment shader
所以我正在尝试在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);
Opengl 隐藏了很多上下文,所以你需要记住它。纹理有三个部分:
- 纹理名称- 只是一个整数,传递它。
-
活动纹理单元- 上下文事物,设置
GL_TEXTURE0
... - 纹理目标- 对于初学者来说,GL_TEXTURE_2D就是您所需要的。
以下是您需要执行的操作,以使2d纹理正常工作:
- 使用
glGenTextures
创建 opengl 纹理名称 -
使用以下一组操作设置纹理:
2.1 使用
glActiveTexture
设置活动纹理单元2.2 指定指定纹理绑定到的活动纹理单元的目标
glBindTexture
。为此,所有三个纹理部分都应该"在控制之下"。2.3 使用
glTexImage2D
为活动纹理单元指定二维纹理图像2.4 使用
glTexParameteri
设置活动纹理单元的参数 -
为了同时使用多个纹理,请确保它们具有唯一的名称和纹理单元:
3.1 将活动纹理单元设置为 0
3.2 将一个命名纹理绑定到活动纹理单元
3.3 将纹理单元(0( 传递给着色器
3.4 将活动纹理单位设置为 1
3.5 将另一个命名纹理绑定到活动纹理单元
3.6 将纹理单元(1(传递给着色器
。
完成后,不要忘记 - 删除所有命名纹理 ,并
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
}
相关文章:
- std::原子加载和存储都需要吗
- 如何加载(或映射)文件部分的最大大小,但适合在Windows上的RAM
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 为什么加载SDF会导致Mobilizer创建闭环错误
- C++atioglxx.pdb未加载错误glBufferData OpenGL
- 如何使用tinyxml2从XML加载父实体和子实体
- 如何在C++中使用pybind11加载一个pickle python列表
- 系统.将数组移交给c#中动态加载的c++DLL时发生AccessViolationException
- 当我尝试加载内核模块时,如何修复C++中的这个 malloc() 错误?
- 树莓上的 Libtorch 无法加载 pt 文件,但在 ubuntu 上工作
- Python ctypes:不会按预期加载 dll
- 为什么会出现 gettnig 运行时错误:加载类型为"_Bit_type"(stl_bvector.h) 的空指针?
- 我的程序有一个保存配置文件的GUI,如何双击此配置文件以直接加载带有配置数据的GUI?
- 保存/加载大量短数组到二进制文件
- 使用 SDL2 和SDL_image C++加载图像
- 无法使用加载库卸载注入的 dll (C++)
- 是否有原子加载非原子值的函数?
- 将 bmp 文件加载到 TSpeedButton 中
- 如何将多个纹理加载到片段着色器中
- 从文件加载后,顶点着色器和片段着色器都不会编译