我试图在屏幕上绘制一个简单的矩形,并在我物理旋转设备时看到它旋转。我设法获得了一些旋转,但没有任何意义,它似乎不随着设备的方向旋转。
我的主要活动:
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 :(得分:0)
如果不通过代码,似乎您没有将旋转的矩阵传递给着色器。
GLES20.glUniformMatrix4fv(uMatrixLocation,1,假,mMVPMatrix,0);
上述代码应替换为:
GLES20.glUniformMatrix4fv(uMatrixLocation,1,false,rotated,0);
顺便说一句,由于您的渲染器工作在与接收屏幕方向的活动不同的线程中,您应该使用queueEvent在onSensorChanged中发布移动:
@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();
}
希望这有帮助!