How can I pass multiple textures to a single shader?

前端 未结 2 817
我寻月下人不归
我寻月下人不归 2020-12-13 06:44

I am using freeglut, GLEW and DevIL to render a textured teapot using a vertex and fragment shader. This is all working fine in OpenGL 2.0 and GLSL 1.2 on Ubuntu 14.04.

相关标签:
2条回答
  • 2020-12-13 07:06

    It is very simple, really. All you need is to bind the sampler to some texture unit with glUniform1i. So for your code sample, assuming the two uniform samplers:

    uniform sampler2D DecalTex;  // The texture  (we'll bind to texture unit 0)
    uniform sampler2D BumpTex;   // The bump-map (we'll bind to texture unit 1)
    

    In your initialization code:

    // Get the uniform variables location. You've probably already done that before...
    decalTexLocation = glGetUniformLocation(shader_program, "DecalTex");
    bumpTexLocation  = glGetUniformLocation(shader_program, "BumpTex");
    
    // Then bind the uniform samplers to texture units:
    glUseProgram(shader_program);
    glUniform1i(decalTexLocation, 0);
    glUniform1i(bumpTexLocation,  1);
    

    OK, shader uniforms set, now we render. To do so, you will need the usual glBindTexture plus glActiveTexture:

    glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
    glBindTexture(GL_TEXTURE_2D, decalTexHandle);
    
    glActiveTexture(GL_TEXTURE0 + 1); // Texture unit 1
    glBindTexture(GL_TEXTURE_2D, bumpHandle);
    
    // Done! Now you render normally.
    

    And in the shader, you will use the textures samplers just like you already do:

    vec4 a = texture2D(DecalTex, tc);
    vec4 b = texture2D(BumpTex,  tc);
    

    Note: For techniques like bump-mapping, you only need one set of texture coordinates, since the textures are the same, only containing different data. So you should probably pass texture coordinates as a vertex attribute.

    0 讨论(0)
  • 2020-12-13 07:27

    instead of using:

    glUniform1i(decalTexLocation, 0);
    glUniform1i(bumpTexLocation,  1);
    

    in your code, you can have:

    layout(binding=0) uniform sampler2D DecalTex;  
    // The texture  (we'll bind to texture unit 0)
    layout(binding=1)uniform sampler2D BumpTex;   
    // The bump-map (we'll bind to texture unit 1)
    

    in your shader. That also mean you don't have to query for the location.

    0 讨论(0)
提交回复
热议问题