Android OpenGL ES: Как вы выбираете 2D-объект?

Я искал вводный 2D-выбор в OpenGL ES в Stack Overflow. Я в основном вижу вопросы о 3D.

Я разрабатываю 2D-редактор уровня на Android 4.0.3 с использованием OpenGL ES. В редакторе уровня есть 2D, желтый, квадратный объект, размещенный в центре экрана. Все, что я хотел, – это обнаружить, был ли объект затронут пользователем.

Введите описание изображения здесь

В редакторе уровня не существует перекрытия плиток. Вместо этого они размещаются бок о бок, как два соседних пикселя в растровом изображении в MS Paint. Моя цель – индивидуально определить событие касания для каждого квадратного объекта в редакторе уровня.

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

Может ли кто-нибудь указать нам, как мне это нужно? Заранее спасибо.

РЕДАКТИРОВАТЬ:

Это функция draw() :

 public void draw(GL10 gl) { gl.glPushMatrix(); gl.glTranslatef(-(deltaX - translateX), (deltaY - translateY), 1f); gl.glColor4f(1f, 1f, 0f, 1f); //TODO: Move ClientState and MatrixStack outside of draw(). gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertices); gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 6); gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); gl.glPopMatrix(); } 

EDIT 2:

Я до сих пор не хватает информации. Вы используете камеру? Или нажатие других матриц перед рендерингом модели ?. Например, если вы используете орфографическую камеру, вы можете легко отобразить координаты экрана [x_screen, y_screen] следующим образом (y аналогично):

Я не использую камеру, но я, вероятно, использую орфографическую проекцию. Опять же, я не знаю, поскольку я просто использую общую функцию OpenGL. Я нажимаю и выталкиваю матрицы, потому что планирую интегрировать многие плитки (квадратные 2D-объекты) с разными матрицами переводов. Никакие две плитки не будут иметь одну и ту же матрицу перевода M.

Является ли перспективная проекция такой же, как орфографическая проекция, когда дело доходит до 2D? Я не вижу различий между ними.

Вот начальная настройка при создании поверхности (класс, расширяющий GLSurfaceView и реализующий GLSurfaceView.Renderer ):

 public void onSurfaceChanged(GL10 gl, int width, int height) { gl.glViewport(0, 0, width, height); } public void onSurfaceCreated(GL10 gl, EGLConfig arg1) { reset(); } public void onDrawFrame(GL10 gl) { clearScreen(gl); gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrthof(0f, super.getWidth(), 0f, super.getHeight(), 1, -1); gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); canvas.draw(gl); } private void clearScreen(GL10 gl) { gl.glClearColor(0.5f, 1f, 1f, 1f); gl.glClear(GL10.GL_COLOR_BUFFER_BIT); } 

Основным подходом было бы следующее:

  1. Определите ограничивающий прямоугольник для каждого «осязаемого» объекта. Это может быть только прямоугольник (x, y, ширина, высота).
  2. Когда вы обновляете плитку в мире, вы обновляете ее ограничивающий прямоугольник (полностью в мировых координатах).
  3. Когда пользователь прикасается к экрану, вам нужно не создавать экранные координаты для координат мира
  4. Проверьте, не пересекается ли непрозрачная точка с любым ограничивающим прямоугольником.

Некоторые намеки на предыдущие предметы. [Изменено]

  • 1 и 2. Вам следует отслеживать, где вы делаете свои плитки. Сохраните их положение и размер. Прямоугольник – удобная структура. В вашем примере это можно было бы вычислить следующим образом. И вы должны перепроверить его, когда меняются модели. Позволяет называть его Rectangle r:

     rx = yourTile.position.x -(deltaX - translateX) ry = yourTile.position.y -(deltaY - translateY) r.width= yourTile.width //as there is no model scaling r.height = yourTile.height// 
  • 3 – если вы используете орфографическую камеру, вы можете легко отобразить координаты экрана [x_screen, y_screen] следующим образом (y аналогично):

     x_model = ((x_screen/GL_viewport_width) -0.5 )*camera.WIDTH + Camera.position.x 
  • 4 – Для каждого из ваших прямоугольников проверьте, [x_model; Y_model] внутри.

