如何在TextureView Android中绘制立方体

时间:2015-01-07 09:52:46

标签: java android view opengl-es

我是opengl ES的新手,我想在TextureView上渲染开放式视图。

以下是立方体绘图的示例open-gl示例https://gist.github.com/ybakos/4151696 但 当我试图使用TextureView绘制相同的立方体时,

我无法绘制那个立方体。 指导我如何使用TextureView绘制opengl多维数据集。

以下是示例代码::

public class DemoGraphicGlctivity extends Activity implements TextureView.SurfaceTextureListener {
    private RenderThread mRenderThread;
    private TextureView mTextureView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mTextureView = new TextureView(this);
        mTextureView.setSurfaceTextureListener(this);
        setContentView(mTextureView, new FrameLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, 400));
    }
    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        mRenderThread = new RenderThread(getResources(), surface, DemoGraphicGlctivity.this);
        mRenderThread.start();
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
    }
    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        mRenderThread.finish();
        try {
            mRenderThread.join();
        } catch (InterruptedException e) {
            Log.e(RenderThread.LOG_TAG, "Could not wait for render thread");
        }
        return true;
    }
    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
    }
    private static class RenderThread extends Thread {
        private static final String LOG_TAG = "GLTextureView";
        static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
        static final int EGL_OPENGL_ES2_BIT = 4;
        private volatile boolean mFinished;
        private final Resources mResources;
        private final SurfaceTexture mSurface;

        private EGL10 mEgl;
        private EGLDisplay mEglDisplay;
        private EGLConfig mEglConfig;
        private EGLContext mEglContext;
        private EGLSurface mEglSurface;
        private GL mGL;
        Context context;

        RenderThread(Resources resources, SurfaceTexture surface, Context mContext) {
            mResources = resources;
            mSurface = surface;
            context = mContext;
        }

        @Override
        public void run() {
            initGL();

         // vertices
            FloatBuffer vertexBuffer = ByteBuffer
                    .allocateDirect(CubeConstant.vertices.length * 4)
                    .order(ByteOrder.nativeOrder()).asFloatBuffer();
            vertexBuffer.put(CubeConstant.vertices);
            vertexBuffer.position(0);

            // texture map
            FloatBuffer textureBuffer = ByteBuffer
                    .allocateDirect(CubeConstant.texture.length * 4)
                    .order(ByteOrder.nativeOrder()).asFloatBuffer();
            textureBuffer.put(CubeConstant.texture);
            textureBuffer.position(0);

            // indices
            ByteBuffer indexBuffer = ByteBuffer.allocateDirect(CubeConstant.indices.length);
            indexBuffer.put(CubeConstant.indices);
            indexBuffer.position(0);


            int texture = loadTexture(R.drawable.receipt_bg);

            //int program = buildProgram(sSimpleVS, sSimpleFS);
            int program = ShaderHelper
                    .linkProgram(ShaderHelper
                            .compileVertexShader(TextResourceReader
                                    .readTextFileFromResource(context,
                                            R.raw.cube_vertex)), ShaderHelper
                            .compileFragmentShader(TextResourceReader
                                    .readTextFileFromResource(context,
                                            R.raw.cube_fragment)));



            int aPositionLocation = glGetAttribLocation(program, "a_Position");
            checkGlError();

            int aTextureCoordinatesLocation = glGetAttribLocation(program, "a_TextureCoordinates");
            checkGlError();



            glBindTexture(GL_TEXTURE_2D, texture);
            checkGlError();

            glUseProgram(program);
            checkGlError();

            glVertexAttribPointer(aPositionLocation, 3 , GL_FLOAT, false , 0, vertexBuffer);
            checkGlError();

            vertexBuffer.position(0);   
            glVertexAttribPointer(aPositionLocation, 3 , GL_FLOAT, false , 0, vertexBuffer);
            glEnableVertexAttribArray(aPositionLocation);
            textureBuffer.position(0);
            glVertexAttribPointer(aTextureCoordinatesLocation, 2, GL_FLOAT, false, 0, textureBuffer);
            glEnableVertexAttribArray(aTextureCoordinatesLocation);
            checkGlError();


            glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
            checkGlError();

            while (!mFinished) {
                checkCurrent();
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                checkGlError();

                glBindTexture(GL_TEXTURE_2D, texture);
                glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indexBuffer);

                if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
                    throw new RuntimeException("Cannot swap buffers");
                }
                checkEglError();
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    // Ignore
                }
            }
            finishGL();
        }
        private int loadTexture(int resource) {
            int[] textures = new int[1];
            glActiveTexture(GL_TEXTURE0);
            glGenTextures(1, textures, 0);
            checkGlError();
            int texture = textures[0];
            glBindTexture(GL_TEXTURE_2D, texture);
            checkGlError();

            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
            Bitmap bitmap = BitmapFactory.decodeResource(mResources, resource);
            GLUtils.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap, GL_UNSIGNED_BYTE, 0);
            checkGlError();
            bitmap.recycle();
            return texture;
        }


        private void checkEglError() {
            int error = mEgl.eglGetError();
            if (error != EGL10.EGL_SUCCESS) {
                Log.w(LOG_TAG, "EGL error = 0x" + Integer.toHexString(error));
            }
        }
        private static void checkGlError() {
            int error = glGetError();
            if (error != GL_NO_ERROR) {
                Log.w(LOG_TAG, "GL error = 0x" + Integer.toHexString(error));
            }
        }
        private void finishGL() {
            mEgl.eglDestroyContext(mEglDisplay, mEglContext);
            mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
        }
        private void checkCurrent() {
            if (!mEglContext.equals(mEgl.eglGetCurrentContext()) ||
                    !mEglSurface.equals(mEgl.eglGetCurrentSurface(EGL10.EGL_DRAW))) {
                if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
                    throw new RuntimeException("eglMakeCurrent failed "
                            + GLUtils.getEGLErrorString(mEgl.eglGetError()));
                }
            }
        }

        private void initGL() {
            mEgl = (EGL10) EGLContext.getEGL();
            mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
            if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {
                throw new RuntimeException("eglGetDisplay failed "
                        + GLUtils.getEGLErrorString(mEgl.eglGetError()));
            }

            int[] version = new int[2];
            if (!mEgl.eglInitialize(mEglDisplay, version)) {
                throw new RuntimeException("eglInitialize failed " +
                        GLUtils.getEGLErrorString(mEgl.eglGetError()));
            }
            mEglConfig = chooseEglConfig();
            if (mEglConfig == null) {
                throw new RuntimeException("eglConfig not initialized");
            }

            mEglContext = createContext(mEgl, mEglDisplay, mEglConfig);
            mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig, mSurface, null);
            if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) {
                int error = mEgl.eglGetError();
                if (error == EGL10.EGL_BAD_NATIVE_WINDOW) {
                    Log.e(LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
                    return;
                }
                throw new RuntimeException("createWindowSurface failed "
                        + GLUtils.getEGLErrorString(error));
            }
            if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
                throw new RuntimeException("eglMakeCurrent failed "
                        + GLUtils.getEGLErrorString(mEgl.eglGetError()));
            }
            mGL = mEglContext.getGL();
        }

        EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
            int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
            return egl.eglCreateContext(eglDisplay, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);            
        }
        private EGLConfig chooseEglConfig() {
            int[] configsCount = new int[1];
            EGLConfig[] configs = new EGLConfig[1];
            int[] configSpec = getConfig();
            if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) {
                throw new IllegalArgumentException("eglChooseConfig failed " +
                        GLUtils.getEGLErrorString(mEgl.eglGetError()));
            } else if (configsCount[0] > 0) {
                return configs[0];
            }
            return null;
        }

        private static int[] getConfig() {
            return new int[] {
                    EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
                    EGL10.EGL_RED_SIZE, 8,
                    EGL10.EGL_GREEN_SIZE, 8,
                    EGL10.EGL_BLUE_SIZE, 8,
                    EGL10.EGL_ALPHA_SIZE, 8,
                    EGL10.EGL_DEPTH_SIZE, 0,
                    EGL10.EGL_STENCIL_SIZE, 0,
                    EGL10.EGL_NONE
            };
        }
        void finish() {
            mFinished = true;
        }
    }
}

请让我知道我哪里出错......

1 个答案:

答案 0 :(得分:0)

我不知道多少但是我必须在这个问题上遵守指示: 创建一个OpenGL上下文

  1. 生成OpenGL纹理名称。
  2. 使用纹理名称创建SurfaceTexture。
  3. 将SurfaceTexture传递给相机。
  4. 收听更新。
  5. 在SurfaceTexture更新中,使用OpenGL使用OpenGL绘制纹理 你想要的着色器。