我正在写一个实现开放式VG和OpenGL的| ES中去,这两者取决于Khronos的EGL API,据说是为了便于携带,我猜.
出于乐趣和教育原因,我正在OpenGL ES上编写一个OpenVG实现 - 我没有做过很多渲染工作,我想了解更多有关开放API和实践明确标准的实践(更容易看看我是否得到了正确的结果).
据我了解,EGL提供了一个标准API,用于检索绘图上下文(或者它正确调用的内容),而不是使用多个OS提供的API之一(GLX,WGL等)

我很难相信Khronos会经历这样的努力并将标准OpenGL从循环中移开但事实是,我还没有发现OpenGL(真正的交易)如何或者是否与EGL接口或者它是否只是OpenGL ES.如果OpenGL ES可以使用EGL的绘图上下文,标准OpenGL是否也可以使用?
我对这一切都很陌生,这就是为什么我很兴奋,但我正在做的真正项目是一个Go小部件工具包,它利用OpenVG进行绘图操作,并尽可能使用硬件加速.
如果OpenVG,OpenGL和OpenGL ES依赖于EGL,我认为我的问题可以用"是"或"否"来回答.请记住,我昨晚首先进入了这个主题.
OpenGL使用或依赖于EGL吗?
关闭主题,但没有EGL标记.应该有吗?
我想进入EGL.但是,我能找到的"唯一"是API参考.搜索"egl guide","egl tutorial"或"egl for beginners"并没有成功.有谁知道一个好的资源?
EGL可能不是"初学者图书馆".在那种情况下,我想我应该从头开始 - 但是,什么是开始?我刚刚读到EGL是依赖于系统的绘图API的抽象层,因此是"正确"的方法.Wayland使用它,kmscon也是如此.然而,查看他们的源代码只会让我头疼.
PS:作为旁注,我对C++感觉更舒服(虽然我猜想,如果它适用于C,它也应该适用于C++).此外,我正在使用最新的内核,以及最新的Mesa版本,所以我猜有可用于EGL的支持.
任何人都能解释一下EGL是什么以及它的作用是什么?
如何在Linux上使用EGL和OpenGL-ES?
EGL是硬件和操作系统之间的一层吗?
TL; DR
即使完全没有绘图,似乎也无法在Android设备上的OpenGL ES渲染线程上保持60Hz的更新速率.神秘的尖峰经常出现(在底部的代码中展示),并且我已经做出的每一项努力来弄清楚为什么或如何导致死路一条.使用自定义渲染线程在更复杂的示例中进行计时一直表明eglSwapBuffers()是罪魁祸首,经常在17ms-32ms内出现.救命?
更多细节
这尤其令人讨厌,因为我们项目的渲染要求是屏幕对齐元素,从屏幕的一侧到另一侧以固定的高速率平滑地水平滚动.换句话说,一个平台游戏.从60Hz频繁下降会导致明显的弹跳和晃动,无论是否有基于时间的移动.由于滚动速度较高,因此在30Hz下渲染不是一种选择,这是设计中不可协商的部分.
我们的项目是基于Java的,以最大限度地兼容并使用OpenGL ES 2.0.我们只深入了解NDK,用于API 7-8设备上的OpenGL ES 2.0渲染和API 7设备上的ETC1支持.在它和下面给出的测试代码中,我已经验证了除了日志打印和我无法控制的自动线程之外没有分配/ GC事件.
我在一个使用股票Android类而没有NDK的文件中重新创建了这个问题.下面的代码可以粘贴到Eclipse中创建的新Android项目中,只要您选择API级别8或更高级别,它就可以开箱即用.
该测试已在具有各种GPU和OS版本的各种设备上重现:
样本输出(从不到1秒的运行时间收集):
Spike: 0.017554
Spike: 0.017767
Spike: 0.018017
Spike: 0.016855
Spike: 0.016759
Spike: 0.016669
Spike: 0.024925
Spike: 0.017083999
Spike: 0.032984
Spike: 0.026052998
Spike: 0.017372
Run Code Online (Sandbox Code Playgroud)
我一直在追逐这一个并且碰到了一堵砖墙.如果无法获得修复,那么至少可以解释为什么会发生这种情况,以及在具有类似要求的项目中如何克服这一问题的建议将非常感激.
示例代码
package com.test.spikeglsurfview;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Window;
import …Run Code Online (Sandbox Code Playgroud) 我尝试了如OpenGL ES2 for Android中所示的程序,但它不能正常工作!
我在Odroid E,三星s3,三星y,三星之星测试过!!
the gl version suported returns 2, but i get
11-22 15:09:45.804: E/oGl-es v(9047): 2.0:131072
11-22 15:09:45.804: E/libEGL(9047): call to OpenGL ES API with no current context (logged once per thread)
11-22 15:09:45.804: E/unable to(9047): createShader
11-22 15:09:45.804: E/libEGL(9047): call to OpenGL ES API with no current context (logged once per thread)
11-22 15:09:45.804: E/unable to(9047): createShader
11-22 15:09:45.804: E/libEGL(9047): call to OpenGL ES API with no current context (logged once per thread)
11-22 15:09:45.804: …Run Code Online (Sandbox Code Playgroud) 是否允许从main()创建egl上下文并从另一个线程渲染,假设上下文句柄从main()传递给线程的函数?
android的版本是2.2.1,该设备是三星galaxy II的完整崩溃日志是:
java.lang.RuntimeException: createWindowSurface failed: EGL_BAD_MATCH
at android.opengl.GLSurfaceView$EglHelper.throwEglException(GLSurfaceView.java:1077)
at android.opengl.GLSurfaceView$EglHelper.createSurface(GLSurfaceView.java:981)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1304)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1116)
Run Code Online (Sandbox Code Playgroud)
这是崩溃的相关代码:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
glView = new GLSurfaceView(this);
glView.setEGLConfigChooser(8 , 8, 8, 8, 16, 0);
glView.setRenderer(this);
setContentView(glView);
\\etc..............}
Run Code Online (Sandbox Code Playgroud)
我使用了setEGLConfigChooser()因为应用程序会在API-17上崩溃,如果它不在那里那么对于这个特定的设备,它正在崩溃我一直在环顾四周,它与设备的PixelFormat有关.
我想知道的是我怎么能使用一些代码所以这不会在三星galaxy II安卓版2.2.1上崩溃,我不能在模拟器中测试这个并且我没有设备来测试它,我只需要确保代码我不知道如何改变它?
我想在类似于这个答案的设置中创建一个我可以管理的具有OpenGL纹理的SurfaceTexture.(引用到这里:)
- 通过OpenGL创建纹理
- 将此纹理传递给新SurfaceTexture的构造函数.
- 将这个新的SurfaceTexture提供给相机.
- 确保您使用的是OES_External(有关详细信息,请参阅文档).
但是,创建OpenGL纹理(如答案的第1步),需要EGL上下文,这需要使EGLSurface成为当前,这需要SurfaceTexture.似乎创建EGL上下文的唯一方法是创建一个SurfaceView(或具有SurfaceTexture的其他视图),并使用它初始化EGLSurface,然后使EGLContext保持最新.
我的目标是创建一个EGLContext并使其在后台线程中是最新的,在相机预览图像上进行一些屏幕外计算(主要使用NDK).我想创建一个库,并使其尽可能独立于UI.两个相关问题:
在Java方面,是否可以在不事先创建SurfaceTexture的情况下创建EGLContext?
在NDK方面,曾经有一个私有API调用来创建本机窗口android_createDisplaySurface(),但它不再起作用,而且,它是一个私有API.有没有办法用NDK创建表面?
我对使用EGL很陌生,我不明白为什么你需要一个EGLSurface来使EGLContext成为最新的.在iOS中,可以首先创建EAGLContexts,然后根据需要创建帧缓冲区.使用EGL似乎总是需要一个原生窗口.
对于我的生活,我找不到任何适用于OpenGL ES 2的纯Android NDK示例.包含native-activity示例项目的示例项目构建了ES 1上下文.是否有任何示例程序演示如何在纯C++中创建ES 2上下文?
我正在编写一个Android应用程序,我需要缓存视频帧,以便我可以轻松地来回转移,几乎没有延迟.
现在我让android解码视频帧,方法是在MediaCodec对象的Configure调用中提供一个Surface 并调用releaseOutputBufferrender flag设置为true.
的唯一方法,我发现访问解码表面数据(除了解码所返回的字节缓冲区,其格式似乎是依赖于设备的)是调用updateTeximage在SurfaceTexture链接到表面,附接这对GL_TEXTURE_EXTERNAL_OES目标和它渲染到GL_TEXTURE2D目标纹理我创建我自己为了缓存它.
我想优化这个缓存过程,并能够解码不同线程上的帧.使用我当前的方法,这意味着我将不得不为视频解码器创建另一个EGL上下文,共享上下文等...
我的问题是:是否可以在不调用的情况下访问与Surface关联的EGL图像或本机缓冲区数据 updateTexImage?
这样我就可以缓存egl图像(根据不需要EGL上下文EGL_ANDROID_image_native_buffer).这也将以YUV格式缓存,这比我现在缓存的原始RGB纹理更具存储效率.