J'apprends Java et OpenGL ES pour Android en lisant des tutoriels et en appliquant ce que je sais déjà. Et j'ai maintenant frappé un mur de briques quand il s'agit de faire tourner un objet.Problème de rotation OpenGL
La rotation d'un cube en touchant l'écran ne pose aucun problème. Mais si je fais pivoter le cube de 180 degrés vers le haut ou le bas, alors quand j'essaie maintenant de faire tourner le cube vers la gauche ou vers la droite, il est inversé. Je sais pourquoi cela se passe mais je ne trouve pas de solution.
Le code est ci-dessous si certains veulent le tester:
Fichier "Rotating.java":
package com.test.opengl;
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
public class Rotating extends Activity {
private GLControlView glControlView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
glControlView = new GLControlView(this);
setContentView(glControlView);
}
}
Fichier "GLControlView.java":
package com.test.opengl;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.opengl.GLSurfaceView.Renderer;
import android.view.MotionEvent;
public class GLControlView extends GLSurfaceView implements Renderer {
private Context context;
private float xPrevious, yPrevious;
private float xRotation = 0.0f, yRotation = 0.0f;
private SimpleCubeObject cubeObject;
public GLControlView(Context context) {
super(context);
this.context = context;
this.setRenderer(this);
this.requestFocus();
this.setFocusableInTouchMode(true);
cubeObject = new SimpleCubeObject();
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
}
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glTranslatef(0.0f, 0.0f, -10.0f);
gl.glPushMatrix();
gl.glRotatef(xRotation, 1.0f, 0.0f, 0.0f);
gl.glRotatef(yRotation, 0.0f, 1.0f, 0.0f);
gl.glPushMatrix();
cubeObject.draw(gl);
gl.glPopMatrix();
gl.glPopMatrix();
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl, 45.0f, ((float)width/(float)height), 0.1f, 100.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float xEvent = event.getX();
float yEvent = event.getY();
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN: {
xPrevious = xEvent;
yPrevious = yEvent;
return true;
}
case MotionEvent.ACTION_MOVE: {
float xDelta = xEvent - xPrevious;
float yDelta = yEvent - yPrevious;
xRotation += (yDelta * 0.5f);
yRotation += (xDelta * 0.5f);
xPrevious = xEvent;
yPrevious = yEvent;
return true;
}
default: return super.onTouchEvent(event);
}
}
}
Fichier « SimpleCubeObject .java ":
package com.test.opengl;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import javax.microedition.khronos.opengles.GL10;
public class SimpleCubeObject {
private int[] textures = new int[ 1 ];
private float[] colors = {
0.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f
};
private short[] indices = {
0, 1, 2, 0, 2, 3,
1, 5, 6, 1, 6, 2,
2, 6, 7, 2, 7, 3,
3, 7, 4, 3, 4, 0,
0, 4, 5, 0, 5, 1,
7, 6, 5, 7, 5, 4
};
private float[] vertices = {
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
1.0f, -1.0f, -1.0f
};
private FloatBuffer colorBuffer;
private ShortBuffer indexBuffer;
private FloatBuffer vertexBuffer;
public SimpleCubeObject() {
ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4);
cbb.order(ByteOrder.nativeOrder());
colorBuffer = cbb.asFloatBuffer();
colorBuffer.put(colors);
colorBuffer.position(0);
ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
ibb.order(ByteOrder.nativeOrder());
indexBuffer = ibb.asShortBuffer();
indexBuffer.put(indices);
indexBuffer.position(0);
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
}
public void draw(GL10 gl) {
gl.glFrontFace(GL10.GL_CCW);
gl.glEnable(GL10.GL_CULL_FACE);
gl.glCullFace(GL10.GL_BACK);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[ 0 ]);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, indexBuffer);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
gl.glDisable(GL10.GL_CULL_FACE);
}
}
J'espère que quelqu'un peut m'aider avec ça. Je crois, comme toujours, que la solution est simple et facile - c'est juste moi qui ne peux pas le voir maintenant.
Merci! Cela semble être une mission impossible à assumer, mais les quaternions sont ce dont j'ai besoin. – Espen