[android]代码库
package com.example.android.image3D;
import android.view.SurfaceView;
import android.view.SurfaceHolder;
import android.content.Context;
import android.util.AttributeSet;
import java.util.ArrayList;
import java.util.concurrent.Semaphore;
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.GL;
import javax.microedition.khronos.opengles.GL10;
public class View3D extends SurfaceView implements SurfaceHolder.Callback {
private static final Semaphore sEglSemaphore = new Semaphore (1);
private boolean mSizeChanged = true;
private SurfaceHolder mHolder;
private GLThread mGLThread;
private GLWrapper mGLWrapper;
public View3D (Context context) {
super (context);
init();
}
public View3D (Context context, AttributeSet attrs) {
super (context, attrs);
init();
}
private void init() {
mHolder = getHolder();
mHolder.addCallback (this);
mHolder.setType (SurfaceHolder.SURFACE_TYPE_GPU);
}
public SurfaceHolder getSurfaceHolder() {
return mHolder;
}
public void setGLWrapper (GLWrapper glWrapper) {
mGLWrapper = glWrapper;
}
public void setRenderer (Renderer renderer) {
mGLThread = new GLThread (renderer);
mGLThread.start();
}
public void surfaceCreated (SurfaceHolder holder) {
mGLThread.surfaceCreated();
}
public void surfaceDestroyed (SurfaceHolder holder) {
mGLThread.surfaceDestroyed();
}
public void surfaceChanged (SurfaceHolder holder,
int format, int w, int h) {
mGLThread.onWindowResize (w, h);
}
public void onPause() {
mGLThread.onPause();
}
public void onResume() {
mGLThread.onResume();
}
@Override
public void onWindowFocusChanged (boolean hasFocus) {
super.onWindowFocusChanged (hasFocus);
mGLThread.onWindowFocusChanged (hasFocus);
}
public void queueEvent (Runnable r) {
mGLThread.queueEvent (r);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mGLThread.requestExitAndWait();
}
public interface GLWrapper {
GL wrap (GL gl);
}
public interface Renderer {
int[] getConfigSpec();
void surfaceCreated (GL10 gl);
void sizeChanged (GL10 gl, int width, int height);
void drawFrame (GL10 gl);
}
private class EglHelper {
EGL10 mEgl;
EGLDisplay mEglDisplay;
EGLSurface mEglSurface;
EGLConfig mEglConfig;
EGLContext mEglContext;
public EglHelper() {
}
public void start (int[] configSpec) {
mEgl = (EGL10) EGLContext.getEGL();
mEglDisplay = mEgl.eglGetDisplay (EGL10.EGL_DEFAULT_DISPLAY);
int[] version = new int[2];
mEgl.eglInitialize (mEglDisplay, version);
EGLConfig[] configs = new EGLConfig[1];
int[] num_config = new int[1];
mEgl.eglChooseConfig (mEglDisplay, configSpec, configs, 1,
num_config);
mEglConfig = configs[0];
mEglContext = mEgl.eglCreateContext (mEglDisplay, mEglConfig,
EGL10.EGL_NO_CONTEXT, null);
mEglSurface = null;
}
public GL createSurface (SurfaceHolder holder) {
if (mEglSurface != null) {
mEgl.eglMakeCurrent (mEglDisplay, EGL10.EGL_NO_SURFACE,
EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
mEgl.eglDestroySurface (mEglDisplay, mEglSurface);
}
mEglSurface = mEgl.eglCreateWindowSurface (mEglDisplay,
mEglConfig, holder, null);
mEgl.eglMakeCurrent (mEglDisplay, mEglSurface, mEglSurface,
mEglContext);
GL gl = mEglContext.getGL();
if (mGLWrapper != null) {
gl = mGLWrapper.wrap (gl);
}
return gl;
}
public boolean swap() {
mEgl.eglSwapBuffers (mEglDisplay, mEglSurface);
return mEgl.eglGetError() != EGL11.EGL_CONTEXT_LOST;
}
public void finish() {
if (mEglSurface != null) {
mEgl.eglMakeCurrent (mEglDisplay, EGL10.EGL_NO_SURFACE,
EGL10.EGL_NO_SURFACE,
EGL10.EGL_NO_CONTEXT);
mEgl.eglDestroySurface (mEglDisplay, mEglSurface);
mEglSurface = null;
}
if (mEglContext != null) {
mEgl.eglDestroyContext (mEglDisplay, mEglContext);
mEglContext = null;
}
if (mEglDisplay != null) {
mEgl.eglTerminate (mEglDisplay);
mEglDisplay = null;
}
}
}
class GLThread extends Thread {
private boolean mDone;
private boolean mPaused;
private boolean mHasFocus;
private boolean mHasSurface;
private boolean mContextLost;
private int mWidth;
private int mHeight;
private Renderer mRenderer;
private ArrayList<Runnable>
mEventQueue = new ArrayList<Runnable>();
private EglHelper mEglHelper;
GLThread (Renderer renderer) {
super();
mDone = false;
mWidth = 0;
mHeight = 0;
mRenderer = renderer;
setName ("GLThread");
}
@Override
public void run() {
try {
try {
sEglSemaphore.acquire();
} catch (InterruptedException e) {
return;
}
guardedRun();
} catch (InterruptedException e) {
} finally {
sEglSemaphore.release();
}
}
private void guardedRun() throws InterruptedException {
mEglHelper = new EglHelper();
int[] configSpec = mRenderer.getConfigSpec();
mEglHelper.start (configSpec);
GL10 gl = null;
boolean tellRendererSurfaceCreated = true;
boolean tellRendererSurfaceChanged = true;
while (!mDone) {
int w, h;
boolean changed;
boolean needStart = false;
synchronized (this) {
Runnable r;
while ( (r = getEvent() ) != null) {
r.run();
}
if (mPaused) {
mEglHelper.finish();
needStart = true;
}
if (needToWait() ) {
while (needToWait() ) {
wait();
}
}
if (mDone) {
break;
}
changed = mSizeChanged;
w = mWidth;
h = mHeight;
mSizeChanged = false;
}
if (needStart) {
mEglHelper.start (configSpec);
tellRendererSurfaceCreated = true;
changed = true;
}
if (changed) {
gl = (GL10) mEglHelper.createSurface (mHolder);
tellRendererSurfaceChanged = true;
}
if (tellRendererSurfaceCreated) {
mRenderer.surfaceCreated (gl);
tellRendererSurfaceCreated = false;
}
if (tellRendererSurfaceChanged) {
mRenderer.sizeChanged (gl, w, h);
tellRendererSurfaceChanged = false;
}
if ( (w > 0) && (h > 0) ) {
mRenderer.drawFrame (gl);
mEglHelper.swap();
}
}
mEglHelper.finish();
}
private boolean needToWait() {
return (mPaused || (! mHasFocus) || (! mHasSurface) || mContextLost)
&& (! mDone);
}
public void surfaceCreated() {
synchronized (this) {
mHasSurface = true;
mContextLost = false;
notify();
}
}
public void surfaceDestroyed() {
synchronized (this) {
mHasSurface = false;
notify();
}
}
public void onPause() {
synchronized (this) {
mPaused = true;
}
}
public void onResume() {
synchronized (this) {
mPaused = false;
notify();
}
}
public void onWindowFocusChanged (boolean hasFocus) {
synchronized (this) {
mHasFocus = hasFocus;
if (mHasFocus == true) {
notify();
}
}
}
public void onWindowResize (int w, int h) {
synchronized (this) {
mWidth = w;
mHeight = h;
mSizeChanged = true;
}
}
public void requestExitAndWait() {
synchronized (this) {
mDone = true;
notify();
}
try {
join();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
public void queueEvent (Runnable r) {
synchronized (this) {
mEventQueue.add (r);
}
}
private Runnable getEvent() {
synchronized (this) {
if (mEventQueue.size() > 0) {
return mEventQueue.remove (0);
}
}
return null;
}
}
}
初级程序员
by: Andy_wang 发表于:2013-04-03 15:48:57 顶(0) | 踩(0) 回复
截图看看运行效果啊!
回复评论