当在glVertexAttribPointer中使用非零步幅时,渲染完全失败

时间:2013-08-14 10:14:25

标签: opengl

我正在尝试编写一个简单的OpenGL 3程序。当顶点缓冲区包含打包位置元素时,它可以正常工作,但是当每个顶点有其他数据成员时,它不能正常工作。

当Vertex对SimpleVertex或ComplexVertex进行typedef时,下面的代码应该完全相同,但它没有。

struct SimpleVertex
{
    glm :: vec3 position;

    SimpleVertex (float x, float y, float z) : position (x, y, z) {}
};

struct ComplexVertex
{
    glm :: vec3 position;
    glm :: vec3 normal; // Will be ignored in this example

    ComplexVertex (float x, float y, float z) : position (x, y, z) {}
};

// Fails when Vertex is ComplexVertex
typedef SimpleVertex Vertex;

GLuint vert_id;
GLuint index_id;
GLint  att_position;

初始化代码:

Vertex verts [] =
{
    {0, 0, 0},
    {1, 0, 0},
    {0, 1, 0}
};

GLubyte indices [] = {0, 1, 2};

glGenBuffers (1, & vert_id);
assert (0 != vert_id);
glBindBuffer (GL_ARRAY_BUFFER, vert_id);
glBufferData (GL_ARRAY_BUFFER, sizeof (verts), & verts [0], GL_STATIC_DRAW);

glGenBuffers (1, & index_id);
assert (0 != index_id);
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, index_id);
glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (indices), & indices [0], GL_STATIC_DRAW);

att_position = glGetAttribLocation (shader_program_id, "position");
assert (att_position >= 0);

assert (GL_NO_ERROR == glGetError ());

渲染循环:

Vertex * dummy = nullptr;

assert (sizeof (glm :: vec3) == 3 * sizeof (GLfloat));

// In theory this should work regardless of the size or
// arrangement of members of Vertex.

glVertexAttribPointer (
    att_position,
    3,
    GL_FLOAT,
    GL_FALSE,
    // This is 0 for SimpleVertex, 12 for ComplexVertex, as expected
    sizeof (Vertex) - 3 * sizeof (GLfloat),
    & (dummy -> position));

assert (GL_NO_ERROR == glGetError ());

glEnableVertexAttribArray (att_position);

glBindBuffer (GL_ARRAY_BUFFER, vert_id);
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, index_id);

glDrawElements (
    GL_TRIANGLES,
    3,
    GL_UNSIGNED_BYTE,
    nullptr);

顶点着色器:

#version 130

attribute vec3 position;

void main ()
{
    gl_Position = vec4 (position, 1);
}

片段着色器:

#version 130

out vec4 finalColor;

void main ()
{
    finalColor = vec4 (1.0, 1.0, 1.0, 1.0);
}

当Vertex是SimpleVertex时,我得到一个未转换的白色三角形,很好。当我将它输入到ComplexVertex时,我什么也得不到。怎么了?感谢。

1 个答案:

答案 0 :(得分:2)

// This is 0 for SimpleVertex, 12 for ComplexVertex, as expected

那是你的问题。因为那肯定不是 OpenGL 所期望的。

stride是从一个属性的开头到数组中下一个属性的开头的字节偏移量。它是实现在此等式中必须使用的值,用于计算指向数组的i元素的指针:

baseOffset + (stride * i)

你可以通过0来获得步幅。这告诉OpenGL该属性是紧密打包的,因此GL将自己计算实际步幅。但这并不意味着步幅实际为零;它只是告诉OpenGL自己计算它。

您应该只使用sizeof(type),只要type是您在数组中存储的实际类型。