Fall back to GLES2 if GLES3 is not working
This adds a static is_viable() method to all rasterizers which has to be called before initializing the rasterizer. This allows us to check what rasterizer to use in OS::initialize together with the GL context initialization. This commit also adds a new project setting "rendering/quality/driver/driver_fallback" which allows the creator of a project to specify whether or not fallback to GLES2 is allowed. This setting is ignored for the editor so the editor will always open even if the project itself cannot run. This will hopefully reduce confusion for users downloading projects from the internet. We also no longer crash when GLES3 is not functioning on a platform. This fixes #15324
This commit is contained in:
parent
8c435a343e
commit
08f452d1a9
16 changed files with 417 additions and 171 deletions
|
@ -658,6 +658,9 @@
|
|||
</member>
|
||||
<member name="rendering/quality/driver/driver_name" type="String" setter="" getter="">
|
||||
</member>
|
||||
<member name="rendering/quality/driver/driver_fallback" type="String" setter="" getter="">
|
||||
Whether to allow falling back to other graphics drivers if the preferred driver is not available. Best means use the best working driver (this is the default). Never means never fall back to another driver even if it does not work. This means the project will not run if the preferred driver does not function.
|
||||
</member>
|
||||
<member name="rendering/quality/filters/anisotropic_filter_level" type="int" setter="" getter="">
|
||||
Maximum Anisotropic filter level used for textures when anisotropy enabled.
|
||||
</member>
|
||||
|
|
|
@ -789,6 +789,10 @@ public:
|
|||
void end_frame(bool p_swap_buffers) {}
|
||||
void finalize() {}
|
||||
|
||||
static Error is_viable() {
|
||||
return OK;
|
||||
}
|
||||
|
||||
static Rasterizer *_create_current() {
|
||||
return memnew(RasterizerDummy);
|
||||
}
|
||||
|
|
|
@ -136,26 +136,21 @@ RasterizerScene *RasterizerGLES2::get_scene() {
|
|||
return scene;
|
||||
}
|
||||
|
||||
void RasterizerGLES2::initialize() {
|
||||
|
||||
print_verbose("Using GLES2 video driver");
|
||||
Error RasterizerGLES2::is_viable() {
|
||||
|
||||
#ifdef GLAD_ENABLED
|
||||
if (!gladLoadGL()) {
|
||||
ERR_PRINT("Error initializing GLAD");
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
// GLVersion seems to be used for both GL and GL ES, so we need different version checks for them
|
||||
#ifdef OPENGL_ENABLED // OpenGL 2.1 Profile required
|
||||
if (GLVersion.major < 2) {
|
||||
#else // OpenGL ES 3.0
|
||||
if (GLVersion.major < 2 || (GLVersion.major == 2 && GLVersion.minor < 1)) {
|
||||
#else // OpenGL ES 2.0
|
||||
if (GLVersion.major < 2) {
|
||||
#endif
|
||||
ERR_PRINT("Your system's graphic drivers seem not to support OpenGL 2.1 / OpenGL ES 2.0, sorry :(\n"
|
||||
"Try a drivers update, buy a new GPU or try software rendering on Linux; Godot will now crash with a segmentation fault.");
|
||||
OS::get_singleton()->alert("Your system's graphic drivers seem not to support OpenGL 2.1 / OpenGL ES 2.0, sorry :(\n"
|
||||
"Godot Engine will self-destruct as soon as you acknowledge this error message.",
|
||||
"Fatal error: Insufficient OpenGL / GLES driver support");
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
#ifdef GLES_OVER_GL
|
||||
|
@ -181,14 +176,21 @@ void RasterizerGLES2::initialize() {
|
|||
glGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameterivEXT;
|
||||
glGenerateMipmap = glGenerateMipmapEXT;
|
||||
} else {
|
||||
ERR_PRINT("Your system's graphic drivers seem not to support GL_ARB(EXT)_framebuffer_object OpenGL extension, sorry :(\n"
|
||||
"Try a drivers update, buy a new GPU or try software rendering on Linux; Godot will now crash with a segmentation fault.");
|
||||
OS::get_singleton()->alert("Your system's graphic drivers seem not to support GL_ARB(EXT)_framebuffer_object OpenGL extension, sorry :(\n"
|
||||
"Godot Engine will self-destruct as soon as you acknowledge this error message.",
|
||||
"Fatal error: Insufficient OpenGL / GLES driver support");
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // GLAD_ENABLED
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void RasterizerGLES2::initialize() {
|
||||
|
||||
print_verbose("Using GLES2 video driver");
|
||||
|
||||
#ifdef GLAD_ENABLED
|
||||
if (true || OS::get_singleton()->is_stdout_verbose()) {
|
||||
if (GLAD_GL_ARB_debug_output) {
|
||||
glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
|
||||
|
@ -198,7 +200,6 @@ void RasterizerGLES2::initialize() {
|
|||
print_line("OpenGL debugging not supported!");
|
||||
}
|
||||
}
|
||||
|
||||
#endif // GLAD_ENABLED
|
||||
|
||||
// For debugging
|
||||
|
|
|
@ -61,9 +61,10 @@ public:
|
|||
virtual void end_frame(bool p_swap_buffers);
|
||||
virtual void finalize();
|
||||
|
||||
static Error is_viable();
|
||||
static void make_current();
|
||||
|
||||
static void register_config();
|
||||
|
||||
RasterizerGLES2();
|
||||
~RasterizerGLES2();
|
||||
};
|
||||
|
|
|
@ -136,28 +136,32 @@ typedef void (*DEBUGPROCARB)(GLenum source,
|
|||
|
||||
typedef void (*DebugMessageCallbackARB)(DEBUGPROCARB callback, const void *userParam);
|
||||
|
||||
Error RasterizerGLES3::is_viable() {
|
||||
|
||||
#ifdef GLAD_ENABLED
|
||||
if (!gladLoadGL()) {
|
||||
ERR_PRINT("Error initializing GLAD");
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
// GLVersion seems to be used for both GL and GL ES, so we need different version checks for them
|
||||
#ifdef OPENGL_ENABLED // OpenGL 3.3 Core Profile required
|
||||
if (GLVersion.major < 3 || (GLVersion.major == 3 && GLVersion.minor < 3)) {
|
||||
#else // OpenGL ES 3.0
|
||||
if (GLVersion.major < 3) {
|
||||
#endif
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
#endif // GLAD_ENABLED
|
||||
return OK;
|
||||
}
|
||||
|
||||
void RasterizerGLES3::initialize() {
|
||||
|
||||
print_verbose("Using GLES3 video driver");
|
||||
|
||||
#ifdef GLAD_ENABLED
|
||||
if (!gladLoadGL()) {
|
||||
ERR_PRINT("Error initializing GLAD");
|
||||
}
|
||||
|
||||
// GLVersion seems to be used for both GL and GL ES, so we need different version checks for them
|
||||
#ifdef OPENGL_ENABLED // OpenGL 3.3 Core Profile required
|
||||
if (GLVersion.major < 3 && GLVersion.minor < 3) {
|
||||
#else // OpenGL ES 3.0
|
||||
if (GLVersion.major < 3) {
|
||||
#endif
|
||||
ERR_PRINT("Your system's graphic drivers seem not to support OpenGL 3.3 / OpenGL ES 3.0, sorry :(\n"
|
||||
"Try a drivers update, buy a new GPU or try software rendering on Linux; Godot will now crash with a segmentation fault.");
|
||||
OS::get_singleton()->alert("Your system's graphic drivers seem not to support OpenGL 3.3 / OpenGL ES 3.0, sorry :(\n"
|
||||
"Godot Engine will self-destruct as soon as you acknowledge this error message.",
|
||||
"Fatal error: Insufficient OpenGL / GLES driver support");
|
||||
}
|
||||
|
||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||
if (GLAD_GL_ARB_debug_output) {
|
||||
glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
|
||||
|
@ -167,7 +171,6 @@ void RasterizerGLES3::initialize() {
|
|||
print_line("OpenGL debugging not supported!");
|
||||
}
|
||||
}
|
||||
|
||||
#endif // GLAD_ENABLED
|
||||
|
||||
/* // For debugging
|
||||
|
|
|
@ -62,9 +62,10 @@ public:
|
|||
virtual void end_frame(bool p_swap_buffers);
|
||||
virtual void finalize();
|
||||
|
||||
static Error is_viable();
|
||||
static void make_current();
|
||||
|
||||
static void register_config();
|
||||
|
||||
RasterizerGLES3();
|
||||
~RasterizerGLES3();
|
||||
};
|
||||
|
|
|
@ -830,6 +830,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
|
|||
video_driver = GLOBAL_GET("rendering/quality/driver/driver_name");
|
||||
}
|
||||
|
||||
GLOBAL_DEF("rendering/quality/driver/driver_fallback", "Best");
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/driver/driver_fallback", PropertyInfo(Variant::STRING, "rendering/quality/driver/driver_fallback", PROPERTY_HINT_ENUM, "Best,Never"));
|
||||
|
||||
GLOBAL_DEF("display/window/size/width", 1024);
|
||||
GLOBAL_DEF("display/window/size/height", 600);
|
||||
GLOBAL_DEF("display/window/size/resizable", true);
|
||||
|
@ -1040,6 +1043,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
|
|||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (init_use_custom_pos) {
|
||||
OS::get_singleton()->set_window_position(init_custom_pos);
|
||||
}
|
||||
|
|
|
@ -62,12 +62,19 @@ public:
|
|||
|
||||
int OS_Android::get_video_driver_count() const {
|
||||
|
||||
return 1;
|
||||
return 2;
|
||||
}
|
||||
|
||||
const char *OS_Android::get_video_driver_name(int p_driver) const {
|
||||
|
||||
return "GLES2";
|
||||
switch (p_driver) {
|
||||
case VIDEO_DRIVER_GLES3:
|
||||
return "GLES3";
|
||||
case VIDEO_DRIVER_GLES2:
|
||||
return "GLES2";
|
||||
}
|
||||
ERR_EXPLAIN("Invalid video driver index " + itos(p_driver));
|
||||
ERR_FAIL_V(NULL);
|
||||
}
|
||||
int OS_Android::get_audio_driver_count() const {
|
||||
|
||||
|
@ -132,26 +139,55 @@ Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int
|
|||
|
||||
bool use_gl3 = get_gl_version_code_func() >= 0x00030000;
|
||||
use_gl3 = use_gl3 && (GLOBAL_GET("rendering/quality/driver/driver_name") == "GLES3");
|
||||
use_gl2 = !use_gl3;
|
||||
bool gl_initialization_error = false;
|
||||
|
||||
if (gfx_init_func)
|
||||
gfx_init_func(gfx_init_ud, use_gl2);
|
||||
|
||||
if (use_gl2) {
|
||||
RasterizerGLES2::register_config();
|
||||
RasterizerGLES2::make_current();
|
||||
video_driver_index = VIDEO_DRIVER_GLES2;
|
||||
} else {
|
||||
RasterizerGLES3::register_config();
|
||||
RasterizerGLES3::make_current();
|
||||
video_driver_index = VIDEO_DRIVER_GLES3;
|
||||
while (true) {
|
||||
if (use_gl3) {
|
||||
if (RasterizerGLES3::is_viable() == OK) {
|
||||
if (gfx_init_func)
|
||||
gfx_init_func(gfx_init_ud, false);
|
||||
RasterizerGLES3::register_config();
|
||||
RasterizerGLES3::make_current();
|
||||
break;
|
||||
} else {
|
||||
if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best") {
|
||||
p_video_driver = VIDEO_DRIVER_GLES2;
|
||||
use_gl3 = false;
|
||||
continue;
|
||||
} else {
|
||||
gl_initialization_error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (RasterizerGLES2::is_viable() == OK) {
|
||||
if (gfx_init_func)
|
||||
gfx_init_func(gfx_init_ud, true);
|
||||
RasterizerGLES2::register_config();
|
||||
RasterizerGLES2::make_current();
|
||||
break;
|
||||
} else {
|
||||
gl_initialization_error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gl_initialization_error) {
|
||||
OS::get_singleton()->alert("Your device does not support any of the supported OpenGL versions.\n"
|
||||
"Please try updating your Android version.",
|
||||
"Unable to initialize Video driver");
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
video_driver_index = p_video_driver;
|
||||
|
||||
visual_server = memnew(VisualServerRaster);
|
||||
/* if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
|
||||
|
||||
visual_server = memnew(VisualServerWrapMT(visual_server, false));
|
||||
};*/
|
||||
|
||||
visual_server->init();
|
||||
// visual_server->cursor_set_visible(false, 0);
|
||||
|
||||
|
|
|
@ -99,8 +99,11 @@ int OSIPhone::get_current_video_driver() const {
|
|||
|
||||
Error OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
|
||||
|
||||
video_driver_index = p_video_driver; //this may be misleading
|
||||
video_driver_index = VIDEO_DRIVER_GLES3;
|
||||
|
||||
if (RasterizerGLES3::is_viable() != OK) {
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
RasterizerGLES3::register_config();
|
||||
RasterizerGLES3::make_current();
|
||||
|
||||
|
|
|
@ -652,23 +652,57 @@ Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver,
|
|||
attributes.alpha = false;
|
||||
attributes.antialias = false;
|
||||
ERR_FAIL_INDEX_V(p_video_driver, VIDEO_DRIVER_MAX, ERR_INVALID_PARAMETER);
|
||||
switch (p_video_driver) {
|
||||
case VIDEO_DRIVER_GLES3:
|
||||
attributes.majorVersion = 2;
|
||||
RasterizerGLES3::register_config();
|
||||
RasterizerGLES3::make_current();
|
||||
break;
|
||||
case VIDEO_DRIVER_GLES2:
|
||||
attributes.majorVersion = 1;
|
||||
RasterizerGLES2::register_config();
|
||||
RasterizerGLES2::make_current();
|
||||
break;
|
||||
|
||||
bool gles3 = true;
|
||||
if (p_video_driver == VIDEO_DRIVER_GLES2) {
|
||||
gles3 = false;
|
||||
}
|
||||
|
||||
bool gl_initialization_error = false;
|
||||
|
||||
while (true) {
|
||||
if (gles3) {
|
||||
if (RasterizerGLES3::is_viable() == OK) {
|
||||
attributes.majorVersion = 2;
|
||||
RasterizerGLES3::register_config();
|
||||
RasterizerGLES3::make_current();
|
||||
break;
|
||||
} else {
|
||||
if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best") {
|
||||
p_video_driver = VIDEO_DRIVER_GLES2;
|
||||
gles3 = false;
|
||||
continue;
|
||||
} else {
|
||||
gl_initialization_error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (RasterizerGLES2::is_viable() == OK) {
|
||||
attributes.majorVersion = 1;
|
||||
RasterizerGLES2::register_config();
|
||||
RasterizerGLES2::make_current();
|
||||
break;
|
||||
} else {
|
||||
gl_initialization_error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(NULL, &attributes);
|
||||
if (emscripten_webgl_make_context_current(ctx) != EMSCRIPTEN_RESULT_SUCCESS) {
|
||||
gl_initialization_error = true;
|
||||
}
|
||||
|
||||
if (gl_initialization_error) {
|
||||
OS::get_singleton()->alert("Your browser does not support any of the supported WebGL versions.\n"
|
||||
"Please update your browser version.",
|
||||
"Unable to initialize Video driver");
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
video_driver_index = p_video_driver;
|
||||
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(NULL, &attributes);
|
||||
ERR_EXPLAIN("WebGL " + itos(attributes.majorVersion) + ".0 not available");
|
||||
ERR_FAIL_COND_V(emscripten_webgl_make_context_current(ctx) != EMSCRIPTEN_RESULT_SUCCESS, ERR_UNAVAILABLE);
|
||||
|
||||
video_mode = p_desired;
|
||||
// Can't fulfil fullscreen request during start-up due to browser security.
|
||||
|
|
|
@ -1276,8 +1276,6 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
|
|||
ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
|
||||
}
|
||||
|
||||
video_driver_index = p_video_driver;
|
||||
|
||||
ADD_ATTR2(NSOpenGLPFAColorSize, colorBits);
|
||||
|
||||
/*
|
||||
|
@ -1333,22 +1331,58 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
|
|||
|
||||
/*** END OSX INITIALIZATION ***/
|
||||
|
||||
// only opengl support here...
|
||||
bool gles3 = true;
|
||||
if (p_video_driver == VIDEO_DRIVER_GLES2) {
|
||||
RasterizerGLES2::register_config();
|
||||
RasterizerGLES2::make_current();
|
||||
} else {
|
||||
RasterizerGLES3::register_config();
|
||||
RasterizerGLES3::make_current();
|
||||
gles3 = false;
|
||||
}
|
||||
|
||||
bool editor = Engine::get_singleton()->is_editor_hint();
|
||||
bool gl_initialization_error = false;
|
||||
|
||||
while (true) {
|
||||
if (gles3) {
|
||||
if (RasterizerGLES3::is_viable() == OK) {
|
||||
RasterizerGLES3::register_config();
|
||||
RasterizerGLES3::make_current();
|
||||
break;
|
||||
} else {
|
||||
if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best" || editor) {
|
||||
p_video_driver = VIDEO_DRIVER_GLES2;
|
||||
gles3 = false;
|
||||
continue;
|
||||
} else {
|
||||
gl_initialization_error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (RasterizerGLES2::is_viable() == OK) {
|
||||
RasterizerGLES2::register_config();
|
||||
RasterizerGLES2::make_current();
|
||||
break;
|
||||
} else {
|
||||
gl_initialization_error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gl_initialization_error) {
|
||||
OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n"
|
||||
"Please update your drivers or if you have a very old or integrated GPU upgrade it.",
|
||||
"Unable to initialize Video driver");
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
video_driver_index = p_video_driver;
|
||||
|
||||
visual_server = memnew(VisualServerRaster);
|
||||
if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
|
||||
|
||||
visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
|
||||
}
|
||||
visual_server->init();
|
||||
|
||||
visual_server->init();
|
||||
AudioDriverManager::initialize(p_audio_driver);
|
||||
|
||||
input = memnew(InputDefault);
|
||||
|
|
|
@ -187,12 +187,78 @@ Error OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
|
|||
main_loop = NULL;
|
||||
outside = true;
|
||||
|
||||
ContextEGL::Driver opengl_api_type = ContextEGL::GLES_2_0;
|
||||
|
||||
if (p_video_driver == VIDEO_DRIVER_GLES2) {
|
||||
gl_context = memnew(ContextEGL(window, ContextEGL::GLES_2_0));
|
||||
} else {
|
||||
gl_context = memnew(ContextEGL(window, ContextEGL::GLES_3_0));
|
||||
opengl_api_type = ContextEGL::GLES_2_0;
|
||||
}
|
||||
gl_context->initialize();
|
||||
|
||||
bool gl_initialization_error = false;
|
||||
|
||||
gl_context = NULL;
|
||||
while (!gl_context) {
|
||||
gl_context = memnew(ContextEGL(window, opengl_api_type));
|
||||
|
||||
if (gl_context->initialize() != OK) {
|
||||
memdelete(gl_context);
|
||||
gl_context = NULL;
|
||||
|
||||
if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best") {
|
||||
if (p_video_driver == VIDEO_DRIVER_GLES2) {
|
||||
gl_initialization_error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
p_video_driver = VIDEO_DRIVER_GLES2;
|
||||
opengl_api_type = ContextEGL::GLES_2_0;
|
||||
} else {
|
||||
gl_initialization_error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (opengl_api_type == ContextEGL::GLES_3_0) {
|
||||
if (RasterizerGLES3::is_viable() == OK) {
|
||||
RasterizerGLES3::register_config();
|
||||
RasterizerGLES3::make_current();
|
||||
break;
|
||||
} else {
|
||||
if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best" || editor) {
|
||||
p_video_driver = VIDEO_DRIVER_GLES2;
|
||||
opengl_api_type = ContextEGL::GLES_2_0;
|
||||
continue;
|
||||
} else {
|
||||
gl_initialization_error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (opengl_api_type == ContextEGL::GLES_2_0) {
|
||||
if (RasterizerGLES2::is_viable() == OK) {
|
||||
RasterizerGLES2::register_config();
|
||||
RasterizerGLES2::make_current();
|
||||
break;
|
||||
} else {
|
||||
gl_initialization_error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gl_initialization_error) {
|
||||
OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n"
|
||||
"Please update your drivers or if you have a very old or integrated GPU upgrade it.",
|
||||
"Unable to initialize Video driver");
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
video_driver_index = p_video_driver;
|
||||
gl_context->make_current();
|
||||
gl_context->set_use_vsync(video_mode.use_vsync);
|
||||
|
||||
VideoMode vm;
|
||||
vm.width = gl_context->get_window_width();
|
||||
vm.height = gl_context->get_window_height();
|
||||
|
@ -230,19 +296,6 @@ Error OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
|
|||
|
||||
set_video_mode(vm);
|
||||
|
||||
gl_context->make_current();
|
||||
|
||||
if (p_video_driver == VIDEO_DRIVER_GLES2) {
|
||||
RasterizerGLES2::register_config();
|
||||
RasterizerGLES2::make_current();
|
||||
} else {
|
||||
RasterizerGLES3::register_config();
|
||||
RasterizerGLES3::make_current();
|
||||
}
|
||||
gl_context->set_use_vsync(vm.use_vsync);
|
||||
|
||||
video_driver_index = p_video_driver;
|
||||
|
||||
visual_server = memnew(VisualServerRaster);
|
||||
// FIXME: Reimplement threaded rendering? Or remove?
|
||||
/*
|
||||
|
@ -253,7 +306,6 @@ Error OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
|
|||
*/
|
||||
|
||||
visual_server->init();
|
||||
|
||||
input = memnew(InputDefault);
|
||||
|
||||
joypad = ref new JoypadUWP(input);
|
||||
|
|
|
@ -108,28 +108,24 @@ Error ContextGL_Win::initialize() {
|
|||
|
||||
hDC = GetDC(hWnd);
|
||||
if (!hDC) {
|
||||
MessageBox(NULL, "Can't Create A GL Device Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
|
||||
return ERR_CANT_CREATE; // Return FALSE
|
||||
}
|
||||
|
||||
pixel_format = ChoosePixelFormat(hDC, &pfd);
|
||||
if (!pixel_format) // Did Windows Find A Matching Pixel Format?
|
||||
{
|
||||
MessageBox(NULL, "Can't Find A Suitable pixel_format.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
|
||||
return ERR_CANT_CREATE; // Return FALSE
|
||||
}
|
||||
|
||||
BOOL ret = SetPixelFormat(hDC, pixel_format, &pfd);
|
||||
if (!ret) // Are We Able To Set The Pixel Format?
|
||||
{
|
||||
MessageBox(NULL, "Can't Set The pixel_format.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
|
||||
return ERR_CANT_CREATE; // Return FALSE
|
||||
}
|
||||
|
||||
hRC = wglCreateContext(hDC);
|
||||
if (!hRC) // Are We Able To Get A Rendering Context?
|
||||
{
|
||||
MessageBox(NULL, "Can't Create A Temporary GL Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
|
||||
return ERR_CANT_CREATE; // Return FALSE
|
||||
}
|
||||
|
||||
|
@ -151,7 +147,6 @@ Error ContextGL_Win::initialize() {
|
|||
|
||||
if (wglCreateContextAttribsARB == NULL) //OpenGL 3.0 is not supported
|
||||
{
|
||||
MessageBox(NULL, "Cannot get Proc Address for CreateContextAttribs", "ERROR", MB_OK | MB_ICONEXCLAMATION);
|
||||
wglDeleteContext(hRC);
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
|
@ -159,7 +154,6 @@ Error ContextGL_Win::initialize() {
|
|||
HGLRC new_hRC = wglCreateContextAttribsARB(hDC, 0, attribs);
|
||||
if (!new_hRC) {
|
||||
wglDeleteContext(hRC);
|
||||
MessageBox(NULL, "Can't Create An OpenGL 3.3 Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
|
||||
return ERR_CANT_CREATE; // Return false
|
||||
}
|
||||
wglMakeCurrent(hDC, NULL);
|
||||
|
@ -168,7 +162,6 @@ Error ContextGL_Win::initialize() {
|
|||
|
||||
if (!wglMakeCurrent(hDC, hRC)) // Try To Activate The Rendering Context
|
||||
{
|
||||
MessageBox(NULL, "Can't Activate The GL 3.3 Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
|
||||
return ERR_CANT_CREATE; // Return FALSE
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1273,21 +1273,74 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
|
|||
}
|
||||
|
||||
#if defined(OPENGL_ENABLED)
|
||||
|
||||
bool gles3_context = true;
|
||||
if (p_video_driver == VIDEO_DRIVER_GLES2) {
|
||||
gl_context = memnew(ContextGL_Win(hWnd, false));
|
||||
gl_context->initialize();
|
||||
|
||||
RasterizerGLES2::register_config();
|
||||
RasterizerGLES2::make_current();
|
||||
} else {
|
||||
gl_context = memnew(ContextGL_Win(hWnd, true));
|
||||
gl_context->initialize();
|
||||
|
||||
RasterizerGLES3::register_config();
|
||||
RasterizerGLES3::make_current();
|
||||
gles3_context = false;
|
||||
}
|
||||
|
||||
video_driver_index = p_video_driver; // FIXME TODO - FIX IF DRIVER DETECTION HAPPENS AND GLES2 MUST BE USED
|
||||
bool editor = Engine::get_singleton()->is_editor_hint();
|
||||
bool gl_initialization_error = false;
|
||||
|
||||
gl_context = NULL;
|
||||
while (!gl_context) {
|
||||
gl_context = memnew(ContextGL_Win(hWnd, gles3_context));
|
||||
|
||||
if (gl_context->initialize() != OK) {
|
||||
memdelete(gl_context);
|
||||
gl_context = NULL;
|
||||
|
||||
if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best" || editor) {
|
||||
if (p_video_driver == VIDEO_DRIVER_GLES2) {
|
||||
gl_initialization_error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
p_video_driver = VIDEO_DRIVER_GLES2;
|
||||
gles3_context = false;
|
||||
} else {
|
||||
gl_initialization_error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (gles3_context) {
|
||||
if (RasterizerGLES3::is_viable() == OK) {
|
||||
RasterizerGLES3::register_config();
|
||||
RasterizerGLES3::make_current();
|
||||
break;
|
||||
} else {
|
||||
if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best" || editor) {
|
||||
p_video_driver = VIDEO_DRIVER_GLES2;
|
||||
gles3_context = false;
|
||||
continue;
|
||||
} else {
|
||||
gl_initialization_error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (RasterizerGLES2::is_viable() == OK) {
|
||||
RasterizerGLES2::register_config();
|
||||
RasterizerGLES2::make_current();
|
||||
break;
|
||||
} else {
|
||||
gl_initialization_error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gl_initialization_error) {
|
||||
OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n"
|
||||
"Please update your drivers or if you have a very old or integrated GPU upgrade it.",
|
||||
"Unable to initialize Video driver");
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
video_driver_index = p_video_driver;
|
||||
|
||||
gl_context->set_use_vsync(video_mode.use_vsync);
|
||||
#endif
|
||||
|
|
|
@ -116,9 +116,14 @@ Error ContextGL_X11::initialize() {
|
|||
};
|
||||
|
||||
int fbcount;
|
||||
GLXFBConfig fbconfig;
|
||||
GLXFBConfig fbconfig = 0;
|
||||
XVisualInfo *vi = NULL;
|
||||
|
||||
XSetWindowAttributes swa;
|
||||
swa.event_mask = StructureNotifyMask;
|
||||
swa.border_pixel = 0;
|
||||
unsigned long valuemask = CWBorderPixel | CWColormap | CWEventMask;
|
||||
|
||||
if (OS::get_singleton()->is_layered_allowed()) {
|
||||
GLXFBConfig *fbc = glXChooseFBConfig(x11_display, DefaultScreen(x11_display), visual_attribs_layered, &fbcount);
|
||||
ERR_FAIL_COND_V(!fbc, ERR_UNCONFIGURED);
|
||||
|
@ -142,16 +147,10 @@ Error ContextGL_X11::initialize() {
|
|||
}
|
||||
ERR_FAIL_COND_V(!fbconfig, ERR_UNCONFIGURED);
|
||||
|
||||
XSetWindowAttributes swa;
|
||||
|
||||
swa.colormap = XCreateColormap(x11_display, RootWindow(x11_display, vi->screen), vi->visual, AllocNone);
|
||||
swa.border_pixel = 0;
|
||||
swa.background_pixmap = None;
|
||||
swa.background_pixel = 0;
|
||||
swa.border_pixmap = None;
|
||||
swa.event_mask = StructureNotifyMask;
|
||||
|
||||
x11_window = XCreateWindow(x11_display, RootWindow(x11_display, vi->screen), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | CWBackPixel, &swa);
|
||||
valuemask |= CWBackPixel;
|
||||
|
||||
} else {
|
||||
GLXFBConfig *fbc = glXChooseFBConfig(x11_display, DefaultScreen(x11_display), visual_attribs, &fbcount);
|
||||
|
@ -160,42 +159,21 @@ Error ContextGL_X11::initialize() {
|
|||
vi = glXGetVisualFromFBConfig(x11_display, fbc[0]);
|
||||
|
||||
fbconfig = fbc[0];
|
||||
|
||||
XSetWindowAttributes swa;
|
||||
|
||||
swa.colormap = XCreateColormap(x11_display, RootWindow(x11_display, vi->screen), vi->visual, AllocNone);
|
||||
swa.border_pixel = 0;
|
||||
swa.event_mask = StructureNotifyMask;
|
||||
|
||||
x11_window = XCreateWindow(x11_display, RootWindow(x11_display, vi->screen), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa);
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V(!x11_window, ERR_UNCONFIGURED);
|
||||
set_class_hint(x11_display, x11_window);
|
||||
XMapWindow(x11_display, x11_window);
|
||||
|
||||
int (*oldHandler)(Display *, XErrorEvent *) =
|
||||
XSetErrorHandler(&ctxErrorHandler);
|
||||
int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&ctxErrorHandler);
|
||||
|
||||
switch (context_type) {
|
||||
case GLES_2_0_COMPATIBLE:
|
||||
case OLDSTYLE: {
|
||||
|
||||
p->glx_context = glXCreateContext(x11_display, vi, 0, GL_TRUE);
|
||||
} break;
|
||||
/*
|
||||
case ContextType::GLES_2_0_COMPATIBLE: {
|
||||
|
||||
static int context_attribs[] = {
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
|
||||
None
|
||||
};
|
||||
|
||||
p->glx_context = glXCreateContextAttribsARB(x11_display, fbconfig, NULL, true, context_attribs);
|
||||
ERR_EXPLAIN("Could not obtain an OpenGL 3.0 context!");
|
||||
ERR_FAIL_COND_V(!p->glx_context, ERR_UNCONFIGURED);
|
||||
} break;
|
||||
*/
|
||||
case GLES_2_0_COMPATIBLE: {
|
||||
|
||||
p->glx_context = glXCreateNewContext(x11_display, fbconfig, GLX_RGBA_TYPE, 0, true);
|
||||
ERR_FAIL_COND_V(!p->glx_context, ERR_UNCONFIGURED);
|
||||
} break;
|
||||
case GLES_3_0_COMPATIBLE: {
|
||||
|
||||
static int context_attribs[] = {
|
||||
|
@ -207,24 +185,22 @@ Error ContextGL_X11::initialize() {
|
|||
};
|
||||
|
||||
p->glx_context = glXCreateContextAttribsARB(x11_display, fbconfig, NULL, true, context_attribs);
|
||||
ERR_EXPLAIN("Could not obtain an OpenGL 3.3 context!");
|
||||
ERR_FAIL_COND_V(ctxErrorOccurred || !p->glx_context, ERR_UNCONFIGURED);
|
||||
} break;
|
||||
}
|
||||
|
||||
swa.colormap = XCreateColormap(x11_display, RootWindow(x11_display, vi->screen), vi->visual, AllocNone);
|
||||
x11_window = XCreateWindow(x11_display, RootWindow(x11_display, vi->screen), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height, 0, vi->depth, InputOutput, vi->visual, valuemask, &swa);
|
||||
|
||||
ERR_FAIL_COND_V(!x11_window, ERR_UNCONFIGURED);
|
||||
set_class_hint(x11_display, x11_window);
|
||||
XMapWindow(x11_display, x11_window);
|
||||
|
||||
XSync(x11_display, False);
|
||||
XSetErrorHandler(oldHandler);
|
||||
|
||||
glXMakeCurrent(x11_display, x11_window, p->glx_context);
|
||||
|
||||
/*
|
||||
glWrapperInit(wrapper_get_proc_address);
|
||||
glFlush();
|
||||
|
||||
glXSwapBuffers(x11_display,x11_window);
|
||||
*/
|
||||
//glXMakeCurrent(x11_display, None, NULL);
|
||||
|
||||
XFree(vi);
|
||||
|
||||
return OK;
|
||||
|
@ -297,7 +273,6 @@ ContextGL_X11::ContextGL_X11(::Display *p_x11_display, ::Window &p_x11_window, c
|
|||
ContextGL_X11::~ContextGL_X11() {
|
||||
release_current();
|
||||
glXDestroyContext(x11_display, p->glx_context);
|
||||
|
||||
memdelete(p);
|
||||
}
|
||||
|
||||
|
|
|
@ -274,21 +274,70 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
|
|||
opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE;
|
||||
}
|
||||
|
||||
context_gl = memnew(ContextGL_X11(x11_display, x11_window, current_videomode, opengl_api_type));
|
||||
context_gl->initialize();
|
||||
bool editor = Engine::get_singleton()->is_editor_hint();
|
||||
bool gl_initialization_error = false;
|
||||
|
||||
switch (opengl_api_type) {
|
||||
case ContextGL_X11::GLES_2_0_COMPATIBLE: {
|
||||
RasterizerGLES2::register_config();
|
||||
RasterizerGLES2::make_current();
|
||||
} break;
|
||||
case ContextGL_X11::GLES_3_0_COMPATIBLE: {
|
||||
RasterizerGLES3::register_config();
|
||||
RasterizerGLES3::make_current();
|
||||
} break;
|
||||
context_gl = NULL;
|
||||
while (!context_gl) {
|
||||
context_gl = memnew(ContextGL_X11(x11_display, x11_window, current_videomode, opengl_api_type));
|
||||
|
||||
if (context_gl->initialize() != OK) {
|
||||
memdelete(context_gl);
|
||||
context_gl = NULL;
|
||||
|
||||
if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best" || editor) {
|
||||
if (p_video_driver == VIDEO_DRIVER_GLES2) {
|
||||
gl_initialization_error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
p_video_driver = VIDEO_DRIVER_GLES2;
|
||||
opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE;
|
||||
} else {
|
||||
gl_initialization_error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
video_driver_index = p_video_driver; // FIXME TODO - FIX IF DRIVER DETECTION HAPPENS AND GLES2 MUST BE USED
|
||||
while (true) {
|
||||
if (opengl_api_type == ContextGL_X11::GLES_3_0_COMPATIBLE) {
|
||||
if (RasterizerGLES3::is_viable() == OK) {
|
||||
RasterizerGLES3::register_config();
|
||||
RasterizerGLES3::make_current();
|
||||
break;
|
||||
} else {
|
||||
if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best" || editor) {
|
||||
p_video_driver = VIDEO_DRIVER_GLES2;
|
||||
opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE;
|
||||
continue;
|
||||
} else {
|
||||
gl_initialization_error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (opengl_api_type == ContextGL_X11::GLES_2_0_COMPATIBLE) {
|
||||
if (RasterizerGLES2::is_viable() == OK) {
|
||||
RasterizerGLES2::register_config();
|
||||
RasterizerGLES2::make_current();
|
||||
break;
|
||||
} else {
|
||||
gl_initialization_error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gl_initialization_error) {
|
||||
OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n"
|
||||
"Please update your drivers or if you have a very old or integrated GPU upgrade it.",
|
||||
"Unable to initialize Video driver");
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
video_driver_index = p_video_driver;
|
||||
|
||||
context_gl->set_use_vsync(current_videomode.use_vsync);
|
||||
|
||||
|
@ -339,8 +388,6 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
|
|||
set_window_always_on_top(true);
|
||||
}
|
||||
|
||||
AudioDriverManager::initialize(p_audio_driver);
|
||||
|
||||
ERR_FAIL_COND_V(!visual_server, ERR_UNAVAILABLE);
|
||||
ERR_FAIL_COND_V(x11_window == 0, ERR_UNAVAILABLE);
|
||||
|
||||
|
@ -510,6 +557,8 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
|
|||
|
||||
visual_server->init();
|
||||
|
||||
AudioDriverManager::initialize(p_audio_driver);
|
||||
|
||||
input = memnew(InputDefault);
|
||||
|
||||
window_has_focus = true; // Set focus to true at init
|
||||
|
|
Loading…
Reference in a new issue