X-Git-Url: https://ecere.com/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ecere%2Fsrc%2Fgfx%2FnewFonts%2FdrawManager.ec;h=4ef28e56111200d4cebd368aa9e4089bf31d78e6;hb=9a7c100dde2eb5b34a79cd73cd3d8b2247bb06ed;hp=1ff2c11b4fe2a0d9628d3db7b9ea79e705cdf53e;hpb=19a144e04e8261c06e72f6b63d1c286801a8308f;p=sdk diff --git a/ecere/src/gfx/newFonts/drawManager.ec b/ecere/src/gfx/newFonts/drawManager.ec index 1ff2c11..4ef28e5 100644 --- a/ecere/src/gfx/newFonts/drawManager.ec +++ b/ecere/src/gfx/newFonts/drawManager.ec @@ -1,210 +1,50 @@ import "OpenGLDisplayDriver" +import "textureManager" -#define _Noreturn +#include "glHelpers.h" -#include -#include +#define _Noreturn #include - -#if !defined(_GLES) - #define SHADERS -#endif - -#if defined(__EMSCRIPTEN__) -#if !defined(_GLES2) - #define _GLES2 -#endif - #include -#endif - -#if defined(__ANDROID__) || defined(__ODROID__) -#if !defined(_GLES) - #define _GLES -#endif - #include -#endif - -#if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__) -# if defined(SHADERS) -//# include "gl_core_3_3.h" -# include "gl_compat_4_4.h" // FIXME: no glPushAttrib() in core profile -# else -# include "gl_compat_4_4.h" -# endif -#endif - -#ifdef SHADERS - -#undef glEnableClientState -#undef glDisableClientState -#undef GL_VERTEX_ARRAY -#undef GL_NORMAL_ARRAY -#undef GL_TEXTURE_COORD_ARRAY -#undef GL_COLOR_ARRAY -#undef glVertexPointer -#undef glTexCoordPointer -#undef glColorPointer - -#define glEnableClientState glEnableVertexAttribArray -#define glDisableClientState glDisableVertexAttribArray -#define GL_VERTEX_ARRAY GLBufferContents::vertex -#define GL_NORMAL_ARRAY GLBufferContents::normal -#define GL_TEXTURE_COORD_ARRAY GLBufferContents::texCoord -#define GL_COLOR_ARRAY GLBufferContents::color -#define glVertexPointer(n, t, s, p) glVertexAttribPointer(GLBufferContents::vertex, n, t, GL_FALSE, s, p) -#define glTexCoordPointer(n, t, s, p) glVertexAttribPointer(GLBufferContents::texCoord, n, t, GL_FALSE, s, p) -#define glColorPointer(n, t, s, p) glVertexAttribPointer(GLBufferContents::color, n, t, GL_FALSE, s, p) - -#endif - -#if defined(_GLES) || defined(_GLES2) || defined(SHADERS) - - #undef glRecti - #undef glBegin - #undef glTexCoord2i - #undef glVertex2i - #undef glTexCoord2d - #undef glVertex2d - #undef glTexCoord2f - #undef glVertex2f - #undef glEnd - #undef glColor3f - #undef glColor4ub - #undef glColor4fv - #undef glNormal3fv - #undef glNormal3f - #undef glTexCoord2fv - #undef glVertex3d - #undef glVertex3dv - #undef glVertex3f - #undef glVertex3fv - - #undef glLoadMatrixd - #undef glLoadMatrixf - #undef glMultMatrixd - #undef glFrustum - #undef glOrtho - #undef glScaled - #undef glScalef - #undef glTranslated - #undef glRotated - #undef glMatrixMode - #undef glLoadIdentity - #undef glPushMatrix - #undef glPopMatrix - - #undef glLineStipple - #undef glColorMaterial - #undef glLightModeli - - #define glRecti glimtkRecti - #define glBegin glimtkBegin - #define glTexCoord2i glimtkTexCoord2i - #define glVertex2i glimtkVertex2i - #define glTexCoord2d glimtkTexCoord2d - #define glVertex2d glimtkVertex2d - #define glTexCoord2f glimtkTexCoord2f - #define glVertex2f glimtkVertex2f - #define glEnd glimtkEnd - #define glColor3f glimtkColor3f - #define glColor4ub glimtkColor4ub - #define glColor4fv glimtkColor4fv - #define glNormal3fv glimtkNormal3fv - #define glNormal3f glimtkNormal3f - #define glTexCoord2fv glimtkTexCoord2fv - #define glVertex3d glimtkVertex3d - #define glVertex3dv glimtkVertex3dv - #define glVertex3f glimtkVertex3f - #define glVertex3fv glimtkVertex3fv - - #define glLoadMatrixd glmsLoadMatrixd - #define glLoadMatrixf glmsLoadMatrixf - #define glMultMatrixd glmsMultMatrixd - #define glFrustum glmsFrustum - #define glOrtho glmsOrtho - #define glScaled glmsScaled - #define glScalef glmsScaled - #define glTranslated glmsTranslated - #define glRotated glmsRotated - #define glMatrixMode glmsMatrixMode - #define glLoadIdentity glmsLoadIdentity - #define glPushMatrix glmsPushMatrix - #define glPopMatrix glmsPopMatrix - - #define glLineStipple glesLineStipple - #define glColorMaterial glesColorMaterial - #define glLightModeli glesLightModeli - -#endif - +#include #include "cc.h" - #define OFFSET(s, m) ((uint)(uintptr) (&((s *) 0)->m)) -import "textureManager" +// TODO: Indices (2/3 data) +// TODO: glMapBufferRange() with GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT +// TODO: movnti to write to VBO: _mm_stream_ps(), _mm_stream_si32(), _mm_stream_si64() +// TODO: When the state changes, it should keep filling up a same VBO, then when the VBO is full (or when we are done), perform all the Draw() calls on that same VBO +// TODO: VAO - -#define DM_ENABLE_IMAGE_ROTATION (1) -#define DM_ENABLE_EXT_COLOR (1) - -//// - -static struct DMDrawVertexFlat -{ - float vertex[2]; - float texcoord0[2]; - uint32 color; -#if DM_ENABLE_EXT_COLOR - uint32 extcolor; -#endif -} __attribute__((aligned(16))); - -static struct DMDrawVertex -{ - short vertex[2]; - short texcoord0[2]; - uint32 color; -#if DM_ENABLE_EXT_COLOR - uint32 extcolor; -#endif -} __attribute__((aligned(16))); +static struct DMDrawVertex { short vx, vy, tx, ty; }; struct DMDrawBuffer { - GLuint vbo; + GLAB vbo; int glType; int vertexCount; int vertexAlloc; void *vertexBuffer; }; -class DMProgramFlags : uint { bool valid:1; } - -struct DMProgram -{ - GLuint glProgram; - GLuint vertexShader; - GLuint fragmentShader; - GLint matrixloc; - GLint vertexloc; - GLint texcoord0loc; - GLint texcoord1loc; - GLint colorloc; -#if DM_ENABLE_EXT_COLOR - GLint extcolorloc; -#endif - GLint texbaseloc; - DMProgramFlags flags; - int64 lastUpdateCount; -}; - class DMImageFlags : uint16 { bool empty:1; // Image is empty, do not draw bool blending:1; // Must draw image with blending + int swizzle:2; } -public struct DMImage +#define DM_BARRIER_ORDER_BITS 5 + +class DMOrderMask : uint32 +{ + int imageOrder:8; + bool blend:1; + int texture:10; + int layer:4; + int barrier:DM_BARRIER_ORDER_BITS; +}; + +struct DMImage { private: Texture texture; @@ -214,111 +54,36 @@ private: short sizex, sizey; // Computed order for sorted rendering, in defineImage() - uint32 orderMask; + DMOrderMask orderMask; public: void clear() { this = { flags = { empty = true } }; } - - void defineImage( Texture texture, int offsetx, int offsety, int sizex, int sizey, bool blending, int programIndex, int layerindex ) - { - int ordx = offsetx >> 6; - int ordy = offsety >> 6; - uint32 orderimage = ccMortonNumber32( ordx, ordy ) & ( ( 1 << DM_IMAGE_ORDER_BITS ) - 1 ); - this = - { - texture = texture; - srcx = (short)offsetx; - srcy = (short)offsety; - sizex = (short)sizex; - sizey = (short)sizey; - programIndex = (short)programIndex; - flags = { blending = blending }; - orderMask = (orderimage << DM_IMAGE_ORDER_SHIFT) | - (( blending == true ) << DM_BLEND_ORDER_SHIFT) | - (programIndex << DM_PROGRAM_ORDER_SHIFT) | - texture.orderMask | - (layerindex << DM_LAYER_ORDER_SHIFT); - }; - } }; struct DMImageBuffer { - DMImage *image; - short offsetx; - short offsety; - short sizex; - short sizey; -#if DM_ENABLE_IMAGE_ROTATION - short angcos; - short angsin; -#endif -#if DM_ENABLE_EXT_COLOR - uint32 extcolor; -#endif - uint32 color; - uint32 orderindex; + int image; + short offsetx, offsety; + short sizex, sizey; + short angcos, angsin; + ColorAlpha color; + uint32 orderIndex; }; - -//// - - -define DM_IMAGE_ORDER_BITS = 8; -define DM_BLEND_ORDER_BITS = 1; -define DM_PROGRAM_ORDER_BITS = 4; -define DM_TEXTURE_ORDER_BITS = 10; -define DM_LAYER_ORDER_BITS = 4; -define DM_BARRIER_ORDER_BITS = 5; - -define DM_IMAGE_ORDER_SHIFT = 0; -define DM_BLEND_ORDER_SHIFT = DM_IMAGE_ORDER_BITS; -define DM_PROGRAM_ORDER_SHIFT = DM_IMAGE_ORDER_BITS+DM_BLEND_ORDER_BITS; -define DM_TEXTURE_ORDER_SHIFT = DM_IMAGE_ORDER_BITS+DM_BLEND_ORDER_BITS+DM_PROGRAM_ORDER_BITS; -define DM_LAYER_ORDER_SHIFT = DM_IMAGE_ORDER_BITS+DM_BLEND_ORDER_BITS+DM_PROGRAM_ORDER_BITS+DM_TEXTURE_ORDER_BITS; -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; +define DRAW_BUFFER_COUNT = 64; // TOFIX: Can't make static? +define DRAW_BUFFER_VERTEX_ALLOC = 1024; define DM_LAYER_COUNT = 1<orderindex < draw1->orderindex ) ? 0 : 1 ); + uint32 ix1 = draw1->orderIndex, ix2 = draw0->orderIndex; + if(ix1 < ix2) return 1; + if(ix1 == ix2 && draw1->color < draw0->color) return 1; + return 0; } #define HSORT_MAIN dmSortImages @@ -620,564 +122,252 @@ static inline int dmSortImagesCmp( DMImageBuffer *draw0, DMImageBuffer *draw1 ) #undef HSORT_CMP #undef HSORT_TYPE - -//// - // TOFIX: Make this private, have a property -public class DrawManagerFlags : uint32 { public: bool prehistoricOpenGL:1; } - public class DrawManager { - DrawManagerFlags flags; + bool renderingFlipped; - // Matrix - float matrix[16]; + int imageCount, imageAlloc; + DMImage *imageList; + imageAlloc = 512; + imageList = new DMImage[imageAlloc]; + + void resetImages() + { + imageCount = 0; + } + + void clearImages() + { + delete imageList; + imageCount = 0; + imageAlloc = 512; + imageList = new DMImage[imageAlloc]; + } - int imageBufferCount; - int imageBufferSize; - DMImageBuffer *imageBuffer; - DMImageBuffer *imageBufferTmp; + int imageBufferCount, imageBufferSize; + DMImageBuffer *imageBuffers, *imageBuffersTmp; // Buffers for drawimages() batching - DMDrawBuffer drawBuffer[DM_CONTEXT_DRAW_BUFFER_COUNT]; - int drawBufferIndex; - int drawBarrierIndex; - uint32 orderBarrierMask; + DMDrawBuffer drawBuffers[DRAW_BUFFER_COUNT]; + int drawBufferIndex, drawBarrierIndex; + DMOrderMask orderBarrierMask; // Counter to track program uniforms and such int64 updateCount; - DMProgram shaderPrograms[DM_PROGRAM_COUNT]; - GLuint prevProgram; - - bool renderingFlipped; - - static DMProgram *flushUseProgram( int programIndex ) + int defineImage( Texture texture, int offsetx, int offsety, int sizex, int sizey, bool blending, int layer ) { - DMProgram *program = &shaderPrograms[ programIndex ]; - if( !program->flags.valid) + int ordx = offsetx >> 6; + int ordy = offsety >> 6; + int imageIndex = imageCount++; + if( imageCount > imageAlloc ) { -#ifdef SHADERS - glUseProgram( 0 ); -#endif - return 0; + imageAlloc <<= 1; + imageList = renew imageList DMImage[imageAlloc]; } - -#ifdef SHADERS - glUseProgram( program->glProgram ); -#endif - if( program->lastUpdateCount != this.updateCount ) + imageList[ imageIndex ] = { -#ifdef SHADERS - glUniformMatrix4fv( program->matrixloc, 1, GL_FALSE, this.matrix ); - glUniform1i( program->texbaseloc, 0 ); -#endif - program->lastUpdateCount = this.updateCount; - } - return program; + texture = texture; + srcx = (short)offsetx; + srcy = (short)offsety; + sizex = (short)sizex; + sizey = (short)sizey; + flags = { blending = blending, swizzle = texture.swizzle }; + orderMask = + { + imageOrder = ccMortonNumber32( ordx, ordy ) & 0xFF, + blend = blending, texture = texture.orderMask, layer = layer + }; + }; + return imageIndex; } -#if !defined(__EMSCRIPTEN__) - static void flushRenderDrawBufferArchaic( DMDrawBuffer drawBuffer, DMProgram program, int vertexCount ) + static void flushRenderDrawBuffer( DMDrawBuffer drawBuffer, int vertexCount ) { - glEnable( GL_TEXTURE_2D ); - glBindBuffer( GL_ARRAY_BUFFER, drawBuffer.vbo ); - glColor3f( 1.0, 1.0, 1.0 ); - - glEnableClientState( GL_VERTEX_ARRAY ); - glEnableClientState( GL_TEXTURE_COORD_ARRAY ); - glEnableClientState( GL_COLOR_ARRAY ); + glBindBuffer( GL_ARRAY_BUFFER, drawBuffer.vbo.buffer ); - glVertexPointer( 2, GL_FLOAT, sizeof(DMDrawVertexFlat), (void *)OFFSET(DMDrawVertexFlat,vertex) ); - glTexCoordPointer( 2, GL_FLOAT, sizeof(DMDrawVertexFlat), (void *)OFFSET(DMDrawVertexFlat,texcoord0) ); - glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(DMDrawVertexFlat), (void *)OFFSET(DMDrawVertexFlat,color) ); + GLVertexPointer (2, GL_SHORT, sizeof(DMDrawVertex), (void *)OFFSET(DMDrawVertex, vx) ); + GLTexCoordPointer(2, GL_SHORT, sizeof(DMDrawVertex), (void *)OFFSET(DMDrawVertex, tx) ); glDrawArrays( GL_TRIANGLES, 0, vertexCount ); - - glDisableClientState( GL_VERTEX_ARRAY ); - glDisableClientState( GL_TEXTURE_COORD_ARRAY ); - glDisableClientState( GL_COLOR_ARRAY ); - glDisable( GL_TEXTURE_2D ); - - #if DM_FLUSH_EACH_RENDER_DRAW_BUFFER - glFlush(); - #endif } - void flushDrawImagesArchaic( ) + void flushImages() { - bool flushflag, stateBlend; - int index, vertexCount, programIndex; - float vx0, vx1, vx2, vx3, vy0, vy1, vy2, vy3; - #if DM_ENABLE_IMAGE_ROTATION - float angsin, angcos, sizex, sizey; - #endif - float tx0, tx1, ty0, ty1; - DMImageBuffer *imageBuffer; - DMImage *image, *bindimage; - Texture texture, bindTexture; - DMDrawBuffer *drawBuffer; - DMDrawVertexFlat *vboVertex = null; -#if defined(_GLES) || defined(_GLES2) - DMDrawVertexFlat *vboStorage = null; -#endif - DMProgram *program; - - ERRORCHECK(); - - drawBarrierIndex = 0; - orderBarrierMask = drawBarrierIndex << DM_BARRIER_ORDER_SHIFT; - if(imageBufferCount) - { - // Sort by image type and texture, minimize state changes - dmSortImages( this.imageBuffer, imageBufferTmp, imageBufferCount, (uint32)( (intptr_t)this.imageBuffer >> 4 ) ); - - // Fill a drawBuffer, write vertex and texcoords - drawBuffer = &this.drawBuffer[drawBufferIndex]; - drawBufferIndex = ( drawBufferIndex + 1 ) % DM_CONTEXT_DRAW_BUFFER_COUNT; - glBindBuffer( GL_ARRAY_BUFFER, drawBuffer->vbo ); -#if defined(_GLES) || defined(_GLES2) - vboVertex = vboStorage = new DMDrawVertexFlat[drawBuffer->vertexAlloc * 1]; -#else - vboVertex = glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY ); -#endif - vertexCount = 0; - - glActiveTexture( GL_TEXTURE0 ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - glDisable( GL_BLEND ); - GLSetupLighting(false); - - #if DM_RENDER_IMAGE_DEBUG - printf( " Flush %d images\n", (int)imageBufferCount ); - #endif - - bindimage = 0; - bindTexture = 0; - stateBlend = 0; - programIndex = -1; - program = 0; - imageBuffer = this.imageBuffer; - for( index = 0 ; index < imageBufferCount ; index++, imageBuffer++ ) - { - image = imageBuffer->image; - texture = image->texture; - - flushflag = 0; - if( image != bindimage ) - { - if( stateBlend != image->flags.blending ) - flushflag = 1; - if( texture != bindTexture ) - flushflag = 1; - } - if( vertexCount >= ( drawBuffer->vertexAlloc - 6 ) ) - flushflag = 1; - - if( flushflag ) - { - if( vertexCount ) - { -#if defined(_GLES) || defined(_GLES2) - glBufferData( GL_ARRAY_BUFFER, drawBuffer->vertexAlloc * sizeof(DMDrawVertexFlat), vboStorage, GL_DYNAMIC_DRAW ); -#else - glUnmapBuffer( GL_ARRAY_BUFFER ); -#endif - // Flush font manager texture updates - flush( ); - // Render buffered images - flushRenderDrawBufferArchaic( drawBuffer, program, vertexCount ); - drawBuffer = &this.drawBuffer[drawBufferIndex]; - drawBufferIndex = ( drawBufferIndex + 1 ) % DM_CONTEXT_DRAW_BUFFER_COUNT; - glBindBuffer( GL_ARRAY_BUFFER, drawBuffer->vbo ); -#if defined(_GLES) || defined(_GLES2) - vboVertex = vboStorage; -#else - vboVertex = glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY ); -#endif - vertexCount = 0; - } + drawBarrierIndex = 0; + orderBarrierMask = 0; - if( stateBlend != ( image->flags.blending ) ) - { - stateBlend = image->flags.blending; - ( stateBlend ? glEnable : glDisable )( GL_BLEND ); - #if DM_RENDER_IMAGE_DEBUG - printf( " Switch blending %d\n", stateBlend != false ); - #endif - } - if( programIndex != image->programIndex ) - { - programIndex = image->programIndex; - program = flushUseProgram( programIndex ); - } - if( texture != bindTexture ) - { - bindTexture = texture; - glBindTexture( GL_TEXTURE_2D, bindTexture.glTex ); - #if DM_RENDER_IMAGE_DEBUG - printf( " Switch to texture 0x%x\n", (int)texture.orderMask ); - #endif - } - bindimage = image; - } - - #if DM_RENDER_IMAGE_DEBUG - printf( " Render image at %d %d, order 0x%x, texture %p\n", (int)imageBuffer->offsetx, (int)imageBuffer->offsety, (int)imageBuffer->orderindex, texture ); - #endif - - #if DM_ENABLE_IMAGE_ROTATION - angsin = (float)imageBuffer->angsin * (1.0f/DM_IMAGE_ROTATION_NORMFACTOR); - angcos = (float)imageBuffer->angcos * (1.0f/DM_IMAGE_ROTATION_NORMFACTOR); - sizex = (float)imageBuffer->sizex; - sizey = (float)imageBuffer->sizey; - vx0 = (float)imageBuffer->offsetx * (1.0f/DM_VERTEX_NORMFACTOR); - vy0 = (float)imageBuffer->offsety * (1.0f/DM_VERTEX_NORMFACTOR); - vx1 = vx0 + ( angcos * sizex ); - vy1 = vy0 + ( angsin * sizex ); - vx2 = vx0 - ( angsin * sizey ); - vy2 = vy0 + ( angcos * sizey ); - vx3 = vx0 + ( angcos * sizex ) - ( angsin * sizey ); - vy3 = vy0 + ( angsin * sizex ) + ( angcos * sizey ); - #else - vx0 = (float)imageBuffer->offsetx * (1.0f/DM_VERTEX_NORMFACTOR); - vy0 = (float)imageBuffer->offsety * (1.0f/DM_VERTEX_NORMFACTOR); - vx3 = vx0 + (float)( imageBuffer->sizex ); - vy3 = vy0 + (float)( imageBuffer->sizey ); - vx1 = vx3; - vy1 = vy0; - vx2 = vx0; - vy2 = vy3; - #endif - - tx0 = (float)( image->srcx ) * texture.widthinv; - ty0 = (float)( image->srcy ) * texture.heightinv; - tx1 = (float)( image->srcx + image->sizex ) * texture.widthinv; - ty1 = (float)( image->srcy + image->sizey ) * texture.heightinv; - - // Write data to VBO - vboVertex[0].vertex[0] = vx3; - vboVertex[0].vertex[1] = vy3; - vboVertex[0].texcoord0[0] = tx1; - vboVertex[0].texcoord0[1] = ty1; - vboVertex[0].color = imageBuffer->color; - #if DM_ENABLE_EXT_COLOR - vboVertex[0].extcolor = imageBuffer->extcolor; - #endif - vboVertex[1].vertex[0] = vx1; - vboVertex[1].vertex[1] = vy1; - vboVertex[1].texcoord0[0] = tx1; - vboVertex[1].texcoord0[1] = ty0; - vboVertex[1].color = imageBuffer->color; - #if DM_ENABLE_EXT_COLOR - vboVertex[1].extcolor = imageBuffer->extcolor; - #endif - vboVertex[2].vertex[0] = vx2; - vboVertex[2].vertex[1] = vy2; - vboVertex[2].texcoord0[0] = tx0; - vboVertex[2].texcoord0[1] = ty1; - vboVertex[2].color = imageBuffer->color; - #if DM_ENABLE_EXT_COLOR - vboVertex[2].extcolor = imageBuffer->extcolor; - #endif - vboVertex[3].vertex[0] = vx0; - vboVertex[3].vertex[1] = vy0; - vboVertex[3].texcoord0[0] = tx0; - vboVertex[3].texcoord0[1] = ty0; - vboVertex[3].color = imageBuffer->color; - #if DM_ENABLE_EXT_COLOR - vboVertex[3].extcolor = imageBuffer->extcolor; - #endif - vboVertex[4].vertex[0] = vx2; - vboVertex[4].vertex[1] = vy2; - vboVertex[4].texcoord0[0] = tx0; - vboVertex[4].texcoord0[1] = ty1; - vboVertex[4].color = imageBuffer->color; - #if DM_ENABLE_EXT_COLOR - vboVertex[4].extcolor = imageBuffer->extcolor; - #endif - vboVertex[5].vertex[0] = vx1; - vboVertex[5].vertex[1] = vy1; - vboVertex[5].texcoord0[0] = tx1; - vboVertex[5].texcoord0[1] = ty0; - vboVertex[5].color = imageBuffer->color; - #if DM_ENABLE_EXT_COLOR - vboVertex[5].extcolor = imageBuffer->extcolor; - #endif - - vboVertex += 6; - vertexCount += 6; - } - -#if defined(_GLES) || defined(_GLES2) // TODO: - glBufferData( GL_ARRAY_BUFFER, drawBuffer->vertexAlloc * sizeof(DMDrawVertexFlat), vboStorage, GL_DYNAMIC_DRAW ); - delete vboStorage; -#else - glUnmapBuffer( GL_ARRAY_BUFFER ); -#endif + if(imageBufferCount) + { + bool stateBlend = true; +#if ENABLE_GL_SHADERS + int swizzleMode = 0; +#endif + int vertexCount = 0; + int index; + DMImageBuffer *imageBuffer = imageBuffers; + DMImage *bindImage = null; + Texture bindTexture = null; + DMDrawBuffer *drawBuffer; + DMDrawVertex *vboVertex = null; + ColorAlpha color = 0; + #if !ENABLE_GL_MAPBUF + DMDrawVertex *vboStorage = null; + #endif - // Flush font manager texture updates - flush(); + ERRORCHECK(); - // Render buffered images - flushRenderDrawBufferArchaic( drawBuffer, program, vertexCount ); - imageBufferCount = 0; + glabCurArrayBuffer = 0; - ERRORCHECK(); + GLFlushMatrices(); - } - } -#endif + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + GLSetupFog(false); + GLSetupTexturing(true); + GLSetupLighting(false); + GLEnableClientState(VERTICES); + GLEnableClientState(TEXCOORDS); + glEnable(GL_BLEND); -#ifdef SHADERS - static void flushRenderDrawBuffer( DMDrawBuffer drawBuffer, DMProgram program, int vertexCount ) - { - glabCurArrayBuffer = 0; + // Sort by image type and texture, minimize state changes + dmSortImages( imageBuffers, imageBuffersTmp, imageBufferCount, (uint32)( (uintptr)imageBuffers >> 4 ) ); - glBindBuffer( GL_ARRAY_BUFFER, drawBuffer.vbo ); - if( program.vertexloc != -1 ) - { - glEnableVertexAttribArray( program.vertexloc ); - glVertexAttribPointer( program.vertexloc, 2, GL_SHORT, GL_FALSE, sizeof(DMDrawVertex), (void *)OFFSET(DMDrawVertex,vertex) ); - } - if( program.texcoord0loc != -1 ) - { - glEnableVertexAttribArray( program.texcoord0loc ); - glVertexAttribPointer( program.texcoord0loc, 2, GL_SHORT, GL_FALSE, sizeof(DMDrawVertex), (void *)OFFSET(DMDrawVertex,texcoord0) ); - } - if( program.colorloc != -1 ) - { - glEnableVertexAttribArray( program.colorloc ); - glVertexAttribPointer( program.colorloc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(DMDrawVertex), (void *)OFFSET(DMDrawVertex,color) ); - } + // Fill a drawBuffer, write vertex and texcoords + drawBuffer = &drawBuffers[drawBufferIndex++]; + drawBufferIndex %= DRAW_BUFFER_COUNT; + glBindBuffer( GL_ARRAY_BUFFER, drawBuffer->vbo.buffer ); + glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); - #if DM_ENABLE_EXT_COLOR - if( program.extcolorloc != -1 ) - { - glEnableVertexAttribArray( program.extcolorloc ); - glVertexAttribPointer( program.extcolorloc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(DMDrawVertex), (void *)OFFSET(DMDrawVertex,extcolor) ); - } - #endif +#if ENABLE_GL_MAPBUF + vboVertex = glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY ); +#else + vboVertex = vboStorage = new DMDrawVertex[drawBuffer->vertexAlloc]; +#endif - glDrawArrays( GL_TRIANGLES, 0, vertexCount ); + for(index = 0; index < imageBufferCount; index++, imageBuffer++) + { + DMImage * image = &imageList[imageBuffer->image]; + Texture texture = image->texture; + short tx0 = (short)( (int)image->srcx * texture.widthinv * DM_TEXCOORD_NORMFACTOR); + short ty0 = (short)( (int)image->srcy * texture.heightinv * DM_TEXCOORD_NORMFACTOR); + short tx1 = (short)(( (int)image->srcx + image->sizex ) * texture.widthinv * DM_TEXCOORD_NORMFACTOR); + short ty1 = (short)(( (int)image->srcy + image->sizey ) * texture.heightinv * DM_TEXCOORD_NORMFACTOR); + short angsin = imageBuffer->angsin, angcos = imageBuffer->angcos; + short sizex = imageBuffer->sizex, sizey = imageBuffer->sizey; + short vx0 = imageBuffer->offsetx; + short vy0 = imageBuffer->offsety; + short vx1 = (short)(vx0 + ((int)angcos * sizex * DM_VERTEX_NORMFACTOR / DM_IMAGE_ROTATION_NORMFACTOR)); + short vy1 = (short)(vy0 + ((int)angsin * sizex * DM_VERTEX_NORMFACTOR / DM_IMAGE_ROTATION_NORMFACTOR)); + short vx2 = (short)(vx0 - ((int)angsin * sizey * DM_VERTEX_NORMFACTOR / DM_IMAGE_ROTATION_NORMFACTOR)); + short vy2 = (short)(vy0 + ((int)angcos * sizey * DM_VERTEX_NORMFACTOR / DM_IMAGE_ROTATION_NORMFACTOR)); + short vx3 = (short)(vx0 + (((int)angcos * sizex - (int)angsin * sizey) * DM_VERTEX_NORMFACTOR / DM_IMAGE_ROTATION_NORMFACTOR)); + short vy3 = (short)(vy0 + (((int)angsin * sizex + (int)angcos * sizey) * DM_VERTEX_NORMFACTOR / DM_IMAGE_ROTATION_NORMFACTOR)); + bool flushFlag = + (imageBuffer->color != color) || + (image != bindImage && (stateBlend != image->flags.blending || texture != bindTexture +#if ENABLE_GL_SHADERS + || (glCaps_shaders && swizzleMode != image->flags.swizzle) +#endif + )) || + (vertexCount >= drawBuffer->vertexAlloc - 6); + + if(flushFlag) + { + if(vertexCount) + { +#if ENABLE_GL_MAPBUF + glUnmapBuffer( GL_ARRAY_BUFFER ); +#else + glBufferSubData( GL_ARRAY_BUFFER, 0, vertexCount * sizeof(DMDrawVertex), vboStorage ); +#endif + // Flush font manager texture updates + flush(); + + // Render buffered images + flushRenderDrawBuffer( drawBuffer, vertexCount ); + drawBuffer = &drawBuffers[drawBufferIndex++]; + drawBufferIndex %= DRAW_BUFFER_COUNT; + glBindBuffer( GL_ARRAY_BUFFER, drawBuffer->vbo.buffer ); +#if ENABLE_GL_MAPBUF + vboVertex = glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY ); +#else + vboVertex = vboStorage; +#endif + vertexCount = 0; + } + + if(color != imageBuffer->color) + { + color = imageBuffer->color; + GLColor4ub(color.color.r, color.color.g, color.color.b, color.a); + } + if( stateBlend != image->flags.blending) + { + stateBlend = image->flags.blending; + ( stateBlend ? glEnable : glDisable )( GL_BLEND ); + } +#if ENABLE_GL_SHADERS + if( swizzleMode != image->flags.swizzle) + { + swizzleMode = image->flags.swizzle; + if(glCaps_shaders) + shader_swizzle( swizzleMode ); + } +#endif + if( texture != bindTexture ) + { + bindTexture = texture; + glBindTexture( GL_TEXTURE_2D, bindTexture.glTex ); + } + bindImage = image; + } - if( program.vertexloc != -1 ) - glDisableVertexAttribArray( program.vertexloc ); - if( program.texcoord0loc != -1 ) - glDisableVertexAttribArray( program.texcoord0loc ); - if( program.colorloc != -1 ) - glDisableVertexAttribArray( program.colorloc ); + // Write data to VBO + // TODO: write vertex/texcoord all at once with SSE + vboVertex[0] = { vx3, vy3, tx1, ty1 }; + vboVertex[1] = { vx1, vy1, tx1, ty0 }; + vboVertex[2] = { vx2, vy2, tx0, ty1 }; + vboVertex[3] = { vx0, vy0, tx0, ty0 }; + vboVertex[4] = { vx2, vy2, tx0, ty1 }; + vboVertex[5] = { vx1, vy1, tx1, ty0 }; + vboVertex += 6; + vertexCount += 6; + + glBindBuffer( GL_ARRAY_BUFFER, drawBuffer->vbo.buffer ); + } - #if DM_FLUSH_EACH_RENDER_DRAW_BUFFER - glFlush(); - #endif - } +#if ENABLE_GL_MAPBUF + glUnmapBuffer( GL_ARRAY_BUFFER ); +#else + glBufferSubData( GL_ARRAY_BUFFER, 0, vertexCount * sizeof(DMDrawVertex), vboStorage ); + delete vboStorage; #endif -#ifdef SHADERS - static void flushDrawImages( ) - { - int index, stateblend, vertexcount, flushflag, programIndex; - float vx0, vx1, vx2, vx3, vy0, vy1, vy2, vy3; - #if DM_ENABLE_IMAGE_ROTATION - float angsin, angcos, sizex, sizey; - #endif - float tx0, tx1, ty0, ty1; - DMImageBuffer *imageBuffer; - DMImage *image, *bindimage; - Texture texture, bindtexture; - DMDrawBuffer *drawBuffer; - DMDrawVertex *vboVertex = null; - DMProgram *program; - - glabCurArrayBuffer = 0; - - ERRORCHECK(); - - this.drawBarrierIndex = 0; - orderBarrierMask = drawBarrierIndex << DM_BARRIER_ORDER_SHIFT; - if( imageBufferCount ) - { - /* Sort by image type and texture, minimize state changes */ - dmSortImages( this.imageBuffer, this.imageBufferTmp, imageBufferCount, (uint32)( (uintptr)this.imageBuffer >> 4 ) ); + // Flush font manager texture updates + flush(); - /* Fill a drawBuffer, write vertex and texcoords */ - drawBuffer = &this.drawBuffer[this.drawBufferIndex]; - this.drawBufferIndex = ( this.drawBufferIndex + 1 ) % DM_CONTEXT_DRAW_BUFFER_COUNT; - glBindBuffer( GL_ARRAY_BUFFER, drawBuffer->vbo ); + // Render buffered images + flushRenderDrawBuffer( drawBuffer, vertexCount ); + imageBufferCount = 0; -#if !defined(_GLES) && !defined(_GLES2) // TODO: - vboVertex = glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY ); -#endif - vertexcount = 0; - - glActiveTexture( GL_TEXTURE0 ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - glDisable( GL_BLEND ); - - #if DM_RENDER_IMAGE_DEBUG - printf( " Flush %d images\n", (int)imageBufferCount ); - #endif - - bindimage = 0; - bindtexture = 0; - stateblend = 0; - programIndex = -1; - program = 0; - imageBuffer = this.imageBuffer; - for( index = 0 ; index < imageBufferCount ; index++, imageBuffer++ ) - { - image = imageBuffer->image; - texture = image->texture; - - flushflag = 0; - if( image != bindimage ) - { - if( stateblend != ( image->flags.blending ) ) - flushflag = 1; - if( texture != bindtexture ) - flushflag = 1; - } - if( vertexcount >= ( drawBuffer->vertexAlloc - 6 ) ) - flushflag = 1; - - if( flushflag ) - { - if( vertexcount ) - { -#if !defined(_GLES) && !defined(_GLES2) // TODO: - glUnmapBuffer( GL_ARRAY_BUFFER ); -#endif - // Flush font manager texture updates - flush(); - - // Render buffered images - flushRenderDrawBuffer( drawBuffer, program, vertexcount ); - drawBuffer = &this.drawBuffer[this.drawBufferIndex]; - this.drawBufferIndex = ( this.drawBufferIndex + 1 ) % DM_CONTEXT_DRAW_BUFFER_COUNT; - glBindBuffer( GL_ARRAY_BUFFER, drawBuffer->vbo ); -#if !defined(_GLES) && !defined(_GLES2) // TODO: - vboVertex = glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY ); -#endif - vertexcount = 0; - } + ERRORCHECK(); - if( stateblend != ( image->flags.blending ) ) - { - stateblend = image->flags.blending; - ( stateblend ? glEnable : glDisable )( GL_BLEND ); - #if DM_RENDER_IMAGE_DEBUG - printf( " Switch blending %d\n", ( stateblend != 0 ) ); - #endif - } - if( programIndex != image->programIndex ) - { - programIndex = image->programIndex; - program = flushUseProgram( programIndex ); - } - if( texture != bindtexture ) - { - bindtexture = texture; - glBindTexture( GL_TEXTURE_2D, bindtexture.glTex ); - #if DM_RENDER_IMAGE_DEBUG - printf( " Switch to texture 0x%x\n", (int)texture.orderMask ); - #endif - } - bindimage = image; - } - - #if DM_RENDER_IMAGE_DEBUG - printf( " Render image at %d %d, order 0x%x, texture %p\n", (int)imageBuffer->offsetx, (int)imageBuffer->offsety, (int)imageBuffer->orderindex, texture ); - #endif - - #if DM_ENABLE_IMAGE_ROTATION - /* FIXME TODO: Don't go through float, compute texcoord integers directly */ - angsin = (float)imageBuffer->angsin * (1.0f/DM_IMAGE_ROTATION_NORMFACTOR); - angcos = (float)imageBuffer->angcos * (1.0f/DM_IMAGE_ROTATION_NORMFACTOR); - sizex = (float)imageBuffer->sizex; - sizey = (float)imageBuffer->sizey; - vx0 = (float)imageBuffer->offsetx * (1.0f/DM_VERTEX_NORMFACTOR); - vy0 = (float)imageBuffer->offsety * (1.0f/DM_VERTEX_NORMFACTOR); - vx1 = vx0 + ( angcos * sizex ); - vy1 = vy0 + ( angsin * sizex ); - vx2 = vx0 - ( angsin * sizey ); - vy2 = vy0 + ( angcos * sizey ); - vx3 = vx0 + ( angcos * sizex ) - ( angsin * sizey ); - vy3 = vy0 + ( angsin * sizex ) + ( angcos * sizey ); - #else - /* FIXME TODO: Don't go through float, compute texcoord integers directly */ - vx0 = (float)imageBuffer->offsetx * (1.0f/DM_VERTEX_NORMFACTOR); - vy0 = (float)imageBuffer->offsety * (1.0f/DM_VERTEX_NORMFACTOR); - vx3 = vx0 + (float)( imageBuffer->sizex ); - vy3 = vy0 + (float)( imageBuffer->sizey ); - vx1 = vx3; - vy1 = vy0; - vx2 = vx0; - vy2 = vy3; - #endif - - /* FIXME TODO: Don't go through float, compute texcoord integers directly */ - tx0 = (float)( image->srcx ) * texture.widthinv; - ty0 = (float)( image->srcy ) * texture.heightinv; - tx1 = (float)( image->srcx + image->sizex ) * texture.widthinv; - ty1 = (float)( image->srcy + image->sizey ) * texture.heightinv; - - /* Write data to VBO */ - /* TODO: write vertex/texcoord all at once with SSE */ - vboVertex[0].vertex[0] = (short)( vx3 * DM_VERTEX_NORMFACTOR ); - vboVertex[0].vertex[1] = (short)( vy3 * DM_VERTEX_NORMFACTOR ); - vboVertex[0].texcoord0[0] = (short)( tx1 * DM_TEXCOORD_NORMFACTOR ); - vboVertex[0].texcoord0[1] = (short)( ty1 * DM_TEXCOORD_NORMFACTOR ); - vboVertex[0].color = imageBuffer->color; - vboVertex[0].extcolor = imageBuffer->extcolor; - vboVertex[1].vertex[0] = (short)( vx1 * DM_VERTEX_NORMFACTOR ); - vboVertex[1].vertex[1] = (short)( vy1 * DM_VERTEX_NORMFACTOR ); - vboVertex[1].texcoord0[0] = (short)( tx1 * DM_TEXCOORD_NORMFACTOR ); - vboVertex[1].texcoord0[1] = (short)( ty0 * DM_TEXCOORD_NORMFACTOR ); - vboVertex[1].color = imageBuffer->color; - vboVertex[1].extcolor = imageBuffer->extcolor; - vboVertex[2].vertex[0] = (short)( vx2 * DM_VERTEX_NORMFACTOR ); - vboVertex[2].vertex[1] = (short)( vy2 * DM_VERTEX_NORMFACTOR ); - vboVertex[2].texcoord0[0] = (short)( tx0 * DM_TEXCOORD_NORMFACTOR ); - vboVertex[2].texcoord0[1] = (short)( ty1 * DM_TEXCOORD_NORMFACTOR ); - vboVertex[2].color = imageBuffer->color; - vboVertex[2].extcolor = imageBuffer->extcolor; - vboVertex[3].vertex[0] = (short)( vx0 * DM_VERTEX_NORMFACTOR ); - vboVertex[3].vertex[1] = (short)( vy0 * DM_VERTEX_NORMFACTOR ); - vboVertex[3].texcoord0[0] = (short)( tx0 * DM_TEXCOORD_NORMFACTOR ); - vboVertex[3].texcoord0[1] = (short)( ty0 * DM_TEXCOORD_NORMFACTOR ); - vboVertex[3].color = imageBuffer->color; - vboVertex[3].extcolor = imageBuffer->extcolor; - vboVertex[4].vertex[0] = (short)( vx2 * DM_VERTEX_NORMFACTOR ); - vboVertex[4].vertex[1] = (short)( vy2 * DM_VERTEX_NORMFACTOR ); - vboVertex[4].texcoord0[0] = (short)( tx0 * DM_TEXCOORD_NORMFACTOR ); - vboVertex[4].texcoord0[1] = (short)( ty1 * DM_TEXCOORD_NORMFACTOR ); - vboVertex[4].color = imageBuffer->color; - vboVertex[4].extcolor = imageBuffer->extcolor; - vboVertex[5].vertex[0] = (short)( vx1 * DM_VERTEX_NORMFACTOR ); - vboVertex[5].vertex[1] = (short)( vy1 * DM_VERTEX_NORMFACTOR ); - vboVertex[5].texcoord0[0] = (short)( tx1 * DM_TEXCOORD_NORMFACTOR ); - vboVertex[5].texcoord0[1] = (short)( ty0 * DM_TEXCOORD_NORMFACTOR ); - vboVertex[5].color = imageBuffer->color; - vboVertex[5].extcolor = imageBuffer->extcolor; - - vboVertex += 6; - vertexcount += 6; - } - -#if !defined(_GLES) && !defined(_GLES2) // TODO: - glUnmapBuffer( GL_ARRAY_BUFFER ); + GLDisableClientState(TEXCOORDS); + GLSetupTexturing(false); +#if ENABLE_GL_SHADERS + if(glCaps_shaders) + shader_swizzle(0); #endif - // Flush font manager texture updates - flush(); - // Render buffered images - flushRenderDrawBuffer( drawBuffer, program, vertexcount ); - imageBufferCount = 0; - ERRORCHECK(); + if(glCaps_vertexBuffer) + { + glBindBuffer( GL_ARRAY_BUFFER, 0 ); + glabCurArrayBuffer = 0; + } } } -#endif public: @@ -1185,59 +375,26 @@ public: virtual void flush(); - bool init( DrawManagerFlags flags ) + bool init() { int drawBufferIndex; - DMDrawBuffer *drawBuffer; - uint vertexSize; + uint vertexSize = sizeof(DMDrawVertex); imageBufferCount = 0; imageBufferSize = 4096; - imageBuffer = new DMImageBuffer[imageBufferSize]; - imageBufferTmp = new DMImageBuffer[imageBufferSize]; - - this.flags = flags; + imageBuffers = new DMImageBuffer[imageBufferSize]; + imageBuffersTmp = new DMImageBuffer[imageBufferSize]; - if( flags.prehistoricOpenGL ) - vertexSize = sizeof(DMDrawVertexFlat); - else + for( drawBufferIndex = 0 ; drawBufferIndex < DRAW_BUFFER_COUNT ; drawBufferIndex++ ) { -#ifdef SHADERS - DMProgram *program; - int programIndex; - for( programIndex = 0 ; programIndex < DM_PROGRAM_COUNT ; programIndex++ ) - { - program = &shaderPrograms[ programIndex ]; - program->flags = 0; - program->lastUpdateCount = -1; - } - program = &shaderPrograms[ DM_PROGRAM_NORMAL ]; - if( !( dmCreateProgram( program, dmVertexShaderNormal, dmFragmentShaderNormal, 0 ) ) ) - return false; - program = &shaderPrograms[ DM_PROGRAM_ALPHABLEND ]; - if( !( dmCreateProgram( program, dmVertexShaderAlpha, dmFragmentShaderAlpha, 0 ) ) ) - return false; - program = &shaderPrograms[ DM_PROGRAM_ALPHABLEND_INTENSITY ]; - if( !( dmCreateProgram( program, dmVertexShaderAlphaIntensity, dmFragmentShaderAlphaIntensity, 0 ) ) ) - return false; - program = &shaderPrograms[ DM_PROGRAM_ALPHABLEND_INTENSITY_EXTCOLOR ]; - if( !( dmCreateProgram( program, dmVertexShaderAlphaIntensityExtColor, dmFragmentShaderAlphaIntensityExtColor, 0 ) ) ) - return false; - // glUseProgram( 0 ); - vertexSize = sizeof(DMDrawVertex); -#endif - } - - for( drawBufferIndex = 0 ; drawBufferIndex < DM_CONTEXT_DRAW_BUFFER_COUNT ; drawBufferIndex++ ) - { - drawBuffer = &this.drawBuffer[drawBufferIndex]; + DMDrawBuffer *drawBuffer = &drawBuffers[drawBufferIndex]; drawBuffer->glType = GL_FLOAT; drawBuffer->vertexCount = 0; - drawBuffer->vertexAlloc = DM_CONTEXT_DRAW_BUFFER_VERTEX_ALLOC; - if(vboAvailable) + drawBuffer->vertexAlloc = DRAW_BUFFER_VERTEX_ALLOC; + if(glCaps_vertexBuffer) { - glGenBuffers( 1, &drawBuffer->vbo ); - glBindBuffer( GL_ARRAY_BUFFER, drawBuffer->vbo ); + glGenBuffers( 1, &drawBuffer->vbo.buffer ); + glBindBuffer( GL_ARRAY_BUFFER, drawBuffer->vbo.buffer ); glBufferData( GL_ARRAY_BUFFER, drawBuffer->vertexAlloc * vertexSize, 0, GL_DYNAMIC_DRAW ); } drawBuffer->vertexBuffer = new byte[drawBuffer->vertexAlloc * vertexSize]; @@ -1245,8 +402,11 @@ public: updateCount = 0; - glabCurArrayBuffer = 0; - + if(glCaps_vertexBuffer) + { + glBindBuffer( GL_ARRAY_BUFFER, 0 ); + glabCurArrayBuffer = 0; + } return true; } @@ -1255,251 +415,86 @@ public: end(); } - void end( ) + void end() { int i; - for( i = 0 ; i < DM_CONTEXT_DRAW_BUFFER_COUNT ; i++ ) + for( i = 0 ; i < DRAW_BUFFER_COUNT ; i++ ) { - DMDrawBuffer *db = &drawBuffer[i]; - if(db->vbo) - glDeleteBuffers( 1, &db->vbo ); + DMDrawBuffer *db = &drawBuffers[i]; + if(db->vbo.buffer) + glDeleteBuffers( 1, &db->vbo.buffer ); delete db->vertexBuffer; } - - // TODO: Destroy the shaders! - delete imageBuffer; - delete imageBufferTmp; + delete imageBuffers; + delete imageBuffersTmp; + delete imageList; } - void ready( int viewportwidth, int viewportheight ) + void ready( int viewportWidth, int viewportHeight ) { - int mindex; - float norminv; -#ifdef SHADERS - if(!flags.prehistoricOpenGL && !prevProgram) - glGetIntegerv(GL_CURRENT_PROGRAM, (GLint *)&prevProgram); -#endif - // while(glGetError()); - - // ERRORCHECK(); + float norminv = 1.0f / DM_VERTEX_NORMFACTOR; + float texinv = 1.0f / DM_TEXCOORD_NORMFACTOR; - // Save OpenGL state - // FIXME: no glPushAttrib() in core profile -#if !defined(_GLES) && !defined(_GLES2) // TODO: - glPushClientAttrib( GL_CLIENT_ALL_ATTRIB_BITS ); - glPushAttrib( GL_ALL_ATTRIB_BITS ); -#endif + GLMatrixMode(MatrixMode::texture); + GLScalef(texinv,texinv,1); - // Prepare rendering pass + GLMatrixMode(MatrixMode::projection); + GLLoadIdentity(); if(renderingFlipped) - matrixOrtho( matrix, 0.0, (float)viewportwidth, 0.0, (float)viewportheight, -1.0f, 1.0 ); + GLOrtho( 0.0, (float)viewportWidth, 0.0, (float)viewportHeight, -1.0f, 1.0 ); else - matrixOrtho( matrix, 0.0, (float)viewportwidth, (float)viewportheight, 0.0, -1.0f, 1.0 ); - norminv = 1.0f / DM_VERTEX_NORMFACTOR; - for( mindex = 0 ; mindex < 12 ; mindex += 4 ) - { - matrix[mindex+0] *= norminv; - matrix[mindex+1] *= norminv; - matrix[mindex+2] *= norminv; - } + GLOrtho( 0.0, (float)viewportWidth, (float)viewportHeight, 0.0, -1.0f, 1.0 ); + GLScalef(norminv, norminv, norminv); + + GLMatrixMode(MatrixMode::modelView); + GLLoadIdentity(); + GLScalef(1,1,1); + drawBarrierIndex = 0; - orderBarrierMask = drawBarrierIndex << DM_BARRIER_ORDER_SHIFT; orderBarrierMask = 0; updateCount++; - - if(flags.prehistoricOpenGL) - { - glMatrixMode(MatrixMode::projection); - glLoadMatrixf(matrix); - - glMatrixMode(MatrixMode::modelView); - glLoadIdentity(); - glScalef(4,4,4); - } - } - - void drawImage( DMImage image, int offsetx, int offsety, int sizex, int sizey, uint32 color ) - { - DMImageBuffer *imageBuffer; - - if( image.flags.empty || ( sizex <= 0 ) || ( sizey <= 0 ) ) - return; - - if( imageBufferCount >= imageBufferSize ) - { - imageBufferSize <<= 1; - this.imageBuffer = renew this.imageBuffer DMImageBuffer[imageBufferSize]; - imageBufferTmp = renew imageBufferTmp DMImageBuffer[imageBufferSize]; - } - - imageBuffer = &this.imageBuffer[ imageBufferCount ]; - imageBuffer->image = image; - imageBuffer->offsetx = (short)(offsetx << DM_VERTEX_NORMSHIFT); - imageBuffer->offsety = (short)(offsety << DM_VERTEX_NORMSHIFT); - imageBuffer->sizex = (short)sizex; - imageBuffer->sizey = (short)sizey; - #if DM_ENABLE_IMAGE_ROTATION - imageBuffer->angsin = 0; - imageBuffer->angcos = (short)DM_IMAGE_ROTATION_NORMFACTOR; - #endif - imageBuffer->color = color; - imageBuffer->orderindex = image.orderMask | orderBarrierMask; - - #if DM_RENDER_IMAGE_DEBUG - printf( " Queue image at %d %d, order 0x%x\n", (int)imageBuffer->offsetx, (int)imageBuffer->offsety, (int)imageBuffer->orderindex ); - #endif - - imageBufferCount++; - } - - void drawImageExtColor( DMImage image, int offsetx, int offsety, int sizex, int sizey, uint32 color, uint32 extcolor ) - { - DMImageBuffer *imageBuffer; - - if( ( image.flags.empty ) || ( sizex <= 0 ) || ( sizey <= 0 ) ) - return; - - if( imageBufferCount >= imageBufferSize ) - { - imageBufferSize <<= 1; - this.imageBuffer = renew this.imageBuffer DMImageBuffer[imageBufferSize]; - imageBufferTmp = renew imageBufferTmp DMImageBuffer[imageBufferSize]; - } - - imageBuffer = &this.imageBuffer[ imageBufferCount ]; - imageBuffer->image = image; - imageBuffer->offsetx = (short)(offsetx << DM_VERTEX_NORMSHIFT); - imageBuffer->offsety = (short)(offsety << DM_VERTEX_NORMSHIFT); - imageBuffer->sizex = (short)sizex; - imageBuffer->sizey = (short)sizey; - #if DM_ENABLE_IMAGE_ROTATION - imageBuffer->angsin = 0; - imageBuffer->angcos = (short)DM_IMAGE_ROTATION_NORMFACTOR; - #endif - imageBuffer->color = color; - #if DM_ENABLE_EXT_COLOR - imageBuffer->extcolor = extcolor; - #endif - imageBuffer->orderindex = image.orderMask | orderBarrierMask; - - #if DM_RENDER_IMAGE_DEBUG - printf( " Queue image at %d %d, order 0x%x\n", (int)imageBuffer->offsetx, (int)imageBuffer->offsety, (int)imageBuffer->orderindex ); - #endif - - this.imageBufferCount++; - } - - void drawImageFloat( DMImage image, float offsetx, float offsety, float sizex, float sizey, float angsin, float angcos, uint32 color ) - { - DMImageBuffer *imageBuffer; - - if( image.flags.empty || sizex <= 0 || sizey <= 0 ) - return; - - if( imageBufferCount >= imageBufferSize ) - { - imageBufferSize <<= 1; - this.imageBuffer = renew this.imageBuffer DMImageBuffer[imageBufferSize]; - imageBufferTmp = renew imageBufferTmp DMImageBuffer[imageBufferSize]; - } - - imageBuffer = &this.imageBuffer[ imageBufferCount ]; - imageBuffer->image = image; - imageBuffer->offsetx = (short)roundf(offsetx * DM_VERTEX_NORMFACTOR); - imageBuffer->offsety = (short)roundf(offsety * DM_VERTEX_NORMFACTOR); - imageBuffer->sizex = (short)sizex; - imageBuffer->sizey = (short)sizey; - #if DM_ENABLE_IMAGE_ROTATION - imageBuffer->angsin = (short)roundf( angsin * DM_IMAGE_ROTATION_NORMFACTOR ); - imageBuffer->angcos = (short)roundf( angcos * DM_IMAGE_ROTATION_NORMFACTOR ); - #endif - imageBuffer->color = color; - imageBuffer->orderindex = image.orderMask | orderBarrierMask; - - #if DM_RENDER_IMAGE_DEBUG - printf( " Queue image at %d %d, order 0x%x\n", (int)imageBuffer->offsetx, (int)imageBuffer->offsety, (int)imageBuffer->orderindex ); - #endif - - imageBufferCount++; - } - - void drawImageFloatExtColor( DMImage image, float offsetx, float offsety, float sizex, float sizey, float angsin, float angcos, uint32 color, uint32 extcolor ) - { - DMImageBuffer *imageBuffer; - - if( ( image.flags.empty ) || ( sizex <= 0 ) || ( sizey <= 0 ) ) - return; - - if( this.imageBufferCount >= this.imageBufferSize ) - { - imageBufferSize <<= 1; - this.imageBuffer = renew this.imageBuffer DMImageBuffer[imageBufferSize]; - imageBufferTmp = renew imageBufferTmp DMImageBuffer[imageBufferSize]; - } - - imageBuffer = &this.imageBuffer[ imageBufferCount ]; - imageBuffer->image = image; - imageBuffer->offsetx = (short)roundf( offsetx * DM_VERTEX_NORMFACTOR ); - imageBuffer->offsety = (short)roundf( offsety * DM_VERTEX_NORMFACTOR ); - imageBuffer->sizex = (short)sizex; - imageBuffer->sizey = (short)sizey; - #if DM_ENABLE_IMAGE_ROTATION - imageBuffer->angsin = (short)roundf( angsin * DM_IMAGE_ROTATION_NORMFACTOR ); - imageBuffer->angcos = (short)roundf( angcos * DM_IMAGE_ROTATION_NORMFACTOR ); - #endif - imageBuffer->color = color; - #if DM_ENABLE_EXT_COLOR - imageBuffer->extcolor = extcolor; - #endif - imageBuffer->orderindex = image.orderMask | orderBarrierMask; - - #if DM_RENDER_IMAGE_DEBUG - printf( " Queue image at %d %d, order 0x%x\n", (int)imageBuffer->offsetx, (int)imageBuffer->offsety, (int)imageBuffer->orderindex ); - #endif - - this.imageBufferCount++; } - void flushImages( ) + void drawImage( int index, float offsetx, float offsety, float angsin, float angcos, ColorAlpha color ) { -#if !defined(_GLES2) - if(flags.prehistoricOpenGL) - flushDrawImagesArchaic(); -#endif - -#if defined(SHADERS) - if(!flags.prehistoricOpenGL) - flushDrawImages( ); -#endif + DMImage * image = &imageList[index]; + float sizex = image->sizex, sizey = image->sizey; + if(!image->flags.empty && sizex > 0 && sizey > 0) + { + if( imageBufferCount >= imageBufferSize ) + { + imageBufferSize <<= 1; + imageBuffers = renew imageBuffers DMImageBuffer[imageBufferSize]; + imageBuffersTmp = renew imageBuffersTmp DMImageBuffer[imageBufferSize]; + } + imageBuffers[ imageBufferCount++ ] = + { + image = index; + offsetx = (short)roundf( offsetx * DM_VERTEX_NORMFACTOR ); + offsety = (short)roundf( offsety * DM_VERTEX_NORMFACTOR ); + sizex = (short)sizex; + sizey = (short)sizey; + angsin = (short)roundf( angsin * DM_IMAGE_ROTATION_NORMFACTOR ); + angcos = (short)roundf( angcos * DM_IMAGE_ROTATION_NORMFACTOR ); + color = color; + orderIndex = image->orderMask | orderBarrierMask; + }; + } } void finish() { flushImages(); - - if(vboAvailable) - glBindBuffer( GL_ARRAY_BUFFER, 0 ); - glabCurArrayBuffer = 0; -#ifdef SHADERS - if( !flags.prehistoricOpenGL ) - glUseProgram( prevProgram ); -#endif - // Restore OpenGL state - // FIXME: no glPushAttrib() in core profile -#if !defined(_GLES) && !defined(_GLES2) // TODO: - glPopAttrib(); - glPopClientAttrib(); -#endif } void drawBarrier( ) { drawBarrierIndex++; - if( drawBarrierIndex >= ( 1 << DM_BARRIER_ORDER_BITS ) ) + if(drawBarrierIndex >= ( 1 << DM_BARRIER_ORDER_BITS )) flushImages( ); - orderBarrierMask = drawBarrierIndex << DM_BARRIER_ORDER_SHIFT; + orderBarrierMask = { barrier = (1 << DM_BARRIER_ORDER_BITS)-1 }; } void clear()