Using C data structures with GLSL shader attributes

I am a beginner to OpenGL learning modern OpenGL from Instead of using the miserable GLfloat[] = { … lots of data … } as vertex data; I thought I would try to use simple structs as shown below:

struct Coord
  float X, Y, Z, W;

struct Color
  float R, G, B, A;
} const RED(1.0f, .0f, .0f), GREEN(.0f, 1.0f, .0f), BLUE(.0f, .0f, 1.0f);

struct Vertex
  Coord Position;
  Color Color;

struct Triangle { Vertex Vertices[3]; };

So I create a triangle and send it to GL_ARRAY_BUFFER and when redisplay is called I set the vertex attribute pointers (0 being position, 1 being color):

std::vector<Triangle> triangles;
      Vertex(Coord(.5f, .75f, .0f), GREEN),
      Vertex(Coord(.5f, -.75f, .0f), GREEN),
      Vertex(Coord(.0f, .0f, .0f), GREEN)

gl::BufferData(gl::GL_ARRAY_BUFFER, triangles.size() * sizeof(Triangle),
    &triangles[0], gl::GL_STATIC_DRAW);

gl::VertexAttribPointer(0, 4, gl::GL_FLOAT, gl::GL_FALSE, sizeof(Color), 0);
gl::VertexAttribPointer(1, 4, gl::GL_FLOAT, gl::GL_FALSE, sizeof(Coord), 
    reinterpret_cast<const void*>(16));

gl::DrawArrays(gl::GL_TRIANGLES, 0, triangles.size() * 3);

This should produce an isosceles triangle that is completely green but what is instead produced is:

Any ideas? This program using a GLfloat array works as expected.

Use vec4 - gives you. xyzw

I’m sorry, what?

The vertex attributes are interleaved in memory, so you have to use a stride of sizeof(Vertex) instead of sizeof(Color) or sizeof(Coord).

That worked. Thanks a lot.

It may be a good idea to use the glm math library. It is specialized for use with OpenGL. In your example, you would do

struct Vertex {
    glm::vec4 Position;
    glm::vec4 Color;

Of course, this change doesn’t help you much in itself. But when you want to do more interesting maths, you get full support (inlined) for most you would want, like matrix operations and transformations, manipulations like normalization, etc.