微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

android – GLSurfaceView onDrawFrame清除行为

我使用GLSurfaceView遇到了不同的行为.
AFAIK是程序的责任,清除每帧的缓冲区(颜色和深度).这意味着如果我不清除缓冲区,我会得到最后一帧的内容(或者之前用于双缓冲的内容).

似乎无论在某些设备上是什么,缓冲区都被清除了.我在Addison Wesley OpenglES2.0编程指南中对一些具有不同结果的测试设备进行了“Hello Triangle”程序的以下修改

> Acer Iconia A500(4.0.3):未清除(预期行为)
> Sony XPERIA Go(4.0.4):已清除
> galaxy S3(4.1.1):清除
> LG Optimus 4x HD(4.0.3):未清除
>三星galaxy Tab 20.1(4.0.4):未清除
>摩托罗拉Xoom(3.2):未清除
> galaxy S2(4.1.2 – rooted):清除

有没有办法强制在每个绘制回调中获得一个未更改的缓冲区?

清除屏幕的设备的结果如下所示:

测试活动如下所示:

package com.example.glcleartest;

import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;

public class MainActivity extends Activity {

protected static final int NUM_VERTICES = 3;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    GLSurfaceView glview = (GLSurfaceView) findViewById(R.id.glview);
    glview.setEGLConfigChooser(false);
    glview.setEGLContextClientVersion(2);
    glview.setRenderer(new Renderer() {

        private int programObject;
        private FloatBuffer vertexBuffer;

        @Override
        public void onSurfaceCreated(GL10 gl,EGLConfig config) {
        }

        @Override
        public void onSurfaceChanged(GL10 gl,int width,int height) {
            GLES20.glViewport(0,width,height);
            init();
        }

        @Override
        public void onDrawFrame(GL10 gl) {
            float x = 0.1f*(float) Math.sin(System.currentTimeMillis()/1000.0);
            float[] vVertices = new float[]{x,0.5f,0.0f,x-0.5f,-0.5f,x+0.5f,0.0f};
            vertexBuffer.rewind();
            vertexBuffer.put(vVertices);
            vertexBuffer.rewind();


            // Use the program object
            GLES20.gluseProgram(programObject);
            int handle = GLES20.glGetUniformlocation(programObject,"uColor");
            float r = (float) (0.5f+Math.sin(System.currentTimeMillis()/1000.0));
            float g = (float) (0.5f+Math.sin(System.currentTimeMillis()/300.0));
            GLES20.gluniform4f(handle,r,g,1);

            // Load the vertex data
            GLES20.glVertexAttribPointer(0,3,GLES20.GL_FLOAT,false,vertexBuffer);
            GLES20.glEnabLevertexAttribArray(0);
            GLES20.glDrawArrays(GLES20.GL_TRIANGLES,3);             
        }

        private void error(String s) {
            Log.e("GLTEST",s);
        }

        private int loadShader(int shaderType,String source) {
            if (shaderType != GLES20.GL_FRAGMENT_SHADER && shaderType != GLES20.GL_VERTEX_SHADER) {
                throw new RuntimeException("Illegal shader type");
            }

            int shader = GLES20.glCreateShader(shaderType);
            if (shader != 0) {
                GLES20.glShaderSource(shader,source);
                GLES20.glCompileShader(shader);
                int[] compiled = new int[1];
                GLES20.glGetShaderiv(shader,GLES20.GL_COMPILE_STATUS,compiled,0);
                if (compiled[0] == 0) {
                    error("Could not compile shader :");
                    error(GLES20.glGetShaderInfoLog(shader));
                    GLES20.glDeleteShader(shader);
                    shader = 0;
                    throw new RuntimeException("Shader Syntax / compilation error");
                }
            }
            return shader;
        }

        private void init() {
            String vShaderStr = "attribute vec4 vPosition; \n" + 
                                    "void main() \n" + "{ \n" + 
                                    " gl_Position = vPosition; \n" + 
                                    "} \n";
            String fShaderStr = "precision mediump float; \n" +
                                        "uniform vec4 uColor;" +
                                        "void main() \n" + 
                                        "{ \n" + 
                                        " gl_FragColor = uColor; \n" + 
                                        "} \n";

            ByteBuffer vbb = ByteBuffer.allocateDirect(NUM_VERTICES*3*4);
            vbb.order(ByteOrder.nativeOrder());
            vertexBuffer = vbb.asFloatBuffer();

            int vertexShader;
            int fragmentShader;

            // Load the vertex/fragment shaders
            vertexShader = loadShader(GLES20.GL_VERTEX_SHADER,vShaderStr);
            fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER,fShaderStr);

            // Create the program object
            programObject = GLES20.glCreateProgram();
            if (programObject == 0)
                return;

            GLES20.glAttachShader(programObject,vertexShader);
            GLES20.glAttachShader(programObject,fragmentShader);
            // Bind vPosition to attribute 0
            GLES20.glBindAttribLocation(programObject,"vPosition");
            // Link the program
            GLES20.glLinkProgram(programObject);
            int[] linkStatus = new int[1];
            GLES20.glGetProgramiv(programObject,GLES20.GL_LINK_STATUS,linkStatus,0);

            if (linkStatus[0] != GLES20.GL_TRUE) {
                error("Could not link program: ");
                error(GLES20.glGetProgramInfoLog(programObject));
                GLES20.glDeleteProgram(programObject);
                programObject = 0;
            }
        }
    });
}
}
最佳答案
如果要在交换后保留后备缓冲内容,则必须将交换表面的EGL_SWAP_BEHAVIOR属性设置为EGL_BUFFER_PRESERVED,如EGL API所记录的那样.尽管在大多数平台上都会意识到,这将是一个相当大的性能影响.在大多数情况下,重新绘制框架要好得多.

有点历史:见http://www.khronos.org/registry/egl/specs/EGLTechNote0001.html

原文地址:https://www.jb51.cc/android/430784.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