0

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

当 Vertex 被 typedef 为 SimpleVertex 或 ComplexVertex 时,下面的代码应该可以正常工作,但事实并非如此。

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 时,我什么也得不到。怎么了?谢谢。

4

1 回答 1

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

嗯,有你的问题。因为这肯定不是OpenGL所期望的。

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

baseOffset + (stride * i)

您可以为步幅传递 0。这告诉 OpenGL 该属性是紧密打包的,因此 GL 将自行计算实际步幅。但这并不意味着步幅实际上为零;它只是告诉 OpenGL 自己计算它。

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

于 2013-08-14T10:23:31.423 回答