看来我的useProgram没有绑定着色器,所以我无法为其设置统一。 但是,当我在着色器的编译代码中使用GlUseProgram时,我可以设置制服。 我正在使用一个资源管理器来处理着色器和纹理,并使用一个Game文件来处理着色器/文本器/游戏设置。

Shader.h:

class Shader
{
    Shader() {};
    void Compile(const std::string& vertexSource, const std::string& fragmentSource, const char* geometrySource = nullptr);
    Shader  &Use();
}

Shader.cpp

Shader & Shader::Use()
}
    glUseProgram(this->ID);
    return *this;
{

void Shader::Compile(const std::string& vertexSource, const std::string& 
    fragmentSource, const char* geometrySource)
{
    unsigned int vShader, fShader, gShader;

    const char* src1 = vertexSource.c_str();
    const char* src2 = fragmentSource.c_str();

    vShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vShader, 1, &src1, NULL);
    glCompileShader(vShader);
    checkCompileErrors(vShader, "VERTEX");

    fShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fShader, 1, &src2, NULL);
    glCompileShader(fShader);
    checkCompileErrors(fShader, "FRAGMENT");

    if (geometrySource != nullptr)
    {
        gShader = glCreateShader(GL_GEOMETRY_SHADER);
        glShaderSource(gShader, 1, &geometrySource, NULL);
        glCompileShader(gShader);
        checkCompileErrors(gShader, "error");
    }

    this->ID = glCreateProgram();
    glAttachShader(this->ID, vShader);
    glAttachShader(this->ID, fShader);

    if (geometrySource != nullptr)
    {
        glAttachShader(this->ID, gShader);
    }
    glLinkProgram(this->ID);
    checkCompileErrors(this->ID, "PROGRAM");

    //glUseProgram(this->ID);

    glDeleteShader(vShader);
    glDeleteShader(fShader);
    if (geometrySource != nullptr)
    {
        glDeleteShader(gShader);
    }
}

您可以看到我在哪里注释掉了GlUseProgram。 如果我不对其进行注释,则着色器将正常工作,但如果对它进行注释,则它将不起作用。

ResourceManager.h:

class ResourceManager
{
public:
    // Resource storage
    static std::unordered_map<std::string, Shader>    shader;
    static Shader loadShader(const std::string& vShaderSource, std::string filename);
    static Shader getShader(std::string name);
    static Shader loadShaderFromFile(const std::string& vShaderFile);

ResourceManager.cpp

std::unordered_map<std::string, Shader> ResourceManager::shader;
Shader ResourceManager::loadShader(const std::string& vShaderSource, std::string filename)
{
    shader[filename] = loadShaderFromFile(vShaderSource);
    return shader[filename];
}

Shader ResourceManager::getShader(std::string filename)
{
    return shader[filename];
}

Shader ResourceManager::loadShaderFromFile(const std::string& vShaderFile)
{
    enum class ShaderType
    {
        none = -1, vertex = 0, fragment = 1
    };

    std::fstream path(vShaderFile);
    std::stringstream ss[2];
    std::string string;
    ShaderType type = ShaderType::none;

    while (std::getline(path, string))
    {
        if (string.find("shader") != std::string::npos) 
        {
            if (string.find("vertex") != std::string::npos)
            {
                type = ShaderType::vertex;
            }
            if (string.find("fragment") != std::string::npos)
            {
                type = ShaderType::fragment;
            }
        }
        else
            ss[(int)type] << string << "\n";
    }

    std::string vertexCode = ss[0].str();
    std::string fragmentCode = ss[1].str();
    const char* geomtryCode = nullptr;

    Shader shader;
    shader.Compile(vertexCode, fragmentCode);

    return shader;
}

最后。 Game.cpp:

void Game::Init()
{
    ResourceManager::loadShader("res/Shader/shader.shader", "sprite");
    ResourceManager::getShader("sprite").Use().setUniform1i("image", 0);
    ResourceManager::getShader("sprite").setUniformMatrix4fv("projection", projection);
}

有人可以解释为什么它似乎不起作用吗?

#1楼 票数:0

4.6规范 7.1节中有关DeleteShader()它仅表示:

如果着色器未附加到任何程序对象,则将其立即删除。 否则,着色器将标记为删除,并且在不再附加到任何程序对象时将被删除。

在7.3节中,关于UseProgram()

如果程序尚未成功链接,则会生成INVALID_OPERATION错误。 当前渲染状态未修改。

使用程序对象时,应用程序可以自由修改附加的着色器对象,编译附加的着色器对象,附加其他着色器对象以及分离着色器对象。 这些操作不会影响程序对象的链接状态或可执行代码。

您会看到,显然,在成功链接之后,您可以在任何地方调用glUseProgram()
如果对您不起作用,则可能是gfx卡驱动程序中的错误。

但是请再次阅读并注意它会告诉您分离着色器,而不是删除着色器。

简而言之,请先删除着色器( glDetachShader ),然后再将其删除( glDeleteShader )。

