PDA

View Full Version : Keeping X, Y and Z data separately



sinaxp19
05-04-2015, 06:11 AM
Hi everyone. I'm trying to draw a 3D spectrum (with initial 2D view of f(x)) using the VBOs. My X data is rarely updated and then comes Y data which updates more often and finally Z data which is updated regularly. There is also a Vector4d per vertex for keeping color data. Currently, I've managed to keep vertex and color data separately and link them using glVertexPointer and glColorPointer. The problem is, for updating the Y data, I have to take a bufferpointer to my data in VBO and update Y data for each point individually. Now I know that glBufferSubData is much faster than working with pointers, but for that, I'll have to copy the identical X and Z data each time with seems very redundant. Moreover, since I receive a vector of only Y data for all points, I do not want to expend time rebuilding a Vector3 array containing all XYZ data and am hence looking for a way to keep X, Y and Z data separately and just use glBufferSubData on the updating direction info. any ideas?

(X1, Y1, Z1), (X2, Y2, Z2), (X3, Y3, Z3), ....
to
(X1X2X3...)(Y1Y2Y3...)(Z1Z2Z3...)

Thanks

hidefromkgb
05-04-2015, 06:28 AM
Do you use shaders? If yes, you can bind three custom vertex attribute arrays for X, Y and Z, accordingly, and import them into your vertex shader and construct the resulting position.
Something like this:

attribute float xpos;
attribute float ypos;
attribute float zpos;

void main() {
gl_Position = vec4(xpos, ypos, zpos, 1.0);
}

sinaxp19
05-04-2015, 07:09 AM
void main() {
gl_Position = vec4(xpos, ypos, zpos, 1.0);
}[/CODE]
This is a bright idea hidefromKGB :) unfortunately my current structure is not shader-based (though, I don't see any problems in drawing vertexes using shaders) but is there an alternative to this (something like glVertexPointer)?
EDIT: This method seems to need reupload X, Y and Z on every draw action.

hidefromkgb
05-04-2015, 07:42 AM
is there an alternative to this (something like glVertexPointer)?
Hm… glInterleavedArrays (https://www.opengl.org/sdk/docs/man2/xhtml/glInterleavedArrays.xml) is the only thing that comes to mind. Unfortunately, it cannot split the array per-coordinate, so it doesn`t fit here.
I can be wrong, of course, but I doubt that fixed pipeline alternatives exist.

EDIT: This method seems to need reupload X, Y and Z on every draw action.
Not necessarily. This may (or may not) happen if GL_STREAM_DRAW is specified upon creation. Rebind — yes. Reupload — no.

mhagain
05-04-2015, 12:11 PM
It's not necessarily going to perform faster if you selectively update individual vector components like this. It may even perform slower.

GPUs like reading each vertex as a contiguous chunk of memory, so splitting them out like that may seem as though it's more efficient, but you're only working opposite to the way your GPU likes to receive it's data. It's a bad idea to optimize based on what "seems very redundant"; instead you should optimize based on actual real measurements of your code's performance. Especially where a GPU is concerned, because things are sometimes quite counter-intuitive.

Nonetheless you may still have a performance problem, and you may be misattributing it to the amount of data you're loading. There is a more likely candidate:
There is also a Vector4d per vertex for keeping color data
This indicates to me that you're using doubles as input to your glColorPointer call, and based on that I'm guessing that you're also likely to be using doubles as input to your glVertexPointer call too.

Don't do that.

See this thread for more (https://www.opengl.org/discussion_boards/showthread.php/186126-Performance-Issue-Drawing-many-primitives-%28-1M%29?p=1265878&viewfull=1#post1265878).

sinaxp19
05-05-2015, 06:49 AM
Hm… glInterleavedArrays (https://www.opengl.org/sdk/docs/man2/xhtml/glInterleavedArrays.xml) is the only thing that comes to mind. Unfortunately, it cannot split the array per-coordinate, so it doesn`t fit here.
I can be wrong, of course, but I doubt that fixed pipeline alternatives exist.


It's not necessarily going to perform faster if you selectively update individual vector components like this. It may even perform slower.

Thanks in advance guys. I found out that rebuilding the whole vertex data prior to sending them to GPU and using glBufferSubData doesn't differ much from using a pointer and updating vertex data in a FOR loop. I'll go with updating a data pack and resending it in every update loop in current sprint and leave shader based approach for the next sprint.