iOS: сглаживание с помощью OpenGL, но не с Cocos2D?

#iphone #ios #opengl-es #cocos2d-iphone #antialiasing

#iPhone #iOS #opengl-es #cocos2d-iphone #сглаживание

Вопрос:

Я новичок в программировании на opengl, но я делаю что-то очень простое, и разница в качестве между пользовательским кодом opengl и cocos2d огромна!

Я пытаюсь просто загрузить изображение и непрерывно поворачивать его каждый кадр. В моем коде я получаю много мерцающих, острых краев, в то время как в cocos2d все красиво и гладко. Я настроил 4-кратное сглаживание с несколькими выборками, используя в своем коде рекомендуемый apple код для iOS 4, и все же он выглядит очень плохо по сравнению с cocos2d без какого-либо MSAA.

Вы можете увидеть различия здесь: пользовательский код opengl (с MSAA): пользовательский код opengl

cocos2D (без MSAA): cocos2d

Кто-нибудь знает, чего мне не хватает, чтобы добиться такой плавной графики? Просмотрев код cocos2d, я нашел несколько ссылок, которые связывали сглаживание с GL_LINEAR. Я добавил параметры GL_LINEAR к своим текстурам точно так же, как cocos, но это все равно выглядит одинаково плохо.

Комментарии:

1. Просто из интереса, вы изучаете OpenGL из любопытства, или есть что-то, что вы хотели бы сделать, чего не может Cocos2D?

2. @Danyal, я тоже изучаю OpenGL, но я хочу любой ценой избежать использования cocos2d и objective c из-за 1) проблем с переносимостью (избегая objective c, чтобы я мог перенести код на Android и, возможно, даже webgl) и 2) языкового барьера, который наложил бы на меня objective C. Я понимаю его основные концепции, но мне действительно не нравится, как это работает.

3. Спасибо @Waneck, как вы, вероятно, можете сказать, мне было интересно, стоит ли мне тоже это изучать! Кстати, вы видели Cocos2d-x? Это версия Cocos2d на C с портом Android. Но я думаю, что это не будет без ошибок, зависящих от платформы.

Ответ №1:

Сглаживание делает именно то, что указано в названии: оно предотвращает использование примитивами псевдонимов, таких как прямая (диагональная) линия, превращающаяся в лестницу. Поскольку сглаживание обычно приводит к «мягким» краям, этот термин иногда используется для применения к любому алгоритмическому «смягчению», но это неправильно.

Предполагая, что ваша исходная текстура уже содержит некоторое сглаживание для отображения изогнутых краев вашего автомобиля в пиксельной сетке (так что, если вы откроете исходный PNG или что-то еще в художественной программе и увеличите масштаб по краям, вы увидите некоторую мягкость), я думаю, что в вашем коде не удается применить мультисэмплингпо какой-либо причине. Если вы увеличите масштаб и посмотрите на верхний край крыши, то обратите внимание на переход между самой верхней частью первого шага справа и слева от него. Резкий темный цвет вверху просто самопроизвольно увеличивает пиксель. Это свидетельствует о том, что этот край находится в исходной текстуре и копируется попиксельно. пиксель за пикселем.

GL_LINEAR является ли параметр фильтрации, который влияет на то, как OpenGL отвечает на такие вопросы, как «если исходный пиксель при (0, 0) имеет один цвет, а при (0, 1) — другой, то какой цвет имеет (0, 0,5)?» Если вы применяете линейную фильтрацию, то при масштабировании текстуры выше ее собственногоразмер дополнительные пиксели, которые должен изобрести OpenGL, будут созданы с использованием линейной комбинации ближайших исходных пикселей. Если бы вы использовали GL_NEAREST тогда, это был бы цвет любого ближайшего исходного пикселя. Так вот в чем разница между текстурами, которые масштабируются, чтобы выглядеть размытыми и низкоконтрастными, и текстурами, которые масштабируются, чтобы выглядеть как мозаика с очевидными пикселями. Таким образом, это (обычно) добавляет размытости и мягкости изображению в целом, но на самом деле не имеет ничего общего со сглаживанием.

Что касается того, почему вы не получаете сглаживание, на ум приходят две возможные причины. Возможно, у вас какая-то ошибка в коде или вы просто используете алгоритм, отличный от Cocos2D. Аппаратная поддержка мультисэмплинга от Apple появилась только в iOS 4, а Cocos2D предшествует этому, поэтому so может придерживаться «программного» метода (в частности, рендеринга всей сцены попиксельно в 4-кратном размере, а затем заставить графический процессор уменьшить его масштаб). Последнее было бы значительно медленнее, но помешало бы аппаратным средствам пытаться оптимизировать процесс. Одна из оптимизаций, которую иногда применяют некоторые аппаратные средства, заключается в том, чтобы использовать многовыборку только на краях геометрии (приблизительно). Это, очевидно, не принесет вам никакой пользы.

Другая возможность заключается в том, что вы уменьшаете масштаб изображения при рисовании (хотя это не похоже), и Cocos2D генерирует mip-карты, тогда как вы этого не делаете. Карты Mip предварительно вычисляют определенные масштабы изображения и работают оттуда при выводе на экран. Выполнение этого таким образом позволяет применять более дорогой алгоритм и, как правило, приводит к меньшему сглаживанию.

Можете ли вы опубликовать какой-нибудь код?

Комментарии:

1. Привет, Томми! Большое вам спасибо за ваш подробный ответ. Я действительно ценю это, и я добавлю код позже сегодня, когда вернусь с работы. На данный момент я могу сказать, что размер текстур такой же, как они отображаются на экране, поэтому я не думаю, что это проблема с отображением mip. Что касается программного режима, это действительно может быть, хотя я не смог найти никаких ссылок на него в исходном коде cocos2d. Я опубликую код, когда вернусь домой! Большое вам спасибо!

2. Томми, похоже, проблема действительно была с GL_LINEAR! Позже я повторно связывал текстуру с помощью GL_NEAREST! Ого! Это имеет такое большое значение! Большое вам спасибо!