Efficiently transferring only needed parts of the vertex data to the GPU (C++/OpenGL) I have a situation, where I have an array of vertices on the CPU side, for which, besides rendering-relevant data, like their position, I have a lot of other data at each vertex. All vertex data is updated (more or less) every frame, requiring transferring the changes over to the GPU every time.
So far I have used two approaches, neither of which I am particularly happy with:
Approach 1
Just copy everything over to the GPU. This might seem silly, but my application does not use a significant amount of VRAM overall, so this is no issue in that regard, but of course, when the vertex count increases, so does the amount of data needlessly transferred to the GPU every frame, which does become a performance issue.
Approach 2
Keep separate arrays for the GPU-relevant vertex data and the non-relevant vertex data. While this solves the unnecessary transfer issue, I find it very clunky to work with on the CPU side, since I at all times have to keep two arrays in sync. Ideally, I would like to have one clean struct per vertex, which I can easily work with.

Is there some other approach to this?
Something I could think of, which unfortunately doesn't seem to exist in OpenGL, is a variant of glBufferData, which I could tell some stride and offset, like with glVertexAttribPointer, which parts of each data block I want to transfer to the buffer in VRAM.
There also might be some way to neatly solve this with some C++ features that I am not aware of. Some way to have two arrays act as one, or something like that.
Any ideas and suggestions are appreciated.
This more or less a long comment than an answer.
Some other options that come to mind are the following:

A little old school, but you can create an interface with one of the texture objects. You can query different mipmap levels for your needs inside the shader. Textures are one of the better cached objects in OpenGL.

You can defer the lightening process by sending everything to a framebuffer with multiple rendering targets. The first pass would filter out the relevant parts of your data and create a geometry buffer. You can use the g-buffer for lightening pass afterwards.

You can create a flat array where your relevant and non relevant data are divided in equal strides, then use the indices of the relevant parts stored in your Element Array Buffer object in glDrawElements call. Basically you can use something like the following:


struct MyRealData {
vec3 myRelevantData
float myNotSoRelevantData
};
void to_drawable(MyRealData[20] ds, vec3[40] flat_drawable_array){
  for (int i = 0; i &lt; 40; i+=2){
    flat_drawable_array[i] = ds[i].myRelevantData;
    flat_drawable_array[i+1] = vec3(ds[i].myNotSoRelevantData, 0, 0);
  }
}
std::vector&lt;unsigned int&gt; indices[] = { 
  0, 2, 4, // first triangle
  2, 6, 4, // second triangle
  4, 6, 8, // third triangle
// ... etc
}; 
.
. // later in the code
.
glDrawElements(GL_TRIANGLES, indices.size() , GL_UNSIGNED_INT, (GLvoid *)indices​.data());

```