frankie
frankie

Reputation: 728

DrawRangeElements don't draw in proper way

I am trying to draw with DrawRangeElements function, but for some reasons it don't draw part of elements.

For example, I have 156 points. My each element contains 52 points (3 elements x 52 points = 156 points).

Consider such code:

        //points contains 156 points
        float[] points = new float[] {
        1f, 2f, 3f, // 0
        //.........            //refers to first element
        4f, 5f, 5f, //51

        6f, 7f, 8f, //52
        //.........            //refers to second element
        9f, 10f, 11f, //103

        6f, 7f, 8f,  //104
        //.........            //refers to third element
        9f, 10f, 11f, //155 
        };

With DrawElements everything works fine.

    var indices1 = Enumerable.Range(0, 52).Select(i => (uint)i).ToArray();
    var indices2 = Enumerable.Range(52, 52).Select(i => (uint)i).ToArray();
    var indices3 = Enumerable.Range(104, 52).Select(i => (uint)i).ToArray();

    GL.DrawElements(PrimitiveType.QuadStrip, 52, DrawElementsType.UnsignedInt, indices1);
    GL.DrawElements(PrimitiveType.QuadStrip, 52, DrawElementsType.UnsignedInt, indices2);
    GL.DrawElements(PrimitiveType.QuadStrip, 52, DrawElementsType.UnsignedInt, indices3);

But for DrawRangeElements my effors fails. Only one from three elements is drawing.

        var indices = Enumerable.Range(0, 156).Select(i => (uint)i).ToArray();

        GL.DrawRangeElements(PrimitiveType.QuadStrip, 0, 51, 52, DrawElementsType.UnsignedInt, indices);
        GL.DrawRangeElements(PrimitiveType.QuadStrip, 52, 103, 52, DrawElementsType.UnsignedInt, indices); 
        GL.DrawRangeElements(PrimitiveType.QuadStrip, 104, 155, 52, DrawElementsType.UnsignedInt, indices); 

How, with DrawRangeElements I can draw my 3 elements?

Upvotes: 0

Views: 546

Answers (1)

derhass
derhass

Reputation: 45322

You misunderstood what glDrawRangeElements() acutally does.

The call

glDrawRangeElements(primtype, count, a, b, dtype, offsst;

is rendering the same data as

glDrawElements(primtype, count, dtype, offset);

no matter what a and b are set to. You just get undefined behavior when you lie to the GL about the range you are going to use. What you are doing here is drawing the same 52 vertices 3 times, with invalid range parameters in the latter two calls.

glDrawRangeElements() is just a performance optimization. The range you specify defines what the minimum and maximum value in your index array will be. So you assure the GL that you only will access some part of the vertex arrays (and VBOs), but not parts of the element array. The GL can use this knowledge for some optimizations (for example, if you update another part of the buffer after the draw call, the GL knows that it can safely do this without having to wait for the draw call to finish).

If you want to use a different part of the element array, just use a different offset (or pointer, in your case, since you seem to use client side arrays). However, I wonder why you use glDrawElements() at all, since glDrawArrays will out of the ox in your scenario, also avoiding the need of creating such abogus enumeration array:

GL.DrawArrays(PrimitiveType.QuadStrip, 0, 52);
GL.DrawArrays(PrimitiveType.QuadStrip, 52, 52);
GL.DrawArrays(PrimitiveType.QuadStrip, 104, 52);

Upvotes: 3

Related Questions