2014-09-11 1 views
3

В моей Android App, который игру в OpenGL ES 2.0, я включил 4 набора графических ресурсов, таких как такОграничения на размер текстуры OpenGL. Предоставление альтернативных ресурсов для конкретных устройств Android

  • ldpi
  • MDPI
  • ИПЧР
  • xhdpi

Теперь в моей папке xhdpi, самый большой актив у меня есть 2560 х 1838, как я таргетинг большие s (например, планшет Google Nexus 10, который получает свои ресурсы из папки XHDPI). До сих пор все работает на устройствах, на которых я проверил (Google Nexus 10, Samsung Galaxy S3, S4 & S5, Nexus 4 & 5 и т.д. и т.п ....)

Я недавно слышал от пользователь, столкнувшийся с проблемами при работе с телефоном HTC One X + (я считаю, что есть другие причины для этого, кроме того, о котором я говорю, поэтому у меня есть отдельный вопрос, открытый для других вопросов).

Дело в том, что в соответствии с: this максимальный размер текстуры для этого телефона составляет 2048x2048, но в соответствии с this этот телефон получает свои ресурсы из папки XHDPI. .

Таким образом, это не будет отображать текстуры из этого атласа (это атлас происхождения, содержащего 6 отдельных фонов 1280 * 612

Теперь у меня есть два варианта, которые я отдаю себе отчет, чтобы исправить это:

  • Уменьшения размера фонов. исключен, так как это может поставить под угрозу качества на устройствах большего экрана (например, связующие 10)

  • разделить на 2 атласы предпочел бы не делать это, как хотелось бы, чтобы все фоны в 1 атласе для оптимизации скорости загрузки (и только, чтобы держать вещи аккуратно)

Есть ли другие варианты? Могу ли я предоставить в подпапке xhdpi другую папку, которая соответствует лимитам 1X +? И если да, то как мне заставить устройство захватывать ресурсы оттуда?

Я делаю это слепое, так как у меня нет 1X +, чтобы проверить это, но из того, что я прочитал, я считаю, что активы, большие, чем 2048 x 2048, вызовут проблемы на этом устройстве.

Это мой код для нанесения текстур:

public static int LoadTexture(GLSurfaceView view, Bitmap imgTex){ 

    //Array for texture 
    int textures[] = new int[1]; 
    try { 
     //texture name 
     GLES20.glGenTextures(1, textures, 0); 
     //Bind textures 
     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]); 
     //Set parameters for texture 
     GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 
     GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); 

     //Apply texture 
     GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, imgTex, 0); 

     //clamp texture 
     GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,GLES20.GL_CLAMP_TO_EDGE); 
     GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,GLES20.GL_CLAMP_TO_EDGE); 

    } catch (Exception e){ 

    } 
    //Increase texture count 
    textureCount++; 
    //Return texture 
    return textures[0]; 
} 

ответ

2

Если вы не знаете, если текстура нагрузка будет работать, вы можете делать все те же операции, за исключением использования GL_PROXY_TEXTURE_2D (или 1D, 3D и т.д. .) вместо GL_TEXTURE_2D, чтобы проверить, будет ли загрузка работать для заданного размера и параметров текстуры. OpenGL пытается выполнить загрузку, и она установит все состояние текстуры на 0, если она не работает или есть другая проблема в параметре текстуры. Затем, если сбой текстурной нагрузки (в вашем случае из-за слишком большого изображения), ваша программа загружает меньшую масштабированную текстуру.

EDIT: Я использую iOS, и мой gl.h не включает GL_PROXY_TEXTURE_ *, и я не могу найти ссылку в OpenGL ES3 specification, поэтому я не уверен, что это сработает для вас с OpenGL.

В качестве альтернативы, получить максимальный размер текстуры (на измерение, например, ширина, высота или глубина) и загрузите подходящее изображение размера с помощью:

glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size); 

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

GLuint name; 
int width = 10000; // really bad width 
int height = 512; 
GLint size; 

glGenTextures(1, &name); 
glBindTexture(GL_TEXTURE_2D, name); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, 
      GL_RGBA, GL_UNSIGNED_BYTE, 0); 

GLenum error = glGetError(); 
if(error) { 
    printf("Failed!"); 
} 
else { 
    printf("Succeeded!"); 
} 
+0

Привет @MtRoad, у меня нет устройства, на котором, чтобы проверить это (ну, не тот, который имеет проблему), однако, я сделал быстрый поиск Google, и я не могу найти пример в любом месте о том, как использовать этот GL_PROXY_TEXTURE_ * D. Не могли бы вы отредактировать свой ответ, чтобы привести пример? Благодарю. Я отредактирую свой вопрос, чтобы включить код текстуры. – Zippy

+0

Да, я только что осуществил проверку, и я протестировал ее на текстуре, которая была (целенаправленно) слишком большой, и она подняла ошибку, возвращая «Invalid_value», чтобы эта часть обнаруживала, когда текстура слишком велика. Однако проблема в том, куда я иду? Как только это не удается, как мне получить код для загрузки меньшей версии текстуры из одной из моих других папок ресурсов? Я не могу найти эту информацию нигде! – Zippy

+0

Не имеет смысла использовать текстуры сверхвысокого качества на дисплеях с низким разрешением, поэтому вы можете сортировать свои текстурные качества как низкие, средние, хорошие, высокие, а не ldpi, mdpi, hdpi и xhdpi. Затем сохраняйте лучшие и все более качественные изображения в каждой папке (низко в ldpi, low/med в mdpi, low/med/good в hdpi и т. Д.), А затем выберите лучшую текстуру, заданную GL_MAX_TEXTURE_SIZE. Или вы можете уменьшить размер текстуры перед загрузкой в ​​OpenGL. – MtRoad