pontifikas's picture

Usage of MultiDrawElements??

I have a mesh consisting of facets with variable vertex count. So I want to draw them separately with multiple MultiDrawElements. It appears though that using the function to access facets beyond the first one fails. The program crashes without even an exception.

int numOfEdgeFacets = 2 * Slices;
                int numOfEdgeIndices = 3 * numOfEdgeFacets;
                int numOfTotalStackFacets = BB_ElementMesh.IndexArray.Length - 2 * numOfEdgeFacets;//Remove top-bottom edges
                int[] Bottom = new int[numOfEdgeFacets];
                int[] body = new int[numOfTotalStackFacets];
                int[] Top = new int[numOfEdgeFacets];
                Array.ConstrainedCopy(BB_ElementMesh.IndexArray, 0, Bottom, 0, numOfEdgeFacets);
                Array.ConstrainedCopy(BB_ElementMesh.IndexArray, BB_ElementMesh.IndexArray.Length - numOfEdgeFacets, Top, 0, numOfEdgeFacets);
                Array.ConstrainedCopy(BB_ElementMesh.IndexArray, numOfEdgeFacets, body, 0, numOfTotalStackFacets);
                //First Draw the BottomPolygon
                GL.MultiDrawElements(BeginMode.Polygon, ref numOfEdgeFacets, DrawElementsType.UnsignedInt, Bottom, 1);
                //Draw the main body
                GL.MultiDrawElements(BeginMode.Polygon, ref numOfTotalStackFacets, DrawElementsType.UnsignedInt, body, 1);
                //Draw the Top
                GL.MultiDrawElements(BeginMode.Polygon, ref numOfEdgeFacets, DrawElementsType.UnsignedInt, Top, 1);

In the Code Above only the first call to MultiDrawElements succeeds. If I commend the first and the second calls (ending up with an identical to the first) the third crashes the program. The only difference I see between the first and the last array is that they reference different parts of the collective Element Array (IndexArray).

What could I be doing wrong, or is there another way to address my problem(drawing variable size facets)?

Thank you in advance.


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

Is a non-zero element array buffer bound via GL.BindBuffer(BufferTarget.ElementArrayBuffer, id)? In that case, indices should be a list of integer offsets into that element array. On the other hand, if no element array is currently bound then indices should contain regular pointers to pinned .Net arrays.

Note that MultiDrawElements is equivalent to:

void MultiDrawElements<T>(BeginMode mode, Int32[] count, DrawElementsType type, T[] indices, Int32 primcount)
    where T : struct
    for (int i = 0; i < primcount; i++)
        GL.DrawElements(mode, count[i], type, indices[i]);

Try using this code to find out where exactly your code crashes. It's possible that indices contains an invalid offset, for example, and this should help uncover the problematic index.

Jase's picture

I know this is an old post, but I was experiencing issues with GL.MultiDrawElements which resulted in a driver crash on windows 7, which windows thankfully caught (says something about the new display driver model in vista/7) and once it restarted the driver, I could continue working. I received no exception in my program, nothing in event log to point to the cause. I did the typical bounds checks, 0 checks, etc etc but nothing helped. It was only after extensive googling that I came across a single post by someone who pointed out what I'm about to point out, so here's my contribution to future googlers.

The index offset isn't "the number of indicies into the array" that you want to start at, it's "how many bytes into the index array" you want to start at.

so if you want to start at index number 381, you set your offset to :
381 * sizeof(ushort)
where ushort is your index array type (either ushort or uint typically)

Once I fixed the offsets I received no more driver crashes.