Пример спрайта из примера проекта AndEngine, выглядит пиксельным при импорте в мой собственный проект - PullRequest
2 голосов
/ 21 марта 2012

Я пробую AndEngine (GLES2) в последние пару дней. У меня проблема с SpriteExample из проекта примеров. В примере SpriteExample в примере проекта спрайт face_box.png выглядит красиво и четко. Однако, когда я копирую тот же код и файл face_box.png в свой отдельный проект, спрайт выглядит пиксельным.

Поскольку код все тот же, я думаю, проблема в некоторых настройках конфигурации, однако я не мог понять это.

Я работаю на Galaxy S2 с ICS.

Кто-нибудь знает, что может вызвать проблему?

Это код, если кому-то интересно -

public class AndEngineMapActivity extends SimpleBaseGameActivity implements OnClickListener {
// ===========================================================
// Constants
// ===========================================================

private static final int CAMERA_WIDTH = 800;
private static final int CAMERA_HEIGHT = 480;

// ===========================================================
// Fields
// ===========================================================

private ITexture mTexture;
private ITextureRegion mFaceTextureRegion;

// ===========================================================
// Constructors
// ===========================================================

// ===========================================================
// Getter & Setter
// ===========================================================

// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================

@Override
public EngineOptions onCreateEngineOptions() {
    final Camera camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);

    return new EngineOptions(true, ScreenOrientation.LANDSCAPE_SENSOR, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera);
}

@Override
public void onCreateResources() {
    try {
        this.mTexture = new BitmapTexture(this.getTextureManager(), new IInputStreamOpener() {
            @Override
            public InputStream open() throws IOException {
                return getAssets().open("gfx/face_box.png");
            }
        });

        this.mTexture.load();
        this.mFaceTextureRegion = TextureRegionFactory.extractFromTexture(this.mTexture);
    } catch (IOException e) {
        Debug.e(e);
    }
}

@Override
public Scene onCreateScene() {
    this.mEngine.registerUpdateHandler(new FPSLogger());

    final Scene scene = new Scene();
    scene.setBackground(new Background(0.09804f, 0.6274f, 0.8784f));

    /* Calculate the coordinates for the face, so its centered on the camera. */
    final float centerX = (CAMERA_WIDTH - this.mFaceTextureRegion.getWidth()) / 2;
    final float centerY = (CAMERA_HEIGHT - this.mFaceTextureRegion.getHeight()) / 2;

    /* Create the face and add it to the scene. */
    final Sprite face = new Sprite(centerX, centerY, this.mFaceTextureRegion, this.getVertexBufferObjectManager());
    scene.attachChild(face);

    return scene;
}

@Override
public void onClick(final ButtonSprite pButtonSprite, final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            Toast.makeText(AndEngineMapActivity.this, "Clicked", Toast.LENGTH_LONG).show();
        }
    });
}

// ===========================================================
// Methods
// ===========================================================

// ===========================================================
// Inner and Anonymous Classes
// ===========================================================

}

** Обновление: ** Следуя совету JoenEye, я попытался загрузить текстуру по-другому с помощью

@Override
public void onCreateResources() {
    try {
        this.mTexture = new BitmapTexture(this.getTextureManager(), new IInputStreamOpener() {
            @Override
            public InputStream open() throws IOException {
                return getAssets().open("gfx/face_box.png");
            }
        }, TextureOptions.BILINEAR_PREMULTIPLYALPHA);

        this.mTexture.load();
        this.mFaceTextureRegion = TextureRegionFactory.extractFromTexture(this.mTexture);
    } catch (IOException e) {
        Debug.e(e);
    }
}

Результаты улучшились, и изображение смайлика выглядит немного лучше, но оно по-прежнему не такое четкое, как в проекте примера.

**** Другое обновление: ****

Это изображения результатов, которые я получаю. - Это один из оригинального примера проекта (лучший результат) This is the one from the original example project (best result) Это один из моего проекта без TextureOptions.BILINEAR_PREMULTIPLYALPHA This is the one from my project without the TextureOptions.BILINEAR_PREMULTIPLYALPHA Это один из моего проекта с TextureOptions.BILINEAR_PREMULTIPLYALPHA (текущий результат This is the one from my project with the TextureOptions.BILINEAR_PREMULTIPLYALPHA (current result

Кстати - интересный результат, однажды я создал еще один пустой проект, в котором был только этот класс, и он работал безупречно и выглядел хорошо.

Так что я думаю, что это должна быть какая-то проблема с настройкой моего собственного проекта.

Я был бы рад получить больше идей!

Спасибо!

Ответы [ 3 ]

2 голосов
/ 27 марта 2012

Я предполагаю, что разница между примером проекта и проектом с плохим результатом заключается либо в расположении субпикселя спрайта, либо в незначительном растяжении / наклоне.Вы осторожны, чтобы нарисовать спрайт точно на границе пикселей?

Проблема в том, что фрагмент рисуется, если фрагмент не полностью выровнен с текстурой, которую он отбирает, тогда он должен генерировать цвет, который не совсем соответствует текстуре.Например, если у вас есть текстура 10x10 пикселей, и вы рисуете ее в координатах экрана (0,5, 0,5), то каждый пиксель должен либо просто выбрать ближайший тексель (NEAREST выборка), либо смешать близлежащие тексели (LINEAR)или BILINEAR выборка).NEAREST может иметь проблемы с округлением, если два текселя находятся на одинаковом расстоянии от точки выборки (что может объяснить немного некрасивое изображение в первом неверном результате).Если вы используете LINEAR сэмплирование, то оно просто смешивает самые близкие тексели, что может дать слегка размытое изображение, которое вы видите во втором результате.

Таким образом, чтобы исправить это для небольших изображений с крошечными элементами, вы всегда должны рисовать изображение так, чтобы оно выровнялось точно с границей пикселя.Можете ли вы проверить, делаете ли вы это в своем приложении?

Для получения дополнительной информации я бы сделал несколько поисков в Google по запросу "Пиксельная выборка / рендеринг", которые дадут вам больше информации.

РЕДАКТИРОВАТЬ, я также заметил это, что может объяснить:

final float centerX = (CAMERA_WIDTH - this.mFaceTextureRegion.getWidth()) / 2;
final float centerY = (CAMERA_HEIGHT - this.mFaceTextureRegion.getHeight()) / 2;

Вы делаете целочисленное деление здесь, что может привести к уменьшению значения 'center' на половинуpixel, если ширина / высота изображения является нечетным числом.Затем, когда вы передаете это значение в AndEngine, ваш центр неверен на полпикселя, что объясняет проблемы с субпикселями.

1 голос
/ 11 апреля 2012

В конце концов я решил просто открыть новый проект и перенести весь свой код в новый проект.

Работает.

Я знаю, что это плохое решение, но оно решило проблему.

Если я когда-нибудь снова возникну с этой проблемой и найду реальное решение, я бы обновил ее здесь.

1 голос
/ 23 марта 2012

Попробуйте использовать стандартный способ загрузки изображений, если метод, который вы используете, не нужен по какой-то причине.

mTexture = new BitmapTexture(1024, 512, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
BitmapTextureRegionFactory.createFromAsset(mTexture, this, "face_box.png", 0, 0);

Возможно, вы в конечном итоге будете использовать готовые текстуры, которые автоматически размещают изображения на текстуре, но этоможет помочь вам определить, где проблема.

...