@@ -55,7 +55,20 @@ pp_addhdr('
5555 int i; \
5656 for (i = 0; i < 3; i++) v[i] *= fac; \
5757 }
58- #define BUFFER_OFFSET(i) ((char *)NULL + (i))
58+ #define BUFFER_OFFSET(i) ((void *)((char *)NULL + (i)))
59+ #if defined(_WIN32) || (defined(__CYGWIN__) && defined(HAVE_W32API))
60+ #define loadProc(proc) \
61+ { \
62+ if (!proc) \
63+ { \
64+ proc = (void *)wglGetProcAddress(#proc); \
65+ if (!proc) croak(#proc " is not supported by this renderer"); \
66+ } \
67+ }
68+ PFNGLMULTIDRAWELEMENTSPROC glMultiDrawElements;
69+ #else /* not using WGL */
70+ #define loadProc(proc)
71+ #endif /* not defined _WIN32, __CYGWIN__, and HAVE_W32API */
5972');
6073
6174my @internal = (Doc => 'internal', NoPthread => 1);
@@ -92,6 +105,15 @@ pp_def(
92105 Pars => 'coords(tri=3,n);',
93106 OtherPars => 'int dim0; int dim1 => nstacks;',
94107 Code => <<'EOF',
108+ loadProc(glMultiDrawElements)
109+ PDL_Long *counts = malloc(sizeof(PDL_Long*) * $SIZE(nstacks));
110+ PDL_ULong **indexptrs = malloc(sizeof(PDL_ULong*) * $SIZE(nstacks));
111+ if (!indexptrs) $CROAK("malloc failed");
112+ loop(nstacks) %{
113+ counts[nstacks] = $COMP(dim0);
114+ indexptrs[nstacks] = BUFFER_OFFSET(nstacks * $COMP(dim0) * sizeof(PDL_ULong));
115+ %}
116+ broadcastloop %{
95117float oldcoord0 = 0.0, oldcoord1 = 0.0, oldcoord2 = 0.0;
96118glPushMatrix();
97119loop(n) %{
@@ -100,12 +122,11 @@ loop(n) %{
100122 $coords(tri=>1) - oldcoord1,
101123 $coords(tri=>2) - oldcoord2
102124 );
103- loop (nstacks) %{
104- glDrawElements(GL_TRIANGLE_STRIP, $COMP(dim0), GL_UNSIGNED_INT, BUFFER_OFFSET(nstacks * $COMP(dim0) * sizeof(PDL_ULong)));
105- %}
125+ glMultiDrawElements(GL_TRIANGLE_STRIP, counts, GL_UNSIGNED_INT, (const GLvoid *const *)indexptrs, $SIZE(nstacks));
106126 oldcoord0 = $coords(tri=>0), oldcoord1 = $coords(tri=>1), oldcoord2 = $coords(tri=>2);
107127%}
108128glPopMatrix();
129+ %}
109130EOF
110131 @internal
111132);
0 commit comments