1 import "OpenGLDisplayDriver"
12 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
14 //# include "gl_core_3_3.h"
15 # include "gl_compat_4_4.h" // FIXME: no glPushAttrib() in core profile
17 # include "gl_compat_4_4.h"
23 #undef glEnableClientState
24 #undef glDisableClientState
25 #undef GL_VERTEX_ARRAY
26 #undef GL_NORMAL_ARRAY
27 #undef GL_TEXTURE_COORD_ARRAY
29 #undef glVertexPointer
30 #undef glTexCoordPointer
33 #define glEnableClientState glEnableVertexAttribArray
34 #define glDisableClientState glDisableVertexAttribArray
35 #define GL_VERTEX_ARRAY GLBufferContents::vertex
36 #define GL_NORMAL_ARRAY GLBufferContents::normal
37 #define GL_TEXTURE_COORD_ARRAY GLBufferContents::texCoord
38 #define GL_COLOR_ARRAY GLBufferContents::color
39 #define glVertexPointer(n, t, s, p) glVertexAttribPointer(GLBufferContents::vertex, n, t, GL_FALSE, s, p)
40 #define glTexCoordPointer(n, t, s, p) glVertexAttribPointer(GLBufferContents::texCoord, n, t, GL_FALSE, s, p)
41 #define glColorPointer(n, t, s, p) glVertexAttribPointer(GLBufferContents::color, n, t, GL_FALSE, s, p)
45 #if defined(ES1_1) || defined(ES2) || defined(SHADERS)
81 #undef glColorMaterial
84 #define glRecti glimtkRecti
85 #define glBegin glimtkBegin
86 #define glTexCoord2i glimtkTexCoord2i
87 #define glVertex2i glimtkVertex2i
88 #define glTexCoord2d glimtkTexCoord2d
89 #define glVertex2d glimtkVertex2d
90 #define glTexCoord2f glimtkTexCoord2f
91 #define glVertex2f glimtkVertex2f
92 #define glEnd glimtkEnd
93 #define glColor3f glimtkColor3f
94 #define glColor4ub glimtkColor4ub
95 #define glColor4fv glimtkColor4fv
96 #define glNormal3fv glimtkNormal3fv
97 #define glNormal3f glimtkNormal3f
98 #define glTexCoord2fv glimtkTexCoord2fv
99 #define glVertex3d glimtkVertex3d
100 #define glVertex3dv glimtkVertex3dv
101 #define glVertex3f glimtkVertex3f
102 #define glVertex3fv glimtkVertex3fv
104 #define glLoadMatrixd glmsLoadMatrixd
105 #define glMultMatrixd glmsMultMatrixd
106 #define glFrustum glmsFrustum
107 #define glOrtho glmsOrtho
108 #define glScaled glmsScaled
109 #define glScalef glmsScaled
110 #define glTranslated glmsTranslated
111 #define glRotated glmsRotated
112 #define glMatrixMode glmsMatrixMode
113 #define glLoadIdentity glmsLoadIdentity
114 #define glPushMatrix glmsPushMatrix
115 #define glPopMatrix glmsPopMatrix
117 #define glLineStipple glesLineStipple
118 #define glColorMaterial glesColorMaterial
119 #define glLightModeli glesLightModeli
125 #define OFFSET(s, m) ((uint)(uintptr) (&((s *) 0)->m))
127 import "textureManager"
130 #define DM_ENABLE_IMAGE_ROTATION (1)
131 #define DM_ENABLE_EXT_COLOR (1)
135 static struct DMDrawVertexFlat
140 #if DM_ENABLE_EXT_COLOR
143 } __attribute__((aligned(16)));
145 static struct DMDrawVertex
150 #if DM_ENABLE_EXT_COLOR
153 } __attribute__((aligned(16)));
164 class DMProgramFlags : uint { bool valid:1; }
170 GLuint fragmentShader;
176 #if DM_ENABLE_EXT_COLOR
180 DMProgramFlags flags;
181 int64 lastUpdateCount;
184 class DMImageFlags : uint16
186 bool empty:1; // Image is empty, do not draw
187 bool blending:1; // Must draw image with blending
190 public struct DMImage
199 // Computed order for sorted rendering, in defineImage()
205 this = { flags = { empty = true } };
208 void defineImage( Texture texture, int offsetx, int offsety, int sizex, int sizey, bool blending, int programIndex, int layerindex )
210 int ordx = offsetx >> 6;
211 int ordy = offsety >> 6;
212 uint32 orderimage = ccMortonNumber32( ordx, ordy ) & ( ( 1 << DM_IMAGE_ORDER_BITS ) - 1 );
216 srcx = (short)offsetx;
217 srcy = (short)offsety;
218 sizex = (short)sizex;
219 sizey = (short)sizey;
220 programIndex = (short)programIndex;
221 flags = { blending = blending };
222 orderMask = (orderimage << DM_IMAGE_ORDER_SHIFT) |
223 (( blending == true ) << DM_BLEND_ORDER_SHIFT) |
224 (programIndex << DM_PROGRAM_ORDER_SHIFT) |
226 (layerindex << DM_LAYER_ORDER_SHIFT);
238 #if DM_ENABLE_IMAGE_ROTATION
242 #if DM_ENABLE_EXT_COLOR
253 define DM_IMAGE_ORDER_BITS = 8;
254 define DM_BLEND_ORDER_BITS = 1;
255 define DM_PROGRAM_ORDER_BITS = 4;
256 define DM_TEXTURE_ORDER_BITS = 10;
257 define DM_LAYER_ORDER_BITS = 4;
258 define DM_BARRIER_ORDER_BITS = 5;
260 define DM_IMAGE_ORDER_SHIFT = 0;
261 define DM_BLEND_ORDER_SHIFT = DM_IMAGE_ORDER_BITS;
262 define DM_PROGRAM_ORDER_SHIFT = DM_IMAGE_ORDER_BITS+DM_BLEND_ORDER_BITS;
263 define DM_TEXTURE_ORDER_SHIFT = DM_IMAGE_ORDER_BITS+DM_BLEND_ORDER_BITS+DM_PROGRAM_ORDER_BITS;
264 define DM_LAYER_ORDER_SHIFT = DM_IMAGE_ORDER_BITS+DM_BLEND_ORDER_BITS+DM_PROGRAM_ORDER_BITS+DM_TEXTURE_ORDER_BITS;
265 define DM_BARRIER_ORDER_SHIFT = DM_IMAGE_ORDER_BITS+DM_BLEND_ORDER_BITS+DM_PROGRAM_ORDER_BITS+DM_TEXTURE_ORDER_BITS+DM_LAYER_ORDER_BITS;
267 define DM_LAYER_COUNT = 1<<DM_LAYER_ORDER_BITS;
268 define DM_PROGRAM_COUNT = 1<<DM_PROGRAM_ORDER_BITS;
270 define DM_CONTEXT_DRAW_BUFFER_COUNT = 64;
271 define DM_CONTEXT_DRAW_BUFFER_VERTEX_ALLOC = 1024;
274 /* Range is from zero to DM_LAYER_COUNT */
295 define DM_LAYER_BOTTOM = DMLayer::DM_LAYER_0_BOTTOM;
296 define DM_LAYER_BELOW = DMLayer::DM_LAYER_3_BELOW;
297 define DM_LAYER_NORMAL = DMLayer::DM_LAYER_6_NORMAL;
298 define DM_LAYER_ABOVE = DMLayer::DM_LAYER_9_ABOVE;
299 define DM_LAYER_TOP = DMLayer::DM_LAYER_15_TOP;
301 define DM_PROGRAM_NORMAL = 0;
302 define DM_PROGRAM_ALPHABLEND = 1;
303 define DM_PROGRAM_ALPHABLEND_INTENSITY = 2;
304 define DM_PROGRAM_ALPHABLEND_INTENSITY_EXTCOLOR = 3;
307 static inline void OpenGLErrorCheck( const char *file, int line )
309 int error = glGetError();
310 if( error != GL_NO_ERROR )
311 printf( "ERROR %d at %s:%d\n", error, file, line );
314 #define ERRORCHECK() OpenGLErrorCheck(__FILE__,__LINE__)
319 #define DM_IMAGE_ROTATION_NORMFACTOR (32767.0f)
321 #define DM_VERTEX_NORMSHIFT (2)
322 #define DM_VERTEX_NORMFACTOR (4.0f)
324 #define DM_TEXCOORD_NORMSHIFT (13)
325 #define DM_TEXCOORD_NORMFACTOR (8192.0f)
327 static GLuint dmCreateShader( GLenum type, const char *shadersource, const char *optionstring )
333 const GLchar *sourcearray[2];
335 shader = glCreateShader( type );
339 if( !( optionstring ) )
341 sourcearray[0] = optionstring;
342 sourcearray[1] = shadersource;
343 glShaderSource( shader, 2, sourcearray, NULL );
344 glCompileShader( shader );
345 glGetShaderiv( shader, GL_COMPILE_STATUS, &status );
346 if( status != GL_TRUE )
348 fprintf( stderr, "ERROR: Failed to compile shader\n" );
349 glGetShaderInfoLog( shader, 8192, &loglength,infolog );
350 fprintf( stderr, "ERROR: \n%s\n\n", infolog );
351 glDeleteShader( shader );
358 static bool dmCreateProgram( DMProgram program, const char *vertexsource, const char *fragmentsource, char *optionstring )
364 program.glProgram = 0;
365 program.vertexShader = 0;
366 program.fragmentShader = 0;
368 program.vertexShader = dmCreateShader( GL_VERTEX_SHADER, vertexsource, optionstring );
369 if( !( program.vertexShader ) )
371 fprintf(stderr, "ERROR: Unable to load vertex shader\n");
374 program.fragmentShader = dmCreateShader( GL_FRAGMENT_SHADER, fragmentsource, optionstring );
375 if( !( program.fragmentShader ) )
377 fprintf(stderr, "ERROR: Unable to load fragment shader\n");
380 program.glProgram = glCreateProgram();
381 if( !( program.glProgram ) )
383 fprintf(stderr, "ERROR: Unable to create program\n");
387 glAttachShader( program.glProgram, program.vertexShader );
388 glAttachShader( program.glProgram, program.fragmentShader );
390 glBindAttribLocation(program.glProgram, GLBufferContents::vertex, "vertex");
391 glBindAttribLocation(program.glProgram, GLBufferContents::texCoord, "texCoord");
392 glBindAttribLocation(program.glProgram, GLBufferContents::color, "color");
393 glBindAttribLocation(program.glProgram, GLBufferContents::normal, "normal");
395 glLinkProgram( program.glProgram );
396 glGetProgramiv( program.glProgram, GL_LINK_STATUS, &status );
397 if( status != GL_TRUE )
399 fprintf( stderr, "ERROR, failed to link shader program\n" );
400 glGetProgramInfoLog( program.glProgram, 8192, &loglength, infolog );
401 fprintf( stderr, "ERROR: \n%s\n\n", infolog );
405 // glUseProgram( program.glProgram );
407 program.matrixloc = glGetUniformLocation( program.glProgram, "uniMatrix" );
408 program.vertexloc = glGetAttribLocation( program.glProgram, "inVertex" );
409 program.texcoord0loc = glGetAttribLocation( program.glProgram, "inTexcoord0" );
410 program.texcoord1loc = glGetAttribLocation( program.glProgram, "inTexcoord1" );
411 program.colorloc = glGetAttribLocation( program.glProgram, "inColor" );
412 #if DM_ENABLE_EXT_COLOR
413 program.extcolorloc = glGetAttribLocation( program.glProgram, "inExtColor" );
415 program.texbaseloc = glGetUniformLocation( program.glProgram, "texBase" );
416 program.flags.valid = true;
421 if( program.fragmentShader )
422 glDeleteShader( program.fragmentShader );
423 if( program.vertexShader )
424 glDeleteShader( program.vertexShader );
425 if( program.glProgram )
426 glDeleteProgram( program.glProgram );
434 const char *dmVertexShaderNormal =
436 "uniform mat4 uniMatrix;\n"
437 "in vec2 inVertex;\n"
438 "in vec2 inTexcoord0;\n"
440 "out vec2 varTexcoord0;\n"
441 "out vec4 varColor;\n"
445 " varTexcoord0 = inTexcoord0 * (1.0/" CC_STRINGIFY(DM_TEXCOORD_NORMFACTOR) ");\n"
446 " varColor = inColor;\n"
447 " gl_Position = uniMatrix * vec4( inVertex, 0.0, 1.0 );\n"
453 const char *dmFragmentShaderNormal =
455 "uniform sampler2D texBase;\n"
456 "in vec2 varTexcoord0;\n"
457 "in vec4 varColor;\n"
460 " gl_FragColor = varColor * texture2D( texBase, varTexcoord0 );\n"
466 const char *dmVertexShaderAlpha =
468 "uniform mat4 uniMatrix;\n"
469 "in vec2 inVertex;\n"
470 "in vec2 inTexcoord0;\n"
472 "out vec2 varTexcoord0;\n"
473 "out vec4 varColor;\n"
477 " varTexcoord0 = inTexcoord0 * (1.0/" CC_STRINGIFY(DM_TEXCOORD_NORMFACTOR) ");\n"
478 " varColor = inColor;\n"
479 " gl_Position = uniMatrix * vec4( inVertex, 0.0, 1.0 );\n"
485 const char *dmFragmentShaderAlpha =
487 "uniform sampler2D texBase;\n"
488 "in vec2 varTexcoord0;\n"
489 "in vec4 varColor;\n"
492 " gl_FragColor = vec4( varColor.rgb, varColor.a * texture2D( texBase, varTexcoord0 ).r );\n"
497 const char *dmVertexShaderAlphaIntensity =
499 "uniform mat4 uniMatrix;\n"
500 "in vec2 inVertex;\n"
501 "in vec2 inTexcoord0;\n"
503 "out vec2 varTexcoord0;\n"
504 "out vec4 varColor;\n"
508 " varTexcoord0 = inTexcoord0 * (1.0/" CC_STRINGIFY(DM_TEXCOORD_NORMFACTOR) ");\n"
509 " varColor = inColor;\n"
510 " gl_Position = uniMatrix * vec4( inVertex, 0.0, 1.0 );\n"
516 const char *dmFragmentShaderAlphaIntensity =
518 "uniform sampler2D texBase;\n"
519 "in vec2 varTexcoord0;\n"
520 "in vec4 varColor;\n"
524 " tex = texture2D( texBase, varTexcoord0 ).rg;\n"
525 " gl_FragColor = vec4( varColor.rgb * tex.g, varColor.a * tex.r );\n"
530 const char *dmVertexShaderAlphaIntensityExtColor =
532 "uniform mat4 uniMatrix;\n"
533 "in vec2 inVertex;\n"
534 "in vec2 inTexcoord0;\n"
536 "in vec4 inExtColor;\n"
537 "out vec2 varTexcoord0;\n"
538 "out vec4 varColor;\n"
539 "out vec4 varExtColor;\n"
543 " varTexcoord0 = inTexcoord0 * (1.0/" CC_STRINGIFY(DM_TEXCOORD_NORMFACTOR) ");\n"
544 " varColor = inColor;\n"
545 " varExtColor = inExtColor;\n"
546 " gl_Position = uniMatrix * vec4( inVertex, 0.0, 1.0 );\n"
552 const char *dmFragmentShaderAlphaIntensityExtColor =
554 "uniform sampler2D texBase;\n"
555 "in vec2 varTexcoord0;\n"
556 "in vec4 varColor;\n"
557 "in vec4 varExtColor;\n"
561 " tex = texture2D( texBase, varTexcoord0 ).rg;\n"
562 " gl_FragColor = vec4( mix( varExtColor.rgb, varColor.rgb, tex.g ), mix( varExtColor.a, varColor.a, tex.g ) * tex.r );\n"
570 static void matrixOrtho( float *m, float left, float right, float bottom, float top, float nearval, float farval )
572 float x = 2.0f / ( right - left );
573 float y = 2.0f / ( top - bottom );
574 float z = -2.0f / ( farval - nearval );
575 float tx = -( right + left ) / ( right - left );
576 float ty = -( top + bottom ) / ( top - bottom );
577 float tz = -( farval + nearval ) / ( farval - nearval );
579 #define M(row,col) m[col*4+row]
580 M(0,0) = x; M(0,1) = 0.0; M(0,2) = 0.0; M(0,3) = tx;
581 M(1,0) = 0.0; M(1,1) = y; M(1,2) = 0.0; M(1,3) = ty;
582 M(2,0) = 0.0; M(2,1) = 0.0; M(2,2) = z; M(2,3) = tz;
583 M(3,0) = 0.0; M(3,1) = 0.0; M(3,2) = 0.0; M(3,3) = 1.0;
590 /* FIXME: Radix sort, not hybrid sort! */
592 static inline int dmSortImagesCmp( DMImageBuffer *draw0, DMImageBuffer *draw1 )
594 return ( ( draw0->orderindex < draw1->orderindex ) ? 0 : 1 );
597 #define HSORT_MAIN dmSortImages
598 #define HSORT_CMP dmSortImagesCmp
599 #define HSORT_TYPE DMImageBuffer
600 #include "cchybridsort.h"
608 // TOFIX: Make this private, have a property
609 public class DrawManagerFlags : uint32 { bool prehistoricOpenGL:1; }
611 public class DrawManager
613 DrawManagerFlags flags;
614 DMProgram shaderPrograms[DM_PROGRAM_COUNT];
619 int imageBufferCount;
621 DMImageBuffer *imageBuffer;
622 DMImageBuffer *imageBufferTmp;
624 // Buffers for drawimages() batching
625 DMDrawBuffer drawBuffer[DM_CONTEXT_DRAW_BUFFER_COUNT];
627 int drawBarrierIndex;
628 uint32 orderBarrierMask;
630 // Counter to track program uniforms and such
635 static DMProgram *flushUseProgram( int programIndex )
637 DMProgram *program = &shaderPrograms[ programIndex ];
638 if( !program->flags.valid)
644 glUseProgram( program->glProgram );
645 if( program->lastUpdateCount != this.updateCount )
647 glUniformMatrix4fv( program->matrixloc, 1, GL_FALSE, this.matrix );
648 glUniform1i( program->texbaseloc, 0 );
649 program->lastUpdateCount = this.updateCount;
655 static void flushRenderDrawBufferArchaic( DMDrawBuffer drawBuffer, DMProgram program, int vertexCount )
657 glEnable( GL_TEXTURE_2D );
658 glBindBuffer( GL_ARRAY_BUFFER, drawBuffer.vbo );
659 glColor3f( 1.0, 1.0, 1.0 );
661 glEnableClientState( GL_VERTEX_ARRAY );
662 glEnableClientState( GL_TEXTURE_COORD_ARRAY );
663 glEnableClientState( GL_COLOR_ARRAY );
665 glVertexPointer( 2, GL_FLOAT, sizeof(DMDrawVertexFlat), (void *)OFFSET(DMDrawVertexFlat,vertex) );
666 glTexCoordPointer( 2, GL_FLOAT, sizeof(DMDrawVertexFlat), (void *)OFFSET(DMDrawVertexFlat,texcoord0) );
667 glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(DMDrawVertexFlat), (void *)OFFSET(DMDrawVertexFlat,color) );
669 glDrawArrays( GL_TRIANGLES, 0, vertexCount );
671 glDisableClientState( GL_VERTEX_ARRAY );
672 glDisableClientState( GL_TEXTURE_COORD_ARRAY );
673 glDisableClientState( GL_COLOR_ARRAY );
674 glDisable( GL_TEXTURE_2D );
676 #if DM_FLUSH_EACH_RENDER_DRAW_BUFFER
681 void flushDrawImagesArchaic( )
683 bool flushflag, stateBlend;
684 int index, vertexCount, programIndex;
685 float vx0, vx1, vx2, vx3, vy0, vy1, vy2, vy3;
686 #if DM_ENABLE_IMAGE_ROTATION
687 float angsin, angcos, sizex, sizey;
689 float tx0, tx1, ty0, ty1;
690 DMImageBuffer *imageBuffer;
691 DMImage *image, *bindimage;
692 Texture texture, bindTexture;
693 DMDrawBuffer *drawBuffer;
694 DMDrawVertexFlat *vboVertex;
699 drawBarrierIndex = 0;
700 orderBarrierMask = drawBarrierIndex << DM_BARRIER_ORDER_SHIFT;
703 // Sort by image type and texture, minimize state changes
704 dmSortImages( this.imageBuffer, imageBufferTmp, imageBufferCount, (uint32)( (intptr_t)this.imageBuffer >> 4 ) );
706 // Fill a drawBuffer, write vertex and texcoords
707 drawBuffer = &this.drawBuffer[drawBufferIndex];
708 drawBufferIndex = ( drawBufferIndex + 1 ) % DM_CONTEXT_DRAW_BUFFER_COUNT;
709 glBindBuffer( GL_ARRAY_BUFFER, drawBuffer->vbo );
710 vboVertex = glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY );
713 glActiveTexture( GL_TEXTURE0 );
714 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
715 glDisable( GL_BLEND );
717 #if DM_RENDER_IMAGE_DEBUG
718 printf( " Flush %d images\n", (int)imageBufferCount );
726 imageBuffer = this.imageBuffer;
727 for( index = 0 ; index < imageBufferCount ; index++, imageBuffer++ )
729 image = imageBuffer->image;
730 texture = image->texture;
733 if( image != bindimage )
735 if( stateBlend != image->flags.blending )
737 if( texture != bindTexture )
740 if( vertexCount >= ( drawBuffer->vertexAlloc - 6 ) )
747 glUnmapBuffer( GL_ARRAY_BUFFER );
748 // Flush font manager texture updates
750 // Render buffered images
751 flushRenderDrawBufferArchaic( drawBuffer, program, vertexCount );
752 drawBuffer = &this.drawBuffer[drawBufferIndex];
753 drawBufferIndex = ( drawBufferIndex + 1 ) % DM_CONTEXT_DRAW_BUFFER_COUNT;
754 glBindBuffer( GL_ARRAY_BUFFER, drawBuffer->vbo );
755 vboVertex = glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY );
759 if( stateBlend != ( image->flags.blending ) )
761 stateBlend = image->flags.blending;
762 ( stateBlend ? glEnable : glDisable )( GL_BLEND );
763 #if DM_RENDER_IMAGE_DEBUG
764 printf( " Switch blending %d\n", stateBlend != false );
767 if( programIndex != image->programIndex )
769 programIndex = image->programIndex;
770 program = flushUseProgram( programIndex );
772 if( texture != bindTexture )
774 bindTexture = texture;
775 glBindTexture( GL_TEXTURE_2D, bindTexture.glTex );
776 #if DM_RENDER_IMAGE_DEBUG
777 printf( " Switch to texture 0x%x\n", (int)texture.orderMask );
783 #if DM_RENDER_IMAGE_DEBUG
784 printf( " Render image at %d %d, order 0x%x, texture %p\n", (int)imageBuffer->offsetx, (int)imageBuffer->offsety, (int)imageBuffer->orderindex, texture );
787 #if DM_ENABLE_IMAGE_ROTATION
788 angsin = (float)imageBuffer->angsin * (1.0f/DM_IMAGE_ROTATION_NORMFACTOR);
789 angcos = (float)imageBuffer->angcos * (1.0f/DM_IMAGE_ROTATION_NORMFACTOR);
790 sizex = (float)imageBuffer->sizex;
791 sizey = (float)imageBuffer->sizey;
792 vx0 = (float)imageBuffer->offsetx * (1.0f/DM_VERTEX_NORMFACTOR);
793 vy0 = (float)imageBuffer->offsety * (1.0f/DM_VERTEX_NORMFACTOR);
794 vx1 = vx0 + ( angcos * sizex );
795 vy1 = vy0 + ( angsin * sizex );
796 vx2 = vx0 - ( angsin * sizey );
797 vy2 = vy0 + ( angcos * sizey );
798 vx3 = vx0 + ( angcos * sizex ) - ( angsin * sizey );
799 vy3 = vy0 + ( angsin * sizex ) + ( angcos * sizey );
801 vx0 = (float)imageBuffer->offsetx * (1.0f/DM_VERTEX_NORMFACTOR);
802 vy0 = (float)imageBuffer->offsety * (1.0f/DM_VERTEX_NORMFACTOR);
803 vx3 = vx0 + (float)( imageBuffer->sizex );
804 vy3 = vy0 + (float)( imageBuffer->sizey );
811 tx0 = (float)( image->srcx ) * texture.widthinv;
812 ty0 = (float)( image->srcy ) * texture.heightinv;
813 tx1 = (float)( image->srcx + image->sizex ) * texture.widthinv;
814 ty1 = (float)( image->srcy + image->sizey ) * texture.heightinv;
817 vboVertex[0].vertex[0] = vx3;
818 vboVertex[0].vertex[1] = vy3;
819 vboVertex[0].texcoord0[0] = tx1;
820 vboVertex[0].texcoord0[1] = ty1;
821 vboVertex[0].color = imageBuffer->color;
822 #if DM_ENABLE_EXT_COLOR
823 vboVertex[0].extcolor = imageBuffer->extcolor;
825 vboVertex[1].vertex[0] = vx1;
826 vboVertex[1].vertex[1] = vy1;
827 vboVertex[1].texcoord0[0] = tx1;
828 vboVertex[1].texcoord0[1] = ty0;
829 vboVertex[1].color = imageBuffer->color;
830 #if DM_ENABLE_EXT_COLOR
831 vboVertex[1].extcolor = imageBuffer->extcolor;
833 vboVertex[2].vertex[0] = vx2;
834 vboVertex[2].vertex[1] = vy2;
835 vboVertex[2].texcoord0[0] = tx0;
836 vboVertex[2].texcoord0[1] = ty1;
837 vboVertex[2].color = imageBuffer->color;
838 #if DM_ENABLE_EXT_COLOR
839 vboVertex[2].extcolor = imageBuffer->extcolor;
841 vboVertex[3].vertex[0] = vx0;
842 vboVertex[3].vertex[1] = vy0;
843 vboVertex[3].texcoord0[0] = tx0;
844 vboVertex[3].texcoord0[1] = ty0;
845 vboVertex[3].color = imageBuffer->color;
846 #if DM_ENABLE_EXT_COLOR
847 vboVertex[3].extcolor = imageBuffer->extcolor;
849 vboVertex[4].vertex[0] = vx2;
850 vboVertex[4].vertex[1] = vy2;
851 vboVertex[4].texcoord0[0] = tx0;
852 vboVertex[4].texcoord0[1] = ty1;
853 vboVertex[4].color = imageBuffer->color;
854 #if DM_ENABLE_EXT_COLOR
855 vboVertex[4].extcolor = imageBuffer->extcolor;
857 vboVertex[5].vertex[0] = vx1;
858 vboVertex[5].vertex[1] = vy1;
859 vboVertex[5].texcoord0[0] = tx1;
860 vboVertex[5].texcoord0[1] = ty0;
861 vboVertex[5].color = imageBuffer->color;
862 #if DM_ENABLE_EXT_COLOR
863 vboVertex[5].extcolor = imageBuffer->extcolor;
870 glUnmapBuffer( GL_ARRAY_BUFFER );
872 // Flush font manager texture updates
875 // Render buffered images
876 flushRenderDrawBufferArchaic( drawBuffer, program, vertexCount );
877 imageBufferCount = 0;
884 void flushRenderDrawBuffer( DMDrawBuffer drawBuffer, DMProgram program, int vertexCount )
886 glBindBuffer( GL_ARRAY_BUFFER, drawBuffer.vbo );
887 if( program.vertexloc != -1 )
889 glEnableVertexAttribArray( program.vertexloc );
890 glVertexAttribPointer( program.vertexloc, 2, GL_SHORT, GL_FALSE, sizeof(DMDrawVertex), (void *)OFFSET(DMDrawVertex,vertex) );
892 if( program.texcoord0loc != -1 )
894 glEnableVertexAttribArray( program.texcoord0loc );
895 glVertexAttribPointer( program.texcoord0loc, 2, GL_SHORT, GL_FALSE, sizeof(DMDrawVertex), (void *)OFFSET(DMDrawVertex,texcoord0) );
897 if( program.colorloc != -1 )
899 glEnableVertexAttribArray( program.colorloc );
900 glVertexAttribPointer( program.colorloc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(DMDrawVertex), (void *)OFFSET(DMDrawVertex,color) );
903 #if DM_ENABLE_EXT_COLOR
904 if( program.extcolorloc != -1 )
906 glEnableVertexAttribArray( program.extcolorloc );
907 glVertexAttribPointer( program.extcolorloc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(DMDrawVertex), (void *)OFFSET(DMDrawVertex,extcolor) );
911 glDrawArrays( GL_TRIANGLES, 0, vertexCount );
913 if( program.vertexloc != -1 )
914 glDisableVertexAttribArray( program.vertexloc );
915 if( program.texcoord0loc != -1 )
916 glDisableVertexAttribArray( program.texcoord0loc );
917 if( program.colorloc != -1 )
918 glDisableVertexAttribArray( program.colorloc );
920 #if DM_FLUSH_EACH_RENDER_DRAW_BUFFER
925 void flushDrawImages( )
927 int index, stateblend, vertexcount, flushflag, programIndex;
928 float vx0, vx1, vx2, vx3, vy0, vy1, vy2, vy3;
929 #if DM_ENABLE_IMAGE_ROTATION
930 float angsin, angcos, sizex, sizey;
932 float tx0, tx1, ty0, ty1;
933 DMImageBuffer *imageBuffer;
934 DMImage *image, *bindimage;
935 Texture texture, bindtexture;
936 DMDrawBuffer *drawBuffer;
937 DMDrawVertex *vboVertex;
942 this.drawBarrierIndex = 0;
943 orderBarrierMask = drawBarrierIndex << DM_BARRIER_ORDER_SHIFT;
944 if( imageBufferCount )
946 /* Sort by image type and texture, minimize state changes */
947 dmSortImages( this.imageBuffer, this.imageBufferTmp, imageBufferCount, (uint32)( (uintptr)this.imageBuffer >> 4 ) );
949 /* Fill a drawBuffer, write vertex and texcoords */
950 drawBuffer = &this.drawBuffer[this.drawBufferIndex];
951 this.drawBufferIndex = ( this.drawBufferIndex + 1 ) % DM_CONTEXT_DRAW_BUFFER_COUNT;
952 glBindBuffer( GL_ARRAY_BUFFER, drawBuffer->vbo );
953 vboVertex = glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY );
956 glActiveTexture( GL_TEXTURE0 );
957 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
958 glDisable( GL_BLEND );
960 #if DM_RENDER_IMAGE_DEBUG
961 printf( " Flush %d images\n", (int)imageBufferCount );
969 imageBuffer = this.imageBuffer;
970 for( index = 0 ; index < imageBufferCount ; index++, imageBuffer++ )
972 image = imageBuffer->image;
973 texture = image->texture;
976 if( image != bindimage )
978 if( stateblend != ( image->flags.blending ) )
980 if( texture != bindtexture )
983 if( vertexcount >= ( drawBuffer->vertexAlloc - 6 ) )
990 glUnmapBuffer( GL_ARRAY_BUFFER );
991 // Flush font manager texture updates
994 // Render buffered images
995 flushRenderDrawBuffer( drawBuffer, program, vertexcount );
996 drawBuffer = &this.drawBuffer[this.drawBufferIndex];
997 this.drawBufferIndex = ( this.drawBufferIndex + 1 ) % DM_CONTEXT_DRAW_BUFFER_COUNT;
998 glBindBuffer( GL_ARRAY_BUFFER, drawBuffer->vbo );
999 vboVertex = glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY );
1003 if( stateblend != ( image->flags.blending ) )
1005 stateblend = image->flags.blending;
1006 ( stateblend ? glEnable : glDisable )( GL_BLEND );
1007 #if DM_RENDER_IMAGE_DEBUG
1008 printf( " Switch blending %d\n", ( stateblend != 0 ) );
1011 if( programIndex != image->programIndex )
1013 programIndex = image->programIndex;
1014 program = flushUseProgram( programIndex );
1016 if( texture != bindtexture )
1018 bindtexture = texture;
1019 glBindTexture( GL_TEXTURE_2D, bindtexture.glTex );
1020 #if DM_RENDER_IMAGE_DEBUG
1021 printf( " Switch to texture 0x%x\n", (int)texture.orderMask );
1027 #if DM_RENDER_IMAGE_DEBUG
1028 printf( " Render image at %d %d, order 0x%x, texture %p\n", (int)imageBuffer->offsetx, (int)imageBuffer->offsety, (int)imageBuffer->orderindex, texture );
1031 #if DM_ENABLE_IMAGE_ROTATION
1032 /* FIXME TODO: Don't go through float, compute texcoord integers directly */
1033 angsin = (float)imageBuffer->angsin * (1.0f/DM_IMAGE_ROTATION_NORMFACTOR);
1034 angcos = (float)imageBuffer->angcos * (1.0f/DM_IMAGE_ROTATION_NORMFACTOR);
1035 sizex = (float)imageBuffer->sizex;
1036 sizey = (float)imageBuffer->sizey;
1037 vx0 = (float)imageBuffer->offsetx * (1.0f/DM_VERTEX_NORMFACTOR);
1038 vy0 = (float)imageBuffer->offsety * (1.0f/DM_VERTEX_NORMFACTOR);
1039 vx1 = vx0 + ( angcos * sizex );
1040 vy1 = vy0 + ( angsin * sizex );
1041 vx2 = vx0 - ( angsin * sizey );
1042 vy2 = vy0 + ( angcos * sizey );
1043 vx3 = vx0 + ( angcos * sizex ) - ( angsin * sizey );
1044 vy3 = vy0 + ( angsin * sizex ) + ( angcos * sizey );
1046 /* FIXME TODO: Don't go through float, compute texcoord integers directly */
1047 vx0 = (float)imageBuffer->offsetx * (1.0f/DM_VERTEX_NORMFACTOR);
1048 vy0 = (float)imageBuffer->offsety * (1.0f/DM_VERTEX_NORMFACTOR);
1049 vx3 = vx0 + (float)( imageBuffer->sizex );
1050 vy3 = vy0 + (float)( imageBuffer->sizey );
1057 /* FIXME TODO: Don't go through float, compute texcoord integers directly */
1058 tx0 = (float)( image->srcx ) * texture.widthinv;
1059 ty0 = (float)( image->srcy ) * texture.heightinv;
1060 tx1 = (float)( image->srcx + image->sizex ) * texture.widthinv;
1061 ty1 = (float)( image->srcy + image->sizey ) * texture.heightinv;
1063 /* Write data to VBO */
1064 /* TODO: write vertex/texcoord all at once with SSE */
1065 vboVertex[0].vertex[0] = (short)( vx3 * DM_VERTEX_NORMFACTOR );
1066 vboVertex[0].vertex[1] = (short)( vy3 * DM_VERTEX_NORMFACTOR );
1067 vboVertex[0].texcoord0[0] = (short)( tx1 * DM_TEXCOORD_NORMFACTOR );
1068 vboVertex[0].texcoord0[1] = (short)( ty1 * DM_TEXCOORD_NORMFACTOR );
1069 vboVertex[0].color = imageBuffer->color;
1070 vboVertex[0].extcolor = imageBuffer->extcolor;
1071 vboVertex[1].vertex[0] = (short)( vx1 * DM_VERTEX_NORMFACTOR );
1072 vboVertex[1].vertex[1] = (short)( vy1 * DM_VERTEX_NORMFACTOR );
1073 vboVertex[1].texcoord0[0] = (short)( tx1 * DM_TEXCOORD_NORMFACTOR );
1074 vboVertex[1].texcoord0[1] = (short)( ty0 * DM_TEXCOORD_NORMFACTOR );
1075 vboVertex[1].color = imageBuffer->color;
1076 vboVertex[1].extcolor = imageBuffer->extcolor;
1077 vboVertex[2].vertex[0] = (short)( vx2 * DM_VERTEX_NORMFACTOR );
1078 vboVertex[2].vertex[1] = (short)( vy2 * DM_VERTEX_NORMFACTOR );
1079 vboVertex[2].texcoord0[0] = (short)( tx0 * DM_TEXCOORD_NORMFACTOR );
1080 vboVertex[2].texcoord0[1] = (short)( ty1 * DM_TEXCOORD_NORMFACTOR );
1081 vboVertex[2].color = imageBuffer->color;
1082 vboVertex[2].extcolor = imageBuffer->extcolor;
1083 vboVertex[3].vertex[0] = (short)( vx0 * DM_VERTEX_NORMFACTOR );
1084 vboVertex[3].vertex[1] = (short)( vy0 * DM_VERTEX_NORMFACTOR );
1085 vboVertex[3].texcoord0[0] = (short)( tx0 * DM_TEXCOORD_NORMFACTOR );
1086 vboVertex[3].texcoord0[1] = (short)( ty0 * DM_TEXCOORD_NORMFACTOR );
1087 vboVertex[3].color = imageBuffer->color;
1088 vboVertex[3].extcolor = imageBuffer->extcolor;
1089 vboVertex[4].vertex[0] = (short)( vx2 * DM_VERTEX_NORMFACTOR );
1090 vboVertex[4].vertex[1] = (short)( vy2 * DM_VERTEX_NORMFACTOR );
1091 vboVertex[4].texcoord0[0] = (short)( tx0 * DM_TEXCOORD_NORMFACTOR );
1092 vboVertex[4].texcoord0[1] = (short)( ty1 * DM_TEXCOORD_NORMFACTOR );
1093 vboVertex[4].color = imageBuffer->color;
1094 vboVertex[4].extcolor = imageBuffer->extcolor;
1095 vboVertex[5].vertex[0] = (short)( vx1 * DM_VERTEX_NORMFACTOR );
1096 vboVertex[5].vertex[1] = (short)( vy1 * DM_VERTEX_NORMFACTOR );
1097 vboVertex[5].texcoord0[0] = (short)( tx1 * DM_TEXCOORD_NORMFACTOR );
1098 vboVertex[5].texcoord0[1] = (short)( ty0 * DM_TEXCOORD_NORMFACTOR );
1099 vboVertex[5].color = imageBuffer->color;
1100 vboVertex[5].extcolor = imageBuffer->extcolor;
1106 glUnmapBuffer( GL_ARRAY_BUFFER );
1107 // Flush font manager texture updates
1109 // Render buffered images
1110 flushRenderDrawBuffer( drawBuffer, program, vertexcount );
1111 imageBufferCount = 0;
1119 virtual void flush();
1121 bool init( DrawManagerFlags flags )
1123 int drawBufferIndex, programIndex;
1124 DMDrawBuffer *drawBuffer;
1127 imageBufferCount = 0;
1128 imageBufferSize = 4096;
1129 imageBuffer = new DMImageBuffer[imageBufferSize];
1130 imageBufferTmp = new DMImageBuffer[imageBufferSize];
1134 if( flags.prehistoricOpenGL )
1135 vertexSize = sizeof(DMDrawVertexFlat);
1139 for( programIndex = 0 ; programIndex < DM_PROGRAM_COUNT ; programIndex++ )
1141 program = &shaderPrograms[ programIndex ];
1143 program->lastUpdateCount = -1;
1145 program = &shaderPrograms[ DM_PROGRAM_NORMAL ];
1146 if( !( dmCreateProgram( program, dmVertexShaderNormal, dmFragmentShaderNormal, 0 ) ) )
1148 program = &shaderPrograms[ DM_PROGRAM_ALPHABLEND ];
1149 if( !( dmCreateProgram( program, dmVertexShaderAlpha, dmFragmentShaderAlpha, 0 ) ) )
1151 program = &shaderPrograms[ DM_PROGRAM_ALPHABLEND_INTENSITY ];
1152 if( !( dmCreateProgram( program, dmVertexShaderAlphaIntensity, dmFragmentShaderAlphaIntensity, 0 ) ) )
1154 program = &shaderPrograms[ DM_PROGRAM_ALPHABLEND_INTENSITY_EXTCOLOR ];
1155 if( !( dmCreateProgram( program, dmVertexShaderAlphaIntensityExtColor, dmFragmentShaderAlphaIntensityExtColor, 0 ) ) )
1157 // glUseProgram( 0 );
1158 vertexSize = sizeof(DMDrawVertex);
1161 for( drawBufferIndex = 0 ; drawBufferIndex < DM_CONTEXT_DRAW_BUFFER_COUNT ; drawBufferIndex++ )
1163 drawBuffer = &this.drawBuffer[drawBufferIndex];
1164 drawBuffer->glType = GL_FLOAT;
1165 drawBuffer->vertexCount = 0;
1166 drawBuffer->vertexAlloc = DM_CONTEXT_DRAW_BUFFER_VERTEX_ALLOC;
1167 glGenBuffers( 1, &drawBuffer->vbo );
1168 glBindBuffer( GL_ARRAY_BUFFER, drawBuffer->vbo );
1169 glBufferData( GL_ARRAY_BUFFER, drawBuffer->vertexAlloc * vertexSize, 0, GL_DYNAMIC_DRAW );
1170 drawBuffer->vertexBuffer = new byte[drawBuffer->vertexAlloc * vertexSize];
1183 for( i = 0 ; i < DM_CONTEXT_DRAW_BUFFER_COUNT ; i++ )
1185 DMDrawBuffer *db = &drawBuffer[i];
1186 glDeleteBuffers( 1, &db->vbo );
1187 delete db->vertexBuffer;
1190 // TODO: Destroy the shaders!
1192 delete imageBufferTmp;
1195 void ready( int viewportwidth, int viewportheight )
1199 glGetIntegerv(GL_CURRENT_PROGRAM, (GLint *)&prevProgram);
1200 // while(glGetError());
1204 // Save OpenGL state
1205 // FIXME: no glPushAttrib() in core profile
1207 glPushClientAttrib( GL_CLIENT_ALL_ATTRIB_BITS );
1208 glPushAttrib( GL_ALL_ATTRIB_BITS );
1211 // Prepare rendering pass
1212 matrixOrtho( matrix, 0.0, (float)viewportwidth, (float)viewportheight, 0.0, -1.0f, 1.0 );
1213 norminv = 1.0f / DM_VERTEX_NORMFACTOR;
1214 for( mindex = 0 ; mindex < 12 ; mindex += 4 )
1216 matrix[mindex+0] *= norminv;
1217 matrix[mindex+1] *= norminv;
1218 matrix[mindex+2] *= norminv;
1220 drawBarrierIndex = 0;
1221 orderBarrierMask = drawBarrierIndex << DM_BARRIER_ORDER_SHIFT;
1222 orderBarrierMask = 0;
1227 void drawImage( DMImage image, int offsetx, int offsety, int sizex, int sizey, uint32 color )
1229 DMImageBuffer *imageBuffer;
1231 if( image.flags.empty || ( sizex <= 0 ) || ( sizey <= 0 ) )
1234 if( imageBufferCount >= imageBufferSize )
1236 imageBufferSize <<= 1;
1237 this.imageBuffer = renew this.imageBuffer DMImageBuffer[imageBufferSize];
1238 imageBufferTmp = renew imageBufferTmp DMImageBuffer[imageBufferSize];
1241 imageBuffer = &this.imageBuffer[ imageBufferCount ];
1242 imageBuffer->image = image;
1243 imageBuffer->offsetx = (short)(offsetx << DM_VERTEX_NORMSHIFT);
1244 imageBuffer->offsety = (short)(offsety << DM_VERTEX_NORMSHIFT);
1245 imageBuffer->sizex = (short)sizex;
1246 imageBuffer->sizey = (short)sizey;
1247 #if DM_ENABLE_IMAGE_ROTATION
1248 imageBuffer->angsin = 0;
1249 imageBuffer->angcos = (short)DM_IMAGE_ROTATION_NORMFACTOR;
1251 imageBuffer->color = color;
1252 imageBuffer->orderindex = image.orderMask | orderBarrierMask;
1254 #if DM_RENDER_IMAGE_DEBUG
1255 printf( " Queue image at %d %d, order 0x%x\n", (int)imageBuffer->offsetx, (int)imageBuffer->offsety, (int)imageBuffer->orderindex );
1261 void drawImageExtColor( DMImage image, int offsetx, int offsety, int sizex, int sizey, uint32 color, uint32 extcolor )
1263 DMImageBuffer *imageBuffer;
1265 if( ( image.flags.empty ) || ( sizex <= 0 ) || ( sizey <= 0 ) )
1268 if( imageBufferCount >= imageBufferSize )
1270 imageBufferSize <<= 1;
1271 this.imageBuffer = renew this.imageBuffer DMImageBuffer[imageBufferSize];
1272 imageBufferTmp = renew imageBufferTmp DMImageBuffer[imageBufferSize];
1275 imageBuffer = &this.imageBuffer[ imageBufferCount ];
1276 imageBuffer->image = image;
1277 imageBuffer->offsetx = (short)(offsetx << DM_VERTEX_NORMSHIFT);
1278 imageBuffer->offsety = (short)(offsety << DM_VERTEX_NORMSHIFT);
1279 imageBuffer->sizex = (short)sizex;
1280 imageBuffer->sizey = (short)sizey;
1281 #if DM_ENABLE_IMAGE_ROTATION
1282 imageBuffer->angsin = 0;
1283 imageBuffer->angcos = (short)DM_IMAGE_ROTATION_NORMFACTOR;
1285 imageBuffer->color = color;
1286 #if DM_ENABLE_EXT_COLOR
1287 imageBuffer->extcolor = extcolor;
1289 imageBuffer->orderindex = image.orderMask | orderBarrierMask;
1291 #if DM_RENDER_IMAGE_DEBUG
1292 printf( " Queue image at %d %d, order 0x%x\n", (int)imageBuffer->offsetx, (int)imageBuffer->offsety, (int)imageBuffer->orderindex );
1295 this.imageBufferCount++;
1298 void drawImageFloat( DMImage image, float offsetx, float offsety, float sizex, float sizey, float angsin, float angcos, uint32 color )
1300 DMImageBuffer *imageBuffer;
1302 if( image.flags.empty || sizex <= 0 || sizey <= 0 )
1305 if( imageBufferCount >= imageBufferSize )
1307 imageBufferSize <<= 1;
1308 this.imageBuffer = renew this.imageBuffer DMImageBuffer[imageBufferSize];
1309 imageBufferTmp = renew imageBufferTmp DMImageBuffer[imageBufferSize];
1312 imageBuffer = &this.imageBuffer[ imageBufferCount ];
1313 imageBuffer->image = image;
1314 imageBuffer->offsetx = (short)roundf(offsetx * DM_VERTEX_NORMFACTOR);
1315 imageBuffer->offsety = (short)roundf(offsety * DM_VERTEX_NORMFACTOR);
1316 imageBuffer->sizex = (short)sizex;
1317 imageBuffer->sizey = (short)sizey;
1318 #if DM_ENABLE_IMAGE_ROTATION
1319 imageBuffer->angsin = (short)roundf( angsin * DM_IMAGE_ROTATION_NORMFACTOR );
1320 imageBuffer->angcos = (short)roundf( angcos * DM_IMAGE_ROTATION_NORMFACTOR );
1322 imageBuffer->color = color;
1323 imageBuffer->orderindex = image.orderMask | orderBarrierMask;
1325 #if DM_RENDER_IMAGE_DEBUG
1326 printf( " Queue image at %d %d, order 0x%x\n", (int)imageBuffer->offsetx, (int)imageBuffer->offsety, (int)imageBuffer->orderindex );
1332 void drawImageFloatExtColor( DMImage image, float offsetx, float offsety, float sizex, float sizey, float angsin, float angcos, uint32 color, uint32 extcolor )
1334 DMImageBuffer *imageBuffer;
1336 if( ( image.flags.empty ) || ( sizex <= 0 ) || ( sizey <= 0 ) )
1339 if( this.imageBufferCount >= this.imageBufferSize )
1341 imageBufferSize <<= 1;
1342 this.imageBuffer = renew this.imageBuffer DMImageBuffer[imageBufferSize];
1343 imageBufferTmp = renew imageBufferTmp DMImageBuffer[imageBufferSize];
1346 imageBuffer = &this.imageBuffer[ imageBufferCount ];
1347 imageBuffer->image = image;
1348 imageBuffer->offsetx = (short)roundf( offsetx * DM_VERTEX_NORMFACTOR );
1349 imageBuffer->offsety = (short)roundf( offsety * DM_VERTEX_NORMFACTOR );
1350 imageBuffer->sizex = (short)sizex;
1351 imageBuffer->sizey = (short)sizey;
1352 #if DM_ENABLE_IMAGE_ROTATION
1353 imageBuffer->angsin = (short)roundf( angsin * DM_IMAGE_ROTATION_NORMFACTOR );
1354 imageBuffer->angcos = (short)roundf( angcos * DM_IMAGE_ROTATION_NORMFACTOR );
1356 imageBuffer->color = color;
1357 #if DM_ENABLE_EXT_COLOR
1358 imageBuffer->extcolor = extcolor;
1360 imageBuffer->orderindex = image.orderMask | orderBarrierMask;
1362 #if DM_RENDER_IMAGE_DEBUG
1363 printf( " Queue image at %d %d, order 0x%x\n", (int)imageBuffer->offsetx, (int)imageBuffer->offsety, (int)imageBuffer->orderindex );
1366 this.imageBufferCount++;
1371 if( flags.prehistoricOpenGL )
1372 flushDrawImagesArchaic( );
1376 glBindBuffer( GL_ARRAY_BUFFER, 0 );
1377 glabCurArrayBuffer = 0;
1378 glUseProgram( prevProgram );
1379 // Restore OpenGL state
1380 // FIXME: no glPushAttrib() in core profile
1383 glPopClientAttrib();
1390 if( drawBarrierIndex >= ( 1 << DM_BARRIER_ORDER_BITS ) )
1392 orderBarrierMask = drawBarrierIndex << DM_BARRIER_ORDER_SHIFT;