简体   繁体   中英

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

I loaded the material and texture information from the Obj file based on this code ( https://github.com/Bly7/OBJ-Loader ). Now I want to load Sponza and render it. However, there are 10 or more textures, and even if all are passed to the shader, it is necessary to correspond to the appropriate vertices. Looking at the result of loading from the Obj file, textures are assigned to each part.

Example.

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
.
. 
.

Textures are kept as an array, and each has a corresponding mesh index. In my opinion, when passing vertex information to the shader, it works well if you divide it by the number of meshes and pass the texture at the same time. However, I'm not sure if this idea is correct, and I've tried several methods but it doesn't work.

This is the current simple code.

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 want to correspond to the mesh index loaded with the "i" in the above code. Please let me know if my idea is wrong or if there is another way.

As your model has only one texture per mesh, I can suggest this simple code to use:

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);

The code much self-explaning. It first activates texture slot 0, then for every mesh it binds texture, vertex buffer, index or element buffer and does any preparation need to draw the mesh. Then it issues draw call.

Note that this is very basic example. Most models would look weird with this code. I would recommend to this tutorial from LearnOpenGL which explain this more broadly but in an easy way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM