写出Android OpenGL ES实现3D抛骰子
时间: 2023-11-11 20:12:02 浏览: 209
android OpenGL 3D骰子
3星 · 编辑精心推荐
好的,下面是一个简单的Android OpenGL ES实现3D抛骰子的示例代码:
首先在build.gradle中添加OpenGL ES依赖:
```groovy
implementation 'com.android.support:support-v4:28.0.0'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.google.android.gms:play-services-gcm:16.0.0'
implementation 'com.google.android.gms:play-services-ads:17.1.1'
implementation 'com.google.android.gms:play-services-auth:16.0.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support:cardview-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.squareup.okhttp3:okhttp:3.11.0'
implementation 'com.squareup.okio:okio:1.14.0'
implementation 'com.github.bumptech.glide:glide:4.9.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.11.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'io.reactivex.rxjava2:rxjava:2.2.8'
```
接着创建一个继承自GLSurfaceView的自定义视图:
```java
public class DiceView extends GLSurfaceView implements Renderer {
private final static int DICE_NUM = 3; // 骰子数量
private final static float DICE_SIZE = 0.5f; // 骰子大小
private final static float DICE_SPEED = 0.1f; // 骰子旋转速度
private Dice[] dices = new Dice[DICE_NUM]; // 骰子数组
private float xAngle = 0; // x轴旋转角度
private float yAngle = 0; // y轴旋转角度
private float zAngle = 0; // z轴旋转角度
public DiceView(Context context) {
super(context);
setRenderer(this);
setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
for (int i = 0; i < DICE_NUM; i++) {
dices[i] = new Dice(getContext(), DICE_SIZE, DICE_SPEED);
}
gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glShadeModel(GL10.GL_SMOOTH);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
float ratio = (float) width / height;
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
}
@Override
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
GLU.gluLookAt(gl, 0, 0, 3, 0, 0, 0, 0, 1, 0);
gl.glRotatef(xAngle, 1, 0, 0);
gl.glRotatef(yAngle, 0, 1, 0);
gl.glRotatef(zAngle, 0, 0, 1);
for (int i = 0; i < DICE_NUM; i++) {
dices[i].draw(gl);
}
}
public void setAngles(float xAngle, float yAngle, float zAngle) {
this.xAngle = xAngle;
this.yAngle = yAngle;
this.zAngle = zAngle;
}
}
```
然后创建一个Dice类来表示骰子:
```java
public class Dice {
private FloatBuffer vertexBuffer;
private FloatBuffer textureBuffer;
private ByteBuffer indexBuffer;
private int[] textures = new int[1];
private int[] diceValues = {1, 2, 3, 4, 5, 6};
private float diceSize;
private float diceSpeed;
private float angleX = 0;
private float angleY = 0;
private float angleZ = 0;
private float[] vertices = {
-0.5f, -0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
0.5f, -0.5f, 0.5f
};
private float[] textureCoords = {
0, 0, 0, 1, 1, 1, 1, 0,
0, 0, 0, 1, 1, 1, 1, 0,
0, 0, 0, 1, 1, 1, 1, 0,
0, 0, 0, 1, 1, 1, 1, 0,
0, 0, 0, 1, 1, 1, 1, 0,
0, 0, 0, 1, 1, 1, 1, 0
};
private byte[] indices = {
0, 1, 2, 0, 2, 3,
0, 3, 7, 0, 7, 4,
0, 4, 5, 0, 5, 1,
1, 5, 6, 1, 6, 2,
3, 2, 6, 3, 6, 7,
4, 7, 6, 4, 6, 5
};
public Dice(Context context, float diceSize, float diceSpeed) {
this.diceSize = diceSize;
this.diceSpeed = diceSpeed;
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
ByteBuffer tbb = ByteBuffer.allocateDirect(textureCoords.length * 4);
tbb.order(ByteOrder.nativeOrder());
textureBuffer = tbb.asFloatBuffer();
textureBuffer.put(textureCoords);
textureBuffer.position(0);
indexBuffer = ByteBuffer.allocateDirect(indices.length);
indexBuffer.put(indices);
indexBuffer.position(0);
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.dice);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
Random random = new Random();
setDiceValue(diceValues[random.nextInt(6)]);
}
public void draw(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
gl.glPushMatrix();
gl.glRotatef(angleX, 1, 0, 0);
gl.glRotatef(angleY, 0, 1, 0);
gl.glRotatef(angleZ, 0, 0, 1);
gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_BYTE, indexBuffer);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
public void setDiceValue(int value) {
angleX = 0;
angleY = 0;
angleZ = 0;
switch (value) {
case 1:
angleX = 90;
break;
case 2:
angleX = -90;
break;
case 3:
angleY = 90;
break;
case 4:
angleY = -90;
break;
case 5:
angleZ = 90;
break;
case 6:
angleZ = -90;
break;
}
}
public void update() {
angleX += diceSpeed;
angleY += diceSpeed;
angleZ += diceSpeed;
}
}
```
最后在Activity中使用DiceView即可:
```java
public class MainActivity extends AppCompatActivity {
private DiceView diceView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diceView = new DiceView(this);
setContentView(diceView);
}
@Override
protected void onResume() {
super.onResume();
diceView.onResume();
}
@Override
protected void onPause() {
super.onPause();
diceView.onPause();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
float dx = x - lastX;
float dy = y - lastY;
diceView.setAngles(dy * 0.5f, dx * 0.5f, 0);
diceView.requestRender();
break;
}
lastX = x;
lastY = y;
return true;
}
}
```
这样就实现了一个简单的Android OpenGL ES实现3D抛骰子的程序。
阅读全文