基于基础多态性的版本GLES 2.0和GLES 3.0的代码合并

问题描述 投票:0回答:1

情况:Android应用程序支持两个版本的OpenGL ES:2.0和3.0。差异仅在着色器中。我不想为版本2和3设置单独的类集,但希望将它们合并。也就是说,而不是两个类似的类:

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");
    ...
  }
}

执行类似操作:

// 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");
    ...
  }
}

但是这种方法(创建实例GLES)似乎不适合调用静态方法。也许还有其他选择,例如反射或其他?谢谢大家。

java android opengl-es
1个回答
1
投票

但是这种方法似乎不适用于调用静态方法GLES。

Android GLES30对象是GLES20的子类,而底层的本机API并没有这种区别,相同的本机函数将用于两者。

[我强烈怀疑这真的没关系,您可以安全地为仅位于GLES20.glFoo()中的函数和常量调用GLES20,并且对于GLES20GLES30内容都可以正常工作。

© www.soinside.com 2019 - 2024. All rights reserved.