glDrawElements() 在无效情况下返回 GL_INVALID_ENUM

Posted

技术标签:

【中文标题】glDrawElements() 在无效情况下返回 GL_INVALID_ENUM【英文标题】:glDrawElements() Returning GL_INVALID_ENUM in Invalid Circumstances 【发布时间】:2013-05-22 00:29:12 【问题描述】:

draw_data 下面的所有方法都是用两个三角形绘制一个正方形。因此硬编码值。正方形渲染得很好,但是,我收到垃圾邮件

vertex_renderer::draw_vertex_data()GL 错误:无效枚举。

来自我的代码。我做错了吗?

我的渲染方法如下:

bool draw_data(const GLsizei start_index = 0, GLsizei index_count = 0) 
  if (!vbo_id_ || start_index + index_count > index_count_) 
    return false;
  

  if (index_count == 0) 
    index_count = index_count_;
  

  glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);

  return !gl_errors::what_errors("vertex_renderer::draw_vertex_data()");

gl_errors::what_errors 定义如下:

class gl_errors

public:
  static bool what_errors(const char * const prefix) 
    GLenum errorCode;
    bool is_error = false;

    while ((errorCode = glGetError()) != GL_NO_ERROR) 
      switch (errorCode) 
      case(GL_INVALID_ENUM): 
        std::cout << prefix << "GL ERROR: Invalid enum." << std::endl;
        is_error = true;
      
        break;
      case(GL_INVALID_VALUE): 
        std::cout << prefix << "GL ERROR: Invalid value." << std::endl;
        is_error = true;
      
        break;
      case(GL_INVALID_OPERATION): 
        std::cout << prefix << "GL ERROR: Invalid operation." << std::endl;
        is_error = true;
      
        break;
      case(GL_STACK_OVERFLOW): 
        std::cout << prefix << "GL ERROR: Stack overflow." << std::endl;
        is_error = true;
      
        break;
      case(GL_STACK_UNDERFLOW): 
        std::cout << prefix << "GL ERROR: Stack underflow." << std::endl;
        is_error = true;
      
        break;
      case(GL_OUT_OF_MEMORY): 
        std::cout << prefix << "GL ERROR: Out of memory." << std::endl;
        is_error = true;
      
        break;
      
    
    return is_error;
  
;

更新

GLsizei stride = sizeof(verticies_t);
pos_id_ = basic_shader_.get_attribute("position");
glEnableVertexAttribArray(pos_id_);
glVertexAttribPointer(pos_id_, 2, GL_FLOAT, GL_FALSE, stride, 0);
gl_extensions::gl_errors::what_errors("1");

这是罪魁祸首,但我不明白为什么会导致问题。 GL_FLOAT 是一个有效的枚举。

【问题讨论】:

调用glDrawElements之前是否有错误? 有,这是一个很好的观点,让我仔细检查以确保我在每次通话后检查错误。 【参考方案1】:

glDrawElements() 只有一个条件可以返回GL_INVALID_ENUM

如果模式不是可接受的值,则生成 GL_INVALID_ENUM。

这应该会让您怀疑对 API 的其他调用,因为您的 glDrawElements() 调用具有有效模式。对之前拨打的电话添加更多检查,看看您是否找到了问题。

【讨论】:

在我完成另一项任务后继续工作。 好点,但对于那些使用 OpenGL ES2 的人:当心!如果您使用整数索引而不是字节或短裤,也会触发 INVALID_ENUM。 khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/… @Bram I 我可以对此给予更多支持!谢谢,您为我节省了大量搜索时间

以上是关于glDrawElements() 在无效情况下返回 GL_INVALID_ENUM的主要内容,如果未能解决你的问题,请参考以下文章

无法让 openGL 的 glDrawElements 与几何着色器一起使用

glDrawElements 崩溃

使用 glDrawElements (iOS) 重用相同的缓冲区

为啥 glreadpixels 仅在某些情况下有效?

OpenGL 优化 - 重复顶点流或重复调用 glDrawElements?

故意返回无效值或类型