Nicolas Lutz
Nicolas Lutz

Reputation: 93

OpenGL with C++: vtable troubles when passing class array to glTexImage2d

I made a class Color with float r, float g, float b, float alpha. It has a base class with a virtual destructor.

I am trying to pass an array of Color to the opengl function glTexImage2D, with a GL_RGBA organization of type float (which would be an array of {float r, float g, float b, float alpha}). This requires Color to contain only 4 floats (size of 16 bytes).

However, sizeof(Color) reveals that my class has a size of 20 bytes due to the base class of Color having a vtable, thanks to the destructor.

How can I keep my vtable and still pass my Color array to glTexImage2D?

Upvotes: 4

Views: 276

Answers (2)

Dietrich Epp
Dietrich Epp

Reputation: 213837

Short answer: No, you can't do that.

You can see all the extra parameters for glTexImage2D() in the glPixelStore() documentation. As you can see, there are no parameters for adding a "stride" or "padding" between pixels. There are options for adding space at the beginning or end of rows, or between images (3D), but nothing between pixels.

Advice: An array of identical 4D vectors with a vtable for each is a design smell. It is a bad design. Your color type, in order to be compatible with C, should be a standard layout type. Note that in particular this means that you cannot use virtual functions.

If you really need a base type with a virtual destructor, create a wrapper type.

Upvotes: 4

Chris Beck
Chris Beck

Reputation: 16224

Some gl functions allow you to pass a stride along with the data pointer, which tells gl how many bytes it should increment the pointer to get to the next data element each time. You could pass a stride of sizeof(Color), and if you can find the offset within the structure layout to get to the floats... well that would be the only way to do this that I can see. However you would definitely need to make some changes. To force adjacent layout, you would have to make the floats all held in a float[4]...

Regardless, glTexImage2D doesn't actually have stride, so this is out the window.

I think the better question is, why does your color structure have a base class or a virtual destructor? Color data is not a resource, so this is likely breaking the rule of three / rule of five / rule of zero.

You might do better to make a simple, POD type for the color, and then whatever fancy stuff you have happening in the destructor, make a second class which contains a color POD, and also has the base class etc.

Upvotes: 4

Related Questions