Android OpenGL ES - я не могу заставить gluLookAt / gluPerspective работать - PullRequest
1 голос
/ 22 сентября 2010

следующий текст немного длиннее, так как я хотел убедиться, что люди с похожими проблемами, например, Google эта страница может легко отслеживать точную проблему и ее решения легко. Но теперь к моей проблеме:

Недавно я начал программировать OpenGL ES на смартфоне с Android и столкнулся с проблемами в понимании того, как используются gluPerspective и gluLookAt. Я думаю Я понимаю, что они делают, однако я не вижу треугольника, который рисую. Я запускаю следующий код в методе onDrawFrame моей деятельности. Упомянутая активность реализует GLSurfaceView.Renderer с onDrawFrame, помеченным @Override. Мой код:

gl.glViewport(0, 0, screen_width, screen_height);
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); //set background to black
gl.glClearDepthf(1.0f); 

gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

gl.glMatrixMode(GL10.GL_PROJECTION); // Change PROJECTION matrix
gl.glLoadIdentity();

float aspect_ratio = (float) screen_width / screen_height;
GLU.gluPerspective(gl, 67, aspect_ratio, 1, 100);

gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glMatrixMode(GL10.GL_MODELVIEW); // Change MODELVIEW matrix
gl.glLoadIdentity();

GLU.gluLookAt(gl, 0, 0, 20, 0, 0, 0, 0, 1, 0);

// make triangle with vertices (-2,0,0), (2,0,0), and (0,.5,0)
float[] vertices = { -2f, 0, 0, 2f, 0, 0, 0, .5f, 0 };
ByteBuffer buffer = ByteBuffer.allocateDirect(vertices.length * 4);
buffer.order(ByteOrder.nativeOrder());
FloatBuffer vertex_buffer = buffer.asFloatBuffer();
for (int i = 0; i < 9; i++) {
    vertex_buffer.put(vertices[i]);
}

gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex_buffer);
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable(GL10.GL_DEPTH_TEST);

Следующие пункты - это короткие заметки о том, что я предположительно знаю о настройках камеры в приведенном выше коде. ПОЖАЛУЙСТА, поправьте меня, если я ошибся в следующих объяснениях, так как это может решить все мои проблемы!

  1. glMatrixMode (GL10.GL_PROJECTION) переключается на изменение матрицы камеры (для которой я загружаю матрицу идентичности непосредственно после этого)
  2. GLU.gluPerspective (gl, 67, aspect_ratio, 1, 100) устанавливает перспективную проекцию с углом обзора 67 градусов в Y-измерении. Используя «aspect_ration = (float) width / height» OpenGL вычисляет угол обзора в x-измерении. Кроме того, «1» - это ближняя плоскость отсечения, а «100» - это значение дальней плоскости отсечения.
  3. Насколько я знаю, не имеет значения, где в коде вызывается gluLookAt, если это делается до фактического рисования (хотя я не уверен в этом). В этом примере я сначала переключаюсь на матрицу MODELVIEW, загружаю единичную матрицу, а затем вызывается gluLookAt. 3.
  4. «GLU.gluLookAt (gl, 0, 0, 20, 0, 0, 0, 0, 1, 0)» фактически состоит из трех 3-элементных векторов. Начальная (в данном примере (0,0,20)) устанавливает положение камеры в мировых координатах (т.е. 20 единиц на положительной оси Z, что означает, что она «торчит» из передней части экрана телефона). ). Второй вектор определяет точку в мировой системе координат, на которую смотрит камера (в этом примере начало координат системы координат, то есть камера смотрит вдоль отрицательной оси z). Третий вектор является вектором вверх, который определяет направление оси Y системы координат камер (и, следовательно, также оси X через перекрестное произведение с вектором от положения камеры до точки, на которую она смотрит).

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

Насколько я понимаю, камера теперь расположена на (0,0,20) и смотрит в начало системы координат. Его начальная точка рисования начинается с значения z 19 и достигает -80 (камера находится в точке 20 оси z и смотрит вдоль отрицательной оси z; у ее обзорной плоскости есть ближняя и дальняя плоскости на 1 и 100 (оба вида вдоль отрицательной оси z в этом случае) соответственно). Следовательно, треугольник должен быть видимым, так как его вершины расположены вокруг начала координат в плоскости оси z = 0 (то есть в плоскости xy), которая явно находится в пределах поля зрения просмотра. Далее нарисованные вершины располагаются против часовой стрелки; по умолчанию в OpenGL.

