gpt4 book ai didi

c++ - glUniform4fv 导致 GL_INVALID_OPERATION

转载 作者:行者123 更新时间:2023-11-28 04:07:15 25 4
gpt4 key购买 nike

嘿,我有一个抽象所有与着色器相关的类,名为 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;
}

这是我的 app.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())));
}
};

现在我得到 GL_INVALID_OPERATION正在调用 glUniform4fv(location, m_Values.size(), reinterpret_cast<const GLfloat*>(m_Values.data()))在对 shader.SetUniform(colorUniform); 的调用中在 app.cpp 的渲染循环中.

docs声明它可能是以下问题之一:

  • 如果没有当前程序,则生成 GL_INVALID_OPERATION对象。
  • GL_INVALID_OPERATION 如果统一变量的大小产生在着色器中声明的大小与glUniform 命令。
  • GL_INVALID_OPERATION 如果签名或未签名之一生成此函数的整数变体用于加载统一变量类型为 float、vec2、vec3、vec4 或这些类型的数组,或者如果其中之一此函数的浮点变体用于加载int 类型的统一变量, ivec2, ivec3, ivec4, unsigned int,uvec2、uvec3、uvec4 或这些的数组。
  • 如果有符号整数之一,则生成 GL_INVALID_OPERATION此函数的变体用于加载类型的统一变量unsigned int、uvec2、uvec3、uvec4 或这些的数组。
  • GL_INVALID_OPERATION 如果其中一个无符号整数生成此函数的变体用于加载类型的统一变量int、ivec2、ivec3、ivec4 或这些的数组。
  • GL_INVALID_OPERATION 如果 location 是一个无效的 uniform 则生成当前程序对象的位置和位置不等于-1.
  • 如果计数大于 1 并且指示的统一变量不是数组变量。
  • GL_INVALID_OPERATION 如果使用glUniform1i 和 glUniform1iv 以外的命令。

我无法确定是哪个错误导致的,以上似乎都不正确。在调试时,我看到传递给 glUniform4fv 的统一值、大小和位置都是正确的,我的着色器程序在BindLink 之后编辑在 app.cpp 中编辑,所以我不确定是什么原因造成的。

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

最佳答案

好吧,我明白了。docs说:

count
For the vector (glUniform*v) commands, specifies the number of elements that are to be modified. This should be 1 if the targeted uniform variable is not an array, and 1 or more if it is an array.

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

关于c++ - glUniform4fv 导致 GL_INVALID_OPERATION,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58512949/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com