flush()
    {
        if (this.currentIndex === 0) return;

        const gl = this.renderer.gl;

        const np2 = bitTwiddle.nextPow2(this.currentIndex);
        const log2 = bitTwiddle.log2(np2);
        const buffer = this.buffers[log2];

        let index = 0;
        let nextTexture = null;
        let currentTexture = null;
        let groupCount = 1;
        let textureCount = 0;
        let currentGroup = this.groups[0];
        let blendMode = this.sprites[0].blendMode || util.BlendMode.NORMAL;

        currentGroup.textures.length = 0;
        currentGroup.start = 0;
        currentGroup.blend = blendMode;
        currentGroup.shader = null;

        TICK++;

        for (let i = 0; i < this.currentIndex; ++i)
        {
            // upload the sprite elemetns...
            // they have all ready been calculated so we just need to push them into the buffer.
            const sprite = this.sprites[i];

            nextTexture = sprite._texture.source;

            // a couple things should break the batch
            if (sprite.shader || !blendMode.equals(sprite.blendMode))
            {
                blendMode = sprite.blendMode;

                // force the batch to break!
                currentTexture = null;
                textureCount = this._maxTextures;
                TICK++;
            }

            if (currentTexture !== nextTexture)
            {
                currentTexture = nextTexture;

                if (nextTexture._enabled !== TICK)
                {
                    if (textureCount === this._maxTextures)
                    {
                        TICK++;

                        textureCount = 0;

                        currentGroup.size = i - currentGroup.start;

                        currentGroup = this.groups[groupCount++];
                        currentGroup.textures.length = 0;
                        currentGroup.blend = blendMode;
                        currentGroup.start = i;
                        currentGroup.shader = sprite.shader;
                    }

                    // TODO: I don't like this, change this to not add properties to texture
                    nextTexture._enabled = TICK;
                    nextTexture._id = textureCount;

                    const glTexture = nextTexture.getGlTexture(this.renderer);

                    if (glTexture)
                    {
                        currentGroup.textures.push(glTexture);
                        textureCount++;
                    }
                }
            }

            // TODO: this sum does not need to be set each frame, dirty flag?
            const tint = sprite.tint.bgr + (sprite.worldAlpha * 255 << 24);
            const uvs = sprite._texture._uvs.uvsUint32;
            const textureId = nextTexture._id;
            const vertexData = sprite.vertexData;

            // xy
            buffer.float32View[index++] = vertexData[0];
            buffer.float32View[index++] = vertexData[1];
            buffer.uint32View[index++] = uvs[0];
            buffer.uint32View[index++] = tint;
            buffer.float32View[index++] = textureId;

            // xy
            buffer.float32View[index++] = vertexData[2];
            buffer.float32View[index++] = vertexData[3];
            buffer.uint32View[index++] = uvs[1];
            buffer.uint32View[index++] = tint;
            buffer.float32View[index++] = textureId;

            // xy
            buffer.float32View[index++] = vertexData[4];
            buffer.float32View[index++] = vertexData[5];
            buffer.uint32View[index++] = uvs[2];
            buffer.uint32View[index++] = tint;
            buffer.float32View[index++] = textureId;

            // xy
            buffer.float32View[index++] = vertexData[6];
            buffer.float32View[index++] = vertexData[7];
            buffer.uint32View[index++] = uvs[3];
            buffer.uint32View[index++] = tint;
            buffer.float32View[index++] = textureId;
        }

        currentGroup.size = this.currentIndex - currentGroup.start;

        this.vertexCount++;

        if (this.vertexBuffers.length <= this.vertexCount)
        {
            this._createVao(gl, this.shaders[1].attributes);
        }

        // @ifdef DEBUG
        debug.ASSERT(this.vertexBuffers.length > this.vertexCount, 'Number of Vertex Buffers is too small.');
        // @endif

        this.vertexBuffers[this.vertexCount].upload(buffer.buffer, 0);
        this.vao = this.vaos[this.vertexCount].bind();

        // render the groups..
        for (let i = 0; i < groupCount; ++i)
        {
            const group = this.groups[i];
            const groupTextureCount = group.textures.length;

            if (!groupTextureCount) continue;

            let shader = null;

            if (group.shader)
            {
                shader = group.shader;
            }
            else
            {
                shader = this.shaders[groupTextureCount - 1];
            }

            if (!shader)
            {
                shader = generateMultiTextureShader(this.renderer, groupTextureCount);
                this.shaders[groupTextureCount - 1] = shader;
            }

            this.renderer.state.setShader(shader);

            for (let j = 0; j < groupTextureCount; ++j)
            {
                group.textures[j].bind(j);
            }

            // set the blend mode..
            this.renderer.state.setBlendMode(group.blend);

            gl.drawElements(gl.TRIANGLES, group.size * 6, gl.UNSIGNED_SHORT, group.start * 6 * 2);
        }

        // reset elements for the next flush
        this.currentIndex = 0;
    }
