Як визначити, які формати текстур OpenGL підтримуються вперше?


10

Наприклад, як визначити, якщо моя відеокарта не підтримує "bgr8" і перетворити її в інший формат, наприклад "rgba8" в програмному режимі.

ОНОВЛЕННЯ: Вибачте за плутанину. Це питання більше про ситуацію , коли я встановив internalFormat в glTexImage2D на що - щось на зразок «bgra8» , але відеодрайвера внутрішньо перетворити дані в інший формат, наприклад «rgba8».

Відповіді:


11

Здається, ваше запитання плутає певні поняття, тож давайте взяти речі зверху. Це визначення функції glTexImage2D:

void glTexImage2D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, void *data );

Є дві речі, які можна назвати "формати текстур". Перший - internalformatпараметр. Це справжній формат зображення, коли OpenGL зберігає його. formatПараметр описує частину формату піксельних даних ви забезпечуєте з dataпараметром.

Інакше кажучи, formatі typeвизначте, як виглядають ваші дані. internalformatце те, як ви говорите OpenGL зберігати свої дані. Зателефонуємо formatі type"формат передачі пікселів", тоді як internalformatбуде "формат зображення".

Формат зображення текстури ніколи не може бути "bgr8". Не існує переліку переліку форматів зображень GL_BGR8. Там є GL_BGR перерахування, але це для формату передачі пікселів, а неформат зображення.

Або кажучи інакше, ваші піксельні дані, які ви даєте OpenGL, можуть зберігатися в порядку BGR. Але реалізація OpenGL сама вирішує, як насправді зберігати дані пікселя. Можливо, він зберігає його в малопомітному порядку. Можливо, він зберігає його великим ендіаном. Можливо, це просто довільно переставляє байти. Ви не знаєте, і OpenGL не дає способу дізнатися.

Немає можливості сказати, чи відповідає певний набір параметрів формату передачі пікселів тим, як реалізація OpenGL буде зберігати їх у форматі зображення.

Є спосіб сказати зараз. І під "зараз" я маю на увазі під OpenGL 4.3 та / або ARB_internalformat_query2. Підхід до відеокарти поблизу:

GLenum format, type;
glGetInternalformativ(texture_target, GL_RGBA8, GL_TEXTURE_IMAGE_FORMAT, 1, &format);
glGetInternalformativ(texture_target, GL_RGBA8, GL_TEXTURE_IMAGE_TYPE, 1, &type);

formatа typeтепер надайте перевагу реалізації formatта typeдля використання glTex(Sub)Imageдзвінків до GL_RGBA8зображень. Є окремі formatі typeзапити для glReadPixelsзавантаження.

Є інші запити , які ви можете зробити .

Якщо у вас немає доступу до них, ви можете використовувати деякі загальні правила, яких дотримується більшість апаратних засобів:

  • буде зберігати дані пікселів для 8-бітних даних на канал у порядку BGRA. Отже, якщо ви хочете відповідати формат вашим піксельним даним, щоб швидше завантажувати текстурні дані, ви хочете використовувати GL_BGRAдля formatі GL_UNSIGNED_INT_8888або GL_UNSIGNED_BYTEдля type.
  • насправді 24-бітні кольори не зберігатимуться як 24-бітні. Це завжди буде замінити їх на 32 біти; альфа буде просто ігноруватися, коли вона читає дані. Так що якщо ви хочете , щоб відповідати форматам, завжди використовувати GL_BGRA formatз GL_RGB8форматами зображень, навіть якщо ви повинні помістити фіктивні дані в альфа - компоненті.

4
Я також знайшов кращий формат GL_BGRA з внутрішнім Format GL_RGBA http.download.nvidia.com/developer/Papers/2005/…
KindDragon

Я б утримався від ребрендингу внутрішнього параметра "Формат" як "формат зображення", оскільки це однаково заплутано. Можливо, є сенс думати про "InternalFormat" як "формат текстурного пікселя". Комбінація параметрів "формат" і "тип" - це "формат пікселя джерела" (це часто зображення, звідси мій коментар). І, звичайно, є формат GPU, який є BGRA для цілих форматів типів.
StarShine

6

Як правило, більшість апаратних засобів не підтримує 3-компонентні формати текстури, тому в цьому конкретному прикладі ви можете зробити досить безпечне припущення, що воно перетворене. 3-складова текстура OpenGL насправді є 4-компонентною апаратною базою, але альфа-компонент ігнорується / встановлюється на 255 / що завгодно.

https://www.khronos.org/opengl/wiki/Common_Mistakes#Texture_upload_and_pixel_reads (Ця сторінка "поширених помилок" - це золота мина - додайте закладку зараз!)

Для більш загального випадку продуктивність glTexSubImage2D може дати точну інформацію про те, чи потрібно завантаження проходити шлях перетворення програмного забезпечення. Ви будете робити це під час запуску програми - просто створіть порожню текстуру (через glTexImage2D з даними NULL), а потім випустіть купу викликів glTexSubImage2D, за якими слідує GLFinish, щоб переконатися, що вона завершується. Ігноруйте перше, тому що кеші / стани / тощо встановлюються для нього, а час інший час. Повторіть це для кількох різних форматів і виберіть найшвидший.

Інша альтернатива - бачити, як ви помітили це питання "Windows", - це створити пристрій D3D при запуску (відразу після створення вікна, але перед тим, як ви вступите в OpenGL), потім використовуйте D3D для перевірки підтримки підтримки формату. Хоча OpenGL дозволяє конвертувати програмне забезпечення у дійсний внутрішній формат, D3D не робить - якщо це не підтримується обладнанням, ви не можете цього зробити. Потім знищити D3D і вивести OpenGL. (Ця методика також може бути використана для запиту інших речей, за якими OpenGL не дає вам запиту безпосередньо).

Це фактично корисне правило, щоб пересвідчитись, що ви робите в OpenGL з документацією на D3D. Якщо D3D не може щось зробити, це може бути хорошим свідченням того, що щось, про що йдеться, не підтримується апаратно. Не завжди правда, але корисне стартове місце.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.