Итак, после этого длительного введения в проблему, мой простой вопрос: что я испортил, чтобы этот код не выполнял то, что я ожидал?

Ответы [ 3 ]

6 голосов
/ 22 сентября 2010

Я когда-либо использовал OpenGL только на ПК, Mac и iOS, но, насколько я могу судить, код выглядит хорошо.С другой стороны, мой всегда тоже, но я все еще получаю пустой экран некоторое время, почти каждый раз, когда начинаю что-нибудь 3D с нуля (независимо от API) ... так что вот некоторые вещи, которые можно попробовать, в значительной степени впорядок, в котором их можно попробовать.Надеюсь, по крайней мере один из них будет тем, что вы еще не пробовали!

  • Добавьте в конце glFlush, потому что вы на самом деле не так много рисуете.Вы могли бы подумать, что драйвер сделает это за вас, когда вы делаете замену буфера, но кажется, что нет никаких гарантий этого - Mac OS X, к примеру, не всегда, например.
  • Установка фоначтобы не черный.Если что-то рисует черным, вы хотите это увидеть.
  • Отключить GL_LIGHTING.Если это включено (что я думаю, что по умолчанию?), Но вы не поставляете нормали, все будет черным.(См. Выше.)
  • Отключить GL_CULL_FACE.Неважно, насколько тщательно вы думаете о порядке намотки, есть вероятность, что вы ошиблись.Но если GL_CULL_FACE выключен, это становится невозможным.
  • Отключить GL_DEPTH_TEST.Это спасло меня пару раз, когда я случайно набрал glClearDepth(0).Похоже, вы в этом отношении в порядке, но все же стоит попробовать.
  • Проверяйте glGetError неукоснительно, после КАЖДОГО вызова API, на всякий случай.(assert(glGetError()==GL_NO_ERROR) подойдет для начинающих, но вы действительно хотите иметь небольшую петлю, которая также выводит результат gluErrorString, чтобы было проще сразу увидеть, что может быть не так.)
  • Makeубедитесь, что вы делаете glBindBuffer, чтобы установить привязки ARRAY_BUFFER и ARRAY_ELEMENT_BUFFER к 0. Чтобы инициализировать VBO, вы должны привязать его, поэтому, если у вас есть что-то, что устанавливает его, оно может просто оставить его связанным,Это заполнит ваш glVertexPointer.
  • В соответствии с линиями последних нескольких - установите больше состояния явно.В этом случае, например, вы можете захотеть glDisableClientState другие типы массивов, на всякий случай.Согласно документам, GL запускается с отключенными вершинными массивами, но эту возможность стоит устранить.
2 голосов
/ 22 сентября 2010

Я нашел ответ, посмотрев другие уроки (а потом заметил и те, что использовал ранее)! Спасибо всем за ответы, они очень помогли в диагностике проблем OpenGL в целом и наверняка помогут мне в будущем!

Решение моей проблемы заключается в ... в том, что проблема не в glulookat или gluperspective, а в моем случае во внутренней позиции FloatBuffer. Я не установил положение переменной vertex_buffer в 0 после цикла for (0 vertex_buffer.rewind () vertex_buffer.position (0) Насколько мне известно, они делают то же самое. Я быстро проверил, где в коде находится сброс позиции, и в моем примере кода я мог вызвать его после gl.glEnableClientState (GL10.GL_VERTEX_ARRAY), однако мне пришлось вызывать его до gl.glVertexPointer (3, GL10.GL_FLOAT, 0, vertex_buffer ), в противном случае возвращалась исходная проблема.

Надеюсь, это поможет другим людям с похожими проблемами или, может быть, это просто недостаток glulookat и gluperspective;)

Еще раз спасибо за ваши предложения!

0 голосов
/ 09 июля 2018

Для пользователей OpenGL ES

В моем случае мне пришлось написать

gl.glMatrixMode(gl.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl,45,1,1.5f,50);
gl.glMatrixMode(gl.GL_MODELVIEW);
gl.glLoadIdentity();

Вместо просто

GLU.gluPerspective(gl,45,1,1.5f,50);

В onSurfaceChanged метод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...