Сохраните самые большие значения из источника и места назначения (побитовое ИЛИ) в OpenGL ES 2.0 - PullRequest
1 голос
/ 05 января 2012

позвольте мне немного объяснить название.В кадровом буфере у меня есть некоторые значения цвета (для простоты я собираюсь сослаться только на один канал цвета в двоичном формате, например, 00000001 в определенном пикселе).Затем в этом конкретном значении я собираюсь написать новое значение.OpenGL должен проверить входящее значение и значение, которое уже существует в этом пикселе, и сохранить максимум обоих.Другими словами, я хочу, чтобы он выполнял BITWISE OR между входящим и существующим значением.Таким образом, если существующее значение равно 00000001, а входящее - 00000010, то результат должен быть 00000011.

В OpenGL ES 1.1, я думаю, этого легко достичь с помощью функции glLogicOp (http://www.opengl.org/sdk/docs/man/xhtml/glLogicOp.xml). Но это НЕ поддерживаетсяв OpenGL ES 2.0 (ПОЧЕМУ, ПОЧЕМУ, ПОЧЕМУ они удалили его ?? :(), и я не могу придумать функцию смешивания, которая может достичь аналогичного результата (я думаю, что это невозможно при смешивании). Должен ли я использовать буфер трафарета или другой приемдля достижения моей цели?

Можете ли вы описать шаги для этого?

PS Я знаю, что все возможно с помощью шейдеров, но это потребует огромных усилий для реализации сейчас. Если этоЕдинственное решение, пожалуйста, дайте мне указания для этого подхода.

Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 06 января 2012

Должен признать, что в моем вопросе было не так ясно. В любом случае, я уточню проблему и представлю решение здесь.

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

Итак, я закрашиваю формы с помощью, скажем, неких цветовых идентификаторов. Я работаю на двоичном уровне: первая фигура на экране имеет идентификатор цвета 00000001, вторая фигура имеет идентификатор 00000010 и так далее. Таким образом, с байтом (скажем, в красном канале) я могу хранить до 8 разных цветовых идентификаторов. Максимальное количество фигур - 32, если я использую формат RGBA8888.

Алгоритм, который я первоначально разработал, заключался в смешении исходного идентификатора цвета с конечным идентификатором цвета с помощью glBlendFunc (GL_ONE, GL_ONE), и все, казалось, работало нормально. Так что если коснулся пиксель с цветом 00010101, то это означало, что были затронуты первая, третья и пятая формы. НО, есть некоторые невыпуклые формы (если это правильное слово для сворачивания фигур), которые могут быть созданы пользователем. В этом случае, если фигура с цветным идентификатором 00000001 сложена пользователем, то перекрывающиеся пиксели получат идентификатор 00000010, потому что форма записывает 00000001, когда она сначала рисуется в буфере кадров, а затем перекрывающиеся пиксели той же формы добавляют еще 00000001 из-за для смешивания.

Итак, если каким-то образом я смогу сделать BITWISE ИЛИ (НЕ логично, как я изначально упоминал в своем вопросе) между идентификаторами цветов, которые были записаны в кадровом буфере, тогда проблема будет решена. Действительно, это имеет место в OpenGL ES 1.1 с использованием функции glLogicOp (GL_OR). К сожалению, это не доступно в OpenGL ES 2.0, и снова должен быть создан один шейдер, еще один проход и т. Д., Который я считаю излишним и сложным в обслуживании.

Решение для OpenGL ES 2.0 таково:

  1. Очистить цвет RenderTexture B до glClearColor (0,0,0,0)
  2. ДЛЯ каждой формы
  3. Очистить цвет Rendertexture A до glClearColor (0,0,0,0)
  4. Нарисуйте фигуру на Rendertexture A, используя фрагментный шейдер, который в качестве цвета пишет его идентификатор цвета.
  5. Смешайте с GL_ONE, GL_ONE Rendertexture A с содержимым Rendertexture B
  6. КОНЕЦ ДЛЯ
  7. RenderTexture B содержит всю необходимую нам информацию.
  8. Когда пользователь касается экрана, сэмплируйте соответствующий пиксель из RenderTexture B, используя glReadPixel, и выясните из двоичного кода коснувшиеся формы.

Лучший

0 голосов
/ 06 января 2012

@ Вызов, извините, если я добавлю дополнительный ответ вместо комментария, у меня недостаточно репутации, чтобы оставлять комментарии.

В любом случае:

Пункт 1: Я уверен, что на 100% вы не можете выполнять побитовое или / и / сдвиг в шейдерах, так как мне пришлось испортить около 2 недель программирования для этого упущения в прошлом месяце. :):)

Пункт 2: Посмотрите на эту статью в Википедии о GLSL (раздел Операторы):

Битовые операторы были добавлены в версии 1.30.

а. Если вы попытаетесь добавить #version 130 в свой шейдер, они не скомпилируются. B. Если вы попытаетесь добавить побитовую операцию, такую ​​как A & B (обратите внимание на одиночный &), A | B, A << 2, B >> 2 и т. Д., Он не будет компилироваться.

Читая, на разных книгах / форумах / SDK, я нашел одно и то же подтверждение.

Я надеюсь избежать той же головной боли, которая у меня была по этому вопросу.

Маурицио Бенедетти

0 голосов
/ 05 января 2012

Я думаю, вам придется использовать шейдер для этого.

1) Создайте две renderTargets [2], которые будут использоваться для обмена с swapIndex.

2) Выполните рендеринг одной renderTarget [swapIndex] и используйте другую renderTarget [1-swapIndex] в качестве эталонной текстуры, из которой вы будете брать образцы в своем GLSL-шейдере.

3) В фрагментном шейдере (он же пиксельный) вы должны сделать выборку из вашей текстуры (он же renderTarget [1-swapIndex]) и установить для gl_FragColor значение max (texture, someColor).

4) Переверните swapIndex {swapIndex = 1-swapIndex;} и начните заново.

...