Search code examples
androidopengl-es-2.0spriteandenginemotion

Motion Streak for specific Sprites?


AndEngine GLES2 has an example for a full scene motion streak/blur which works great, but I would like to apply that motion blur to only specific sprites.

Kind of like I don't want my characters to motion blur, just the spells(Sprites).

This is what I am using to do a motion blur right now, it is simply the AndEngine example, but the problem is it seems to take a snapshot of the whole screen, apply an aplha, and then merge it with the next frame of the screen, and I would only like to apply this "alpha" blurring affect to individual sprites.

@Override
public Engine onCreateEngine(EngineOptions pEngineOptions) {
    return new Engine(pEngineOptions) {
        private static final int RENDERTEXTURE_COUNT = 2;

        private boolean mRenderTextureInitialized;

        private final RenderTexture[] mRenderTextures = new RenderTexture[RENDERTEXTURE_COUNT];
        private final Sprite[] mRenderTextureSprites = new Sprite[RENDERTEXTURE_COUNT];

        private int mCurrentRenderTextureIndex = 0;

        @Override
        public void onDrawFrame(final GLState pGLState) throws InterruptedException {
            final boolean firstFrame = !this.mRenderTextureInitialized;

            if(firstFrame) {
                this.initRenderTextures(pGLState);
                this.mRenderTextureInitialized = true;
            }

            final int surfaceWidth = this.mCamera.getSurfaceWidth();
            final int surfaceHeight = this.mCamera.getSurfaceHeight();

            final int currentRenderTextureIndex = this.mCurrentRenderTextureIndex;
            final int otherRenderTextureIndex = (currentRenderTextureIndex + 1) % RENDERTEXTURE_COUNT;

            this.mRenderTextures[currentRenderTextureIndex].begin(pGLState, false, true);
            {
                /* Draw current frame. */
                super.onDrawFrame(pGLState);

                /* Draw previous frame with reduced alpha. */
                if(!firstFrame) {
                    if(Info.motionStreaking) {
                        this.mRenderTextureSprites[otherRenderTextureIndex].setAlpha(0.9f);
                        this.mRenderTextureSprites[otherRenderTextureIndex].onDraw(pGLState, this.mCamera);
                    }
                }
            }
            this.mRenderTextures[currentRenderTextureIndex].end(pGLState);

            /* Draw combined frame with full alpha. */
            {
                pGLState.pushProjectionGLMatrix();
                pGLState.orthoProjectionGLMatrixf(0, surfaceWidth, 0, surfaceHeight, -1, 1);
                {
                    this.mRenderTextureSprites[otherRenderTextureIndex].setAlpha(1);
                    this.mRenderTextureSprites[otherRenderTextureIndex].onDraw(pGLState, this.mCamera);
                }
                pGLState.popProjectionGLMatrix();
            }

            /* Flip RenderTextures. */
            this.mCurrentRenderTextureIndex = otherRenderTextureIndex;
        }

        private void initRenderTextures(final GLState pGLState) {
            final int surfaceWidth = this.mCamera.getSurfaceWidth();
            final int surfaceHeight = this.mCamera.getSurfaceHeight();

            final VertexBufferObjectManager vertexBufferObjectManager = this.getVertexBufferObjectManager();
            for(int i = 0; i <= 1; i++) {
                this.mRenderTextures[i] = new RenderTexture(DodgingGame.this.getTextureManager(), surfaceWidth, surfaceHeight);
                this.mRenderTextures[i].init(pGLState);

                final ITextureRegion renderTextureATextureRegion = TextureRegionFactory.extractFromTexture(this.mRenderTextures[i]);
                this.mRenderTextureSprites[i] = new Sprite(0, 0, renderTextureATextureRegion, vertexBufferObjectManager);
            }
        }
    };
}

How can I change it to work for specific sprites instead of the whole visible screen?


Solution

  • You could use a particle system to create motion blur effect.