  ask by anttton translate from so

未解决问题?本站智能推荐:

1回复

影响着色器流量和性能的均匀性

我正在用OpenGL片段着色器进行实验,方法是通过两遍(一次水平,一次垂直)进行巨大的模糊处理(300 * 300)。 我注意到,以均匀的方向(vec2)传递方向比直接在代码中写入(140至12 fps)要慢大约10倍。 即: 似乎比以下速度更快: 创建两个使用不同制服的程序不会
1回复

在着色器上实现GL_REPEAT

我正在尝试在 glsl 上实现 GL_REPEAT。 我使用 mod 函数写了一些东西,但是两个纹理结合起来存在问题。 你能解释为什么它不起作用吗? 在主要: 我的着色器代码如下所示:
1回复

Open_gl1颜色着色器

我认为着色器有问题。 应该打印1种颜色的纹理。 没用 如果我改为绑定3色(GL_RGB)纹理,它会像原始图片一样显示。 我绑定这样的纹理: 数组现在是恒定矩形大小的测试版本: 然后,我调用负责选择要绘制的字母并将其绘制的函数: 这是声明: 顶点着色器。 注意“ InPo
1回复

gl_PointCoord奇怪的OpenGL片段着色器行为

我正在尝试绘制二维线,在两种颜色之间具有平滑的渐变。 我的应用程序允许我单击并拖动,线段的第一个点是第一个单击点,线的第二个点跟随鼠标光标的位置。 我使用glDrawArrays(GL_LINES, 0, points.size());绘制glDrawArrays(GL_LINES, 0,
1回复

C++打开GL着色器编译失败

我正在尝试学习 cpp 中的 gl 并尝试创建一些着色器,阅读其文档并遵循 yt 教程。 它只是编译失败。 昨天它只是在控制台着色器“+ filePath +”中打印,今天编译失败,它打印: 错误:0:7:'gl_position':未声明的标识符错误:0:7:“xy”:字段选择需要左侧的结构、向
1回复

GL_POINTS着色器中的纹理样本

我有一个着色器,可以绘制纯色的粒子。 我想让着色器对FBO纹理进行采样,以便每个粒子可以对其后面的颜色起作用。 看起来应该很简单,但不是。 我已经简化了代码,以至于我希望我的FBO可以在每个粒子的表面上绘制,缩小。 丑陋,但它至少会证明我的粒子可以对纹理进行采样。 相反,每个粒子只是
1回复

面向简单着色器的GL程序的OO架构

我正在设计一个OO程序(用C ++),该程序处理用OpenGL实现的适度简单的图形。 我已经为我的Drawable对象编写了一些顶点着色器程序。 另外,我在Shader类中封装了着色器管理(编译,链接和用法)。 我的问题是,由于我所有的类都将使用这套小的着色器来渲染可视对象,并且它们都具
1回复

如何正确链接OpenGL着色器的打开GL法线

我正在尝试在OpenGL 2.1和Qt5中渲染一个简单的地图。 但我在非常基本的问题上失败了。 我在这里展示的是表面法线。 我有4个由三角形几何体组成的物体。 简单的geoetry是一个动态分配的Vertex数组,其中Vertex是两个QVector3D ,Qt中预定义的3D位置类。