• LearnOpenGL学习笔记(六)——纹理单元


    #version 330 core
    out vec4 FragColor;
    in vec3 ourColor;
    in vec2 TexCoord;
    
    uniform sampler2D ourTexture;
    void main()
    {
    FragColor = texture(ourTexture, TexCoord);
    }

          在刚才的程序中,关于片段着色器的中我们声明了一个采样器(Sampler),一般来讲我们需要用glUniform1i()函数进行将纹理对象(数据),从CPU中传入显存中的着色器这样一个过程。但是现实是我们没有这么做,我们只是在主函数里绑定了目标,就自动传入到片段着色器里面了。这就是我们忽视的一个概念——纹理单元。

        一个纹理的位置值通常称为一个纹理单元(Texture Unit)。之所以我们没有去用glUniform1i()函数,是因为一个纹理的默认纹理单元是0,它是默认的激活纹理单元。

    如果我们只传入一个纹理对象,那么倒是不用担心纹理单元的问题,反正自动传入,你绑定就好了。但是当有多个纹理对象要传入的时候,我们必须指定纹理对象,然后再主函数用glUniform1i()函数一个一个对接到着色器内部完毕,否则一切就乱套了。

          纹理单元的主要目的是让我们在着色器中可以使用多于一个的纹理。

    使用glUniform1i设置采样器:

           使用glUniform1i()函数作为着色器内部和程序沟通的桥梁需要知道两件事情,一个是在着色器内部接受信息的对象为位置
    (layout)。一个是外界的数据对象。严格来讲传入数据本身也不是这个函数做的,这个函数是告诉着色器那个纹理对象对应哪个采样
    器对象。至于传入这个是没有函数对应的,就是激活纹理对象,绑定纹理对象,激活下一个纹理对象,绑定下一个对象。就可以告诉计算
    机全部了。
    glActiveTexture(GL_TEXTURE0); // 在绑定纹理之前先激活纹理单元 
    glBindTexture(GL_TEXTURE_2D, texture);

    渲染之前设置:

    ourShader.use(); // 别忘记在激活着色器前先设置uniform!
    glUniform1i(glGetUniformLocation(ourShader.ID, "texture1"), 0); // 手动设置
    ourShader.setInt("texture2", 1); // 或者使用着色器类设置
    
    while(...) 
    {
        [...]
    }

    渲染过程中:

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture1);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, texture2);
    
    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    //glBindTexture函数调用会绑定这个纹理到当前激活的纹理单元,纹理单元GL_TEXTURE0默认总是被激活,所以我们在前面的例子
    里当我们使用glBindTexture的时候,无需激活任何纹理单元。

      

  • 相关阅读:
    关于RGB屏调试的一些知识(转)
    分享调试SI4432的一些小经验(转)
    音频压缩SPEEX应用,对讲机
    Codec 2 开源语音编解码器
    java导读
    视频监控知识汇总
    “inno setup打包,win7下安装没有桌面快捷方式,xp下安装正常”
    MFC设置窗体大小SetWindowPos
    C++中运行外部程序
    C++调用外部应用程序的方法的整理总结(常用)
  • 原文地址:https://www.cnblogs.com/zobol/p/10739458.html
Copyright © 2020-2023  润新知