Войти
ПрограммированиеФорумГрафика

выравнивание текстуры GL_NEAREST по UV координатам в формате GLubyte

Страницы: 1 2 Следующая »
#0
10:57, 14 мар. 2017

Привет всем!

GLfloat | выравнивание текстуры GL_NEAREST по UV координатам в формате GLubyte На первой картинке исходный вид объекта с UV координатами GLfloat. Настройки текстуры обычные:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture.w, texture.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture.data);
glGenerateMipmap(GL_TEXTURE_2D);

Заморочился (в OpenGL core 3.3) сэкономить графическую память поменяв в буфере UV координаты вершин с float на GLubyte. По результату экономится по три байта на каждую вершину [sizeof(float) = 4]. Но текстура стала вырезаться из текстурной карты со сдвигом:

GLubyte | выравнивание текстуры GL_NEAREST по UV координатам в формате GLubyte

У меня подозрение, что проблема в том, что OpenGL перед тем как отрендерить картинку тупо конвертирует UV координаты из буфера в float (с погрешностями). Кто-нибудь знает, это как-то лечится или нет?


#1
11:01, 14 мар. 2017

bigov
А точности то хватает? Текстура не больше 256 пикселей в ширину/высоту?
И давай код, как ты у себя конвертируешь в Byte текстурные координаты.

#2
11:11, 14 мар. 2017

MrShoor
> Текстура не больше 256 пикселей в ширину/высоту?
Текстура может быть любого размера, но точность координат будет 1/256 от ее размера.

bigov
> тупо конвертирует UV координаты из буфера в float (с погрешностями)
Они до конверсии уже с погрешностями.

#3
11:13, 14 мар. 2017

Текстура 512х512 (пробовал 256х256) - результат похожий.  Конвертирую так:

// размерность текстурной карты (8х8)
GLubyte texture_scale = 8;
// шаг сетки текстуры по-умолчанию = 256/8
GLubyte tS = 32;

//Опорная точка:
U1 =   static_cast<GLubyte>((номер_текстуры % texture_scale) * tS)
V1 =   static_cast<GLubyte>((номер_текстуры / texture_scale) * tS))

на выходе (в отладчике) смотрел - корректные пары координат. Например: 0,0; 32,0; 32,32; 0,32.

Если поправить так: 0,0; 31,0; 31,31; 0,31, то вместо захвата соседней текстуры обрезается часть текущей.

#4
11:15, 14 мар. 2017

Так какое решение - только подгонять(уменьшать) размеры текстурной карты?

#5
11:25, 14 мар. 2017

bigov
Byte превращается во флоат как-то так:
TexCoord / 255.0
то есть 255 превратится в 1.0
Твой же код рассчитывает на то, что 256 будет сконвертировано в 1.0
Отсюда и смещение. Попробуй сделать после своего кода:
U1 = Trunc(U1/256.0*255.0);
V1 = Trunc(V1/256.0*255.0);
Это все для текстуры в 256 пикселей. Для текстуры в 512 пикселей с байтом уже ничего не выйдет, но можно использовать word аналогичным образом.

#6
11:28, 14 мар. 2017

Точно, блин, 256 - это же первый разряд ВТОРОГО байта!
Спасибо. Попробую в течении дня, сразу отпишусь.

#7
16:04, 14 мар. 2017

MrShoor
> 255 превратится в 1.0

Нет, все фигня. Не вырезает по границе между пикселями, как при GLfloat. По крайней мере на текстурной карте 256x256. Я вручную создавал массивы координат для текстуры размером от 4 до 50 пикселей с вырезанием фрагмента от опорной точки (0,0) и от точки (255,255) в "обратную сторону". Ни разу граница фрагмента не попала точно между писелями исходной картинки.

Так что точно вырезать текстурный фрагмент с фильтром glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) при использовании UV координат с типом GLubyte технически невозможно (для текстурной карты 265x256).

#8
16:14, 14 мар. 2017

bigov
> при использовании UV координат с типом GLubyte технически невозможно (для текстурной карты 265x256)
GL_HALF_FLOAT ?

#9
16:21, 14 мар. 2017

bigov
> Заморочился (в OpenGL core 3.3) сэкономить графическую память поменяв в буфере
> UV координаты вершин с float на GLubyte. По результату экономится по три байта
> на каждую вершину [sizeof(float) = 4].

Экономия на спичках. Попробуй short

#10
21:44, 14 мар. 2017

bigov
> Нет, все фигня. Не вырезает по границе между пикселями, как при GLfloat. По
> крайней мере на текстурной карте 256x256.
Ну тогда фиг знает. Смотреть надо что там происходит. Скорее всего у тебя где-то ошибка. Я вполне себе с помощью byte адресовал пиксели на 256*256 текстуре, и у меня все работало.

#11
3:09, 15 мар. 2017

Andrey
>GL_HALF_FLOAT
Я тоже пока смотрю в эту сторону. Немного напрягает отсутствие аналогичного базового типа в С++, надо подбирать реализацию или рисовать свой вариант.

#12
3:21, 15 мар. 2017

MrShoor

> где-то ошибка.
Ерунда, там негде ошибаться - один массив, одна команда заполнения буфера и пару строчек настройки фильтров. Возми минимальный исходный код урока с текстурой из любого учебника и проверь.

> с помощью byte адресовал пиксели на 256*256 текстуре
возможно НЕ с фильтром  "GL_TEXTURE_MAG_FILTER, GL_NEAREST" а со сглаживанием.

Всем спасибо за участие в обсуждении.

#13
3:28, 15 мар. 2017

bigov
> возможно НЕ с фильтром  "GL_TEXTURE_MAG_FILTER, GL_NEAREST" а со сглаживанием.
С мультисемплингом чтоль? Так оно решается centroid интерполяцией, но у тебя не эта проблема, т.к. текстура уехала больше чем на 1 пиксель.

bigov
> Возми минимальный исходный код урока с текстурой из любого учебника и проверь.
Давай лучше ты выложишь минимальный пример с багом сюда?

#14
4:12, 15 мар. 2017

MrShoor
> Давай лучше ты выложишь

Извиняюсь за наглость. Спасибо за предложение, что есть желание продолжить. Я чуть позже подготовлю - вместе посмотрим.

Страницы: 1 2 Следующая »
ПрограммированиеФорумГрафика

Тема в архиве.