/**
     * Renders the content and empties the current batch.
     *
     */
Renders the content and empties the current batch.
Renders the content and empties the current batch .
flush()
    {
        if (this.currentIndex === 0) return;
        const gl = this.renderer.gl;
        const np2 = bitTwiddle.nextPow2(this.currentIndex);
        const log2 = bitTwiddle.log2(np2);
        const buffer = this.buffers[log2];
        let index = 0;
        let nextTexture = null;
        let currentTexture = null;
        let groupCount = 1;
        let textureCount = 0;
        let currentGroup = this.groups[0];
        let blendMode = this.sprites[0].blendMode || util.BlendMode.NORMAL;
        currentGroup.textures.length = 0;
        currentGroup.start = 0;
        currentGroup.blend = blendMode;
        currentGroup.shader = null;
        TICK++;
        for (let i = 0; i < this.currentIndex; ++i)
        {
            const sprite = this.sprites[i];
            nextTexture = sprite._texture.source;
            if (sprite.shader || !blendMode.equals(sprite.blendMode))
            {
                blendMode = sprite.blendMode;
                currentTexture = null;
                textureCount = this._maxTextures;
                TICK++;
            }
            if (currentTexture !== nextTexture)
            {
                currentTexture = nextTexture;
                if (nextTexture._enabled !== TICK)
                {
                    if (textureCount === this._maxTextures)
                    {
                        TICK++;
                        textureCount = 0;
                        currentGroup.size = i - currentGroup.start;
                        currentGroup = this.groups[groupCount++];
                        currentGroup.textures.length = 0;
                        currentGroup.blend = blendMode;
                        currentGroup.start = i;
                        currentGroup.shader = sprite.shader;
                    }
                    nextTexture._enabled = TICK;
                    nextTexture._id = textureCount;
                    const glTexture = nextTexture.getGlTexture(this.renderer);
                    if (glTexture)
                    {
                        currentGroup.textures.push(glTexture);
                        textureCount++;
                    }
                }
            }
            const tint = sprite.tint.bgr + (sprite.worldAlpha * 255 << 24);
            const uvs = sprite._texture._uvs.uvsUint32;
            const textureId = nextTexture._id;
            const vertexData = sprite.vertexData;
            buffer.float32View[index++] = vertexData[0];
            buffer.float32View[index++] = vertexData[1];
            buffer.uint32View[index++] = uvs[0];
            buffer.uint32View[index++] = tint;
            buffer.float32View[index++] = textureId;
            buffer.float32View[index++] = vertexData[2];
            buffer.float32View[index++] = vertexData[3];
            buffer.uint32View[index++] = uvs[1];
            buffer.uint32View[index++] = tint;
            buffer.float32View[index++] = textureId;
            buffer.float32View[index++] = vertexData[4];
            buffer.float32View[index++] = vertexData[5];
            buffer.uint32View[index++] = uvs[2];
            buffer.uint32View[index++] = tint;
            buffer.float32View[index++] = textureId;
            buffer.float32View[index++] = vertexData[6];
            buffer.float32View[index++] = vertexData[7];
            buffer.uint32View[index++] = uvs[3];
            buffer.uint32View[index++] = tint;
            buffer.float32View[index++] = textureId;
        }
        currentGroup.size = this.currentIndex - currentGroup.start;
        this.vertexCount++;
        if (this.vertexBuffers.length <= this.vertexCount)
        {
            this._createVao(gl, this.shaders[1].attributes);
        }
        debug.ASSERT(this.vertexBuffers.length > this.vertexCount, 'Number of Vertex Buffers is too small.');
        this.vertexBuffers[this.vertexCount].upload(buffer.buffer, 0);
        this.vao = this.vaos[this.vertexCount].bind();
        for (let i = 0; i < groupCount; ++i)
        {
            const group = this.groups[i];
            const groupTextureCount = group.textures.length;
            if (!groupTextureCount) continue;
            let shader = null;
            if (group.shader)
            {
                shader = group.shader;
            }
            else
            {
                shader = this.shaders[groupTextureCount - 1];
            }
            if (!shader)
            {
                shader = generateMultiTextureShader(this.renderer, groupTextureCount);
                this.shaders[groupTextureCount - 1] = shader;
            }
            this.renderer.state.setShader(shader);
            for (let j = 0; j < groupTextureCount; ++j)
            {
                group.textures[j].bind(j);
            }
            this.renderer.state.setBlendMode(group.blend);
            gl.drawElements(gl.TRIANGLES, group.size * 6, gl.UNSIGNED_SHORT, group.start * 6 * 2);
        }
        this.currentIndex = 0;
    }
