Название: Прогрессия Отправлено: Авварон от Май 19, 2018, 22:25 Возникла для самообразования задачка. Вот, допустим, у нас есть картинка, 13*13 пикселей с мипмапами (т.е. серия картинок 13*13, 6*6, 3*3, 1*1).
И хотим мы просуммировать, допустим, ширины - 13+6+3+1 = 23. Понятно, что можно сделать это циклом за O(levels), где levels - кол-во мипмапов (4 в данном примере). А можно ли за линейное время? Пффф, это же убывающая геометрическая прогрессия (https://ru.wikipedia.org/wiki/Геометрическая_прогрессия), подумал я. Для неё есть формула суммы - b1*(1 - q^n) / (1 - q). Немного мат. преобразований и получаем такую формулу: Код: int sum(int width, int levels) Внимание вопрос, а как же получить "неточную" (с учетом округлений) сумму? Название: Re: Прогрессия Отправлено: Igors от Май 20, 2018, 07:30 И хотим мы просуммировать, допустим, ширины - 13+6+3+1 = 23. А что это за суммирование, в чем его смысл?Название: Re: Прогрессия Отправлено: Авварон от Май 20, 2018, 10:20 Хороший вопрос, изначально я хотел высчитать offset N-й мипмапы, т.е.
Код: Σ(level) bytesPerImage(std::max(width >> level, 1), std::max<(height >> level, 1)) где bytesPerImage: Код: qsizetype bytesPerImage(w, h) { h * ((w * bitsPerPixel(format) + 31) >> 5) << 2} Название: Re: Прогрессия Отправлено: Igors от Май 21, 2018, 08:46 изначально я хотел высчитать offset N-й мипмапы, т.е. Все равно не дошло. Возможно Вы хотели просто посчитать масштаб(ы) чтобы переводить x,y пикселя из оригинальной текстуры в одну из уменьшенных MIP'ов. Ну степени двойки этот масштаб никак не равен и должен быть флоат. Но он не зависит от переводимого пикселя, просчитать (в цикле) один раз и кешировать. Название: Re: Прогрессия Отправлено: qate от Май 21, 2018, 10:08 А если хранить размеры картинок степени двойки сразу ?
Название: Re: Прогрессия Отправлено: Авварон от Май 21, 2018, 13:21 изначально я хотел высчитать offset N-й мипмапы, т.е. Все равно не дошло. Возможно Вы хотели просто посчитать масштаб(ы) чтобы переводить x,y пикселя из оригинальной текстуры в одну из уменьшенных MIP'ов. Ну степени двойки этот масштаб никак не равен и должен быть флоат. Но он не зависит от переводимого пикселя, просчитать (в цикле) один раз и кешировать. мне нужно что-то типа uchar *pos = data + mipmapOffset(level) + bytesPerLine(level) * y + x; Ну да, пока просто просчитал в цикле и закешировал результаты. Как я понимаю, хитрую формулу написать не получится (ведь оффсет - это уже не прогрессия, а комбинация арифм и геом прогрессий)? Название: Re: Прогрессия Отправлено: Igors от Май 22, 2018, 13:12 мне нужно что-то типа uchar *pos = data + mipmapOffset(level) + bytesPerLine(level) * y + x; Если мы мапируемся в одну из MIP, то один пиксель (куда попали) не имеет смысла, нужны его коодинаты обязательно в флотах чтобы интерполировать значение с учетом соседних пыкселей (часто bilinear)Название: Re: Прогрессия Отправлено: Авварон от Май 22, 2018, 14:28 Если мы мапируемся в одну из MIP, то один пиксель (куда попали) не имеет смысла, нужны его коодинаты обязательно в флотах чтобы интерполировать значение с учетом соседних пыкселей (часто bilinear) Это всё очень интересно, но у меня файлики с текстурами, там нет флоатов и не надо ничо "ынтерполировать". Мипмапа либо есть (и ее "пыксели" целочисленны), либо её нет, и тут уже ОГЛ будет разбираться что и как интерполировать. Так-то да, попиксельный доступ особо не нужен, но хочется иметь метод типа scanLine(int y) для того, чтобы ворочать не здоровенным куском данных, а хотя бы построчно. Название: Re: Прогрессия Отправлено: Igors от Май 22, 2018, 14:36 и тут уже ОГЛ будет разбираться что и как интерполировать. Кстати он умеет сам создавать MIPы на ходуТак-то да, попиксельный доступ особо не нужен, но хочется иметь метод типа scanLine(int y) для того, чтобы ворочать не здоровенным куском данных, а хотя бы построчно. Не знаю чего Вы хотите добиться. В софтверных реализациях текстура обычно подгружается страницами, вытесняются обычным LRU. В любом случае нужно знать "область интереса" (интересующее место в MIP)Название: Re: Прогрессия Отправлено: Авварон от Май 22, 2018, 14:51 Не знаю чего Вы хотите добиться. В софтверных реализациях текстура обычно подгружается страницами, вытесняются обычным LRU. В любом случае нужно знать "область интереса" (интересующее место в MIP) Считать текстуру из файлика. Понятно, что можно сделать типа memcpy(file.readAll().data(), buffer, file.size()) (за вычетом хедера), но хочется читать мипмапы построчно, а не загружать весь файл в память. Название: Re: Прогрессия Отправлено: Авварон от Май 22, 2018, 15:09 Да даже ладно, фиг с ним с построчным доступом, всё равно надо посчитать оффсет мипмапы, чтобы знать, куда грузить кусок данных
|