【问题标题】:GL_ERROR == 1282 for both glVertexAttribPointer and glDrawArrays only when using a opengl 3.2 context or higherGL_ERROR == 1282 对于 glVertexAttribPointer 和 glDrawArrays 仅在使用 opengl 3.2 上下文或更高版本时
【发布时间】:2017-01-24 03:26:19
【问题描述】:

我不能 100% 确定这篇文章标题中描述的错误来自哪里。它可能是上下文创建,也可能是实际的绘图代码。我将从绘图代码开始。下面的代码将使用 2.0 到 3.1 版本的上下文进行渲染,但在 3.2 或更高版本的上下文中停止渲染。应该注意的是,上下文是使用 glX 系列函数创建的。如果需要该代码,请在 cmets 部分发布。我还假设 glDrawArrays 的错误与在顶点着色器中获取“位置”变量的顶点属性指针时生成的错误有关?

绘制及初始化代码如下:

void start_func()
{
  // Create Window
  // Create Context
  // Start Message Pump
  // Clean Up
}

GLuint vbo;
GLuint shaderProgram;

bool compiler_errors(GLuint shaderId)
{
  bool errors = false;

  GLint isCompiled = 0;

  glGetShaderiv(shaderId, GL_COMPILE_STATUS, &isCompiled);
    GL_CALL("glGetShaderiv")
  if(isCompiled == GL_FALSE) {
    GLint maxLength = 0;
    glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &maxLength);
      GL_CALL("glGetShaderiv")
    std::vector<char> errorLog(maxLength);
    glGetShaderInfoLog(shaderId, maxLength, &maxLength, &errorLog[0]);
      GL_CALL("glGetShaderInfoLog")
    std::stringstream out;
    std::copy(errorLog.begin(), errorLog.end(),
      std::ostream_iterator<char>(out, ""));
    std::string errorsStr = out.str();
    std::cerr << "Shader Compiler Erros " << errorsStr.c_str();
    errors = true;
  }

  return errors;
}

void init()
{
  const GLchar* vertexSource =
    "#version 150 core\n"
    "in vec2 position;"
    "void main()"
    "{"
    "  gl_Position = vec4(position, 0.0, 1.0);"
    "}";
  const GLchar* fragmentSource =
    "#version 150 core\n"
    "out vec4 outColor;"
    "void main()"
    "{"
    "  outColor = vec4(1.0, 1.0, 1.0, 1.0);"
    "}";

  glGenBuffers(1, &vbo); GL_CALL(glGenBuffers)

  GLfloat vertices[] = {
    +0.0f, +0.5f,
    +0.5f, -0.5f,
    -0.5f, -0.5f
  };

  glBindBuffer(GL_ARRAY_BUFFER, vbo); GL_CALL(glBindBuffer)
  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices,
    GL_STATIC_DRAW); GL_CALL(glBufferData)

  // Create and compile the vertex shader
  GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    GL_CALL(glCreateShader)
  glShaderSource(vertexShader, 1, &vertexSource, NULL);
    GL_CALL(glShaderSource)
  glCompileShader(vertexShader);
    GL_CALL(glCompileShader)

  if(compiler_errors(vertexShader) == GL_TRUE) {
    throw std::runtime_error("Failed to compile vertex shader.");
  }

  // Create and compile the fragment shader
  GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    GL_CALL(glCreateShader)
  glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
    GL_CALL(glShaderSource);
  glCompileShader(fragmentShader);
    GL_CALL(glCompileShader);
  if(compiler_errors(fragmentShader) == GL_TRUE) {
    throw std::runtime_error("Failed to compile fragment shader.");
  }

  // Link the vertex and fragment shader into a shader program
  shaderProgram = glCreateProgram();
    GL_CALL(glCreateProgram)
  glAttachShader(shaderProgram, vertexShader);
    GL_CALL(glAttachShader);
  glAttachShader(shaderProgram, fragmentShader);
    GL_CALL(glAttachShader);
  glLinkProgram(shaderProgram);
    GL_CALL(glLinkProgram);
  glUseProgram(shaderProgram);
    GL_CALL(glUseProgram);
}

void render()
{
  glViewport(0, 0, 800, 600); GL_CALL(glViewport)
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GL_CALL(glClear)

  // Clear the screen to black
  glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    GL_CALL("glClearColor")
  glClear(GL_COLOR_BUFFER_BIT);
    GL_CALL("glClear(GL_COLOR_BUFFER_BIT)")

  // Draw a triangle from the 3 vertices
  glUseProgram(shaderProgram);
    GL_CALL("glUseProgram")
  glBindBuffer(GL_ARRAY_BUFFER, vbo);
    GL_CALL("glBindBuffer")

  GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
    GL_CALL("glGetAttribLocation")
  glEnableVertexAttribArray(posAttrib);
    GL_CALL("glEnableVertexAttribArray")
  glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
    GL_CALL("glVertexAttribPointer")
  glDrawArrays(GL_TRIANGLES, 0, 3);
    GL_CALL("glDrawArrays")
}

int main(int argc, char *argv[])
{
    ...
    start_func();
    ...
}    

【问题讨论】:

  • 只是附带说明,您设置了一次清除颜色,并在渲染中调用 glClear() 但不是多次。所以将 glClearColor 移出循环并删除行 glClear(GL_COLOR_BUFFER_BIT);
  • 什么是GL_CALL?它使您的代码非常难以阅读。
  • @eldo GL_CALL 是一个宏,用于检查 dbug 构建中 opengl 中的错误。在发布时它是一个空语句。

标签: c++ linux opengl


【解决方案1】:

在核心配置文件中,必须使用顶点数组对象 (VAO)。在 3.2 之前,VAO 0 是有效对象(可以说是全局状态 VAO),但从 3.2 开始 核心,VAO 0 是无效对象。由于您没有创建和绑定自己的 VAO,因此每当您尝试修改 VAO 状态 (glVertexAttribPointer) 或尝试使用无效的 0 VAO 进行绘制时,都会收到 GL_INVALID_OPERATION 错误。

更多信息可以在here找到。

【讨论】:

  • 感谢 BDL。我从没想过这是问题所在。
  • 感谢您的回答,它帮助我解决了我的问题。但是,您所说的在 3.1 opengl 版本中是正确的。我尝试了 3.0 并且它正在工作。 3.1 不是这样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-04
  • 2020-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多