flush ( ) { if ( this . currentIndex === 0 ) return ; const gl = this . renderer . gl ; const np2 = bitTwiddle . nextPow2 ( this . currentIndex ) ; const log2 = bitTwiddle . log2 ( np2 ) ; const buffer = this . buffers [ log2 ] ; let index = 0 ; let nextTexture = null ; let currentTexture = null ; let groupCount = 1 ; let textureCount = 0 ; let currentGroup = this . groups [ 0 ] ; let blendMode = this . sprites [ 0 ] . blendMode || util . BlendMode . NORMAL ; currentGroup . textures . length = 0 ; currentGroup . start = 0 ; currentGroup . blend = blendMode ; currentGroup . shader = null ; TICK ++ ; for ( let i = 0 ; i < this . currentIndex ; ++ i ) { const sprite = this . sprites [ i ] ; nextTexture = sprite . _texture . source ; if ( sprite . shader || ! blendMode . equals ( sprite . blendMode ) ) { blendMode = sprite . blendMode ; currentTexture = null ; textureCount = this . _maxTextures ; TICK ++ ; } if ( currentTexture !== nextTexture ) { currentTexture = nextTexture ; if ( nextTexture . _enabled !== TICK ) { if ( textureCount === this . _maxTextures ) { TICK ++ ; textureCount = 0 ; currentGroup . size = i - currentGroup . start ; currentGroup = this . groups [ groupCount ++ ] ; currentGroup . textures . length = 0 ; currentGroup . blend = blendMode ; currentGroup . start = i ; currentGroup . shader = sprite . shader ; } nextTexture . _enabled = TICK ; nextTexture . _id = textureCount ; const glTexture = nextTexture . getGlTexture ( this . renderer ) ; if ( glTexture ) { currentGroup . textures . push ( glTexture ) ; textureCount ++ ; } } } const tint = sprite . tint . bgr + ( sprite . worldAlpha * 255 << 24 ) ; const uvs = sprite . _texture . _uvs . uvsUint32 ; const textureId = nextTexture . _id ; const vertexData = sprite . vertexData ; buffer . float32View [ index ++ ] = vertexData [ 0 ] ; buffer . float32View [ index ++ ] = vertexData [ 1 ] ; buffer . uint32View [ index ++ ] = uvs [ 0 ] ; buffer . uint32View [ index ++ ] = tint ; buffer . float32View [ index ++ ] = textureId ; buffer . float32View [ index ++ ] = vertexData [ 2 ] ; buffer . float32View [ index ++ ] = vertexData [ 3 ] ; buffer . uint32View [ index ++ ] = uvs [ 1 ] ; buffer . uint32View [ index ++ ] = tint ; buffer . float32View [ index ++ ] = textureId ; buffer . float32View [ index ++ ] = vertexData [ 4 ] ; buffer . float32View [ index ++ ] = vertexData [ 5 ] ; buffer . uint32View [ index ++ ] = uvs [ 2 ] ; buffer . uint32View [ index ++ ] = tint ; buffer . float32View [ index ++ ] = textureId ; buffer . float32View [ index ++ ] = vertexData [ 6 ] ; buffer . float32View [ index ++ ] = vertexData [ 7 ] ; buffer . uint32View [ index ++ ] = uvs [ 3 ] ; buffer . uint32View [ index ++ ] = tint ; buffer . float32View [ index ++ ] = textureId ; } currentGroup . size = this . currentIndex - currentGroup . start ; this . vertexCount ++ ; if ( this . vertexBuffers . length <= this . vertexCount ) { this . _createVao ( gl , this . shaders [ 1 ] . attributes ) ; } debug . ASSERT ( this . vertexBuffers . length > this . vertexCount , 'Number of Vertex Buffers is too small.' ) ; this . vertexBuffers [ this . vertexCount ] . upload ( buffer . buffer , 0 ) ; this . vao = this . vaos [ this . vertexCount ] . bind ( ) ; for ( let i = 0 ; i < groupCount ; ++ i ) { const group = this . groups [ i ] ; const groupTextureCount = group . textures . length ; if ( ! groupTextureCount ) continue ; let shader = null ; if ( group . shader ) { shader = group . shader ; } else { shader = this . shaders [ groupTextureCount - 1 ] ; } if ( ! shader ) { shader = generateMultiTextureShader ( this . renderer , groupTextureCount ) ; this . shaders [ groupTextureCount - 1 ] = shader ; } this . renderer . state . setShader ( shader ) ; for ( let j = 0 ; j < groupTextureCount ; ++ j ) { group . textures [ j ] . bind ( j ) ; } this . renderer . state . setBlendMode ( group . blend ) ; gl . drawElements ( gl . TRIANGLES , group . size * 6 , gl . UNSIGNED_SHORT , group . start * 6 * 2 ) ; } this . currentIndex = 0 ; }
Renders the content and empties the current batch.
Renders the content and empties the current batch .
// upload the sprite elemetns... // they have all ready been calculated so we just need to push them into the buffer. // a couple things should break the batch // force the batch to break! // TODO: I don't like this, change this to not add properties to texture // TODO: this sum does not need to be set each frame, dirty flag? // xy // xy // xy // xy // @ifdef DEBUG // @endif // render the groups.. // set the blend mode.. // reset elements for the next flush