当前位置: 首页 > 知识库问答 >
问题:

glUniform4fv结果GL_INVALID_OPERATION

徐兴昌
2023-03-14

嘿,我有一个抽象所有与着色器相关的类,叫做shader。cpp

#include "Shader.h"
#include "Renderer.h"

#include <iostream>
#include <fstream>

Shader::Shader()
{
    GLCALL(m_RenderedID = glCreateProgram());
}


Shader::~Shader()
{
    GLCALL(glDeleteProgram(m_RenderedID));
}

void Shader::Bind() const
{
    GLCALL(glUseProgram(m_RenderedID));
}

void Shader::Unbind() const
{
    GLCALL(glUseProgram(0));
}

std::string ParseShader(const std::string& path)
{
    std::ifstream ifs(path);
    return std::string((std::istreambuf_iterator<char>(ifs)),
        (std::istreambuf_iterator<char>()));
}

static unsigned int CompileShader(unsigned int type, const std::string& source)
{
    GLCALL(unsigned int id = glCreateShader(type));
    const char* src = source.c_str();
    GLCALL(glShaderSource(id, 1, &src, nullptr));
    GLCALL(glCompileShader(id));

    int result;
    GLCALL(glGetShaderiv(id, GL_COMPILE_STATUS, &result));

    if (result == GL_FALSE)
    {
        int length;
        glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
        char* message = (char*)alloca(length * sizeof(char));
        GLCALL(glGetShaderInfoLog(id, length, &length, message));
        std::cout << "Failed to compile shader!" << std::endl;
        std::cout << message << std::endl;
        glDeleteShader(id);
        return 0;
    }
    return id;
}

void Shader::Attach(const unsigned int type, const std::string& path)
{
    unsigned int id = CompileShader(type, ParseShader(path));
    if (m_ShaderFiles.find(id) == m_ShaderFiles.end())
        m_ShaderFiles[id] = ShaderFile({ type, path });
    GLCALL(glAttachShader(m_RenderedID, id));
}

void Shader::Link()
{
    int result;

    GLCALL(glLinkProgram(m_RenderedID));
    GLCALL(glGetProgramiv(m_RenderedID, GL_LINK_STATUS, &result));

    if (result == GL_FALSE)
    {
        std::cout << "Failed to link shader!" << std::endl;
        return;
    }

    GLCALL(glValidateProgram(m_RenderedID));
    GLCALL(glGetProgramiv(m_RenderedID, GL_VALIDATE_STATUS, &result));

    if (result == GL_FALSE)
    {
        std::cout << "Failed to validate shader!" << std::endl;
        return;
    }

    for (const auto& shaderFile : m_ShaderFiles) {
        GLCALL(glDeleteShader(shaderFile.first));
    }
}

// this part is taken from Shader.h because it's templated
template<typename T, unsigned int S>
void SetUniform(Uniform<T, S>& uniform)
{
    Bind();
    uniform.Set(GetUniformLocation(uniform.GetName()));
}

int Shader::GetUniformLocation(const std::string& name)
{
    if (m_UniformLocationCache.find(name) != m_UniformLocationCache.end())
        return m_UniformLocationCache[name];

    GLCALL(int location = glGetUniformLocation(m_RenderedID, name.c_str()));
    m_UniformLocationCache[name] = location;
    return location;
}

这是我的应用。cpp使用着色器类:

#include <GL/glew.h>
#include <GLFW/glfw3.h>

#include <iostream>
#include <fstream>
#include <string>

#include "core/renderer/Shader.h"
#include "core/renderer/uniform/Uniform4f.cpp"
#include "core/renderer/VertexArray.h"
#include "core/renderer/VertexBufferLayout.h"
#include "core/renderer/VertexBuffer.h"
#include "core/renderer/IndexBuffer.h"

int main(void)
{
    GLFWwindow* window;

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);

    glfwSwapInterval(1);

    if (glewInit() != GLEW_OK)
        std::cout << "Error!" << std::endl;

    std::cout << glGetString(GL_VERSION) << std::endl;

    float vertices[] = {
        -0.5f, -0.5f,
        0.5f, -0.5f,
        0.5f, 0.5f,
        -0.5f, 0.5f
    };

    unsigned int indices[] = {
        0, 1, 2,
        2, 3, 0
    };

    VertexArray va;
    VertexBufferLayout layout;
    layout.Push({ GL_FLOAT, 2, sizeof(float) * 2, GL_FALSE });

    VertexBuffer vb(vertices, sizeof(vertices), layout);

    IndexBuffer ib(indices, 6);

    va.AddVertexBuffer(vb);

    Shader shader;
    shader.Attach(GL_VERTEX_SHADER, "res/shaders/basic_vs.shader");
    shader.Attach(GL_FRAGMENT_SHADER, "res/shaders/basic_fs.shader");
    shader.Link();
    shader.Bind();

    Uniform4f colorUniform("u_Color");

    float r = 0.00f;
    float increment = 0.05f;
    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);

        colorUniform.SetValues({ r, 0.5f, 0.9f, 1.0f });
        shader.SetUniform(colorUniform);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);

        if (r > 1.0f)
            increment = -0.05f;
        else if (r < 0.0f)
            increment = 0.05f;

        r += increment;

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}
#include <iostream>

这是Uniform4f的。cpp我正在尝试设置:

#include "Uniform.h"
#include "../Renderer.h"

#include <iostream>

class Uniform4f : public Uniform<float, 4>
{
public:
    Uniform4f(const std::string& name, const std::array<float, 4>& values = {})
        : Uniform(name, values)
    {

    }