[2nd Edit] Кстати, вы обновляете свои матрицы, вы можете подумать, что используете камеру с постингированием surfaceView.width () / 2, surfaceView.height () / 2. Вы сопоставляете 1 пиксель на экране с 1 единиц в мире, поэтому вам не нужно ничего проектировать. Вы можете заменить эти значения в моей формуле и получить x_screen = x_model – (вам нужно перевернуть Y-компонент сенсорного события из-за того, что Y растет вниз в Java и вверх в GL).

Заключительные слова. Если пользователь касается точки [x, y], проверьте, что [x, screenHeight-y] * попадает на некоторые из ваших прямоугольников, и вы закончили. Сделайте некоторые отладки, запишите трогательные точки и посмотрите, насколько они ожидаются. Создайте прямоугольники и посмотрите, соответствуют ли они тому, что вы видите на экране, а затем проверяете, находится ли точка внутри прямоугольника.

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

* Перевернутый я сказал вам. PS: придерживаться орфографической проекции (перспектива будет более сложной в использовании).

Пожалуйста, позвольте мне отправить второй ответ на ваш вопрос. Это полностью более высокий уровень / философский. Может быть, глупый, бесполезный ответ, но, надеюсь, это поможет кому-то новому в компьютерной графике изменить свое мнение на «графический режим».

Вы не можете выбрать треугольник на экране. Этот квадрат не является 2 треугольниками. Этот квадрат – всего лишь кучка желтых пикселей. OpenGL берет несколько вершин, соединяет их, обрабатывает их и окрашивает некоторые пиксели на экране. На одном этапе графического конвейера даже геометрическая информация теряется, и у вас только изолированные пиксели. Это аналогично письму, напечатанному принтером на бумаге. Обычно вы не обрабатываете информацию из бумаги (хорошо, возможно, читатель штрих-кода: D)

Если вам нужно дополнительно обработать ваши рисунки, вы должны смоделировать их и обработать их самостоятельно со вспомогательными структурами данных. Вот почему я предложил создать прямоугольник для моделирования ваших фрагментов. Вы создаете свой воображаемый «мир» объектов, а затем визуализируете их на экране. Пользователь touch-event не принадлежит к одному миру, поэтому вам нужно «перевести» экранные координаты в ваши мировые координаты. Затем вы меняете что-то в своем мире (может быть, пользователь тащит свой палец, и вам нужно переместить объект), и снова скажите OpenGL, чтобы отобразить ваш мир на экране.

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

Вы проверили LibGDX ?

Делает жизнь намного проще при работе с OpenGL ES.

Intereting Posts
Увеличить масштаб, уменьшить масштаб – javascript / jquery / jquery мобильные события для Интернета на платформе Android? Android: поддержание глобального состояния приложения Использование нескольких DotSpan в MaterialCalendarView Добавление XML-файла ресурсов в проект приводит к исключению среды выполнения Android: Сгенерированный QR-код с использованием Zxing имеет поля (не подходит для области) Как избежать четких уведомлений о завершении деятельности Ожидание ожидаемого намерения не будет работать после того, как приложение будет приостановлено или убито Добавление формы в LinearLayout Android Указание «зачеркивания» в разделе текста TextView Gradle «манифест требует замены замещающего» ошибки, но manifestPlaceholders поставляет значение Добавление базы данных / backend в приложения для Android Как открыть PDF через Intent с SD-карты Можно ли определить действие внутри Android-теста и запустить тест против него? Sugar ORM требует, чтобы записи сохранялись каждый раз во время модульного тестирования? Измените синий цвет по умолчанию в теме головоломки Android на оранжевый (или что-нибудь еще)