OpenGL:如何使用一个变量将多个纹理传递给着色器

OpenGL : How can I pass multiple texture to a shader with one variable?

本文关键字:纹理 变量 何使用 一个 OpenGL      更新时间:2024-04-28

我根据以下代码从Obj文件加载了材质和纹理信息(https://github.com/Bly7/OBJ-Loader)。现在我想加载Sponza并渲染它。但是,有10个或更多的纹理,即使所有纹理都传递给着色器,也需要对应相应的顶点。从Obj文件加载的结果来看,纹理被指定给每个零件。

示例。

Mesh 0 : Pillar
position0(x, y, z), position1(x, y, z), uv0(x, y) ... 
diffuse texture : tex0.png
Mesh 1 : Wall
position0(x, y, z), position1(x, y, z), uv0(x, y) ... 
diffuse texture : tex1.png
.
. 
.

纹理保持为一个数组,每个纹理都有相应的网格索引。在我看来,将顶点信息传递给着色器时,如果将其除以网格数并同时传递纹理,效果会很好。然而,我不确定这个想法是否正确,我尝试了几种方法,但都不起作用。

这是当前的简单代码。

main.cpp :
do {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture[i]);  // texture[] : Array of textures loaded from obj file.
glUniform1i(glGetUniformLocation(shaderID, "myTex"), 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertex_position);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, texCoord);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);    
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element);
glDrawElements(GL_TRIANGLES, element_indices.size(), GL_UNSIGNED_INT, (void*)0);
} while(glfwWindowShouldClose(window) == 0);
Fragment shader :
layout(location = 0) out vec4 out_color;
// from vertex shader
in vec2 texCoord; 
uniform sampler2D myTex;
void main() {
out_color = texture(myTex, texCoord);
}

我想对应于加载有";i〃;在上面的代码中。如果我的想法是错误的,或者有其他方法,请告诉我。

由于您的模型每个网格只有一个纹理,我可以建议使用以下简单代码:

do {
glActiveTexture(GL_TEXTURE0);
glUniform1i(glGetUniformLocation(shaderID, "myTex"), 0);

for (unsigned int i = 0; i < mesh_count; i++) {
glcall(glBindTexture(type, texture[i]));

// Bind vertex and index (or element) buffer and setup vertex attribute pointers

// Draw mesh
}
} while (window_open);

这段代码是自我解释的。它首先激活纹理槽0,然后为每个网格绑定纹理、顶点缓冲区、索引或元素缓冲区,并进行绘制网格所需的任何准备工作。然后发出抽签通知。

请注意,这是一个非常基本的示例。使用此代码,大多数模型看起来都很奇怪。我建议使用LearnOpenGL的本教程,它可以更广泛但简单地解释这一点。