用户注册



邮箱:

密码:

用户登录


邮箱:

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

发表随想


还能输入: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、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。


扫码下载

加载中,请稍后...

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

加载中,请稍后...