简体   繁体   中英

Correctly initialize array of struct for OpenGL

I want to store some Vertex-Data in two arrays , one for static use and the other one should be dynamic .

The first array will contain the position-data , that's not gonna change, but the second one will contain the texture-coordinates (I use a texture-atlas). They may change at runtime.


Imagine I have two structs:

typedef struct _vertexStatic
{
    GLfloat position[2];
} vertexStatic;

typedef struct _vertexDynamic
{
    GLfloat texCoords[2];
} vertexDynamic;

I declare my two arrays and I want to initialize them for testing.

//Static (position)
//Four vertices that form one quad in the end
const vertexStatic m_StaticVertexData[4] =
{
    {-0.5f,  0.5f}, 
    {0.5f,  0.5f},  
    {0.5f, -0.5f},  
    {-0.5f, -0.5f}  
};

//Dynamic (texture coordinates)
vertexDynamic m_DynamicVertexData[4] =
{
    {0.2f, 0.0f},
    {0.3f, 0.0f},
    {0.3f, 0.1f},
    {0.2f, 0.1f}
};

const GLubyte m_indices[6] =
{
    ?, ?, ?,
    ?, ?, ?
};

This initialization is not correct. I get some array must be initialized with a brace-enclosed initializer and too many initializers for 'const vertexStatic {aka const _vertexStatic} errors while compiling.


My question:

How do I correctly initialize the vertex-data and how would it look for larger amounts of elements?

You code looks a bit like C code, but since you tagged it with c++, I guess you are using a c++ compiler. If so, you should note that a struct is nothing different from a class, except that all its member become public by default.

That said it is more obvious that you can not initialize a stuct -- which is in fact a class -- with an initializer list (that's what you actually o with the { ... } code), unless you created an appropriate constructor, that takes a initializer list.

So you have create an initializer_list constructor to make it work. That however is a bit error prone, since you are allowed to init it with as many doubles as you want:

struct vertexStatic {
    GLfloat position[2];
    vertexStatic(std::initializer_list<double> l) { 
        int i = 0;
        for(double d : l) {
            position[i] = d;
            i++;
            if(i>1) break;  // this is a bit hacky, maybe you should 
                            // raise an exception if there are more than
                            // two doubles in the init list
        } 
    }
};

Another way would be to use only a typedef , that however hides that you are handling an array type:

typedef GLfloat vertexStatic[2];

A third -- and I think preferably way would be to introduce a normal constructor to the structs and call them in the initialization:

struct vertexStatic {
    GLfloat position[2];
    vertexStatic(GLfloat a, GLfloat b) {
        position[0] = a;
        position[1] = b;
    }
}
// ...
const vertexStatic m_StaticVertexData[4] =
{
    vertexStatic(-0.5f,  0.5f), 
    vertexStatic(0.5f,  0.5f),  
    vertexStatic(0.5f, -0.5f),  
    vertexStatic(-0.5f, -0.5f)  
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM