glDrawElements不显示 [英] No display from glDrawElements

查看:306
本文介绍了glDrawElements不显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When I use glDrawArrays I get a triangle in the middle of my screen, as expected. But when I try to use glDrawElements nothing comes up at all.

我尝试了各种事情,例如对gl调用进行重新排序,移动属性指针,甚至硬编码的vert和index似乎也无济于事,如我的代码所示.

I have tried all sorts of things like reordering the gl calls, moving the attribute pointers, and even hard coding verts and index appears to do nothing as shown in my code.

此代码运行一次:

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

这是我要达到的目标的简化版本,但问题却完全相同.

This is a very cut down version of what I am trying to achieve but the problem is exactly the same.

推荐答案

glDrawElements(GL_TRIANGLES,3,GL_UNSIGNED_INT,& index); //这 不起作用

glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, &index); // this doesn't work

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

Of course it doesn't. You are storing your indices in a buffer object. In the same way the last pointer argument to glVertexAttribPointer is interpreted as an offset into the currently bound GL_ARRAY_BUFFER (if one is bound), the last pointer argument to glDrawElements is interpreted as an offset into the buffer currently bound to GL_ELEMENT_ARRAY_BUFFER. You already properly store your indices into that, so you have to tell `glDrawElements that the indices start at offset 0 of this buffer, like you did with glVertexAttribPointer:

glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr);

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

And like bwroga points out in his answer, you should start your indices with 0 instead of 1.

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

And you also pass the wrong sizes into glBufferData. You use sizeof(verts) * sizeof(floats) (and likewise for index), but verts is an array and the sizeof an array already is the size of the whole thing in bytes and not just the number of elements, so it should rather just be sizeof(verts), otherwise the glBufferData will try to read data beyond the actual array size which is undefined behaviour (and in your case unfortunately seems to work).

当然,正如 Grimmy 在他的评论中指出的那样,您不应该在每次绘制时重新创建VAO和VBO,这是初始化工作.但这更多是概念上/优化上的错误(尽管很严重),而不是实际的无效"错误.

And of course as Grimmy points out in his comment you shouldn't recreate your VAO and VBO each time you draw, that's initialization stuff. But this is more of a conceptual/optimization error (albeit a severe one) rather than an actual "non-working" error.

这篇关于glDrawElements不显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