2015-07-02 2 views
0

Я рисую треугольник в OpenGL, как:Преобразование пиксельных координат для нормированных координат во время жеребьевки в OpenGL 3.0

  MyGLRenderer() 
      { 
       fSampleVertices = ByteBuffer.allocateDirect(fSampleVerticesData.length * 4) 
         .order (ByteOrder.nativeOrder()).asFloatBuffer(); 

       fSampleVertices.put(fSampleVerticesData).position (0); 

       Log.d(TAG, "MyGLRender()"); 
      } 

      private FloatBuffer fSampleVertices; 

      private final float[] fSampleVerticesData = 
        { .8f, .8f, 0.0f, -.8f, .8f, 0.0f, -.8f, -.8f, 0.0f }; 

      public void onDrawFrame(GL10 unused) 
      { 
       GLES30.glViewport (0, 0, mWidth, mHeight); 

       GLES30.glClear (GLES30.GL_COLOR_BUFFER_BIT); 

       GLES30.glUseProgram (dProgramObject1); 

       GLES30.glVertexAttribPointer (0, 3, GLES30.GL_FLOAT, false, 0, fSampleVertices); 

       GLES30.glEnableVertexAttribArray (0); 

       GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, 3); 

       //Log.d(TAG, "onDrawFrame()"); 
      } 

Так, так как я экспериментировал с координатами не принимают чтобы выяснить, что видимая область экрана находится между -1,1. Итак, треугольник занимает 80% экрана. Также я определил, что размеры пикселей моего GLSurfaceView имеют ширину 2560 и 1600 дюймов.

Итак дан треугольник с этими пикселями на основе координат (fBoardOuter):

1112.0f 
    800.0f 
    0.0f 
    -1280.0f 
    800.0f 
    0.0f 
    -1280.0f 
    -800.0f 
    0.0f 

я должен либо преобразовать эти пиксельные координаты к чему-то между -1,1 и выяснить путь к имеют gl конвертировать эти координаты в момент их рисования? Поскольку я очень новичок в OpenGL, я ищу некоторые рекомендации для этого?

Моих вершинные шейдеры, как:

String sVertexShader1 = 
       "#version 300 es    \n" 
      + "in vec4 vPosition;   \n" 
      + "void main()     \n" 
      + "{       \n" 
      + " gl_Position = vPosition; \n" 
      + "}       \n"; 

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


Я обнаружил, что Android имеет эту функцию:

orthoM(float[] m, int mOffset, float left, float right, float bottom, float top, float near, float far) 

Однако нет ничего в документации, я прочитал, что до сих пор объяснить использование матрицы, как поплавок [] с координатами пикселей могут быть преобразованы в нормализованные координаты с этой матрицей в GLES30.

Я также нашел документацию здесь:

http://developer.android.com/guide/topics/graphics/opengl.html

Основе документацию я попытался создать пример:

http://pastebin.com/5PTsfSdz

В Pastebin например fSampleVertices я думал было бы намного меньше и в центре экрана, но это не тот почти весь экран, и fBoardOuter просто показывает мне черный экран, если я попытаюсь вставить его в gl DrawArray.

ответ

1

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

Система координат, которую вы обнаружили, где диапазон [-1.0, 1.0] в направлениях координат x и y официально называется координатами нормализованных устройств, часто сокращается как NDC. Это очень похоже на имя, с которым вы столкнулись, поэтому некоторые термины OpenGL на самом деле очень логичны. :)

По крайней мере, пока вы имеете дело с 2D-координатами, это диапазон координат, который должен произвести ваш вершинный шейдер. То есть координаты, которые вы назначаете встроенной переменной gl_Position, должны находиться в этом диапазоне, чтобы быть видимыми на выходе.Все становится немного сложнее, если вы имеете дело с 3D-координатами и применяете перспективные прогнозы, но пока мы пропустим эту часть.

Теперь, как вы уже догадались, у вас есть два основных варианта, если вы хотите, чтобы указать свои координаты в другой системе координат:

  1. Вы превратить их в НДЦ в вашем коде, прежде чем передать их в OpenGL.
  2. У вас есть OpenGL применить преобразования к вашим входным координатам.

Вариант 2, безусловно, лучший, поскольку графические процессоры очень эффективны при выполнении этой работы.

На очень простом уровне это означает, что вы изменяете координаты в своем вершинном шейдере. Если вы посмотрите на очень простой первый вершинный шейдере:

in vec4 vPosition; 
void main() 
{ 
    gl_Position = vPosition; 
} 

вы получите координаты, предоставляемые код приложения из переменной vPosition ввода, и назначить точно он же координату к выходу gl_Position шейдера вершин.

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

Современные версии OpenGL больше не имеют имени для этих систем координат. Раньше были «координаты модели» и «мировые координаты», когда некоторые из этих материалов по-прежнему были жестко привязаны к фиксированному конвейеру. Теперь, когда это делается с помощью программируемого шейдерного кода, эти концепции больше не актуальны с точки зрения OpenGL. Все, о чем он заботится, это координаты, которые выходят из вершинного шейдера. Все, что происходит до этого, - это ваш собственный бизнес.

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

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

in vec4 vPosition; 
uniform mat4 TransformMat; 
void main() 
{ 
    gl_Position = TransformMat * vPosition; 
} 

Чтобы установить значение этой матрицы, вам необходимо получить расположение равномерных переменного сразу после соединения шейдера, с prog вашим шейдером программы :

GLint transformLoc = GLES20.glGetUniformLocation(prog, "TransformMat"); 

Тогда, по крайней мере, один раз, и каждый раз, когда вы хотите изменить матрицу, вы звоните:

GLES20.glUniformMatrix4fv(transformLoc, 1, GL_FALSE, mat, 0); 

, где mat - это матрица, которую вы либо сами создали, либо получили от одной из служебных функций в android.opengl.Matrix. Обратите внимание, что этот вызов должен быть после, вы делаете программу текущей с glUseProgram().

 Смежные вопросы

  • Нет связанных вопросов^_^