是否可以从RoboVM访问OpenGL ES而不使用LibGDX?

不使用LibGDX ,可以从RoboVM访问iOS上的OpenGL ES吗? 如果是这样,有没有有用的参考?

我能find的唯一的事情就是2年前的这个超级简单的演示:
http://robovm.com/ios-opengles-in-java-on-robovm/
但是除了glClearColor和glClear之外,它不提供任何函数。

虽然,苹果GLKit框架似乎已经实施。 我只是无法find所有的实际glWhatever(…)function…

对的,这是可能的。 您需要两件事:1.访问OpenGL ES函数(如glClear(...)等),2.在您的应用程序中可以绘制GL图像的UIView 。

结果第二点很简单。 如果你怀旧,可以使用GLKView (需要iOS 5.0)或者CAEAGLLayer (需要iOS 2.0)。 对于这两者,网上有很多关于如何在Objective-C中使用它们的教程,这些教程可以很容易地转换成RoboVM。 所以,我不会在这里花太多时间。

由于RoboVM没有提供开箱即用的定义文件,因此访问OpenGL ES函数有点困难。 所以,我们必须用Bro来build立我们自己的。 事实certificate,一旦你围绕Bro处理Cstring,variables指针,IntBuffers等(这实际上相当漂亮!),你真的很直截了当。 我在原始问题中链接到的超级简单演示是正确的出发点。

为了简洁,让我在这里发布一个我写的文件的非常简化的版本,以说明不同数据types可以被处理的方式:

 import java.nio.Buffer; import java.nio.IntBuffer; import org.robovm.rt.bro.Bro; import org.robovm.rt.bro.Struct; import org.robovm.rt.bro.annotation.Bridge; import org.robovm.rt.bro.annotation.Library; import org.robovm.rt.bro.ptr.BytePtr; import org.robovm.rt.bro.ptr.BytePtr.BytePtrPtr; import org.robovm.rt.bro.ptr.IntPtr; @Library("OpenGLES") public class GLES20 { public static final int GL_DEPTH_BUFFER_BIT = 0x00000100; public static final int GL_STENCIL_BUFFER_BIT = 0x00000400; public static final int GL_COLOR_BUFFER_BIT = 0x00004000; public static final int GL_FALSE = 0; public static final int GL_TRUE = 1; private static final int MAX_INFO_LOG_LENGTH = 10*1024; private static final ThreadLocal<IntPtr> SINGLE_VALUE = new ThreadLocal<IntPtr>() { @Override protected IntPtr initialValue() { return Struct.allocate(IntPtr.class, 1); } }; private static final ThreadLocal<BytePtr> INFO_LOG = new ThreadLocal<BytePtr>() { @Override protected BytePtr initialValue() { return Struct.allocate(BytePtr.class, MAX_INFO_LOG_LENGTH); } }; static { Bro.bind(GLES20.class); } @Bridge public static native void glClearColor(float red, float green, float blue, float alpha); @Bridge public static native void glClear(int mask); @Bridge public static native void glGetIntegerv(int pname, IntPtr params); // DO NOT CALL THE NEXT METHOD WITH A pname THAT RETURNS MORE THAN ONE VALUE!!! public static int glGetIntegerv(int pname) { IntPtr params = SINGLE_VALUE.get(); glGetIntegerv(pname, params); return params.get(); } @Bridge private static native int glGetUniformLocation(int program, BytePtr name); public static int glGetUniformLocation(int program, String name) { return glGetUniformLocation(program, BytePtr.toBytePtrAsciiZ(name)); } @Bridge public static native int glGenFramebuffers(int n, IntPtr framebuffers); public static int glGenFramebuffer() { IntPtr framebuffers = SINGLE_VALUE.get(); glGenFramebuffers(1, framebuffers); return framebuffers.get(); } @Bridge private static native void glShaderSource(int shader, int count, BytePtrPtr string, IntPtr length); public static void glShaderSource(int shader, String code) { glShaderSource(shader, 1, new BytePtrPtr().set(BytePtr.toBytePtrAsciiZ(code)), null); } @Bridge private static native void glGetShaderInfoLog(int shader, int maxLength, IntPtr length, BytePtr infoLog); public static String glGetShaderInfoLog(int shader) { BytePtr infoLog = INFO_LOG.get(); glGetShaderInfoLog(shader, MAX_INFO_LOG_LENGTH, null, infoLog); return infoLog.toStringAsciiZ(); } @Bridge public static native void glGetShaderPrecisionFormat(int shaderType, int precisionType, IntBuffer range, IntBuffer precision); @Bridge public static native void glTexImage2D(int target, int level, int internalformat, int width, int height, int border, int format, int type, IntBuffer data); @Bridge private static native void glVertexAttribPointer(int index, int size, int type, int normalized, int stride, Buffer pointer); public static void glVertexAttribPointer(int index, int size, int type, boolean normalized, int stride, Buffer pointer) { glVertexAttribPointer(index, size, type, normalized ? GL_TRUE : GL_FALSE, stride, pointer); } } 

请注意,大多数方法只是通过简单的@Bridge注解本机定义而暴露出来,但对于某些方法来说,在Java中定义一个将String转换为*char或从IntPtr解包结果的包装方法是很方便的。

我没有发布我的整个库文件,因为它仍然是非常不完整的,它只会使它更难find如何处理不同的参数types的例子。

为了节省一些工作,您可以从libGDX的GL20.java复制GL常量定义。 而OpenGL ES文档是方法的调用签名(数据typesGLenumGLbitfield对应于Java int )的很好的参考。

然后您可以通过预先GLES20.静态调用gl-methods GLES20. (就像在Android上),例如:

 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); 

结果Bro非常聪明,甚至不需要在robovm.xml中包含<framework>OpenGLES</framework>标签,就像使用libGDX一样。

而且 – 你知道什么? – 我的应用程序的启动速度是使用libGDX时的3倍。 它解决了我的另一个问题(请参阅LibGDX在应用程序暂停时显示黑屏,但在iOS上仍然可见(例如,在应用内购买密码对话框中 )。 “好极了!” 为了摆脱不必要的行李。

让生活有点恼人的一件事是,如果你搞砸了一个方法或内存分配的调用签名,你的应用程序将会在IDE控制台中一个非常无用的“终止由于信号11”消息而崩溃没有关于应用程序死亡的信息。