question about glMultiDrawElements...

i was using glMultiDrawElements in past without any problems, but now i want something, which i don’t think is possible with it.

i want to draw many (some times more then 150k) line strips (1 - 16 segments, rarely more then 16). i am using vertex program to change vertices positions and i set for every strip one uniform for vertex program. is thery any chance to do it with glMultiDrawElements? in particular that part with different uniform for every strip. or any ideas how to render this in one function call?

thank you

-now i am using for-cycle where i make glDrawElements calls and using vertex program. before i was using immediate mode and making the math on cpu and the performance is the same. sometimes the immediate mode is a bit faster :stuck_out_tongue:

What about providing the uniform variables as additional per vertex data in an vertex data array? However, this depends on the number of needed uniform variables…

that uniform is one float from range 0.0 - 1.0.

if will send it as vertex attribute, then i must change my data structure and it will take double the space :frowning:

Another solution is to use a vertex attribute instead of a uniform, but don’t include it in the vertex array. Just set it using an immediate mode call before drawing the line strip with a vertex array.

The problem with this is you still have 150k glDrawElements calls, but you don’t have to change a uniform parameter, which can be a very costly operation.

PS: I’d really like to hear a better suggestion from the people in the ARB that decided instancing is not needed because this feature is already in OpenGL :stuck_out_tongue:

is glVertexAttribute cheaper call then glUniform? because the glUniform is very expensive, when calling it 150k times :frowning: (

…when i call glVertexAttribute for first vertex and then don’t call it again for other vertices, what will it value in shader?

glVertexAttribute is supposed to be much cheaper then glUniform. And if you call it just once, the value in the shader will stay the same for every vertex until you call it again.

interesting. and what is the purpose of uniform then?

Vertex attributes are a limited resource. There are much more uniforms than attributes available. If you use only vertex attributes for everything you will run out attributes…

Also I’m not sure about the performance implications of using attributes for something that changes infrequently.

Originally posted by shelll:
interesting. and what is the purpose of uniform then?
The following is what I’ve picked up along the way largely through inference and various online conversations. Its not a definitive truth, but hopefully will provide a useful guideline.

Vertex attributes and uniforms from a “vertex program” programmers stand point are just different ways to get variables into a vertex program, so from this perspective there isn’t much difference in using a constant/slow varying vertex attribute over a uniform.

The difference really comes in how the vertex pipeline is wired up and implemented down on the GPU. Vertex attributes are streamed into a vertex program, and even if an attribute is not varying its just copied and streamed in like the rest of the per vertex attributes. The only real overhead in changing a vertex attribute is the API cost and the cost of transferring the data, nothing else in the pipeline need be reconfigured or pipelines flushed.

Uniforms in a vertex program are different to attributes in that they require all the vertex processors to change to that setting, which in turn means that you need to flush all currently processed vertices stalling the GPU, before you can change the uniform value. Uniforms may even be implemented as constants rather than variable registers, in this case a new program would be linked by the driver and then set down to the GPU replacing the old one.

Robert.

Can you just use display lists?

Are the uniforms dynamic? If not, you can sort them by uniform. Then, you’ll only have as many draw calls as uniform values rather than primitive sets. This will be helpful even if you use attribs instead of uniforms. If you use attribs, you can do pseudo-instancing, where you go:

VertexAttrib(…)
DrawElements(…)

…for each attrib/geometry combination.

-W

those uniforms are arbitrary values from 0.0 to 1.0, i’ll try to use attribs instead of uniforms and we’ll see :slight_smile:

i changed that uniform to attrib and now i have exactly the same performance as the CPU + immediate mode, which is a bit better then using uniform. i have also written the ASM version of program and the performance is still the same.

i must speed it up, so i think i should change my data structure or not rendering line strips, but instead just lines and do it somehow in fewer function calls.

any ideas? if some one want to help me, i’ll give you more info.

thank you

150k draw calls is a lot! DrawElements is relatively cheap, but it’s not that cheap! At these numbers the number of draw calls is definitely the bottleneck, that’s why you see no/minimal change from uniforms to attributes. In my opinion there’s no other way to speed it up than reducing the number of draw calls. You will have to use lines instead of line strips, and have to include that attribute with every vertex. Yes, eats up a lot more memory, but trust me, it will fly! Some times you can have your cake and eat it too, well this is not one of those… :wink:

(Disclaimer: I haven’t seen any answers to Won’s questions, so I’m assuming here that everything is fully dynamic. Otherwise his ideas could win.)

i know that number of function calls is the bottleneck :frowning:

i have another problem:
i don’t change vertex array pointer and don’t change one vertex attrib array pointer. but in the cycle i change that one uniform and one vertex attrib pointer and every draw call is with the same indices…

those same indices are one of my problems. is there any chance to tell that it should render always with them or i must make one big array of indices (copy the same array many times (every frame!, because indices may change all the time), i tried it, but was very slow).

thank you

those same indices are one of my problems. is there any chance to tell that it should render always with them or i must make one big array of indices (copy the same array many times (every frame!, because indices may change all the time), i tried it, but was very slow).

Doesn’t sound like you’re using VBO’s. You can create vertex arrays and element arrays that stay on the video card. That way you don’t have to transfer the values on every frame. Create a static element array for the indices, and use glMapBufferARB() to change the values when necessary… You can use the same element array (indices) for different vertex arrays.

http://oss.sgi.com/projects/ogl-sample/registry/ARB/vertex_buffer_object.txt

They have some example code at the bottom.

PS: Even using VBOs, 150k vertex arrays would still be slow… you definitely need to merge the data into less arrays.

i know the VBO, but i don’t need it now. there is still the problem, that it is impossible to tell GL to render multiple elements with the same indices.