用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字
云代码 - android代码库

3D魔方

2013-03-10 作者: 海大软件1102班举报

[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;
        }
    }
}


网友评论    (发表评论)

共3 条评论 1/1页

发表评论:

评论须知:

  • 1、评论每次加2分,每天上限为30;
  • 2、请文明用语,共同创建干净的技术交流环境;
  • 3、若被发现提交非法信息,评论将会被删除,并且给予扣分处理,严重者给予封号处理;
  • 4、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。


扫码下载

加载中,请稍后...

输入口令后可复制整站源码

加载中,请稍后...