2013-03-25 4 views
0

Edit 6 - полностью переписана в связи с комментариями/проводящихся исследованийПростой поворот текстурированной четырехъядерный в OpenGL ES 2.0

Edit 7 - Добавлена ​​проекция/вид матрицы .....

Поскольку я не увлекаюсь этим, я добавил матрицу представлений/прогнозов из демонстрации Google - см. Код ниже: Если кто-нибудь может указать, куда я иду, это действительно будет оценено, так как я все еще получаю пустой экран, когда я помещаю «gl_position = a_position * uMVPMatrix;» + в мой вершинный шейдер (с «gl_position = a_position;» + мой квадрат отображается как минимум .......)

Заявлен на уровне класса: (Quad класса)

private final float[] rotationMat = new float[16]; 
    private FloatBuffer flotRotBuf; 
    ByteBuffer rotBuf; 
    private int muRotationHandle = -1;    // Handle to the rotation matrix in the vertex shader called "uRotate" 

Заявленный в классе рычага: (рендерер класс)

private final float[] mVMatrix = new float[16]; 
    private final float[] mProjMatrix = new float[16]; 
    private final float[] mMVPMatrix = new float[16]; 

процедуру, которая устанавливает текстуру и делает (или предположительно) вращение (это в моем классе Quad

public void setTexture(GLSurfaceView view, Bitmap imgTexture, float[] mvpMatrix){ 
     this.imgTexture=imgTexture; 

     // get handle to shape's transformation matrix 
     mMVPMatrixHandle = GLES20.glGetUniformLocation(iProgId, "uMVPMatrix"); 

     // Apply the projection and view transformation 
     GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0); 

//  Matrix.setRotateM(rotationMat, 0, 45f, 0, 0, 1.0f); //Set rotation matrix with angle and (z) axis 

//  rotBuf = ByteBuffer.allocateDirect(rotationMat.length * 4); 
     // use the device hardware's native byte order 
//  rotBuf.order(ByteOrder.nativeOrder()); 
     // create a floating point buffer from the ByteBuffer 
//  flotRotBuf = rotBuf.asFloatBuffer(); 
     // add the coordinates to the FloatBuffer 
//  flotRotBuf.put(rotationMat); 
     // set the buffer to read the first coordinate 
//  flotRotBuf.position(0); 

//  muRotationHandle = GLES20.glGetUniformLocation(iProgId, "uRotation"); // grab the variable from the shader 
//  GLES20.glUniformMatrix4fv(muRotationHandle, 1, false, flotRotBuf); //Pass floatbuffer contraining rotation matrix info into vertex shader 
     //GLES20.glUniformMatrix4fv(muRotationHandle, 1, false, rotationMat, 1); //Also tried this ,not use floatbuffer 

     //Vertex shader 
     String strVShader = 
      // "uniform mat4 uRotation;" + 
        "uniform mat4 uMVPMatrix;" + 
        "attribute vec4 a_position;\n"+ 
        "attribute vec2 a_texCoords;" + 
        "varying vec2 v_texCoords;" + 
        "void main()\n" + 
        "{\n" + 
        "gl_Position = a_Position * uMVPMatrix;"+ //This is where it all goes wrong....   
        "v_texCoords = a_texCoords;" + 
        "}"; 

     //Fragment shader 

     String strFShader = 
      "precision mediump float;" + 
      "varying vec2 v_texCoords;" + 
      "uniform sampler2D u_baseMap;" + 
      "void main()" + 
      "{" + 
      "gl_FragColor = texture2D(u_baseMap, v_texCoords);" + 
      "}"; 


     iProgId = Utils.LoadProgram(strVShader, strFShader); 
     iBaseMap = GLES20.glGetUniformLocation(iProgId, "u_baseMap"); 
     iPosition = GLES20.glGetAttribLocation(iProgId, "a_position"); 
     iTexCoords = GLES20.glGetAttribLocation(iProgId, "a_texCoords"); 
     texID = Utils.LoadTexture(view, imgTexture); 

    } 

Из моего класса визуализатора:

public void onSurfaceChanged(GL10 gl, int width, int height) { 
    // TODO Auto-generated method stub 

    //Set viewport size based on screen dimensions  
    GLES20.glViewport(0, 0, width, height); 

    float ratio = (float) width/height; 
    Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7); 

} 

    public void onDrawFrame(GL10 gl) { 
    // TODO Auto-generated method stub 

    //Paint the screen the colour defined in onSurfaceCreated 
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); 

    // Set the camera position (View matrix) 
    Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f); 


    // Calculate the projection and view transformation 
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0); 

    quad1.setTexture(curView, myBitmap, mMVPMatrix); //SetTexture now modified to take a float array (See above) - Note I know it's not a good idea to have this in my onDrawFrame method - will move it once I have it working! 

    quad1.drawBackground(); 
} 

