[Go Back]
兹以Android程序来实现图2的设计,其原始程序代码如下:
// -------- ac01.java程序代码 ---------
package com.misoo.ppxx;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.CompoundButton.OnCheckedChangeListener;
public class ac01 extends Activity implements OnCheckedChangeListener {
private final int WC = LinearLayout.LayoutParams.WRAP_CONTENT;
private int state_var_A, state_var_B;
public boolean isCube;
@Override protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
state_var_A = 0; state_var_B = 0; isCube = false;
goto_state_1();
}
void goto_state_1() {
setTitle("State_1");
state_var_A = 1;
LinearLayout layout_01 = new LinearLayout(this);
layout_01.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams param =
new LinearLayout.LayoutParams(200, 250);
param.leftMargin = 1; param.topMargin = 3;
if(state_var_B == 0 || state_var_B == 3) isCube = false;
else isCube = true;
MySurfaceView sv = new MySurfaceView(this);
sv.setCube(isCube);
layout_01.addView(sv,param);
setContentView(layout_01);
}
void goto_state_2() {
setTitle("State_2"); state_var_A = 2;
goto_state_3(); // default state
}
void show_layout_02() {
LinearLayout.LayoutParams para;
LinearLayout layout_02 = new LinearLayout(this);
layout_02.setOrientation(LinearLayout.HORIZONTAL);
para = new LinearLayout.LayoutParams(200, 250);
para.leftMargin = 1;
para.topMargin = 3;
MySurfaceView sv = new MySurfaceView(this);
sv.setCube(isCube);
layout_02.addView(sv,para);
CheckBox cx = new CheckBox(this);
cx.setText("Cube");
cx.setChecked(isCube);
cx.setOnCheckedChangeListener(this);
para = new LinearLayout.LayoutParams(WC, WC);
para.leftMargin = 30;
para.topMargin = 30;
layout_02.addView(cx, para);
setContentView(layout_02);
}
void goto_state_3() { state_var_A = 2; state_var_B = 3; setTitle("State_3"); }
void goto_state_4() { state_var_A = 2; state_var_B = 4; setTitle("State_4"); }
@Override public boolean onKeyDown(int keyCode, KeyEvent msg) {
switch(keyCode) {
case KeyEvent.KEYCODE_A:
if(state_var_A == 1)
if(isCube) { this.show_layout_02(); goto_state_4(); }
else { this.show_layout_02(); goto_state_3(); }
else if(state_var_A == 2) goto_state_1();
break;
}
return true;
}
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(state_var_A == 2){
if(state_var_B == 3) goto_state_4();
else if(state_var_B == 4) goto_state_3();
}}}
以下是3D绘图的程序代码:
// -------- MySurfaceView.java程序代码 ---------
package com.misoo.ppxx;
import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGL11;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLSurface;
import javax.microedition.khronos.opengles.GL10;
class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {
SurfaceHolder mHolder;
private GLThread mGLThread;
private MyCube mCube_cb, mCube_pr;
private float mAngle;
private boolean isCube;
MySurfaceView(Context context) { super(context); init(); }
public void setCube(boolean cb) { isCube = cb; }
public MySurfaceView(Context context, AttributeSet attrs) {
super(context, attrs); init(); }
private void init() {
mHolder = getHolder(); mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
}
public void surfaceCreated(SurfaceHolder holder) {
mGLThread = new GLThread();
mGLThread.start();
}
public void surfaceDestroyed(SurfaceHolder holder) {
mGLThread.requestExitAndWait();
mGLThread = null;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
mGLThread.onWindowResize(w, h);
}
// ----------------------------------------------------------------------
class GLThread extends Thread {
private boolean mDone;
private boolean mSizeChanged = true;
private int mWidth, mHeight;
GLThread() {
super();
mDone = false; mWidth = 0; mHeight = 0;
byte indices_cb[] = {
0, 7, 3, 7, 0, 4,
4, 0, 5, 5, 0, 1,
5, 1, 2, 5, 2, 6,
6, 2, 7, 7, 2, 3,
2, 1, 3, 3, 1, 0,
7, 4, 5, 6, 7, 5,
};
byte indices_pr[] = {
6, 0, 1, 5, 1, 0,
1, 5, 6, 0, 6, 5,
};
mCube_cb = new MyCube(indices_cb);
mCube_pr = new MyCube(indices_pr);
}
@Override public void run() {
EGL10 egl = (EGL10)EGLContext.getEGL();
EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
int[] version = new int[2];
egl.eglInitialize(dpy, version);
int[] configSpec = {
EGL10.EGL_RED_SIZE, 8,
EGL10.EGL_GREEN_SIZE, 8,
EGL10.EGL_BLUE_SIZE, 8,
EGL10.EGL_DEPTH_SIZE, 16,
EGL10.EGL_NONE
};
EGLConfig[] configs = new EGLConfig[1];
int[] num_config = new int[1];
egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config);
EGLConfig config = configs[0];
EGLContext glc = egl.eglCreateContext(dpy, config,
EGL10.EGL_NO_CONTEXT, null);
EGLSurface surface = null;
GL10 gl = null;
while (!mDone) {
int w, h;
boolean changed;
synchronized(this) {
changed = mSizeChanged;
w = mWidth;
h = mHeight;
mSizeChanged = false;
}
if (changed) {
surface = egl.eglCreateWindowSurface(dpy, config, mHolder, null);
egl.eglMakeCurrent(dpy, surface, surface, glc);
gl = (GL10)glc.getGL();
gl.glDisable(GL10.GL_DITHER);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
GL10.GL_FASTEST);
gl.glClearColor(1,1,1,1);
gl.glEnable(GL10.GL_CULL_FACE);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glViewport(0, 0, w, h);
float ratio = (float)w / h;
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
}
drawFrame(gl);
egl.eglSwapBuffers(dpy, surface);
if (egl.eglGetError() == EGL11.EGL_CONTEXT_LOST) {
Context c = getContext();
if (c instanceof Activity) {
((Activity)c).finish();
}}}
egl.eglMakeCurrent(dpy, EGL10.EGL_NO_SURFACE,
EGL10.EGL_NO_SURFACE,
EGL10.EGL_NO_CONTEXT);
egl.eglDestroySurface(dpy, surface);
egl.eglDestroyContext(dpy, glc);
egl.eglTerminate(dpy);
}
private void drawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | L10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glTranslatef(0, 0, -3.0f);
gl.glRotatef(mAngle, 0, 1, 0);
gl.glRotatef(mAngle*0.25f, 1, 0, 0);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
mCube_pr.draw(gl);
gl.glRotatef(mAngle*2.0f, 0, 1, 1);
gl.glTranslatef(0.5f, 0.5f, 0.5f);
if(isCube) mCube_cb.draw(gl);
mAngle += 1.2f;
}
public void onWindowResize(int w, int h) {
synchronized(this) {
mWidth = w; mHeight = h;
mSizeChanged = true;
}}
public void requestExitAndWait() {
mDone = true;
try { join(); }
catch (InterruptedException ex) { }
}}}
// -------- MyCube.java程序代码 ---------
package com.misoo.ppxx;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import javax.microedition.khronos.opengles.GL10;
class MyCube {
private int mTriangles;
public MyCube(byte [] indices) {
int one = 0x10000;
int vertices[] = {
-one, -one, -one,
one, -one, -one,
one, one, -one,
-one, one, -one,
-one, -one, one,
one, -one, one,
one, one, one,
-one, one, one,
};
int colors[] = {
0, 0, 0, one,
one, 0, 0, one,
one, 0, one, one,
0, one, 0, one,
0, 0, one, one,
one, one, 0, one,
one, one, one, one,
0, one, one, one,
};
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer = vbb.asIntBuffer();
mVertexBuffer.put(vertices);
mVertexBuffer.position(0);
ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);
cbb.order(ByteOrder.nativeOrder());
mColorBuffer = cbb.asIntBuffer();
mColorBuffer.put(colors);
mColorBuffer.position(0);
mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
mIndexBuffer.put(indices);
mIndexBuffer.position(0);
mTriangles = indices.length;
}
@SuppressWarnings("static-access")
public void draw(GL10 gl) {
gl.glFrontFace(GL10.GL_CW);
gl.glVertexPointer(3, gl.GL_FIXED, 0, mVertexBuffer);
gl.glColorPointer(4, gl.GL_FIXED, 0, mColorBuffer);
gl.glDrawElements(gl.GL_TRIANGLES, mTriangles, gl.GL_UNSIGNED_BYTE,
mIndexBuffer);
}
private IntBuffer mVertexBuffer;
private IntBuffer mColorBuffer;
private ByteBuffer mIndexBuffer;
}
[Go Back]