    virtual void Set(int location)
    {
        GLCALL(glUniform4fv(location, m_Values.size(), reinterpret_cast<const GLfloat*>(m_Values.data())));
    }
};

现在我在调用glUniform4fv(location,m_Values.size(),reinterprepret_cast)时得到了GL_INVALID_OPERATION

文件指出,这可能是以下问题之一:

  • 如果没有当前程序对象,则生成GL_INVALID_OPERATION。
  • 如果着色器中声明的统一变量的大小与glUniform命令指示的大小不匹配,则生成GL_INVALID_OPERATION。
  • 如果此函数的有符号或无符号整数变体之一用于加载类型为浮动、vec2、vec3、vec4或其数组的统一变量,或者如果此函数的浮点变体之一用于加载类型为int、ivec2、ivec3、ivec4、无符号int、uvec2、uvec3、uvec4或其数组的统一变量,则会生成GL_INVALID_OPERATION。
  • 如果使用此函数的有符号整数变体之一来加载无符号int、uvec2、uvec3、uvec4或其数组类型的统一变量,则会生成GL_INVALID_OPERATION。
  • 如果使用此函数的无符号整数变体之一加载int、ivec2、ivec3、ivec4或其数组类型的统一变量,则会生成GL_INVALID_OPERATION。
  • 如果位置是当前程序对象的无效统一位置并且位置不等于-1,则生成GL_INVALID_OPERATION。
  • 如果count大于1并且指示的统一变量不是数组变量,则生成GL_INVALID_OPERATION。
  • 如果使用glUniform1i和glUniform1iv以外的命令加载采样器,则会生成GL_INVALID_OPERATION。

我真的不知道是哪个错误导致了它,上面这些似乎都不对。在调试过程中,我发现传递给glUniform4fv的统一值、大小和位置都是正确的,我在Bind中的着色器程序在Linked后在应用程序中执行。cpp,所以我不确定是什么导致了这种情况。

如果能在这方面得到任何帮助,我将不胜感激。


共有1个答案

谷梁波
2023-03-14

好吧,我知道了。文件说:

count
对于vector(glUniform*v)命令,指定要修改的元素数。如果目标统一变量不是数组,则为1;如果是数组,则为1或更多。

这有点令人困惑,但我的错误是,目标统一变量只有1vec4,而不是vec4的数组,这就是count所代表的。

 类似资料:
  • 主要内容:分发结果类型:,FreeMaker结果类型:,重定向结果类型:正如前面提到的,<results>标签在Struts2的MVC框架的视图中所扮演的角色。动作是负责执行业务逻辑。执行业务逻辑后,接下来的步骤是使用<results>标签显示的视图。  经常有一些附带导航规则的结果。例如,如果在操作方法是对用户进行验证,有三种可能的结果。 (一)成功登录;(二)不成功的登录,用户名或密码错误;(三)帐户锁定。 在这种情况下的动作方法将被配置呈现的结果有三种可能的结果

  • 本文向大家介绍的结果相关面试题,主要包含被问及的结果时的应答技巧和注意事项,需要的朋友参考一下 首先出现的运算符包括:一元加、逻辑非、加法(优先级低于前两者); 所以这表达式简化为:!+[] 和 五个 !![] 相加,其中+[]为0,!+[] 则为 true,!![] 也为true,布尔值相加时,先通过Number () 方法转成数字,Number(true)得1,所以最后表达式简化为六个1相加得

  • 使用匹配链接结果会得到极其繁琐的内容;幸运的是,? 运算符可以使事情再次变得干净漂亮。? 运算符用在返回值为 Result 的表式式后面,等同于这样一个匹配表式,其中 Err(err) 分支展开成提前(返回)return Err(err),同时 Ok(ok) 分支展开成 ok 表达式。 mod checked { #[derive(Debug)] enum MathError {

  • 我创建了一个应用程序,其中一个地点列表保存在数据库中。我只根据Google留档保存了保存地点的地点ID。 然后我创建了一个界面,让用户输入他们的当前位置(mCurrentLocation)。 然后,我创建了一个异步任务,检查数据库中保存的每个地点ID,并检查哪些地点距离用户位置500米以内。这是在doInBackground中完成的。根据Google文档,我使用了getPlaceById和setR

  • 主要内容:ResultSet类型,ResultSet的并发性,浏览结果集,查看结果集,更新结果集SQL语句执行后从数据库查询读取数据,返回的数据放在结果集中。 语句用于从数据库中选择行并在结果集中查看它们的标准方法。 接口表示数据库查询的结果集。 对象维护指向结果集中当前行的游标。 术语“结果集”是指包含在对象中的行和列数据。 接口的方法可以分为三类: 浏览方法:用于移动光标。 获取方法:用于查看光标指向的当前行的列中的数据。 更新方法:用于更新当前行的列中的数据。 然后在基础数据库中更新数

  • 效果快速参考艺术效果 效果 动作 “效果 ”>“3D” 将开放路径或封闭路径,或是位图对象,转换为可以旋转、打光和投影的三维 (3D) 对象。另请参阅:第 219 页的 “创建 3D 对象 ” “效果 ”>“艺术效果 ” 在传统介质上模拟应用绘画效果。另请参阅:第 320 页的 “艺术效果 ” “效果 ”>“模糊 ” 可在图像中对指定线条和阴影区域的轮廓边线旁的像素进行平衡,从而润色图像,使过渡显