Antialiasing in OpenGL ES 2.0?

后端 未结 2 1539
暗喜
暗喜 2020-12-15 02:01

Is there a way to implement Anitaliasing technique in OpenGL ES 2.0 ? I have goggled and found few methods but there was no change in the output.

In the worst case

2条回答
  •  -上瘾入骨i
    2020-12-15 02:36

    On Android platform, you can download this OpenGL demo apps source code from GDC 2011: it contains lots of best practices and show you how to do multisampling, including coverage antialiasing.

    What you need to do is just customize GLSurfaceView.EGLConfigChooser and set this chooser:

    // Set this chooser before calling setRenderer()
    setEGLConfigChooser(new MultisampleConfigChooser());
    setRenderer(mRenderer);
    

    MultisampleConfigChooser.java sample code below:

    package com.example.gdc11;
    
    import javax.microedition.khronos.egl.EGL10;
    import javax.microedition.khronos.egl.EGLConfig;
    import javax.microedition.khronos.egl.EGLDisplay;
    
    import android.opengl.GLSurfaceView;
    import android.util.Log;
    
    // This class shows how to use multisampling. To use this, call
    //   myGLSurfaceView.setEGLConfigChooser(new MultisampleConfigChooser());
    // before calling setRenderer(). Multisampling will probably slow down
    // your app -- measure performance carefully and decide if the vastly
    // improved visual quality is worth the cost.
    public class MultisampleConfigChooser implements GLSurfaceView.EGLConfigChooser {
        static private final String kTag = "GDC11";
        @Override
        public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
            mValue = new int[1];
    
            // Try to find a normal multisample configuration first.
            int[] configSpec = {
                    EGL10.EGL_RED_SIZE, 5,
                    EGL10.EGL_GREEN_SIZE, 6,
                    EGL10.EGL_BLUE_SIZE, 5,
                    EGL10.EGL_DEPTH_SIZE, 16,
                    // Requires that setEGLContextClientVersion(2) is called on the view.
                    EGL10.EGL_RENDERABLE_TYPE, 4 /* EGL_OPENGL_ES2_BIT */,
                    EGL10.EGL_SAMPLE_BUFFERS, 1 /* true */,
                    EGL10.EGL_SAMPLES, 2,
                    EGL10.EGL_NONE
            };
    
            if (!egl.eglChooseConfig(display, configSpec, null, 0,
                    mValue)) {
                throw new IllegalArgumentException("eglChooseConfig failed");
            }
            int numConfigs = mValue[0];
    
            if (numConfigs <= 0) {
                // No normal multisampling config was found. Try to create a
                // converage multisampling configuration, for the nVidia Tegra2.
                // See the EGL_NV_coverage_sample documentation.
    
                final int EGL_COVERAGE_BUFFERS_NV = 0x30E0;
                final int EGL_COVERAGE_SAMPLES_NV = 0x30E1;
    
                configSpec = new int[]{
                        EGL10.EGL_RED_SIZE, 5,
                        EGL10.EGL_GREEN_SIZE, 6,
                        EGL10.EGL_BLUE_SIZE, 5,
                        EGL10.EGL_DEPTH_SIZE, 16,
                        EGL10.EGL_RENDERABLE_TYPE, 4 /* EGL_OPENGL_ES2_BIT */,
                        EGL_COVERAGE_BUFFERS_NV, 1 /* true */,
                        EGL_COVERAGE_SAMPLES_NV, 2,  // always 5 in practice on tegra 2
                        EGL10.EGL_NONE
                };
    
                if (!egl.eglChooseConfig(display, configSpec, null, 0,
                        mValue)) {
                    throw new IllegalArgumentException("2nd eglChooseConfig failed");
                }
                numConfigs = mValue[0];
    
                if (numConfigs <= 0) {
                    // Give up, try without multisampling.
                    configSpec = new int[]{
                            EGL10.EGL_RED_SIZE, 5,
                            EGL10.EGL_GREEN_SIZE, 6,
                            EGL10.EGL_BLUE_SIZE, 5,
                            EGL10.EGL_DEPTH_SIZE, 16,
                            EGL10.EGL_RENDERABLE_TYPE, 4 /* EGL_OPENGL_ES2_BIT */,
                            EGL10.EGL_NONE
                    };
    
                    if (!egl.eglChooseConfig(display, configSpec, null, 0,
                            mValue)) {
                        throw new IllegalArgumentException("3rd eglChooseConfig failed");
                    }
                    numConfigs = mValue[0];
    
                    if (numConfigs <= 0) {
                      throw new IllegalArgumentException("No configs match configSpec");
                    }
                } else {
                    mUsesCoverageAa = true;
                }
            }
    
            // Get all matching configurations.
            EGLConfig[] configs = new EGLConfig[numConfigs];
            if (!egl.eglChooseConfig(display, configSpec, configs, numConfigs,
                    mValue)) {
                throw new IllegalArgumentException("data eglChooseConfig failed");
            }
    
            // CAUTION! eglChooseConfigs returns configs with higher bit depth
            // first: Even though we asked for rgb565 configurations, rgb888
            // configurations are considered to be "better" and returned first.
            // You need to explicitly filter the data returned by eglChooseConfig!
            int index = -1;
            for (int i = 0; i < configs.length; ++i) {
                if (findConfigAttrib(egl, display, configs[i], EGL10.EGL_RED_SIZE, 0) == 5) {
                    index = i;
                    break;
                }
            }
            if (index == -1) {
                Log.w(kTag, "Did not find sane config, using first");
            }
            EGLConfig config = configs.length > 0 ? configs[index] : null;
            if (config == null) {
                throw new IllegalArgumentException("No config chosen");
            }
            return config;
        }
    
        private int findConfigAttrib(EGL10 egl, EGLDisplay display,
                EGLConfig config, int attribute, int defaultValue) {
            if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
                return mValue[0];
            }
            return defaultValue;
        }
    
        public boolean usesCoverageAa() {
            return mUsesCoverageAa;
        }
    
        private int[] mValue;
        private boolean mUsesCoverageAa;
    }
    

    Before using this feature, you should known this will affect rendering efficiency, and may need to do a fully performance test.

提交回复
热议问题