summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabio Alessandrelli <fabio.alessandrelli@gmail.com>2021-10-25 19:16:40 +0200
committerFabio Alessandrelli <fabio.alessandrelli@gmail.com>2021-11-19 16:59:27 +0100
commit46fdba5f8b09e2c52247ab28047f578e32414f1a (patch)
treebbad8bc21370aa46c5ddc2bc584586ff4c6c9e27
parent42f8bfaff0dc5a94ca351b1eaadc42cb95655b87 (diff)
[HTML5] Add WebGL2 (GLES3) support using the OpenGL renderer.
Note, the editor build requires the mbedtls module to be manually enabled, as it is currently needed as a ResourceUID dependency. This will need to be addressed in a separate PR.
-rw-r--r--SConstruct17
-rw-r--r--core/os/os.h2
-rw-r--r--drivers/SCsub5
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp2
-rw-r--r--misc/dist/html/editor.html10
-rw-r--r--platform/javascript/detect.py21
-rw-r--r--platform/javascript/display_server_javascript.cpp102
-rw-r--r--platform/javascript/display_server_javascript.h7
-rw-r--r--platform/javascript/os_javascript.h1
9 files changed, 81 insertions, 86 deletions
diff --git a/SConstruct b/SConstruct
index fea0e0ab28..f7d589e799 100644
--- a/SConstruct
+++ b/SConstruct
@@ -16,7 +16,6 @@ from collections import OrderedDict
import methods
import glsl_builders
import gles3_builders
-from platform_methods import run_in_subprocess
# Scan possible build platforms
@@ -706,20 +705,14 @@ if selected_platform in platform_list:
suffix="glsl.gen.h",
src_suffix=".glsl",
),
+ "GLES3_GLSL": env.Builder(
+ action=env.Run(gles3_builders.build_gles3_headers, 'Building GLES3 GLSL header: "$TARGET"'),
+ suffix="glsl.gen.h",
+ src_suffix=".glsl",
+ ),
}
env.Append(BUILDERS=GLSL_BUILDERS)
- if not env["platform"] == "server":
- env.Append(
- BUILDERS={
- "GLES3_GLSL": env.Builder(
- action=run_in_subprocess(gles3_builders.build_gles3_headers),
- suffix="glsl.gen.h",
- src_suffix=".glsl",
- )
- }
- )
-
scons_cache_path = os.environ.get("SCONS_CACHE")
if scons_cache_path != None:
CacheDir(scons_cache_path)
diff --git a/core/os/os.h b/core/os/os.h
index abfa7ac993..3042696cce 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -243,7 +243,7 @@ public:
void set_stdout_enabled(bool p_enabled);
void set_stderr_enabled(bool p_enabled);
- bool is_single_window() const;
+ virtual bool is_single_window() const;
virtual void disable_crash_handler() {}
virtual bool is_disable_crash_handler() const { return false; }
diff --git a/drivers/SCsub b/drivers/SCsub
index 714d4110de..dd81fc645c 100644
--- a/drivers/SCsub
+++ b/drivers/SCsub
@@ -25,10 +25,9 @@ SConscript("winmidi/SCsub")
# Graphics drivers
if env["vulkan"]:
SConscript("vulkan/SCsub")
- SConscript("gles3/SCsub")
+if env["opengl3"]:
SConscript("gl_context/SCsub")
-else:
- SConscript("dummy/SCsub")
+ SConscript("gles3/SCsub")
# Core dependencies
SConscript("png/SCsub")
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index 10093d42a3..92c9dfb9ae 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -68,7 +68,7 @@
#endif
#endif
-#ifndef IPHONE_ENABLED
+#if !defined(IPHONE_ENABLED) && !defined(JAVASCRIPT_ENABLED)
// We include EGL below to get debug callback on GLES2 platforms,
// but EGL is not available on iOS.
#define CAN_DEBUG
diff --git a/misc/dist/html/editor.html b/misc/dist/html/editor.html
index 69e267f665..8b077a5725 100644
--- a/misc/dist/html/editor.html
+++ b/misc/dist/html/editor.html
@@ -281,8 +281,7 @@
<label for="videoMode" style="margin-right: 1rem">Video driver:</label>
<select id="videoMode">
<option value="" selected="selected">Auto</option>
- <option value="GLES2">WebGL</option>
- <option value="GLES3">WebGL 2</option>
+ <option value="opengl3">WebGL 2</option>
</select>
<br />
<br />
@@ -562,8 +561,9 @@
const is_project_manager = args.filter(function(v) { return v == '--project-manager' }).length != 0;
const is_game = !is_editor && !is_project_manager;
if (video_driver) {
- args.push('--video-driver', video_driver);
+ args.push('--rendering-driver', video_driver);
}
+
if (is_game) {
if (game) {
console.error("A game is already running. Close it first");
@@ -651,9 +651,9 @@
selectVideoMode();
showTab('editor');
setLoaderEnabled(false);
- const args = ['--project-manager'];
+ const args = ['--project-manager', '--single-window'];
if (video_driver) {
- args.push('--video-driver', video_driver);
+ args.push('--rendering-driver', video_driver);
}
editor.start({'args': args, 'persistentDrops': true}).then(function() {
setStatusMode('hidden');
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index 891ae419bd..b57f3b3f16 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -180,6 +180,13 @@ def configure(env):
env.Prepend(CPPPATH=["#platform/javascript"])
env.Append(CPPDEFINES=["JAVASCRIPT_ENABLED", "UNIX_ENABLED"])
+ if env["opengl3"]:
+ env.AppendUnique(CPPDEFINES=["GLES3_ENABLED"])
+ # This setting just makes WebGL 2 APIs available, it does NOT disable WebGL 1.
+ env.Append(LINKFLAGS=["-s", "USE_WEBGL2=1"])
+ # Allow use to take control of swapping WebGL buffers.
+ env.Append(LINKFLAGS=["-s", "OFFSCREEN_FRAMEBUFFER=1"])
+
if env["javascript_eval"]:
env.Append(CPPDEFINES=["JAVASCRIPT_EVAL_ENABLED"])
@@ -218,25 +225,11 @@ def configure(env):
# us since we don't know requirements at compile-time.
env.Append(LINKFLAGS=["-s", "ALLOW_MEMORY_GROWTH=1"])
- # This setting just makes WebGL 2 APIs available, it does NOT disable WebGL 1.
- env.Append(LINKFLAGS=["-s", "USE_WEBGL2=1"])
-
# Do not call main immediately when the support code is ready.
env.Append(LINKFLAGS=["-s", "INVOKE_RUN=0"])
- # Allow use to take control of swapping WebGL buffers.
- env.Append(LINKFLAGS=["-s", "OFFSCREEN_FRAMEBUFFER=1"])
-
# callMain for manual start, cwrap for the mono version.
env.Append(LINKFLAGS=["-s", "EXPORTED_RUNTIME_METHODS=['callMain','cwrap']"])
# Add code that allow exiting runtime.
env.Append(LINKFLAGS=["-s", "EXIT_RUNTIME=1"])
-
- # TODO remove once we have GLES support back (temporary fix undefined symbols due to dead code elimination).
- env.Append(
- LINKFLAGS=[
- "-s",
- "EXPORTED_FUNCTIONS=['_main', '_emscripten_webgl_get_current_context']",
- ]
- )
diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp
index d12e1aeee8..7648ddaf43 100644
--- a/platform/javascript/display_server_javascript.cpp
+++ b/platform/javascript/display_server_javascript.cpp
@@ -30,6 +30,9 @@
#include "platform/javascript/display_server_javascript.h"
+#ifdef GLES3_ENABLED
+#include "drivers/gles3/rasterizer_gles3.h"
+#endif
#include "platform/javascript/os_javascript.h"
#include "servers/rendering/rasterizer_dummy.h"
@@ -50,14 +53,6 @@ DisplayServerJavaScript *DisplayServerJavaScript::get_singleton() {
}
// Window (canvas)
-void DisplayServerJavaScript::focus_canvas() {
- godot_js_display_canvas_focus();
-}
-
-bool DisplayServerJavaScript::is_canvas_focused() {
- return godot_js_display_canvas_is_focused() != 0;
-}
-
bool DisplayServerJavaScript::check_size_force_redraw() {
return godot_js_display_size_update() != 0;
}
@@ -141,11 +136,12 @@ void DisplayServerJavaScript::key_callback(int p_pressed, int p_repeat, int p_mo
int DisplayServerJavaScript::mouse_button_callback(int p_pressed, int p_button, double p_x, double p_y, int p_modifiers) {
DisplayServerJavaScript *ds = get_singleton();
+ Point2 pos(p_x, p_y);
+ Input::get_singleton()->set_mouse_position(pos);
Ref<InputEventMouseButton> ev;
ev.instantiate();
- ev->set_pressed(p_pressed);
- ev->set_position(Point2(p_x, p_y));
- ev->set_global_position(ev->get_position());
+ ev->set_position(pos);
+ ev->set_global_position(pos);
ev->set_pressed(p_pressed);
dom2godot_mod(ev, p_modifiers);
@@ -222,13 +218,15 @@ void DisplayServerJavaScript::mouse_move_callback(double p_x, double p_y, double
return;
}
+ Point2 pos(p_x, p_y);
+ Input::get_singleton()->set_mouse_position(pos);
Ref<InputEventMouseMotion> ev;
ev.instantiate();
dom2godot_mod(ev, p_modifiers);
ev->set_button_mask(input_mask);
- ev->set_position(Point2(p_x, p_y));
- ev->set_global_position(ev->get_position());
+ ev->set_position(pos);
+ ev->set_global_position(pos);
ev->set_relative(Vector2(p_rel_x, p_rel_y));
Input::get_singleton()->set_mouse_position(ev->get_position());
@@ -397,6 +395,10 @@ DisplayServer::MouseMode DisplayServerJavaScript::mouse_get_mode() const {
return MOUSE_MODE_VISIBLE;
}
+Point2i DisplayServerJavaScript::mouse_get_position() const {
+ return Input::get_singleton()->get_mouse_position();
+}
+
// Wheel
int DisplayServerJavaScript::mouse_wheel_callback(double p_delta_x, double p_delta_y) {
if (!godot_js_display_canvas_is_focused()) {
@@ -580,7 +582,9 @@ void DisplayServerJavaScript::process_joypads() {
Vector<String> DisplayServerJavaScript::get_rendering_drivers_func() {
Vector<String> drivers;
- drivers.push_back("dummy");
+#ifdef GLES3_ENABLED
+ drivers.push_back("opengl3");
+#endif
return drivers;
}
@@ -678,40 +682,34 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive
// Expose method for requesting quit.
godot_js_os_request_quit_cb(request_quit_callback);
- RasterizerDummy::make_current(); // TODO OpenGL in Godot 4.0... or webgpu?
-#if 0
- EmscriptenWebGLContextAttributes attributes;
- emscripten_webgl_init_context_attributes(&attributes);
- attributes.alpha = GLOBAL_GET("display/window/per_pixel_transparency/allowed");
- attributes.antialias = false;
- ERR_FAIL_INDEX_V(p_video_driver, VIDEO_DRIVER_MAX, ERR_INVALID_PARAMETER);
-
- if (p_desired.layered) {
- set_window_per_pixel_transparency_enabled(true);
- }
-
- bool gl_initialization_error = false;
-
- if (RasterizerGLES3::is_viable() == OK) {
- attributes.majorVersion = 1;
- RasterizerGLES3::register_config();
- RasterizerGLES3::make_current();
- } else {
- gl_initialization_error = true;
- }
-
- EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(canvas_id, &attributes);
- if (emscripten_webgl_make_context_current(ctx) != EMSCRIPTEN_RESULT_SUCCESS) {
- gl_initialization_error = true;
+#ifdef GLES3_ENABLED
+ // TODO "vulkan" defaults to webgl2 for now.
+ bool wants_webgl2 = p_rendering_driver == "opengl3" || p_rendering_driver == "vulkan";
+ bool webgl2_init_failed = wants_webgl2 && !godot_js_display_has_webgl(2);
+ if (wants_webgl2 && !webgl2_init_failed) {
+ EmscriptenWebGLContextAttributes attributes;
+ emscripten_webgl_init_context_attributes(&attributes);
+ //attributes.alpha = GLOBAL_GET("display/window/per_pixel_transparency/allowed");
+ attributes.alpha = true;
+ attributes.antialias = false;
+ attributes.majorVersion = 2;
+
+ webgl_ctx = emscripten_webgl_create_context(canvas_id, &attributes);
+ if (emscripten_webgl_make_context_current(webgl_ctx) != EMSCRIPTEN_RESULT_SUCCESS) {
+ webgl2_init_failed = true;
+ } else {
+ RasterizerGLES3::make_current();
+ }
}
-
- if (gl_initialization_error) {
- OS::get_singleton()->alert("Your browser does not seem to support WebGL. Please update your browser version.",
+ if (webgl2_init_failed) {
+ OS::get_singleton()->alert("Your browser does not seem to support WebGL2. Please update your browser version.",
"Unable to initialize video driver");
- return ERR_UNAVAILABLE;
}
-
- video_driver_index = p_video_driver;
+ if (!wants_webgl2 || webgl2_init_failed) {
+ RasterizerDummy::make_current();
+ }
+#else
+ RasterizerDummy::make_current();
#endif
// JS Input interface (js/libs/library_godot_input.js)
@@ -738,8 +736,12 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive
}
DisplayServerJavaScript::~DisplayServerJavaScript() {
- //emscripten_webgl_commit_frame();
- //emscripten_webgl_destroy_context(webgl_ctx);
+#ifdef GLES3_ENABLED
+ if (webgl_ctx) {
+ emscripten_webgl_commit_frame();
+ emscripten_webgl_destroy_context(webgl_ctx);
+ }
+#endif
}
bool DisplayServerJavaScript::has_feature(Feature p_feature) const {
@@ -968,5 +970,9 @@ bool DisplayServerJavaScript::get_swap_cancel_ok() {
}
void DisplayServerJavaScript::swap_buffers() {
- //emscripten_webgl_commit_frame();
+#ifdef GLES3_ENABLED
+ if (webgl_ctx) {
+ emscripten_webgl_commit_frame();
+ }
+#endif
}
diff --git a/platform/javascript/display_server_javascript.h b/platform/javascript/display_server_javascript.h
index 80ce772a79..843bb61984 100644
--- a/platform/javascript/display_server_javascript.h
+++ b/platform/javascript/display_server_javascript.h
@@ -51,6 +51,10 @@ private:
};
JSKeyEvent key_event;
+#ifdef GLES3_ENABLED
+ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE webgl_ctx = 0;
+#endif
+
WindowMode window_mode = WINDOW_MODE_WINDOWED;
ObjectID window_attached_instance_id = {};
@@ -72,8 +76,6 @@ private:
bool swap_cancel_ok = false;
// utilities
- static void focus_canvas();
- static bool is_canvas_focused();
static void dom2godot_mod(Ref<InputEventWithModifiers> ev, int p_mod);
static const char *godot2dom_cursor(DisplayServer::CursorShape p_shape);
@@ -121,6 +123,7 @@ public:
// mouse
virtual void mouse_set_mode(MouseMode p_mode) override;
virtual MouseMode mouse_get_mode() const override;
+ virtual Point2i mouse_get_position() const override;
// touch
virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h
index aacf87e6c5..fbab95d33b 100644
--- a/platform/javascript/os_javascript.h
+++ b/platform/javascript/os_javascript.h
@@ -90,6 +90,7 @@ public:
String get_user_data_dir() const override;
bool is_userfs_persistent() const override;
+ bool is_single_window() const override { return true; }
void alert(const String &p_alert, const String &p_title = "ALERT!") override;