Проблемы с GLUtils.texImage2D и Alpha в текстурах - PullRequest
5 голосов
/ 13 октября 2010

Я успешно генерирую свои текстуры, используя GLUtils.texImage2D, но когда я использую сгенерированные текстуры, у меня возникают проблемы с альфа: они темнее, чем хотелось.

проверив несколько вещей, я, наконец, пришел к выводу, что проблема исходит от GLUtils.texImage2D (GL10.GL_TEXTURE_2D, level, BMP, 0);

Я создал вторую функцию, которая использует gl.glTexImage2D (GL10.GL_TEXTURE_2D, уровень, GL10.GL_RGBA, ширина, высота, 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, пикселей2);

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

Кто-нибудь это заметил? и если да, то как ты решил это ...

Джейсон


Спасибо за ваш ответ, Я уже использую

gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);

и я получаю эту проблему

Моя проблема в том, что альфа, сгенерированная GLUtils, не является текстурой, она темнее.

Разница в том, как смотреть на цвет на солнце и в тени (если это имеет смысл).

Я уже пробовал gl.gltextimage2d, но создание буфера занимает слишком много времени, если только не существует инструмента для преобразования растрового изображения в байтовый буфер, о котором я не знаю ...

Ответы [ 5 ]

5 голосов
/ 20 ноября 2010

GLUtils.texImage2D генерирует предварительно умноженную альфа-текстуру.В этой сгенерированной текстуре все пиксели умножаются на альфа-значение, поэтому вам не нужно снова умножать альфа-значение.Давайте попробуем

gl.glBlendFunc (GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);

3 голосов
/ 06 ноября 2013

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

В конструкторе SurfaceView

    setEGLConfigChooser(8, 8, 8, 8, 0, 0); 
    getHolder().setFormat(PixelFormat.RGBA_8888); 

В View.Renderer onSurfaceCreated

    gl.glEnable(GL10.GL_BLEND); 
    gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA); 
3 голосов
/ 27 сентября 2011

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

  • Оцените вашу самую большую текстуру (например, 1024x1024) и создайте массив int такого размера (1024 * 1024), который вы сохраните в некоторой статической переменной или где-нибудь, где вы сможете получить к ней доступ, чтобы вам не нужно было воссоздавать этот массив (время выделения здесь драгоценно)

  • затем сделайте это:

    bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
    gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, width, height, 
         0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, IntBuffer.wrap(pixels));
    

Я сожалею, что не нашел другого решения ... оригинальная проблема заключается в том, что разработчик функции GLUtils.texImage2D неправильно обработал альфа-канал, что приводит к появлению черных границ, когда изображение отображается больше, чем оно есть ( Билинейный фильтр вычисляет цвет между четырьмя пикселями, и когда значения rgb пикселей с прозрачными альфа-изображениями искажены (например, установлены в черный цвет), в результате возникает некое «цветное кровотечение» над прозрачной границей, которое формируется там. Очень некрасиво. Может быть, это было сделано для улучшения степени сжатия, поскольку значения RGB в альфа-прозрачных областях в PSD содержат много мусора, что при устранении дает много возможностей для улучшения алгоритмов сжатия)

Редактировать: К сожалению, этот подход правильно работал только для серых изображений, так как красный и синий каналы меняются местами при получении пикселей из растрового изображения. По крайней мере, на МОЕМ устройстве. Я не уверен, насколько это правильно для других устройств, но в моем случае это помогло:

for (int i=0;i<pixels.length;i+=1) {
    int argb = pixels[i];
    pixels[i] = argb&0xff00ff00 | ((argb&0xff)<<16) | ((argb>>16)&0xff);
}
1 голос
/ 31 августа 2012

Android Bitmap хранит изображения, загруженные из PNG, с предварительно умноженными цветами.GLUtils.texImage2D также использует цвета, предварительно умноженные на альфа, поэтому вы не можете получить оригинальные цвета таким образом.

Для загрузки изображений PNG без предварительного умножения RGB каналов я использую стороннюю PNGDecoder и загрузить текстуру с помощью glTexImage2D.Вы можете получить PNGDecoder библиотеку для декодирования PNG отсюда: http://twl.l33tlabs.org/#downloads

0 голосов
/ 13 октября 2010

В GLUtils есть проблемы с предварительно умноженной альфой. Единственное, что я могу предложить, это использовать:

gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA)

Если вам нужны другие функции смешивания, вам придется использовать gl.glTexImage2D.

...