【问题标题】:Multitexture rendering (glActiveTexture beyong GL_TEXTURE0) not working [duplicate]多纹理渲染(glActiveTexture beyong GL_TEXTURE0)不起作用[重复]
【发布时间】:2020-11-08 19:26:57
【问题描述】:

我一直在尝试使用 sampler2D 数组 + glActiveTexture() 将多个纹理发送到我的着色器。 使用 GL_TEXTURE0 和带有索引 0 的 sampler2D 数组发送的第一个纹理效果很好。但是,第二个纹理不渲染(重复第一个纹理)。 到目前为止,我一直在网上搜索无济于事的解决方案。 所以,我来了。

如果您能伸出援手,我们将不胜感激。如果您需要任何其他信息,请告诉我。

这是我尝试调试的一些东西。

  1. 切换枚举 GL_TEXTURE0 和 GL_TEXTURE1 只会渲染第二个纹理 (head2.png)。这让我相信我的纹理文件解析工作正常。
  2. glActiveTexture 之后的glEnable(GL_TEXTURE_2D) 无法解决问题。
  3. 确保我作为浮点数发送的纹理 ID 抓取了正确的索引。例如color = aa[int(tid)] 其中 aa 是具有不同颜色的 vec4 数组。
  4. 即使我在着色器中硬编码索引,它也不会显示第二个纹理。事实上,所有 32 个索引将始终显示第一个纹理。

下面是我的主文件和使用的一些方法。

  • main.cxx
// C++
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
#include <stdlib.h>

// OpenGL
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <FreeImage.h>

// Custom
#include "window.h"
#include "math.h"
#include "shader.h"

#include "texture.h"

using namespace std;
using namespace JDEngine;


int main()
{
    Window window("Test", 800, 800);
    window.SetClearColor(0.0, 0.0, 0.0, 1.0);


    Shader* shader =  new Shader("src/shaders/testvert.shader", "src/shaders/testfrag.shader");

    shader->Enable();
    shader->SetUniformMat4("pr_matrix", Mat4::Orthographic(-4,4,-4,4,-4,4));
    shader->Disable();


    GLfloat data[24] = {0,0,0,0,1,0,1,0,0,1,1,0, -1,-1,0,-1,0,0,0,-1,0,0,0,0};
    GLfloat uv[16] = {0,0,0,1,1,0,1,1, 0,0,0,1,1,0,1,1};
    GLfloat tid[8] = {0,0,0,0, 1,1,1,1}; // 0s going into GL_TEXTURE0, 1s to GL_TEXTURE1
    GLuint ind[12] = {0,1,2,2,1,3, 4,5,6,6,5,7};


    // For buffers & vertices
    GLuint vao, vbo, vbouv, vbotid, ibo;
    Texture* tex1 = new Texture("data/body2.png"); // yellow square
    Texture* tex2 = new Texture("data/head2.png"); // blue square
    cout << endl << tex1->GetTID() << " " << tex2->GetTID(); // spits out "1 2"

    glGenVertexArrays(1, &vao);    // Vertex Array Object
    glBindVertexArray(vao);

    glGenBuffers(1, &vbo);         // Vertex Buffer Object
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);


    glGenBuffers(1, &vbouv);         // Vertex Buffer Object
    glBindBuffer(GL_ARRAY_BUFFER, vbouv);
    glBufferData(GL_ARRAY_BUFFER, sizeof(uv), uv, GL_STATIC_DRAW);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, 0);


    glGenBuffers(1, &vbotid);         // Vertex Buffer Object
    glBindBuffer(GL_ARRAY_BUFFER, vbotid);
    glBufferData(GL_ARRAY_BUFFER, sizeof(tid), tid, GL_STATIC_DRAW);
    glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(GLfloat), 0);
    glEnableVertexAttribArray(2);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindVertexArray(0);

    glGenBuffers(1, &ibo);         // Index Buffer Object
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(ind), ind, GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);




    //glEnable(GL_DEPTH_TEST);
    while (!window.ShouldClose())
    {
        window.Clear();
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        // *********************************************************************
        shader->Enable();
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, tex1->GetTID());

        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, tex2->GetTID());

        glBindVertexArray(vao);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
        glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_INT, nullptr); // seeing two yellow squares (GL_TEXTURE0 worked but not 1)
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
        // *********************************************************************
        window.Update();
    }
    window.Close();
    return 0;
}

  • texture.cxx
#include "texture.h"
namespace JDEngine
{
    // ********************************************************************
    Texture::Texture(const string& filename)
    : mFileName(filename)
    {
        mTID = Load();
    }
    // ********************************************************************
    GLuint Texture::Load()
    {
        BYTE* pixels = LoadImage(mFileName.c_str(), &mWidth, &mHeight);

        GLuint result;
        glGenTextures(1, &result);
        glBindTexture(GL_TEXTURE_2D, result);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
        glBindTexture(GL_TEXTURE_2D, 0);

        free(pixels);

        return result;
    }
    // ********************************************************************
}

  • testfrag.shader
#version 330 core

layout (location = 0) out vec4 color;

uniform sampler2D textures[32];

in DATA
{
    vec4 pos;
    vec2 uv;
    float tid;
} fs_in;

void main()
{
    color = texture(textures[int(fs_in.tid + 0.5)], fs_in.uv);
}

【问题讨论】:

    标签: c++ opengl shader rendering textures


    【解决方案1】:

    textures[int(fs_in.tid + 0.5)] 是未定义的行为,因为textures 的类型为sampler2D,而fs_in.tid 是片段着色器输入,而不是Dynamically uniform expression

    OpenGL Shading Language 4.60 Specification - 4.1.7. Opaque Types

    纹理组合采样器类型是不透明类型,其声明和行为与上述不透明类型相同。当在着色器中聚合成数组时,只能使用动态统一的积分表达式对它们进行索引,否则结果是不确定的。 [...]


    我建议使用sampler2DArray(请参阅Sampler)而不是sampler2D 的数组。
    当您使用sampler2DArray 时,您根本不需要任何索引,因为“索引”在纹理查找时被编码在纹理坐标的第三个分量中(参见texture)。

    【讨论】:

    • 感谢您的建议。也许我确实应该寻找 2Darray。但是,我确实尝试在我的着色器中使用硬编码索引。但这并没有解决问题(即使我使用蓝色索引时也只看到黄色框)。这也属于你的解释吗?例如不是统一的整数表达式?
    • 在哪里将纹理单元索引分配给纹理采样器制服?
    • 例如,我将 color = texture(textures[...]) 换成了 texture(textures[1])。
    猜你喜欢
    • 2021-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-01
    相关资源
    最近更新 更多