【问题标题】:No display from glDrawElementsglDrawElements 没有显示
【发布时间】:2016-12-29 11:47:35
【问题描述】:

当我使用 glDrawArrays 时,我的屏幕中间出现了一个三角形,正如预期的那样。 但是当我尝试使用 glDrawElements 时,什么都没有出现。

我尝试了各种方法,例如重新排序 gl 调用、移动属性指针,甚至硬编码 verts 和 index 似乎都没有做任何事情,如我的代码所示。

此代码运行一次:

// Initialise GLFW
if( !glfwInit() )
{
        fprintf( stderr, "Failed to initialize GLFW\n" );
        //return -1;
}

glfwOpenWindowHint(GLFW_FSAA_SAMPLES, 4); // 4x antialiasing
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); // We want OpenGL 3.3
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 3);
glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE); //We don't want the old OpenGL

// Open a window and create its OpenGL context
if( !glfwOpenWindow( mApplication->getWindowWidth(), mApplication->getWindowHeight(), 0,0,0,0, 32,0, GLFW_WINDOW ) )
{
        fprintf( stderr, "Failed to open GLFW window\n" );
        glfwTerminate();
        //return -1;
}

// Initialize GLEW
glewExperimental=true; // Needed in core profile
if (glewInit() != GLEW_OK)
{
        fprintf( stderr, "Failed to initialize GLEW\n");
        //return -1;
}

glfwSetWindowTitle( "Hello World" );
glViewport( 0, 0, mApplication->getWindowWidth(), mApplication->getWindowHeight());
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0.0f, 0.0f, 0.4f, 0.0f); // colour to use when clearing

这会运行每一步:

float verts[] = {
        -0.5f,  0.0f,   0.0f,
         0.5f,  0.0f,   0.0f,
         0.0f,  0.5f,   0.0f,
};

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

glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

// VAO
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);

// VBO
glGenBuffers(1, &VBO );
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts) * sizeof(float), verts, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

// IBO
glGenBuffers(1, &IBO );
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(index) * sizeof(unsigned int), index, GL_STATIC_DRAW);

glDrawArrays(GL_TRIANGLES, 0, 3); // this works
//glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, &index); // this doesnt

glfwSwapBuffers();

这是我试图实现的一个非常精简的版本,但问题完全相同。

【问题讨论】:

  • 所以您每次绘画时都会创建您的 VAO/VBO?那不是这样做的方法。创建一次..然后绘制。
  • @legends2k 我已经读过了,但看起来我的代码仍然应该运行。

标签: c++ opengl


【解决方案1】:

glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, &index); // 这个 不工作

当然不是。您将索引存储在缓冲区对象中。同样,glVertexAttribPointer 的最后一个指针参数被解释为当前绑定的GL_ARRAY_BUFFER 的偏移量(如果有绑定),glDrawElements 的最后一个指针参数被解释为当前绑定到的缓冲区的偏移量GL_ELEMENT_ARRAY_BUFFER。您已经正确地将索引存储到其中,因此您必须告诉 `glDrawElements 索引从该缓冲区的偏移量 0 开始,就像您对 glVertexAttribPointer 所做的那样:

glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr);

编辑:就像 bwroga 在他的回答中指出的那样,您应该以 0 而不是 1 开始索引。

编辑:您还将错误的尺寸传递给glBufferData。您使用sizeof(verts) * sizeof(floats)(同样用于index),但verts 是一个数组,而sizeof 一个数组已经是整个事物的大小(以字节为单位),而不仅仅是元素的数量,所以它应该宁可只需sizeof(verts),否则glBufferData 将尝试读取超出实际数组大小的数据,这是未定义的行为(不幸的是,在您的情况下似乎有效)。

编辑: 当然,正如 Grimmy 在他的评论中指出的那样,您不应该在每次绘制时重新创建 VAO 和 VBO,这是初始化的东西。但这更像是一个概念/优化错误(尽管是一个严重的错误),而不是实际的“非工作”错误。

【讨论】:

  • nullptr 是关键,谢谢。 gl 的文档有时非常混乱,它看起来好像您需要指向索引列表的内存位置。
  • @Brae 因为这就是在 VBO 发挥作用之前使用 glDrawElements(和 glVertexAttribPointer)的方式。
  • @Brae “nullptr 是关键” - 但仍然不要忽略其他错误,它们同样严重。
  • nullptr 建议您使用它而不是 0 可能是个坏主意。它应该是一个字节偏移量;它只是采取作为指针值。如果您想使用非零值,您现在需要进行强制转换,您应该一直这样做。最好举个后面最容易改的例子。
  • @NicolBolas 它仍然是一个指针参数,如果使用偏移量,无论如何都必须指定为指针。由于3 不起作用(与static_cast<const char*>(nullptr)+3reinpterpret_cast<const void*>(3) 相反),我认为0 也违反直觉。也许reinterpret_cast<const void*>(0) 会这样做,但我想避免这种情况。但也许这是一个观点的问题。 nullptr 并没有隐藏这样一个事实,即它首先是一个指针类型的参数,不管它是如何被函数插入的。
【解决方案2】:

我认为是这样的:

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

应该是这样的:

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

【讨论】:

    【解决方案3】:

    正如其他人指出的那样,我会从零开始您的索引。但是我看到了另一个问题......

    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, &index);
    

    应该是……

    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, index);
    

    ...因为索引是一个数组,它已经是一个指针,不需要&。

    【讨论】:

      猜你喜欢
      • 2016-12-13
      • 1970-01-01
      • 2012-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-19
      • 1970-01-01
      相关资源
      最近更新 更多