Add off-screen GL context
This commit is contained in:
parent
25f01cb09d
commit
abdf931832
|
@ -719,6 +719,12 @@ const char *OS::get_video_driver_name(int p_driver) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OS::is_offscreen_gl_available() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OS::set_offscreen_gl_current(bool p_current) {}
|
||||||
|
|
||||||
int OS::get_audio_driver_count() const {
|
int OS::get_audio_driver_count() const {
|
||||||
return AudioDriverManager::get_driver_count();
|
return AudioDriverManager::get_driver_count();
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,6 +191,9 @@ public:
|
||||||
virtual const char *get_video_driver_name(int p_driver) const;
|
virtual const char *get_video_driver_name(int p_driver) const;
|
||||||
virtual int get_current_video_driver() const = 0;
|
virtual int get_current_video_driver() const = 0;
|
||||||
|
|
||||||
|
virtual bool is_offscreen_gl_available() const;
|
||||||
|
virtual void set_offscreen_gl_current(bool p_current);
|
||||||
|
|
||||||
virtual int get_audio_driver_count() const;
|
virtual int get_audio_driver_count() const;
|
||||||
virtual const char *get_audio_driver_name(int p_driver) const;
|
virtual const char *get_audio_driver_name(int p_driver) const;
|
||||||
|
|
||||||
|
|
|
@ -407,6 +407,18 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean createOffscreenGL() {
|
||||||
|
return mView.createOffscreenGL();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroyOffscreenGL() {
|
||||||
|
mView.destroyOffscreenGL();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffscreenGLCurrent(boolean p_current) {
|
||||||
|
mView.setOffscreenGLCurrent(p_current);
|
||||||
|
}
|
||||||
|
|
||||||
public void setKeepScreenOn(final boolean p_enabled) {
|
public void setKeepScreenOn(final boolean p_enabled) {
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
if (p_enabled) {
|
if (p_enabled) {
|
||||||
|
|
|
@ -72,10 +72,9 @@ public class GodotLib {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked on the GL thread when the underlying Android surface is created or recreated.
|
* Invoked on the GL thread when the underlying Android surface is created or recreated.
|
||||||
* @param p_32_bits
|
|
||||||
* @see android.opengl.GLSurfaceView.Renderer#onSurfaceCreated(GL10, EGLConfig)
|
* @see android.opengl.GLSurfaceView.Renderer#onSurfaceCreated(GL10, EGLConfig)
|
||||||
*/
|
*/
|
||||||
public static native void newcontext(boolean p_32_bits);
|
public static native void newcontext();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forward {@link Activity#onBackPressed()} event from the main thread to the GL thread.
|
* Forward {@link Activity#onBackPressed()} event from the main thread to the GL thread.
|
||||||
|
|
|
@ -76,7 +76,7 @@ class GodotRenderer implements GLSurfaceView.Renderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
||||||
GodotLib.newcontext(GLUtils.use_32);
|
GodotLib.newcontext();
|
||||||
for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) {
|
for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) {
|
||||||
plugin.onGLSurfaceCreated(gl, config);
|
plugin.onGLSurfaceCreated(gl, config);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,10 @@ import android.view.GestureDetector;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
import javax.microedition.khronos.egl.EGL10;
|
||||||
|
import javax.microedition.khronos.egl.EGLConfig;
|
||||||
|
import javax.microedition.khronos.egl.EGLContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple GLSurfaceView sub-class that demonstrate how to perform
|
* A simple GLSurfaceView sub-class that demonstrate how to perform
|
||||||
* OpenGL ES 2.0 rendering into a GL Surface. Note the following important
|
* OpenGL ES 2.0 rendering into a GL Surface. Note the following important
|
||||||
|
@ -75,6 +79,10 @@ public class GodotView extends GLSurfaceView {
|
||||||
private final GestureDetector detector;
|
private final GestureDetector detector;
|
||||||
private final GodotRenderer godotRenderer;
|
private final GodotRenderer godotRenderer;
|
||||||
|
|
||||||
|
private EGLConfigChooser eglConfigChooser;
|
||||||
|
private EGLContextFactory eglContextFactory;
|
||||||
|
private EGLContext eglSecondaryContext;
|
||||||
|
|
||||||
public GodotView(Context context, Godot godot, XRMode xrMode, boolean p_use_gl3,
|
public GodotView(Context context, Godot godot, XRMode xrMode, boolean p_use_gl3,
|
||||||
boolean p_use_32_bits, boolean p_use_debug_opengl, boolean p_translucent) {
|
boolean p_use_32_bits, boolean p_use_debug_opengl, boolean p_translucent) {
|
||||||
super(context);
|
super(context);
|
||||||
|
@ -123,10 +131,10 @@ public class GodotView extends GLSurfaceView {
|
||||||
switch (xrMode) {
|
switch (xrMode) {
|
||||||
case OVR:
|
case OVR:
|
||||||
// Replace the default egl config chooser.
|
// Replace the default egl config chooser.
|
||||||
setEGLConfigChooser(new OvrConfigChooser());
|
eglConfigChooser = new OvrConfigChooser();
|
||||||
|
|
||||||
// Replace the default context factory.
|
// Replace the default context factory.
|
||||||
setEGLContextFactory(new OvrContextFactory());
|
eglContextFactory = new OvrContextFactory();
|
||||||
|
|
||||||
// Replace the default window surface factory.
|
// Replace the default window surface factory.
|
||||||
setEGLWindowSurfaceFactory(new OvrWindowSurfaceFactory());
|
setEGLWindowSurfaceFactory(new OvrWindowSurfaceFactory());
|
||||||
|
@ -147,7 +155,7 @@ public class GodotView extends GLSurfaceView {
|
||||||
/* Setup the context factory for 2.0 rendering.
|
/* Setup the context factory for 2.0 rendering.
|
||||||
* See ContextFactory class definition below
|
* See ContextFactory class definition below
|
||||||
*/
|
*/
|
||||||
setEGLContextFactory(new RegularContextFactory());
|
eglContextFactory = new RegularContextFactory();
|
||||||
|
|
||||||
/* We need to choose an EGLConfig that matches the format of
|
/* We need to choose an EGLConfig that matches the format of
|
||||||
* our surface exactly. This is going to be done in our
|
* our surface exactly. This is going to be done in our
|
||||||
|
@ -156,24 +164,49 @@ public class GodotView extends GLSurfaceView {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (GLUtils.use_32) {
|
if (GLUtils.use_32) {
|
||||||
setEGLConfigChooser(translucent
|
eglConfigChooser = translucent
|
||||||
? new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil,
|
? new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil,
|
||||||
new RegularConfigChooser(8, 8, 8, 8, 16, stencil))
|
new RegularConfigChooser(8, 8, 8, 8, 16, stencil))
|
||||||
: new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil,
|
: new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil,
|
||||||
new RegularConfigChooser(5, 6, 5, 0, 16, stencil)));
|
new RegularConfigChooser(5, 6, 5, 0, 16, stencil));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
setEGLConfigChooser(translucent
|
eglConfigChooser = translucent
|
||||||
? new RegularConfigChooser(8, 8, 8, 8, 16, stencil)
|
? new RegularConfigChooser(8, 8, 8, 8, 16, stencil)
|
||||||
: new RegularConfigChooser(5, 6, 5, 0, 16, stencil));
|
: new RegularConfigChooser(5, 6, 5, 0, 16, stencil);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
setEGLConfigChooser(eglConfigChooser);
|
||||||
|
setEGLContextFactory(eglContextFactory);
|
||||||
|
|
||||||
/* Set the renderer responsible for frame rendering */
|
/* Set the renderer responsible for frame rendering */
|
||||||
setRenderer(godotRenderer);
|
setRenderer(godotRenderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean createOffscreenGL() {
|
||||||
|
EGL10 egl = (EGL10)EGLContext.getEGL();
|
||||||
|
EGLConfig eglConfig = eglConfigChooser.chooseConfig(egl, egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY));
|
||||||
|
eglSecondaryContext = eglContextFactory.createContext(egl, egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY), eglConfig);
|
||||||
|
if (eglSecondaryContext == EGL10.EGL_NO_CONTEXT) {
|
||||||
|
eglSecondaryContext = null;
|
||||||
|
}
|
||||||
|
return eglSecondaryContext != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffscreenGLCurrent(boolean p_current) {
|
||||||
|
EGL10 egl = (EGL10)EGLContext.getEGL();
|
||||||
|
egl.eglMakeCurrent(egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY), EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, p_current ? eglSecondaryContext : EGL10.EGL_NO_CONTEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroyOffscreenGL() {
|
||||||
|
if (eglSecondaryContext != null) {
|
||||||
|
EGL10 egl = (EGL10)EGLContext.getEGL();
|
||||||
|
eglContextFactory.destroyContext(egl, egl.eglGetCurrentDisplay(), eglSecondaryContext);
|
||||||
|
eglSecondaryContext = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
godot.onBackPressed();
|
godot.onBackPressed();
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,6 +152,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env
|
||||||
delete godot_io_java;
|
delete godot_io_java;
|
||||||
}
|
}
|
||||||
if (godot_java) {
|
if (godot_java) {
|
||||||
|
godot_java->destroy_offscreen_gl(env);
|
||||||
delete godot_java;
|
delete godot_java;
|
||||||
}
|
}
|
||||||
if (input_handler) {
|
if (input_handler) {
|
||||||
|
@ -212,11 +213,11 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, j
|
||||||
os_android->set_display_size(Size2(width, height));
|
os_android->set_display_size(Size2(width, height));
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jboolean p_32_bits) {
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz) {
|
||||||
if (os_android) {
|
if (os_android) {
|
||||||
if (step.get() == 0) {
|
if (step.get() == 0) {
|
||||||
// During startup
|
// During startup
|
||||||
os_android->set_context_is_16_bits(!p_32_bits);
|
os_android->set_offscreen_gl_available(godot_java->create_offscreen_gl(env));
|
||||||
} else {
|
} else {
|
||||||
// GL context recreated because it was lost; restart app to let it reload everything
|
// GL context recreated because it was lost; restart app to let it reload everything
|
||||||
step.set(-1); // Ensure no further steps are attempted and no further events are sent
|
step.set(-1); // Ensure no further steps are attempted and no further events are sent
|
||||||
|
|
|
@ -41,7 +41,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz);
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz);
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline);
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline);
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jint width, jint height);
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jint width, jint height);
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jboolean p_32_bits);
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz);
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jclass clazz);
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jclass clazz);
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jclass clazz);
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jclass clazz);
|
||||||
void touch_preprocessing(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray positions, jint buttons_mask = 0, jfloat vertical_factor = 0, jfloat horizontal_factor = 0);
|
void touch_preprocessing(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray positions, jint buttons_mask = 0, jfloat vertical_factor = 0, jfloat horizontal_factor = 0);
|
||||||
|
|
|
@ -59,6 +59,9 @@ GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_activity, jobject p_
|
||||||
|
|
||||||
// get some Godot method pointers...
|
// get some Godot method pointers...
|
||||||
_on_video_init = p_env->GetMethodID(godot_class, "onVideoInit", "()V");
|
_on_video_init = p_env->GetMethodID(godot_class, "onVideoInit", "()V");
|
||||||
|
_create_offscreen_gl = p_env->GetMethodID(godot_class, "createOffscreenGL", "()Z");
|
||||||
|
_destroy_offscreen_gl = p_env->GetMethodID(godot_class, "destroyOffscreenGL", "()V");
|
||||||
|
_set_offscreen_gl_current = p_env->GetMethodID(godot_class, "setOffscreenGLCurrent", "(Z)V");
|
||||||
_restart = p_env->GetMethodID(godot_class, "restart", "()V");
|
_restart = p_env->GetMethodID(godot_class, "restart", "()V");
|
||||||
_finish = p_env->GetMethodID(godot_class, "forceQuit", "()V");
|
_finish = p_env->GetMethodID(godot_class, "forceQuit", "()V");
|
||||||
_set_keep_screen_on = p_env->GetMethodID(godot_class, "setKeepScreenOn", "(Z)V");
|
_set_keep_screen_on = p_env->GetMethodID(godot_class, "setKeepScreenOn", "(Z)V");
|
||||||
|
@ -131,6 +134,29 @@ void GodotJavaWrapper::on_video_init(JNIEnv *p_env) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GodotJavaWrapper::create_offscreen_gl(JNIEnv *p_env) {
|
||||||
|
if (_create_offscreen_gl) {
|
||||||
|
return p_env->CallBooleanMethod(godot_instance, _create_offscreen_gl);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GodotJavaWrapper::destroy_offscreen_gl(JNIEnv *p_env) {
|
||||||
|
if (_destroy_offscreen_gl) {
|
||||||
|
p_env->CallBooleanMethod(godot_instance, _destroy_offscreen_gl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GodotJavaWrapper::set_offscreen_gl_current(JNIEnv *p_env, bool p_current) {
|
||||||
|
if (_set_offscreen_gl_current) {
|
||||||
|
if (p_env == NULL)
|
||||||
|
p_env = get_jni_env();
|
||||||
|
ERR_FAIL_COND(p_env == nullptr);
|
||||||
|
p_env->CallVoidMethod(godot_instance, _set_offscreen_gl_current, p_current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GodotJavaWrapper::on_godot_setup_completed(JNIEnv *p_env) {
|
void GodotJavaWrapper::on_godot_setup_completed(JNIEnv *p_env) {
|
||||||
if (_on_godot_setup_completed) {
|
if (_on_godot_setup_completed) {
|
||||||
if (p_env == NULL) {
|
if (p_env == NULL) {
|
||||||
|
|
|
@ -48,6 +48,9 @@ private:
|
||||||
jclass activity_class;
|
jclass activity_class;
|
||||||
|
|
||||||
jmethodID _on_video_init = 0;
|
jmethodID _on_video_init = 0;
|
||||||
|
jmethodID _create_offscreen_gl = 0;
|
||||||
|
jmethodID _destroy_offscreen_gl = 0;
|
||||||
|
jmethodID _set_offscreen_gl_current = 0;
|
||||||
jmethodID _restart = 0;
|
jmethodID _restart = 0;
|
||||||
jmethodID _finish = 0;
|
jmethodID _finish = 0;
|
||||||
jmethodID _set_keep_screen_on = 0;
|
jmethodID _set_keep_screen_on = 0;
|
||||||
|
@ -77,6 +80,9 @@ public:
|
||||||
jobject get_class_loader();
|
jobject get_class_loader();
|
||||||
|
|
||||||
void gfx_init(bool gl2);
|
void gfx_init(bool gl2);
|
||||||
|
bool create_offscreen_gl(JNIEnv *p_env);
|
||||||
|
void destroy_offscreen_gl(JNIEnv *p_env);
|
||||||
|
void set_offscreen_gl_current(JNIEnv *p_env, bool p_current);
|
||||||
void on_video_init(JNIEnv *p_env = NULL);
|
void on_video_init(JNIEnv *p_env = NULL);
|
||||||
void on_godot_setup_completed(JNIEnv *p_env = NULL);
|
void on_godot_setup_completed(JNIEnv *p_env = NULL);
|
||||||
void on_godot_main_loop_started(JNIEnv *p_env = NULL);
|
void on_godot_main_loop_started(JNIEnv *p_env = NULL);
|
||||||
|
|
|
@ -484,10 +484,18 @@ String OS_Android::get_system_dir(SystemDir p_dir, bool p_shared_storage) const
|
||||||
return godot_io_java->get_system_dir(p_dir, p_shared_storage);
|
return godot_io_java->get_system_dir(p_dir, p_shared_storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OS_Android::set_context_is_16_bits(bool p_is_16) {
|
void OS_Android::set_offscreen_gl_available(bool p_available) {
|
||||||
//use_16bits_fbo = p_is_16;
|
secondary_gl_available = p_available;
|
||||||
//if (rasterizer)
|
}
|
||||||
// rasterizer->set_force_16_bits_fbo(p_is_16);
|
|
||||||
|
bool OS_Android::is_offscreen_gl_available() const {
|
||||||
|
return secondary_gl_available;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OS_Android::set_offscreen_gl_current(bool p_current) {
|
||||||
|
if (secondary_gl_available) {
|
||||||
|
godot_java->set_offscreen_gl_current(nullptr, p_current);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OS_Android::is_joy_known(int p_device) {
|
bool OS_Android::is_joy_known(int p_device) {
|
||||||
|
|
|
@ -45,7 +45,7 @@ class OS_Android : public OS_Unix {
|
||||||
bool use_gl2;
|
bool use_gl2;
|
||||||
bool use_apk_expansion;
|
bool use_apk_expansion;
|
||||||
|
|
||||||
bool use_16bits_fbo;
|
bool secondary_gl_available = false;
|
||||||
|
|
||||||
VisualServer *visual_server;
|
VisualServer *visual_server;
|
||||||
|
|
||||||
|
@ -137,7 +137,9 @@ public:
|
||||||
void set_opengl_extensions(const char *p_gl_extensions);
|
void set_opengl_extensions(const char *p_gl_extensions);
|
||||||
void set_display_size(Size2 p_size);
|
void set_display_size(Size2 p_size);
|
||||||
|
|
||||||
void set_context_is_16_bits(bool p_is_16);
|
void set_offscreen_gl_available(bool p_available);
|
||||||
|
virtual bool is_offscreen_gl_available() const;
|
||||||
|
virtual void set_offscreen_gl_current(bool p_current);
|
||||||
|
|
||||||
virtual void set_screen_orientation(ScreenOrientation p_orientation);
|
virtual void set_screen_orientation(ScreenOrientation p_orientation);
|
||||||
virtual ScreenOrientation get_screen_orientation() const;
|
virtual ScreenOrientation get_screen_orientation() const;
|
||||||
|
|
|
@ -53,6 +53,7 @@ bool gles3_available = true;
|
||||||
GLint backingHeight;
|
GLint backingHeight;
|
||||||
|
|
||||||
EAGLContext *context;
|
EAGLContext *context;
|
||||||
|
EAGLContext *context_offscreen;
|
||||||
GLuint viewRenderbuffer, viewFramebuffer;
|
GLuint viewRenderbuffer, viewFramebuffer;
|
||||||
GLuint depthRenderbuffer;
|
GLuint depthRenderbuffer;
|
||||||
}
|
}
|
||||||
|
@ -75,6 +76,9 @@ bool gles3_available = true;
|
||||||
gles3_available = false;
|
gles3_available = false;
|
||||||
fallback_gl2 = true;
|
fallback_gl2 = true;
|
||||||
NSLog(@"Failed to create OpenGL ES 3.0 context. Falling back to OpenGL ES 2.0");
|
NSLog(@"Failed to create OpenGL ES 3.0 context. Falling back to OpenGL ES 2.0");
|
||||||
|
} else {
|
||||||
|
context_offscreen = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
|
||||||
|
OSIPhone::get_singleton()->set_offscreen_gl_context(context_offscreen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,6 +134,9 @@ bool gles3_available = true;
|
||||||
if (context) {
|
if (context) {
|
||||||
context = nil;
|
context = nil;
|
||||||
}
|
}
|
||||||
|
if (context_offscreen) {
|
||||||
|
context_offscreen = nil;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)createFramebuffer {
|
- (BOOL)createFramebuffer {
|
||||||
|
|
|
@ -61,6 +61,8 @@ private:
|
||||||
|
|
||||||
VideoMode video_mode;
|
VideoMode video_mode;
|
||||||
|
|
||||||
|
EAGLContext *offscreen_gl_context;
|
||||||
|
|
||||||
virtual int get_video_driver_count() const;
|
virtual int get_video_driver_count() const;
|
||||||
virtual const char *get_video_driver_name(int p_driver) const;
|
virtual const char *get_video_driver_name(int p_driver) const;
|
||||||
|
|
||||||
|
@ -162,6 +164,10 @@ public:
|
||||||
|
|
||||||
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const;
|
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const;
|
||||||
|
|
||||||
|
void set_offscreen_gl_context(EAGLContext *p_context);
|
||||||
|
virtual bool is_offscreen_gl_available() const;
|
||||||
|
virtual void set_offscreen_gl_current(bool p_current);
|
||||||
|
|
||||||
virtual void set_keep_screen_on(bool p_enabled);
|
virtual void set_keep_screen_on(bool p_enabled);
|
||||||
|
|
||||||
virtual bool can_draw() const;
|
virtual bool can_draw() const;
|
||||||
|
|
|
@ -417,6 +417,22 @@ void OSIPhone::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) c
|
||||||
p_list->push_back(video_mode);
|
p_list->push_back(video_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OSIPhone::set_offscreen_gl_context(EAGLContext *p_context) {
|
||||||
|
offscreen_gl_context = p_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OSIPhone::is_offscreen_gl_available() const {
|
||||||
|
return offscreen_gl_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSIPhone::set_offscreen_gl_current(bool p_current) {
|
||||||
|
if (p_current) {
|
||||||
|
[EAGLContext setCurrentContext:offscreen_gl_context];
|
||||||
|
} else {
|
||||||
|
[EAGLContext setCurrentContext:nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool OSIPhone::can_draw() const {
|
bool OSIPhone::can_draw() const {
|
||||||
if (native_video_is_playing())
|
if (native_video_is_playing())
|
||||||
return false;
|
return false;
|
||||||
|
@ -683,6 +699,7 @@ OSIPhone::OSIPhone(String p_data_dir, String p_cache_dir) {
|
||||||
|
|
||||||
main_loop = NULL;
|
main_loop = NULL;
|
||||||
visual_server = NULL;
|
visual_server = NULL;
|
||||||
|
offscreen_gl_context = NULL;
|
||||||
|
|
||||||
// can't call set_data_dir from here, since it requires DirAccess
|
// can't call set_data_dir from here, since it requires DirAccess
|
||||||
// which is initialized in initialize_core
|
// which is initialized in initialize_core
|
||||||
|
|
|
@ -115,6 +115,7 @@ public:
|
||||||
id cursor;
|
id cursor;
|
||||||
NSOpenGLPixelFormat *pixelFormat;
|
NSOpenGLPixelFormat *pixelFormat;
|
||||||
NSOpenGLContext *context;
|
NSOpenGLContext *context;
|
||||||
|
NSOpenGLContext *context_offscreen;
|
||||||
|
|
||||||
Vector<Vector2> mpath;
|
Vector<Vector2> mpath;
|
||||||
bool layered_window;
|
bool layered_window;
|
||||||
|
@ -250,6 +251,9 @@ public:
|
||||||
virtual VideoMode get_video_mode(int p_screen = 0) const;
|
virtual VideoMode get_video_mode(int p_screen = 0) const;
|
||||||
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const;
|
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const;
|
||||||
|
|
||||||
|
virtual bool is_offscreen_gl_available() const;
|
||||||
|
virtual void set_offscreen_gl_current(bool p_current);
|
||||||
|
|
||||||
virtual String get_executable_path() const;
|
virtual String get_executable_path() const;
|
||||||
virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr);
|
virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr);
|
||||||
|
|
||||||
|
|
|
@ -1666,6 +1666,8 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
|
||||||
|
|
||||||
[window_view setOpenGLContext:context];
|
[window_view setOpenGLContext:context];
|
||||||
|
|
||||||
|
context_offscreen = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
|
||||||
|
|
||||||
[context makeCurrentContext];
|
[context makeCurrentContext];
|
||||||
|
|
||||||
GLint dim[2];
|
GLint dim[2];
|
||||||
|
@ -2427,6 +2429,18 @@ OS::VideoMode OS_OSX::get_video_mode(int p_screen) const {
|
||||||
void OS_OSX::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
|
void OS_OSX::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OS_OSX::is_offscreen_gl_available() const {
|
||||||
|
return context_offscreen != nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OS_OSX::set_offscreen_gl_current(bool p_current) {
|
||||||
|
if (p_current) {
|
||||||
|
[context makeCurrentContext];
|
||||||
|
} else {
|
||||||
|
[NSOpenGLContext clearCurrentContext];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int OS_OSX::get_screen_count() const {
|
int OS_OSX::get_screen_count() const {
|
||||||
NSArray *screenArray = [NSScreen screens];
|
NSArray *screenArray = [NSScreen screens];
|
||||||
return [screenArray count];
|
return [screenArray count];
|
||||||
|
@ -3426,6 +3440,7 @@ OS_OSX *OS_OSX::singleton = NULL;
|
||||||
|
|
||||||
OS_OSX::OS_OSX() {
|
OS_OSX::OS_OSX() {
|
||||||
context = nullptr;
|
context = nullptr;
|
||||||
|
context_offscreen = nullptr;
|
||||||
|
|
||||||
memset(cursors, 0, sizeof(cursors));
|
memset(cursors, 0, sizeof(cursors));
|
||||||
key_event_pos = 0;
|
key_event_pos = 0;
|
||||||
|
|
|
@ -58,6 +58,18 @@ void ContextGL_Windows::make_current() {
|
||||||
wglMakeCurrent(hDC, hRC);
|
wglMakeCurrent(hDC, hRC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ContextGL_Windows::is_offscreen_available() const {
|
||||||
|
return hRC_offscreen != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContextGL_Windows::make_offscreen_current() {
|
||||||
|
ERR_FAIL_COND(!wglMakeCurrent(hDC, hRC_offscreen));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContextGL_Windows::release_offscreen_current() {
|
||||||
|
ERR_FAIL_COND(!wglMakeCurrent(hDC, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
HDC ContextGL_Windows::get_hdc() {
|
HDC ContextGL_Windows::get_hdc() {
|
||||||
return hDC;
|
return hDC;
|
||||||
}
|
}
|
||||||
|
@ -205,6 +217,8 @@ Error ContextGL_Windows::initialize() {
|
||||||
{
|
{
|
||||||
return ERR_CANT_CREATE; // Return FALSE
|
return ERR_CANT_CREATE; // Return FALSE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hRC_offscreen = wglCreateContextAttribsARB(hDC, 0, attribs);
|
||||||
}
|
}
|
||||||
|
|
||||||
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
|
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
|
||||||
|
@ -217,6 +231,7 @@ Error ContextGL_Windows::initialize() {
|
||||||
ContextGL_Windows::ContextGL_Windows(HWND hwnd, bool p_opengl_3_context) {
|
ContextGL_Windows::ContextGL_Windows(HWND hwnd, bool p_opengl_3_context) {
|
||||||
opengl_3_context = p_opengl_3_context;
|
opengl_3_context = p_opengl_3_context;
|
||||||
hWnd = hwnd;
|
hWnd = hwnd;
|
||||||
|
hRC_offscreen = NULL;
|
||||||
use_vsync = false;
|
use_vsync = false;
|
||||||
vsync_via_compositor = false;
|
vsync_via_compositor = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ typedef int(APIENTRY *PFNWGLGETSWAPINTERVALEXTPROC)(void);
|
||||||
class ContextGL_Windows {
|
class ContextGL_Windows {
|
||||||
HDC hDC;
|
HDC hDC;
|
||||||
HGLRC hRC;
|
HGLRC hRC;
|
||||||
|
HGLRC hRC_offscreen;
|
||||||
unsigned int pixel_format;
|
unsigned int pixel_format;
|
||||||
HWND hWnd;
|
HWND hWnd;
|
||||||
bool opengl_3_context;
|
bool opengl_3_context;
|
||||||
|
@ -63,6 +64,10 @@ public:
|
||||||
|
|
||||||
void make_current();
|
void make_current();
|
||||||
|
|
||||||
|
bool is_offscreen_available() const;
|
||||||
|
void make_offscreen_current();
|
||||||
|
void release_offscreen_current();
|
||||||
|
|
||||||
HDC get_hdc();
|
HDC get_hdc();
|
||||||
HGLRC get_hglrc();
|
HGLRC get_hglrc();
|
||||||
|
|
||||||
|
|
|
@ -1672,6 +1672,24 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OS_Windows::is_offscreen_gl_available() const {
|
||||||
|
#if defined(OPENGL_ENABLED)
|
||||||
|
return gl_context->is_offscreen_available();
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void OS_Windows::set_offscreen_gl_current(bool p_current) {
|
||||||
|
#if defined(OPENGL_ENABLED)
|
||||||
|
if (p_current) {
|
||||||
|
return gl_context->make_offscreen_current();
|
||||||
|
} else {
|
||||||
|
return gl_context->release_offscreen_current();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void OS_Windows::set_clipboard(const String &p_text) {
|
void OS_Windows::set_clipboard(const String &p_text) {
|
||||||
// Convert LF line endings to CRLF in clipboard content
|
// Convert LF line endings to CRLF in clipboard content
|
||||||
// Otherwise, line endings won't be visible when pasted in other software
|
// Otherwise, line endings won't be visible when pasted in other software
|
||||||
|
|
|
@ -386,6 +386,9 @@ protected:
|
||||||
virtual void initialize_core();
|
virtual void initialize_core();
|
||||||
virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
||||||
|
|
||||||
|
virtual bool is_offscreen_gl_available() const;
|
||||||
|
virtual void set_offscreen_gl_current(bool p_current);
|
||||||
|
|
||||||
virtual void set_main_loop(MainLoop *p_main_loop);
|
virtual void set_main_loop(MainLoop *p_main_loop);
|
||||||
virtual void delete_main_loop();
|
virtual void delete_main_loop();
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ typedef GLXContext (*GLXCREATECONTEXTATTRIBSARBPROC)(Display *, GLXFBConfig, GLX
|
||||||
|
|
||||||
struct ContextGL_X11_Private {
|
struct ContextGL_X11_Private {
|
||||||
::GLXContext glx_context;
|
::GLXContext glx_context;
|
||||||
|
::GLXContext glx_context_offscreen;
|
||||||
};
|
};
|
||||||
|
|
||||||
void ContextGL_X11::release_current() {
|
void ContextGL_X11::release_current() {
|
||||||
|
@ -57,6 +58,18 @@ void ContextGL_X11::make_current() {
|
||||||
glXMakeCurrent(x11_display, x11_window, p->glx_context);
|
glXMakeCurrent(x11_display, x11_window, p->glx_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ContextGL_X11::is_offscreen_available() const {
|
||||||
|
return p->glx_context_offscreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContextGL_X11::make_offscreen_current() {
|
||||||
|
glXMakeCurrent(x11_display, x11_window, p->glx_context_offscreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContextGL_X11::release_offscreen_current() {
|
||||||
|
glXMakeCurrent(x11_display, None, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void ContextGL_X11::swap_buffers() {
|
void ContextGL_X11::swap_buffers() {
|
||||||
glXSwapBuffers(x11_display, x11_window);
|
glXSwapBuffers(x11_display, x11_window);
|
||||||
}
|
}
|
||||||
|
@ -181,6 +194,7 @@ Error ContextGL_X11::initialize() {
|
||||||
|
|
||||||
p->glx_context = glXCreateContextAttribsARB(x11_display, fbconfig, nullptr, true, context_attribs);
|
p->glx_context = glXCreateContextAttribsARB(x11_display, fbconfig, nullptr, true, context_attribs);
|
||||||
ERR_FAIL_COND_V(ctxErrorOccurred || !p->glx_context, ERR_UNCONFIGURED);
|
ERR_FAIL_COND_V(ctxErrorOccurred || !p->glx_context, ERR_UNCONFIGURED);
|
||||||
|
p->glx_context_offscreen = glXCreateContextAttribsARB(x11_display, fbconfig, nullptr, true, context_attribs);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,12 +289,16 @@ ContextGL_X11::ContextGL_X11(::Display *p_x11_display, ::Window &p_x11_window, c
|
||||||
glx_minor = glx_major = 0;
|
glx_minor = glx_major = 0;
|
||||||
p = memnew(ContextGL_X11_Private);
|
p = memnew(ContextGL_X11_Private);
|
||||||
p->glx_context = nullptr;
|
p->glx_context = nullptr;
|
||||||
|
p->glx_context_offscreen = nullptr;
|
||||||
use_vsync = false;
|
use_vsync = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ContextGL_X11::~ContextGL_X11() {
|
ContextGL_X11::~ContextGL_X11() {
|
||||||
release_current();
|
release_current();
|
||||||
glXDestroyContext(x11_display, p->glx_context);
|
glXDestroyContext(x11_display, p->glx_context);
|
||||||
|
if (p->glx_context_offscreen) {
|
||||||
|
glXDestroyContext(x11_display, p->glx_context_offscreen);
|
||||||
|
}
|
||||||
memdelete(p);
|
memdelete(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,10 @@ public:
|
||||||
int get_window_height();
|
int get_window_height();
|
||||||
void *get_glx_context();
|
void *get_glx_context();
|
||||||
|
|
||||||
|
bool is_offscreen_available() const;
|
||||||
|
void make_offscreen_current();
|
||||||
|
void release_offscreen_current();
|
||||||
|
|
||||||
Error initialize();
|
Error initialize();
|
||||||
|
|
||||||
void set_use_vsync(bool p_use);
|
void set_use_vsync(bool p_use);
|
||||||
|
|
|
@ -869,6 +869,24 @@ void OS_X11::finalize() {
|
||||||
args.clear();
|
args.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OS_X11::is_offscreen_gl_available() const {
|
||||||
|
#if defined(OPENGL_ENABLED)
|
||||||
|
return context_gl->is_offscreen_available();
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void OS_X11::set_offscreen_gl_current(bool p_current) {
|
||||||
|
#if defined(OPENGL_ENABLED)
|
||||||
|
if (p_current) {
|
||||||
|
return context_gl->make_offscreen_current();
|
||||||
|
} else {
|
||||||
|
return context_gl->release_offscreen_current();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void OS_X11::set_mouse_mode(MouseMode p_mode) {
|
void OS_X11::set_mouse_mode(MouseMode p_mode) {
|
||||||
if (p_mode == mouse_mode) {
|
if (p_mode == mouse_mode) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -239,6 +239,9 @@ protected:
|
||||||
virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
||||||
virtual void finalize();
|
virtual void finalize();
|
||||||
|
|
||||||
|
virtual bool is_offscreen_gl_available() const;
|
||||||
|
virtual void set_offscreen_gl_current(bool p_current);
|
||||||
|
|
||||||
virtual void set_main_loop(MainLoop *p_main_loop);
|
virtual void set_main_loop(MainLoop *p_main_loop);
|
||||||
|
|
||||||
void _window_changed(XEvent *event);
|
void _window_changed(XEvent *event);
|
||||||
|
|
Loading…
Reference in New Issue