Я теперь удалены все связанные вещи вращения и теперь просто пытаются получить статический четверной для отображения после применения uMVPMatrix в вершинном шейдере. Но до сих пор ничего :-(

Если я просто не изменить эту строку обратно в «по умолчанию»:

"gl_Position = a_position;\n"+ 

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

Кроме того, чтобы указать, что mvpMatrix окончательно получает intact в метод setTexture, действителен (содержит те же данные, что и при регистрации содержимого mvpMatrix из кода разработчиков Google). Я не уверен, как чтобы проверить, не принимает ли шейдер его нетронутым? У меня нет оснований полагать, что это не так.

Действительно ценю и все помогаю - я должен быть очень не прав, но я просто не могу это понять. Спасибо!

EDIT 2: Добавив Баунти на этот вопрос, я хотел бы знать, как, как повернуть мою текстурированной четверной спрайт (2D), сохраняя код, я должен сделать его в качестве основы. (то есть, что мне нужно добавить к нему, чтобы повернуть и почему). Благодаря!

РЕДАКТИРОВАТЬ 3 N/A

РЕДАКТИРОВАТЬ 4 сформулированное Повторное/упрощенный вопрос

РЕДАКТИРОВАТЬ матрица 5 Добавлен скриншот ошибки

enter image description here

+0

В glUniformMatrix4v false! = GL_FALSE. false - ключевое слово C++, а GL_FALSE - перечисление. –

+0

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

+0

Если я поместил GL_FALSE, я просто получаю: «GL_FALSE не может быть разрешен переменной» – Zippy

ответ

0

вращения для вращения вокруг z:

cos a -sin a 0 
sin a cos a 0 
    0  0 1 

Как запомнить, как его построить:
a - угол в радианах, при a = 0 матрица дает единичную матрицу. cos должен быть на диагонали. Должен быть один знак перед одним грехом, переключение знаков обращает направление вращения.

Аналогично вращения вокруг х и у могут быть построены:

1  0  0 
0 cos a sin a 
0 -sin a cos a 

cos a 0 sin a 
    0 1  0 
-sin a 0 cos a 

Если вы не знакомы с матрицей-арифметики, вот некоторый код:

for (int i=0; i<4; i++) { 
    vertices_new[i*5+0] = cos(a) * vertices[i*5+0] - sin(a) * vertices[i*5+1]; // cos(a) * v[i].x - sin(a) * v[i].y + 0 * v[i].z 
    vertices_new[i*5+1] = sin(a) * vertices[i*5+0] + cos(a) * vertices[i*5+1]; // sin(a) * v[i].x + cos(a) * v[i].y + 0 * v[i].z 
    vertices_new[i*5+2] = vertices[i*5+2]; // 0 * v[i].x + 0 * v[i].y + 1 * v[i].z 
    vertices_new[i*5+3] = vertices[i*5+3]; // copy texture u 
    vertices_new[i*5+4] = vertices[i*5+4]; // copy texture v 
} 
+0

Спасибо, не могли бы вы подробно рассказать о том, что происходит в вашем коде, пожалуйста, @TobiasSchlegel, а также, можете ли вы дать мне указание на то, как я буду внедрять это в код, который я изначально разместил, - спасибо. – Zippy

0

Edit: Под редакцией поддержке Java с использованием Android SDK.

Как указал Тобиас, идиоматическое решение любого преобразования вершин в OpenGL выполняется с помощью операций с матрицами. Если вы планируете продолжить разработку с помощью OpenGL, важно, чтобы вы (в конце концов) понимали базовую линейную алгебру, участвующую в матричных операциях, но часто лучше всего использовать математическую библиотеку для абстрагирования вычисления линейной алгебры в более читаемый формат. Под андроидом среды, вы должны манипулировать с плавающей точкой массивов с [матрицей] [1] класс, чтобы создать матрицу вращения, как это:

// initialize rotation matrix 
float[16] rotationMat; 
Matrix.setIdentityM(rotationMat,0); 

// angle in degrees to rotate 
float angle = 90; 

// axis to rotate about (z axis in your case) 
float[3] axis = { 0.0,0.0,1.0}; 

// For your case, rotate angle (in degrees) about the z axis. 
Matrix.rotateM(rotationMat,0,angle,axis[0],axis[1],axis[2]); 

Затем вы можете связать матрицы поворота к программе шейдера, как это:

// assuming shader program is currently bound ... 
GLES20.glUniformMatrix4fv(GLES20.glGetUniformLocation(shaderProgramID, "uRotation"), 1, GL_FALSE, rotationMat); 

Где ваши вершинные шейдеры (программа передаются rotationMat) будет выглядеть примерно так:

precision mediump float; 
uniform mat4 uMVPMatrix; 
uniform mat4 uRotation; 
attribute vec2 a_texCoords; 
attribute vec3 a_position; 
varying v_texCoord; 

void main(void) 
{ 
    v_texCoord = a_texCoords; 
    gl_Position = uMVPMatrix* uRotation * vec4(a_position,1.0f); 
} 

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

После того, как вы удобно используете этот API более высокого уровня для операций с матрицами, вы можете исследовать, как выполняется внутренняя операция, прочитав фантастический учебник this, написанный Nicol Bolas.

+0

Эй, @SirDigbyChickenCaesa, спасибо за это, я обязательно посмотрю ссылку, которую вы отправили. Я слышал о GLM Before, но никогда не смотрел в нее. Правильно ли я предполагаю, что это C? И если это так, мне нужно было бы реализовать его как таковое (с помощью NDK я предполагаю?), Если так, я могу сделать это вращение только с помощью SDK/Java? Еще раз спасибо!! – Zippy

+0

Ничего себе, извините! Я так привык думать в главном пространстве C++ при использовании OpenGL, что забыл, что вы, скорее всего, используете Java на Android.Я буду искать подходящую математическую библиотеку Java, и я отредактирую сообщение. –

+0

Ничего себе это не так просто, как я думал. Я думаю, что есть вопросы лицензирования с vecmath? Любые другие варианты? У меня есть код от разработчиков Android, который рисует вращающийся треугольник в центре экрана, но для жизни меня, когда я пытаюсь перевести код на мой, я ничего не получаю. Это когда я меняю строку «gl_Position = a_Position;» в моем шейдере на «gl_Position = uMVPMatrix * a_Position;» Я отправлю код ..... Еще раз спасибо – Zippy