Bezier Control Points

Hi everyone,

I’ve been whacking my brains out over the last 2 days trying to figure something pretty fundamental out, but i must be completely misunderstanding what I’m trying to do.

Basically, i want to pass 4 bezier control points into the vertex shader so i can do the calculations on the gpu instead. The system I’m implementing is a particle system, so every particle has its own 4 bezier points.

I’ve thought about using glVertexAttribPointer to pass an array of control points, but it seems that can only pass 1 array of control points? Also, I don’t think there are 4 free generic attribute indices i can use to bind to.

I also found glMap1f, which seems to be exactly what i want, except it doesn’t pass the information to the shader? Or i don’t know how.

Any tips pointing me into the right direction would be a great help.

Basically, i want to pass 4 bezier control points into the vertex shader so i can do the calculations on the gpu instead. The system I’m implementing is a particle system, so every particle has its own 4 bezier points.

I don’t think that’s going to be faster than doing the position computations on the CPU. The memory transfer overhead of passing 16 floats per-point to the GPU (plus a float for the interpolation alpha value) will probably be greater than that of computing 4 floats on the CPU (position) and passing them as normal.

Also, I don’t think there are 4 free generic attribute indices i can use to bind to.

There are 16 attributes available; how much data are you passing that you don’t have 4?

Hi Alfonse, and thanks for the reply.

I don’t think that’s going to be faster than doing the position computations on the CPU. The memory transfer overhead of passing 16 floats per-point to the GPU (plus a float for the interpolation alpha value) will probably be greater than that of computing 4 floats on the CPU (position) and passing them as normal.

Maybe I’m taking the wrong approach to this. For the flame I’m trying to create, each particle has a slightly different path. If i don’t give them different paths, the flame doesn’t look quite right. Unfortunately, for this assignment I’m working on, they require us to create a flame both with and without a shader. So far I’ve only managed to create it without a shader. I’ve seen other student’s work, and they can have nearly 10x more particles using the gpu shading, and it looks like their particle paths are all slightly different.

There are 16 attributes available; how much data are you passing that you don’t have 4?

I might be misunderstanding something, but i saw an article that mentioned that 13 of those are reserved in nvidia cards. I’m actually quite confused about this, since an example i was given uses one of the indices that are supposedly reserved, yet still works properly.

If i change those indices to ones that aren’t supposed to be reserved, the particle behavior changes unexpectedly.

I might be misunderstanding something, but i saw an article that mentioned that 13 of those are reserved in nvidia cards.

You must have misunderstood something, because that’s not true. NVIDIA’s cards have aliasing between generic attributes and special-case ones. But if you’re using only generic attributes, it’s nothing you have to worry about.

If i change those indices to ones that aren’t supposed to be reserved, the particle behavior changes unexpectedly.

Are you actually using only generic attributes or are you combining generic attributes with regular ones?

Thanks heaps for the help Alfonse. I just started learning about shaders recently, so it’s all a bit confusing still.

Are you actually using only generic attributes or are you combining generic attributes with regular ones?

I’m actually not sure, but these are the commands I’m using in relation to that.



// in the class:
int program;
static final int VELOCITY_ARRAY = 1;

// in the init() function
program = ShaderUtil.makeShaders(gl, ".", "particle");
 - create an array of velocities via BufferUtil.newFloatBuffer()
gl.glBindAttribLocation(program, VELOCITY_ARRAY, "velocity");
gl.glUseProgram(program);

// in the display() function
velocities.rewind();
gl.glVertexAttribPointer(VELOCITY_ARRAY, 3, GL.GL_FLOAT, false, 0, velocities);
gl.glEnableVertexAttribArray(VELOCITY_ARRAY);
 - draw the particles here
gl.glDisableVertexAttribArray(VELOCITY_ARRAY);

I think they’re generic attributes, but I’ve been learning from examples, and they don’t always explain everything completely. It’s when i change “static final int VELOCITY_ARRAY = 1;” to have a value of say, 3,4,5,6,7,8, etc, the behavior changes unexpectedly.

Thanks!

program = ShaderUtil.makeShaders(gl, “.”, “particle”);

  • create an array of velocities via BufferUtil.newFloatBuffer()
    gl.glBindAttribLocation(program, VELOCITY_ARRAY, “velocity”);
    gl.glUseProgram(program);

glBindAttribLocation should be called before linking the program (which I assume is what makeShaders does, since you immediate use the program). It will not have an affect on the compiled program until you actually link it.

There are 3 ways to specify attribute locations for vertex attributes. You can use glBindAttribLocation for each attribute before linking the program. You can link the program without binding attribute locations, and use glGetAttribLocation to fetch the attribute that was automatically assigned.

And if you are using GL 3.2 or better (or have access to the GL_ARB_explict_attrib_location extension), you can have the shader itself assign attribute locations to attributes.

It’s when i change “static final int VELOCITY_ARRAY = 1;” to have a value of say, 3,4,5,6,7,8, etc, the behavior changes unexpectedly.

Setting the value to 1 only worked because of luck, essentially.

OpenGL implementations will avoid automatically assigning attribute locations to location 0, for historical reasons. So, as luck would have it, it picked 1 for your attribute. And since your glBindAttribLocation call wasn’t actually doing anything, it only worked when you just so happened to use the attribute location that was automatically assigned.

Ahhhh, thanks Alfonse. It’s starting to make a little more sense.

OpenGL implementations will avoid automatically assigning attribute locations to location 0, for historical reasons. So, as luck would have it, it picked 1 for your attribute. And since your glBindAttribLocation call wasn’t actually doing anything, it only worked when you just so happened to use the attribute location that was automatically assigned.

So does that mean from my example above (and makeShaders does link the program), that glBindAttribLocation doesn’t actually bind the location i specified with VELOCITY_ARRAY since that needs to be called before linking the program?

And if glBindAttribLocation is called after the linking of the program, it gets assigned a “randomly” unused location regardless of what i specified? Or does it only get assigned (randomly by opengl) when i get down to actually calling glVertexAttribPointer in the display() function?

I hope that makes sense, it was a bit awkward to word.

If that’s the case, it all makes a lot more sense!

Thanks!

And if glBindAttribLocation is called after the linking of the program, it gets assigned a “randomly” unused location regardless of what i specified?

No, it gets an arbitrarily assigned location if you don’t manually assign one with either glBindAttribLocation (before linking) or explicit attribute locations in the shader. Your call to glBindAttribLocation after linking has no effect on this.

All attributes of a program have a location after linking, either one explicitly assigned or given by OpenGL.

Thanks Alfonse. You’ve been a great help, and very prompt with your replies!

I’ll take all this in and see how it goes once i modify my implementation. If i have any other questions, ill ask :slight_smile:

Thanks again!

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.