简体   繁体   English

OpenGL ES 2.0 和 OpenGL ES 3.0 的单一代码

[英]Single code for OpenGL ES 2.0 and OpenGL ES 3.0

Situation: Android application supports two versions of OpenGL ES: 2.0 and 3.0.情况:Android 应用程序支持两个版本的 OpenGL ES:2.0 和 3.0。 Differences are only in shaders.差异仅在着色器中。 I do not want to make separate sets of classes for versions 2 and 3, but want merge them.我不想为版本 2 和 3 制作单独的类集,但想要合并它们。 That is, instead of two similar classes:也就是说,而不是两个相似的类:

import android.opengl.GLES20;
class ObjectGLES20 {
    public ObjectGLES20() {
        ...
        // invoke static methods from GLES20
        int positionLink = GLES20.glGetAttribLocation(programObject, "a_position");
        int lightPositionLink = GLES20.glGetUniformLocation(programObject, "u_lightPosition");
        ...
    }
}

import android.opengl.GLES30;
class ObjectGLES30 {
    public ObjectGLES30() {
        ...
        // invoke static methods from GLES30
        int positionLink = GLES30.glGetAttribLocation(programObject, "a_position");
        int lightPositionLink = GLES30.glGetUniformLocation(programObject, "u_lightPosition");
        ...
    }
}

Do something like this:做这样的事情:

// define supported version OpenGL ES
if (getVersionGLES() >= 3.0 && Build.VERSION.SDK_INT >= 18) { 
    objectAll = new ObjectAll(new GLES30(), true) // use polymorphism
} else objectAll = new ObjectAll(new GLES20(), false)
...
/** @param gles - instance of GLES20 or GLES30 */
class ObjectAll {
    public ObjectAll(GLES20 gles, boolean isSupportGLES30) {
        String pathToVertexShader;
        String pathToFragmentShader;
        if (isSupportGLES30) {
            pathToVertexShader = "shaders/gles30/vertex_shader.glsl";
            pathToFragmentShader = "shaders/gles30/fragment_shader.glsl";
        } else {
            pathToVertexShader = "shaders/gles20/vertex_shader.glsl";
            pathToFragmentShader = "shaders/gles20/fragment_shader.glsl";
        }
        int programObject = linkProgram(pathToVertexShader, pathToFragmentShader);
        ...
        // invoke static methods from GLES20 or GLES30 depending on supported version
        // TIP!: static member accessed via instance reference
        int positionLink = gles.glGetAttribLocation(programObject, "a_position");
        int lightPositionLink = gles.glGetUniformLocation(programObject, 
            "u_lightPosition");
        ...
    }
}

But this approach (create instances GLES) seems not good for calling static methods.但是这种方法(创建实例 GLES)似乎不太适合调用静态方法。 Maybe there are other options, such as reflection or others?也许还有其他选择,例如反思或其他? Thank you all.谢谢你们。

But this approach seems not good for calling static methods GLES.但是这种方法似乎不太适合调用静态方法 GLES。

The Android GLES30 object is a subclass of GLES20 , and the underlying native API doesn't make such a distinction and the same native function will be used for both.而Android GLES30对象是类的子类GLES20 ,和底层本地API不作这样的区分,并且在同一本地函数将被用于两者。

I strongly suspect it really doesn't matter and you can safely call GLES20.glFoo() for the functions and constants that are only in GLES20 and it will work fine for both GLES20 and GLES30 content.我强烈怀疑这真的无关紧要,您可以安全地为仅在GLES20的函数和常量调用GLES20.glFoo() ,它对GLES20GLES30内容都可以正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM