2017-01-21 6 views
0

У меня есть этот вершинный шейдер, который я использую для поворота или перевода obj в зависимости от значений состояния.Понимание буфера в OpenGLES android

private final String vertexShader="" + 
     "attribute vec4 vertex;" + 
     "attribute vec4 colors;" + 
     "varying vec4 vcolors;" + 
     "uniform int x;" + 
     "uniform vec4 translate;"+ 
     "uniform mat4 rotate;"+ 
     "void main(){" + 
      "vec4 app_verte=vertex;" + 
      "if(x==1){" + 
      "app_verte=vertex+translate;" + 
      "}else if(x==2){" + 
      "app_verte=rotate*app_verte;" + 
      "}" + 
      "vcolors=colors;" + 
      "gl_Position=app_verte;" + 
     "}"; 

Для вращения я использую матрица, с помощью матрицы associeted строится из поплавковой [16] массива следующим образом:

|cos(angle),-sin(angle),0,0| 
|sin(angle), cos(angle),0,0| 
|0   ,   ,0,0| 

Теперь у меня есть разные вопросы becouse я действительно трудно понять. Если я хочу изменить тип преобразования, я должен установить значение x. Теперь, чтобы иметь преобразование континуума, я предположил, что буферизация вершин будет одинаковой, и после преобразования значение буфера будет изменено. Теперь ничего не случилось, потому что он трансформировался и рисовал с одинаковыми координатами. Сначала я устанавливаю только координаты. Существует способ использовать один и тот же буфер, который является VRAM, не помещая его каждый раз, и если нет, то как можно вытащить измененный буфер в мой буфер obj после tranformation без преобразования точки с помощью массива и поместить его в буфер ?? Извините за мой английский и спасибо всем.

+0

Трудно получить ваш вопрос. Можете ли вы упростить вопрос? если вы спрашиваете, как преобразовать каждую вершину в свой вершинный шейдер, используйте еще один атрибут float x вместо равномерного x – Sung

ответ

0

Буферы вершины разработаны таким образом, что вы отправляете их на GPU только один раз, чтобы уменьшить трафик. Затем вы используете матрицы (или другие системы, такие как вектор трансляции), чтобы применить преобразование в вершинном шейдере, чтобы вы отправляли только буфера с плавающей запятой до 4x4.

ЕСЛИ Я понимаю, в чем заключается ваша проблема, заключается в том, что вы одновременно используете несколько систем. У вас есть вектор перевода и матрица, но вы используете один или другой. Так что в вашем случае вы могли бы просто применить оба из них в шейдере как app_verte = rotate*app_verte + translate; или app_verte = rotate*(app_verte + translate); уже эти 2 не совпадают, и я предполагаю, что в какой-то момент вам понадобится что-то вроде app_verte = rotate2*(rotate1*app_verte + translate1) + translate2;, которое не разрешимо, так как число операции со временем увеличится.

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

Итак, у вас есть единая матрица, которая в начале установлена ​​на личность, которая соответствует x=0. Тогда для x=1 ситуация установила эту матрицу как матрицу перевода myMatrix = generateTranslationMatrix(x, y, z). И для x=2 сделать то же самое с матрицей поворота myMatrix = generateRotationMatrix(x, y, z, angle). Теперь, когда вам нужно продолжить операцию, чтобы выполнить эти два, вы просто умножаете их, поэтому для обоих вы сделаете myMatrix = generateTranslationMatrix(x, y, z)*generateRotationMatrix(x, y, z, angle). Но нет никаких причин, чтобы сохранить ценности отдельно, а поэтому в конце концов, вы просто хотите, чтобы некоторые методы управления состоянием ориентации:

Matrix myMatrix; 

onLoad() { 
    myMatrix = Matrix.identity(); 
} 

onTurnRight(float angle) { 
    myMatrix = myMatrix * generateRotationMatrix(0, 1, 0, angle); 
} 

onMove(float x, float y, float z) { 
    myMatrix = myMatrix * generateTranslationMatrix(x, y, z); 
} 

Затем вы можете добавить другие методы в свой код, как это необходимо, но, например, если вы регулируете событие прикосновения и когда палец перемещается вверх или вниз, вы будете двигаться вперед или назад, а влево и вправо будете вращать объект, то он будет выглядеть примерно так:

onFingerMoved(float x, float y) { 
    const float xfactor = 0.01; // Modify to control the speed of rotation 
    const float yfactor = -0.1; // Modify to control the speed of movement 

    float dx = previousX - x; 
    float dy = previousy - y; 
    onTurnRight(dx); 
    onMove(.0, .0, dy); // Assuming the Z coordinate is forward 

    previousX = x; 
    previousY = y; 
} 
Смежные вопросы