2015-11-30 102 views
1

我試圖在屏幕上繪製一個簡單的矩形,並看到它隨着我物理旋轉我的設備而旋轉。我已經設法得到一些旋轉,但它沒有任何意義,它似乎不隨設備的方向旋轉。通過設備旋轉旋轉簡單的3d對象

我的主要活動:

public class MainActivity extends Activity implements SensorEventListener { 
    public static final double RAD2DEG=57.2957795; 
    private static final String SENSOR_TAG = "SENSOR"; 
    private GLSurfaceView glSurfaceView; 
    private boolean rendererSet = false; 
    private SensorManager sensorManager; 
    private Sensor rotationSensor; 
    private float[] rotationVector; 
    private float[] rotatinMatrix = new float[16]; 
    private float[] orientationVals = new float[3]; 
    public Renderer renderer; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     renderer = new Renderer(this); 
     createGLsurface(); 
     getSensors(); 

    } 

    protected void createGLsurface(){ 
     glSurfaceView = new GLSurfaceView(this); 
     glSurfaceView.setEGLContextClientVersion(2); 
     glSurfaceView.setRenderer(renderer); 
     rendererSet=true; 
     setContentView(glSurfaceView); 
    } 

    protected void getSensors(){ 
     sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 
     rotationSensor=sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR); 

    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     if (rendererSet) 
      glSurfaceView.onPause(); 
     sensorManager.unregisterListener(this); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     if (rendererSet) 
      glSurfaceView.onResume(); 
     sensorManager.registerListener(this,rotationSensor,SensorManager.SENSOR_DELAY_NORMAL); 
    } 

    @Override 
    public void onSensorChanged(SensorEvent event) { 

     SensorManager.getRotationMatrixFromVector(rotatinMatrix, event.values); 


     renderer.setRotationMatrix(rotatinMatrix); 

    } 

    @Override 
    public void onAccuracyChanged(Sensor sensor, int accuracy) { 

    } 
} 

我的渲​​染:

public class Renderer implements GLSurfaceView.Renderer { 

    private static final String A_COLOR = "a_Color"; 
    private static final String U_MATRIX = "u_Matrix"; 
    private static final String A_POSITION = "a_Position"; 
    private static final int BYTES_PER_FLOAT = 4 ; 
    private static final int POSITION_COMPONENT_COUNT = 2; 
    private static final int COLOR_COMPONENT_COUNT = 3; 
    private static final int STRIDE = (POSITION_COMPONENT_COUNT+COLOR_COMPONENT_COUNT)*BYTES_PER_FLOAT; 
    private final Context context; 
    private final FloatBuffer vertexData; 
    private int program; 
    private int uColorLocation ; 
    private int aPositionLocation; 
    private int aColorLocation; 
    private int uMatrixLocation; 
    private float[] projectionMatrix = new float[16]; 
    private float[] mViewMatrix = new float[16]; 
    private float[] mMVPMatrix = new float[16]; 
    private float[] rotationMatrix = new float[16]; 
    private float[] rotated = new float[16]; 

    public Renderer(Context context) { 
     this.context = context ; 
     float[] table = { 
       //triangle fan 
       // X ,  Y , R , G , B 
        0 ,  0 ,  1f , 1f , 1f , 
       -0.5f , -0.5f , 0.7f , 0.2f , 0.2f , 
       0.5f , -0.5f , 0.7f , 0.2f , 0.2f , 
       0.5f , 0.5f , 0.7f , 0.2f , 0.2f , 
       -0.5f , 0.5f , 0f , 0f , 0.7f , 
       -0.5f , -0.5f , 0f , 0f , 0.7f 
     }; 

     vertexData = ByteBuffer.allocateDirect(table.length * BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
     vertexData.put(table); 

    } 

    @Override 
    public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
     GLES20.glClearColor(0f,0f,0f,0f); 
     String vertexShaderSource = TextResourceReader.readTextFileFromResource(context,R.raw.simple_vertex_shader); //read simple_vertex_shader.glsl 
     String fragmentShaderSource = TextResourceReader.readTextFileFromResource(context, R.raw.simple_fragment_shader); //read simple_fragment_shader.glsl 
     int vertexShader = ShaderHelper.compileVertexShader(vertexShaderSource); //compile the vertex shader 
     int fragmentShader = ShaderHelper.compileFragmentShader(fragmentShaderSource); //compile the fragment shader 
     program=ShaderHelper.linkProgram(vertexShader,fragmentShader); //link the shaders into a program object 
     if (Logger.logging) 
      ShaderHelper.validateProgram(program); 

     GLES20.glUseProgram(program); //enable the program we just created 

     uMatrixLocation = GLES20.glGetUniformLocation(program,U_MATRIX); 
     aPositionLocation=GLES20.glGetAttribLocation(program,A_POSITION); //get attribute for position 
     aColorLocation = GLES20.glGetAttribLocation(program,A_COLOR); //get attribute for color 

     //tell openGL where to find the attribute location 
     vertexData.position(0); 
     GLES20.glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDE, vertexData); 
     GLES20.glEnableVertexAttribArray(aPositionLocation); //enable the vertex array 


     //tell openGL where to find the attribute for color 
     vertexData.position(POSITION_COMPONENT_COUNT); 
     GLES20.glVertexAttribPointer(aColorLocation, COLOR_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDE, vertexData); 
     GLES20.glEnableVertexAttribArray(aColorLocation); 







    } 

    @Override 
    public void onSurfaceChanged(GL10 gl, int width, int height) { 
     GLES20.glViewport(0, 0, width, height); 
     float ratio = (float)width/height; 
     Matrix.frustumM(projectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7); 

    } 

    @Override 
    public void onDrawFrame(GL10 gl) { 
     GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); 
     Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -4.0f, 0f, 0f, 0f, 0f, 6.0f, 0.0f); 
     Matrix.multiplyMM(mMVPMatrix, 0, projectionMatrix, 0, mViewMatrix, 0); 
     Matrix.multiplyMM(rotated,0,mMVPMatrix,0,rotationMatrix,0); 



     GLES20.glUniformMatrix4fv(uMatrixLocation,1,false,mMVPMatrix,0); 


     GLES20.glUniform4f(uColorLocation,1.0f,1.0f,1.0f,1.0f); 
     GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN,0,6); 

    } 

    public void setRotationMatrix(float[] rotationMatrix) { 
     this.rotationMatrix = rotationMatrix; 
    } 
} 

回答

0

沒有通過您的代碼要多,看來你不旋轉矩陣傳遞給着色器。

GLES20.glUniformMatrix4fv(uMatrixLocation,1,false,mMVPMatrix,0);

上面的代碼應改爲:

GLES20.glUniformMatrix4fv(uMatrixLocation,1,false,rotated,0); 

順便說一句,作爲你的渲染器在不同的線程比您的活動正在接收屏幕方向的工作,你應該張貼在運動onSensorChanged使用queueEvent:

@Override 
public void onSensorChanged(SensorEvent event) { 

    SensorManager.getRotationMatrixFromVector(rotatinMatrix, event.values); 

    final ConditionVariable syncObj = new ConditionVariable(); 
    glSurfaceView.queueEvent(new Runnable() {  
     @Override 
     public void run() { 
      renderer.setRotationMatrix(rotatinMatrix, syncObj); 
     } 
    }); 

    syncObj.block(); 
}; 

而且不要忘記中渲染開syncObj:

public void setRotationMatrix(float[] rotationMatrix, ConditionVariable syncObj) { 
    this.rotationMatrix = rotationMatrix; 
    syncObj.open(); 
} 

希望這有助於!