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

本文介绍如何通过启用抖动(dithering)来改善AndEngine中纹理的质量,特别是针对梯度背景出现的颜色带状问题。提供了两种方法:一是针对特定实体启用抖动;二是通过引擎选项全局启用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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)
Picture
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.
Picture
        Gradient image without dithering.
Picture
             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);
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小涵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值