memcpy vertex arrays

hi guys,

super lost here…
working with VBOs and working with memcpy for the first time
basically trying to add a set of new vertrex to the start of a float array.

  
		if( trailIndex < MAX_TRAIL_LENGTH )  
		{  
			trl[ i ][ trailIndex * 3 + 0 ] = pos[ i ][ 0 ];  
			trl[ i ][ trailIndex * 3 + 1 ] = pos[ i ][ 1 ];  
			trl[ i ][ trailIndex * 3 + 2 ] = pos[ i ][ 2 ];  
		}  
		else  
		{  
			float trlTemp[ 3 * ( MAX_TRAIL_LENGTH - 1 ) ];  
			int trlTempSize = sizeof( trlTemp );  
			memcpy( trlTemp, trl[ i ] + 3 * 4, trlTempSize );  
			  
			trl[ i ][ 0 ] = pos[ i ][ 0 ];  
			trl[ i ][ 1 ] = pos[ i ][ 1 ];  
			trl[ i ][ 2 ] = pos[ i ][ 2 ];  
			  
			memcpy( trl + 3 * 4, trlTemp, trlTempSize );  
		}  
  

so firstly i fill the entire array until it is full… this is ok.
next if its full, i move up all the values in the array to make room for the new ones.
this is where its failing… any ideas guys?

L.

hey, why don’t you use a std::vector? does all this for you and you can access the whole thing as a pointer by using vector::first()

on a side note there seems to be a little bit of a logic error in your code. if I understand correctly:

  • if current index is less than MAX, then add vertex data to buffer at index position
  • else:
  • allocate a temp buffer which can take MAX-1 vertices
  • copy all but the first vertex data into the temp buffer (i think this is the wrong bit)
  • modify the first vertex data in orig buffer
  • copy temp buffer (which contains all but first orig data) into orig buffer starting at 2nd position

so basically you’re just modifying the first vertex in the orig buffer and don’t need to do any copying stuff around! I’m guessing you want a kind of sliding buffer where the as data gets older it moves down the array and new entries keep getting adding at the beginning? If thats the case, the 2nd step is wrong, you wanna copy from trl to trlTemp but starting at the beginning of trl - so you get the first vertex too, but now it moves to 2nd position.

P.S. If you use memmove instead of memcpy you don’t need to worry about overlapping source and destination, so you omit the temp buffer:

memmove(trl + 3 * sizeof(float), trl, 3*(MAX_TRAIL_LENGTH - 1) * sizeof(float));
and then fill in the first entry

(i haven’t tested the above code, but it should work).

edit:
its probably easier to read if you type:
memmove(&(trl[1]), trl, 3*(MAX_TRAIL_LENGTH - 1) * sizeof(float));

since this is a situation which I run into a lot too, here is an idea (Which I haven’t tested yet).

For trails I usually use circular buffers - have a fixed 1D array, and keep track of a ‘oldestIndex’ where I always write the newest data to (overwriting oldest data), and then decrement oldestIndex (wrapping around when necessary).

So if you have two buffers, one is the circular buffer (lets call this the live buffer) where you write data to, and then another for your VBO, and before sending to the gfx card, you first copy from live buffer (oldestIndex+1 to the end of the buffer) to the VBO buffer, and then from beginning of live buffer to oldestIndex to after that. dunno if that makes sense?

This way you only ever copy MAX_TRAIL_LENGTH count of vertex data per frame instead of (MAX_TRAIL_LENGTH-1) * 2

Theoretically this may be faster as you are copying less bytes, but most probably you will not see any speed difference though :stuck_out_tongue:

ah yeah… you’re right memo, don’t know how i missed that logic error.
although im still getting some unexpected results.
and even with the logic bug fixed, im getting two different results for memcpy and memmove, graphically that is.
it could be that im doing something wrong when drawing the trails.
i wonder if using 2D arrays with memcpy or memmove can muck things up?

i was also using circular buffers for storing vertex positions and looping the buffer index.
although i didn’t think about creating another array that re-shuffles the array values for the VBO. think the thought crossed my mind but figured that the overhead would be larger then just shifting the array values with memcpy or memmove since on every frame you will still need to use memcpy to create a new array… why not just do it once?

anyhoo, thx for your help, good to know that someone else is thinking along the same lines.
be sure to post the result once i figure it out.

L.

ok, so worked out the correct syntax.

lets say you have a float array conviniently named floatArray.

  
float floatArray[ 10 ];  
memmove( floatArray + 1, floatArray, sizeof( float ) * ( 10 - 1 ) );     // shifts array by one.  
memmove( floatArray + 2, floatArray, sizeof( float ) * ( 10 - 2 ) );     // shifts array by two.  

position in the destination array is simply done by adding an offset, so +1 is moving values to floatArray[ 1 ] (shifting by 1 to the right).
same for the source array.
just have to watch out when specifying the size of the block of memory to move, so you will need to work out the size of of your array type using the sizeof() function.

L.

ah yea of course, sorry my mistake. I had said:

  
memmove(trl + 3 * sizeof(float), ...  

but what you said is correct and it should be

  
memmove(trl + 1, ...  

when you add an integer to the pointer, it includes in the offset calculation the size of the elements it is pointing to. i.e. trl + n will give the address of the n’th element &trl[n] NOT the n’th byte after trl.