我正在尝试使用官方NDK加载一些着色器并使用android GLSurfaceView和C ++渲染一个hello world三角形。但是我收到错误“调用没有当前上下文的OpenGL ES API”。这是我的简单单个文件java(注意这是整个项目中唯一的java代码)来自google's tutorial的侧面上下文创建代码:
class GLESRenderer implements GLSurfaceView.Renderer
{
static {
System.loadLibrary("native_code");
}
private native void ntInit();
private native void ntRender();
private native void ntUpdateScreen(int width, int height);
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
ntInit(); // LOAD SHADERS AND VBO DATA!!!!
}
public void onDrawFrame(GL10 unused) {
ntRender(); // DRAW USING SHADERS AND VBO DATA!!!!
}
public void onSurfaceChanged(GL10 unused, int width, int height) {
ntUpdateScreen(width, height); // UPDATE SCREEN!!!
}
}
class GLES_SurfaceView extends GLSurfaceView {
private final GLESRenderer mRenderer;
public GLES_SurfaceView(Context context){
super(context);
setEGLContextClientVersion(2);
mRenderer = new GLESRenderer();
setRenderer(mRenderer);
}
}
public class Main extends Activity {
private GLSurfaceView mGLView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGLView = new GLES_SurfaceView(this);
if(Build.VERSION.SDK_INT < 16) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
ActionBar bar = getActionBar();
if(bar != null)
bar.hide();
}
setContentView(mGLView);
}
}
许多其他堆栈溢出问题(没有一个使用NDK,所以它们可能是不同的问题)表明这是一个线程问题,但是这段代码清楚地调用了GLSurfaceView.Renderer中的本机函数,所以我很确定这不是一个线程问题。
此外,多个教程使用相同的方法使用opengl和NDK进行渲染。例如:Intel's tutorial和learnopengles's tutorial。
因此,我认为我的上下文创建存在问题
答案 0 :(得分:0)
忘了回答这个问题。出现此问题是因为C ++的默认构造函数系统。在我的OpenGL上下文创建之前,我正在加载我的&#34; native_code&#34;图书馆。然而,我的本机着色器类具有默认构造函数,这些构造函数使OpenGL调用自己进行初始化。像这样:
class LightingShader
{
LightingShader()
{
glCreateShader(...) // BAD TO CALL OPENGL HERE WITHOUT CONTEXT CREATED
....
}
};
....
LightingShader light_shader; // <- GLOBAL VARIABLE, DEFAULT CONSTRUCTOR CALLED!!!!
所以基本上当它们加载库时,C ++着色器会自动调用它们的构造函数。在初始化OpenGL之前调用了这个库!我通过删除默认构造函数来修复此问题,而是使用返回对象的函数:
class LightingShader
{
LightingShader getLightingShaderInstance()
{
glCreateShader(...)
....
}
};
因此,对我来说,这是一个隐藏在糟糕的面向对象设计中的偷偷摸摸的错误。