AndEngine:关于Texture质量问题 和 Gradient背景

1、http://www.matim-dev.com/dithering---improve-gradient-quality.html

At beginning, lets explain what exactly is dithering. It adds some grains to the image, delivering overall quality. Lets take a look at those two images, to understand it. Lets say you want to use this image in you app, as you can see there is gradient background (images taken from  TeturePacker website)
AndEngine:关于Texture质量问题 和 Gradient背景_第1张图片
But on your device, you would see much lower quality of the gradient, with following results: image on the left is with  NO DITHERING, and image on the right is with  DITHERING ENABLED.
AndEngine:关于Texture质量问题 和 Gradient背景_第2张图片
        Gradient image without dithering.
AndEngine:关于Texture质量问题 和 Gradient背景_第3张图片
             Gradient image with dithering.
You can expect such quality issues while using gradients, but also, while using lower quality texture type  RGBA 4444 instead of high quality one  RGBA 8888. What is the conclusion? You can cut memory usage by half, by using lower quality texture type, with dithering enabled! Lets explain now, how to enable dithering for particular entity.

1. Enabling dithering in particular Entity:

final Sprite sprite = new Sprite(pX, pY, pTextureRegion, pVertexBufferObject)
{
    @Override
    protected void preDraw(final GLState pGLState, final Camera pCamera)
    {
        super.preDraw(pGLState, pCamera);
        pGLState.enableDither();
    }
};
As you can see, we simply override preDraw method, enabling dithering, with this easy way, quality should be greatly improved. We can also enable dithering in engine options by default for our application.

2. Enabling dithering for whole engine:

public EngineOptions onCreateEngineOptions()
{
    camera = new GameCamera(0, 0, 800, 480);
    EngineOptions engineOptions = new EngineOptions(...);
    engineOptions.getRenderOptions().setDithering(true);
    return engineOptions;
}
While creating engine options, we can get render options, and enable dithering.

2、http://stackoverflow.com/questions/16888017/how-to-apply-gradient-background-in-andengine

The following code inside your activity class (onCreateScene or onPopulateScene) should set a red/blue gradient as your background.

Gradient g = new Gradient(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT, this.getVertexBufferObjectManager()); g.setGradient(Color.RED, Color.BLUE, 1, 0); this.setBackground(new EntityBackground(g));

3、http://www.andengine.org/forums/gles2/gradient-background-t10758.html

Hey Guys,

I was searching for an off the shelf code for andengine gradient background, couldn't find one (within a 5 mins search), i only found a code snippet for GLES1, so i ported it to GLES2 and posting it in case someone needs it.

(Credits goes to AlexNunn for GLES1.0 version of this code in post19020.html?hilit=brightBackgroundSprite#p19020)

Of course if any expert wants to give it a "retouche", feel free : )

Syntax: [  Download ] [  Hide ]
Using  java Syntax Highlighting
  1.  
  2.                 BitmapTextureAtlas backgroundGradientTexture  =  new BitmapTextureAtlas (textureManager, 2, 512, TextureOptions. NEAREST ) ;
  3.  
  4.                 EmptyBitmapTextureAtlasSource bitmap  =  new EmptyBitmapTextureAtlasSource (2, 512 ) ;
  5.                 LinearGradientFillBitmapTextureAtlasSourceDecorator gradientSource  =  newLinearGradientFillBitmapTextureAtlasSourceDecorator (
  6.                                 bitmap,  new RectangleBitmapTextureAtlasSourceDecoratorShape ( ), Color. rgb (50, 10, 50 )Color. rgb (255, 50, 255 ),
  7.                                 LinearGradientDirection. TOP_TO_BOTTOM ) ;
  8.  
  9.                 TextureRegion backgroundGradientTextureRegion  =TextureRegionFactory. createFromSource (backgroundGradientTexture,
  10.                                 gradientSource, 0, 0 ) ;
  11.                 backgroundGradientTexture. load ( ) ;
  12.  
  13.                 Sprite brightBackgroundSprite  =  new Sprite (0, 0, CAMERA_WIDTH, CAMERA_HEIGHT, backgroundGradientTextureRegion,
  14.                                 vertexBufferManager ) ;
  15.  
  16.                  this. splashScene. attachChild (brightBackgroundSprite ) ;
Parsed in 0.033 seconds, using  GeSHi 1.0.8.4


This is usefull when you have already a png image with a gradient background, remove the background from your image, make it transparent to save image space and use andengine to draw the background.
I saved around 500Kbytes using this technique.


4、http://www.kaifajie.cn/android/8346.html

问题:

 

The problem: poor texture quality in android app written with Andengine(wraps opengl), especially on gradients which appear as steps in few colours. Problem occurs on real and virtual device

Settings: default texture, fullscreen, native resolution, android 2.2. I have tried to enforce PixelFromat with:

public void onAttachedToWindow() {
    super.onAttachedToWindow();
    Window window = getWindow();
    window.setFormat(PixelFormat.RGBA_8888);
}Haven't made any difference.

Commenting line: GLHelper.disableDither(pGL); helped a little with textures, but made particles look bad, so a guess it is not the source of problem.

Example loading code:

public static void loadResources(StreamgameActivity game) {
    magnetTexture = new BitmapTextureAtlas(512, 512, TextureOptions.BILINEAR);
    magnetTextureRegion = BitmapTextureAtlasTextureRegionFactory
       .createFromAsset(magnetTexture, game,"bateria128CMatte_none.png", 0, 0);
    game.getEngine().getTextureManager().loadTexture(magnetTexture);
}
解决方法:方法一:
Andengine seems to use be default 16bit rendering mode. To change that I have done:
this.mRenderSurfaceView = new RenderSurfaceView(this);
mRenderSurfaceView.setEGLConfigChooser(8,8,8,8,0,0);//!!
mRenderSurfaceView.setRenderer(mEngine);
mRenderSurfaceView.getHolder().setFormat(PixelFormat.RGBA_8888);//!!
in onSetContentView method.
方法二:
if someone is experiencing poor texture quality and banding for GLES2 here is the solution: just overridepreDraw() of your Sprite and enable dithering like this:
Sprite electricityOff = new Sprite(0, 0, mElectricityOffTextureRegion, getVertexBufferObjectManager()) {
    @Override
    protected void preDraw(GLState pGLState, Camera pCamera) {
        super.preDraw(pGLState, pCamera);
        pGLState.enableDither();
    }
};
Key element is pGLState.enableDither();. You will not need anything else but in case you want to ensure 32bit rendering for the surface and activity you can add:
@Override
protected void onSetContentView() {
    mRenderSurfaceView = new RenderSurfaceView(this);
    mRenderSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 24, 0);
    mRenderSurfaceView.setRenderer(mEngine, this);
    mRenderSurfaceView.getHolder().setFormat(PixelFormat.RGBA_8888);

    this.setContentView(mRenderSurfaceView, BaseGameActivity.createSurfaceViewLayoutParams());
}


@Override
public void onAttachedToWindow() {
    super.onAttachedToWindow();
    Window window = getWindow();
    window.setFormat(PixelFormat.RGBA_8888);
}




你可能感兴趣的:(AndEngine:关于Texture质量问题 和 Gradient背景)