没有来自glDrawElements的显示

时间:2013-06-19 12:30:55

标签: c++ opengl

当我使用glDrawArrays时,我在屏幕中间得到一个三角形,正如预期的那样。 但是当我尝试使用glDrawElements时,根本没有任何东西出现。

我已经尝试了各种各样的事情,比如重新排序gl调用,移动属性指针,甚至硬编码顶点和索引似乎什么都不做,如我的代码所示。

此代码运行一次:

// 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();

这是我想要实现的非常简化版本,但问题完全相同。

3 个答案:

答案 0 :(得分:21)

  

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,这是初始化的东西。但这更像是一个概念/优化错误(尽管是一个严重错误),而不是一个实际的“非工作”错误。

答案 1 :(得分:3)

我想这个:

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

应该是这样的:

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

答案 2 :(得分:0)

正如其他人所指出的,我会将你的指数开始为零。但是我看到还有另一个问题......

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

应该是......

glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, index);

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