How to rotate a camera view in OpenGL 2.0 ES

2019-08-13 23:12发布

问题:

I want to make a 360-world using OpenGL 2.0 ES on Smart phone. And I want to make camera view follow the Smart phone Sensor using a quaternion, like an youtube 360 video or an Oculus.

  • I get a Quarternion value using public void setquaternion(...) Function.
  • I change the Quarternion values to 4x4 rotate matrix using makeRotateMatrix() function.
  • How can I control the camera view using this matrixes....?(moving camera's sight)
  • I'm getting hard time because of this... please help me..... ;(

And My Rendering source code is.. (This source just shows the Blue Square box)

package com.lookie.tom.superlookie;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
import android.util.Log;


public class MyGLRenderer implements GLSurfaceView.Renderer {

    private static final String TAG = "MyGLRenderer";
    private Square   mSquare;

    // mMVPMatrix is an abbreviation for "Model View Projection Matrix"
    private final float[] mMVPMatrix = new float[16];
    private final float[] mProjectionMatrix = new float[16];
    private final float[] mViewMatrix = new float[16];
    private float mQw = 0;
    private float mQx = 0;
    private float mQy = 0;
    private float mQz = 0;

    @Override
    public void onSurfaceCreated(GL10 unused, EGLConfig config) {

        // Set the background frame color
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        mSquare   = new Square();
    }

    @Override
    public void onDrawFrame(GL10 unused) {
        float[] scratch = new float[16];
        float[] temp = new float[16];
        // Draw background color
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);


        Matrix.setLookAtM(mViewMatrix, 0,
                0, 0, -0.2f,
                0f, 0f, 0f,
                0.0f, 1.0f, 0.0f
        );

        // Calculate the projection and view transformation
        Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
         mSquare.draw(mMVPMatrix);
        // Draw square

    }

    @Override
    public void onSurfaceChanged(GL10 unused, int width, int height) {
        // Adjust the viewport based on geometry changes,
        // such as screen rotation
        GLES20.glViewport(0, 0, width, height);

        float ratio = (float) width / height;

        // this projection matrix is applied to object coordinates
        // in the onDrawFrame() method
        Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 0.2f, 7 );

    }


    public static int loadShader(int type, String shaderCode){

        // create a vertex shader type (GLES20.GL_VERTEX_SHADER)
        // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
        int shader = GLES20.glCreateShader(type);

        // add the source code to the shader and compile it
        GLES20.glShaderSource(shader, shaderCode);
        GLES20.glCompileShader(shader);

        return shader;
    }

    private float[] makeRotateMatrix(){
        float [] tempMatrix = {
                1.0f - 2.0f*mQy*mQy - 2.0f*mQz*mQz, 2.0f*mQx*mQy - 2.0f*mQz*mQw, 2.0f*mQx*mQz + 2.0f*mQy*mQw, 0.0f,
                2.0f*mQx*mQy + 2.0f*mQz*mQw, 1.0f - 2.0f*mQx*mQx - 2.0f*mQz*mQz, 2.0f*mQy*mQz - 2.0f*mQx*mQw, 0.0f,
                2.0f*mQx*mQz - 2.0f*mQy*mQw, 2.0f*mQy*mQz + 2.0f*mQx*mQw, 1.0f - 2.0f*mQx*mQx - 2.0f*mQy*mQy, 0.0f,
                0.0f, 0.0f, 0.0f, 1.0f
        };
        return tempMatrix;
    }

    public void setQuaternion(float x, float y, float z, float w){
        mQx=x;
        mQy=y;
        mQz=z;
        mQw=w;
    }


    public static void checkGlError(String glOperation) {
        int error;
        while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
            Log.e(TAG, glOperation + ": glError " + error);
            throw new RuntimeException(glOperation + ": glError " + error);
        }
    }
}