diff options
74 files changed, 1211 insertions, 247 deletions
diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index afde6863a3..ac6ad0fdd2 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -1460,7 +1460,7 @@ Variant ClassDB::class_get_default_property_value(const StringName &p_class, con if (Engine::get_singleton()->has_singleton(p_class)) { c = Engine::get_singleton()->get_singleton_object(p_class); cleanup_c = false; - } else if (ClassDB::can_instantiate(p_class)) { // Keep this condition in sync with doc_tools.cpp get_documentation_default_value. + } else if (ClassDB::can_instantiate(p_class) && !ClassDB::is_virtual(p_class)) { // Keep this condition in sync with doc_tools.cpp get_documentation_default_value. c = ClassDB::instantiate(p_class); cleanup_c = true; } diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index c6cc4cc4ac..2ba389fc4d 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -1460,15 +1460,25 @@ String String::num(double p_num, int p_decimals) { fmt[5] = 'f'; fmt[6] = 0; } - char buf[256]; + // if we want to convert a double with as much decimal places as as + // DBL_MAX or DBL_MIN then we would theoretically need a buffer of at least + // DBL_MAX_10_EXP + 2 for DBL_MAX and DBL_MAX_10_EXP + 4 for DBL_MIN. + // BUT those values where still giving me exceptions, so I tested from + // DBL_MAX_10_EXP + 10 incrementing one by one and DBL_MAX_10_EXP + 17 (325) + // was the first buffer size not to throw an exception + char buf[325]; #if defined(__GNUC__) || defined(_MSC_VER) - snprintf(buf, 256, fmt, p_num); + // PLEASE NOTE that, albeit vcrt online reference states that snprintf + // should safely truncate the output to the given buffer size, we have + // found a case where this is not true, so we should create a buffer + // as big as needed + snprintf(buf, 325, fmt, p_num); #else sprintf(buf, fmt, p_num); #endif - buf[255] = 0; + buf[324] = 0; //destroy trailing zeroes { bool period = false; diff --git a/doc/classes/AnimatedTexture.xml b/doc/classes/AnimatedTexture.xml index f0c86ba47b..57a7f86901 100644 --- a/doc/classes/AnimatedTexture.xml +++ b/doc/classes/AnimatedTexture.xml @@ -57,6 +57,7 @@ <member name="pause" type="bool" setter="set_pause" getter="get_pause" default="false"> If [code]true[/code], the animation will pause where it currently is (i.e. at [member current_frame]). The animation will continue from where it was paused when changing this property to [code]false[/code]. </member> + <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" /> <member name="speed_scale" type="float" setter="set_speed_scale" getter="get_speed_scale" default="1.0"> The animation speed is multiplied by this value. If set to a negative value, the animation is played in reverse. </member> diff --git a/doc/classes/AtlasTexture.xml b/doc/classes/AtlasTexture.xml index 809d983a9d..fc75459e46 100644 --- a/doc/classes/AtlasTexture.xml +++ b/doc/classes/AtlasTexture.xml @@ -23,5 +23,6 @@ <member name="region" type="Rect2" setter="set_region" getter="get_region" default="Rect2(0, 0, 0, 0)"> The region used to draw the [member atlas]. </member> + <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" /> </members> </class> diff --git a/doc/classes/CameraTexture.xml b/doc/classes/CameraTexture.xml index 8eedfe3580..e7020c869e 100644 --- a/doc/classes/CameraTexture.xml +++ b/doc/classes/CameraTexture.xml @@ -16,6 +16,7 @@ <member name="camera_is_active" type="bool" setter="set_camera_active" getter="get_camera_active" default="false"> Convenience property that gives access to the active property of the [CameraFeed]. </member> + <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" /> <member name="which_feed" type="int" setter="set_which_feed" getter="get_which_feed" enum="CameraServer.FeedImage" default="0"> Which image within the [CameraFeed] we want access to, important if the camera image is split in a Y and CbCr component. </member> diff --git a/doc/classes/CanvasTexture.xml b/doc/classes/CanvasTexture.xml index 2dc83790c7..d5bf65835f 100644 --- a/doc/classes/CanvasTexture.xml +++ b/doc/classes/CanvasTexture.xml @@ -17,6 +17,7 @@ The normal map texture to use. Only has a visible effect if [Light2D]s are affecting this [CanvasTexture]. [b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines. </member> + <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" /> <member name="specular_color" type="Color" setter="set_specular_color" getter="get_specular_color" default="Color(1, 1, 1, 1)"> The multiplier for specular reflection colors. The [Light2D]'s color is also taken into account when determining the reflection color. Only has a visible effect if [Light2D]s are affecting this [CanvasTexture]. </member> diff --git a/doc/classes/CompressedTexture2D.xml b/doc/classes/CompressedTexture2D.xml index f74265b8d5..f7464d8951 100644 --- a/doc/classes/CompressedTexture2D.xml +++ b/doc/classes/CompressedTexture2D.xml @@ -21,5 +21,6 @@ <member name="load_path" type="String" setter="load" getter="get_load_path" default=""""> The CompressedTexture's file path to a [code].ctex[/code] file. </member> + <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" /> </members> </class> diff --git a/doc/classes/CurveTexture.xml b/doc/classes/CurveTexture.xml index 85473fc237..03e008d738 100644 --- a/doc/classes/CurveTexture.xml +++ b/doc/classes/CurveTexture.xml @@ -13,6 +13,7 @@ <member name="curve" type="Curve" setter="set_curve" getter="get_curve"> The [Curve] that is rendered onto the texture. </member> + <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" /> <member name="texture_mode" type="int" setter="set_texture_mode" getter="get_texture_mode" enum="CurveTexture.TextureMode" default="0"> The format the texture should be generated with. When passing a CurveTexture as a input to a [Shader], this may need to be adjusted. </member> diff --git a/doc/classes/CurveXYZTexture.xml b/doc/classes/CurveXYZTexture.xml index e3f2e8fc45..8c4e2dce0f 100644 --- a/doc/classes/CurveXYZTexture.xml +++ b/doc/classes/CurveXYZTexture.xml @@ -19,6 +19,7 @@ <member name="curve_z" type="Curve" setter="set_curve_z" getter="get_curve_z"> The [Curve] that is rendered onto the texture's blue channel. </member> + <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" /> <member name="width" type="int" setter="set_width" getter="get_width" default="256"> The width of the texture (in pixels). Higher values make it possible to represent high-frequency data better (such as sudden direction changes), at the cost of increased generation time and memory usage. </member> diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index 113987bb52..76c67fd704 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -1725,9 +1725,17 @@ </constant> <constant name="WINDOW_VIEW" value="2" enum="HandleType"> Window view: + - Windows: [code]HDC[/code] for the window (only with the GL Compatibility renderer). - macOS: [code]NSView*[/code] for the window main view. - iOS: [code]UIView*[/code] for the window main view. </constant> + <constant name="OPENGL_CONTEXT" value="3" enum="HandleType"> + OpenGL context (only with the GL Compatibility renderer): + - Windows: [code]HGLRC[/code] for the window. + - Linux: [code]GLXContext*[/code] for the window. + - MacOS: [code]NSOpenGLContext*[/code] for the window. + - Android: [code]EGLContext[/code] for the window. + </constant> <constant name="TTS_UTTERANCE_STARTED" value="0" enum="TTSUtteranceEvent"> Utterance has begun to be spoken. </constant> diff --git a/doc/classes/EditorSpinSlider.xml b/doc/classes/EditorSpinSlider.xml index 784a3c1214..de105b32e1 100644 --- a/doc/classes/EditorSpinSlider.xml +++ b/doc/classes/EditorSpinSlider.xml @@ -22,6 +22,8 @@ <member name="read_only" type="bool" setter="set_read_only" getter="is_read_only" default="false"> If [code]true[/code], the slider can't be interacted with. </member> + <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" default="1" /> + <member name="step" type="float" setter="set_step" getter="get_step" overrides="Range" default="1.0" /> <member name="suffix" type="String" setter="set_suffix" getter="get_suffix" default=""""> The suffix to display after the value (in a faded color). This should generally be a plural word. You may have to use an abbreviation if the suffix is too long to be displayed. </member> diff --git a/doc/classes/GradientTexture1D.xml b/doc/classes/GradientTexture1D.xml index 3254754ac1..fa572eeed0 100644 --- a/doc/classes/GradientTexture1D.xml +++ b/doc/classes/GradientTexture1D.xml @@ -12,6 +12,7 @@ <member name="gradient" type="Gradient" setter="set_gradient" getter="get_gradient"> The [Gradient] that will be used to fill the texture. </member> + <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" /> <member name="use_hdr" type="bool" setter="set_use_hdr" getter="is_using_hdr" default="false"> If [code]true[/code], the generated texture will support high dynamic range ([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/code], the generated texture will use low dynamic range; overbright colors will be clamped ([constant Image.FORMAT_RGBA8] format). </member> diff --git a/doc/classes/GradientTexture2D.xml b/doc/classes/GradientTexture2D.xml index 7561f1b947..87d86e7a59 100644 --- a/doc/classes/GradientTexture2D.xml +++ b/doc/classes/GradientTexture2D.xml @@ -27,6 +27,7 @@ <member name="repeat" type="int" setter="set_repeat" getter="get_repeat" enum="GradientTexture2D.Repeat" default="0"> The gradient repeat type, one of the [enum Repeat] values. The texture is filled starting from [member fill_from] to [member fill_to] offsets by default, but the gradient fill can be repeated to cover the entire texture. </member> + <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" /> <member name="use_hdr" type="bool" setter="set_use_hdr" getter="is_using_hdr" default="false"> If [code]true[/code], the generated texture will support high dynamic range ([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/code], the generated texture will use low dynamic range; overbright colors will be clamped ([constant Image.FORMAT_RGBA8] format). </member> diff --git a/doc/classes/ImageTexture.xml b/doc/classes/ImageTexture.xml index 45cbd7ac87..03d1947475 100644 --- a/doc/classes/ImageTexture.xml +++ b/doc/classes/ImageTexture.xml @@ -67,4 +67,7 @@ </description> </method> </methods> + <members> + <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" /> + </members> </class> diff --git a/doc/classes/MeshTexture.xml b/doc/classes/MeshTexture.xml index 8e2bccc79f..d09fa4c898 100644 --- a/doc/classes/MeshTexture.xml +++ b/doc/classes/MeshTexture.xml @@ -18,5 +18,6 @@ <member name="mesh" type="Mesh" setter="set_mesh" getter="get_mesh"> Sets the mesh used to draw. It must be a mesh using 2D vertices. </member> + <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" /> </members> </class> diff --git a/doc/classes/PhysicsDirectBodyState2D.xml b/doc/classes/PhysicsDirectBodyState2D.xml index e8062f3e94..eca6a1cbc7 100644 --- a/doc/classes/PhysicsDirectBodyState2D.xml +++ b/doc/classes/PhysicsDirectBodyState2D.xml @@ -209,40 +209,40 @@ </method> </methods> <members> - <member name="angular_velocity" type="float" setter="set_angular_velocity" getter="get_angular_velocity" default="0.0"> + <member name="angular_velocity" type="float" setter="set_angular_velocity" getter="get_angular_velocity"> The body's rotational velocity in [i]radians[/i] per second. </member> - <member name="center_of_mass" type="Vector2" setter="" getter="get_center_of_mass" default="Vector2(0, 0)"> + <member name="center_of_mass" type="Vector2" setter="" getter="get_center_of_mass"> The body's center of mass position relative to the body's center in the global coordinate system. </member> - <member name="center_of_mass_local" type="Vector2" setter="" getter="get_center_of_mass_local" default="Vector2(0, 0)"> + <member name="center_of_mass_local" type="Vector2" setter="" getter="get_center_of_mass_local"> The body's center of mass position in the body's local coordinate system. </member> - <member name="inverse_inertia" type="float" setter="" getter="get_inverse_inertia" default="0.0"> + <member name="inverse_inertia" type="float" setter="" getter="get_inverse_inertia"> The inverse of the inertia of the body. </member> - <member name="inverse_mass" type="float" setter="" getter="get_inverse_mass" default="0.0"> + <member name="inverse_mass" type="float" setter="" getter="get_inverse_mass"> The inverse of the mass of the body. </member> - <member name="linear_velocity" type="Vector2" setter="set_linear_velocity" getter="get_linear_velocity" default="Vector2(0, 0)"> + <member name="linear_velocity" type="Vector2" setter="set_linear_velocity" getter="get_linear_velocity"> The body's linear velocity in pixels per second. </member> - <member name="sleeping" type="bool" setter="set_sleep_state" getter="is_sleeping" default="false"> + <member name="sleeping" type="bool" setter="set_sleep_state" getter="is_sleeping"> If [code]true[/code], this body is currently sleeping (not active). </member> - <member name="step" type="float" setter="" getter="get_step" default="0.0"> + <member name="step" type="float" setter="" getter="get_step"> The timestep (delta) used for the simulation. </member> - <member name="total_angular_damp" type="float" setter="" getter="get_total_angular_damp" default="0.0"> + <member name="total_angular_damp" type="float" setter="" getter="get_total_angular_damp"> The rate at which the body stops rotating, if there are not any other forces moving it. </member> - <member name="total_gravity" type="Vector2" setter="" getter="get_total_gravity" default="Vector2(0, 0)"> + <member name="total_gravity" type="Vector2" setter="" getter="get_total_gravity"> The total gravity vector being currently applied to this body. </member> - <member name="total_linear_damp" type="float" setter="" getter="get_total_linear_damp" default="0.0"> + <member name="total_linear_damp" type="float" setter="" getter="get_total_linear_damp"> The rate at which the body stops moving, if there are not any other forces moving it. </member> - <member name="transform" type="Transform2D" setter="set_transform" getter="get_transform" default="Transform2D(1, 0, 0, 1, 0, 0)"> + <member name="transform" type="Transform2D" setter="set_transform" getter="get_transform"> The body's transformation matrix. </member> </members> diff --git a/doc/classes/PhysicsDirectBodyState3D.xml b/doc/classes/PhysicsDirectBodyState3D.xml index 4c6d51c85a..a809384642 100644 --- a/doc/classes/PhysicsDirectBodyState3D.xml +++ b/doc/classes/PhysicsDirectBodyState3D.xml @@ -216,45 +216,45 @@ </method> </methods> <members> - <member name="angular_velocity" type="Vector3" setter="set_angular_velocity" getter="get_angular_velocity" default="Vector3(0, 0, 0)"> + <member name="angular_velocity" type="Vector3" setter="set_angular_velocity" getter="get_angular_velocity"> The body's rotational velocity in [i]radians[/i] per second. </member> - <member name="center_of_mass" type="Vector3" setter="" getter="get_center_of_mass" default="Vector3(0, 0, 0)"> + <member name="center_of_mass" type="Vector3" setter="" getter="get_center_of_mass"> The body's center of mass position relative to the body's center in the global coordinate system. </member> - <member name="center_of_mass_local" type="Vector3" setter="" getter="get_center_of_mass_local" default="Vector3(0, 0, 0)"> + <member name="center_of_mass_local" type="Vector3" setter="" getter="get_center_of_mass_local"> The body's center of mass position in the body's local coordinate system. </member> - <member name="inverse_inertia" type="Vector3" setter="" getter="get_inverse_inertia" default="Vector3(0, 0, 0)"> + <member name="inverse_inertia" type="Vector3" setter="" getter="get_inverse_inertia"> The inverse of the inertia of the body. </member> - <member name="inverse_inertia_tensor" type="Basis" setter="" getter="get_inverse_inertia_tensor" default="Basis(1, 0, 0, 0, 1, 0, 0, 0, 1)"> + <member name="inverse_inertia_tensor" type="Basis" setter="" getter="get_inverse_inertia_tensor"> The inverse of the inertia tensor of the body. </member> - <member name="inverse_mass" type="float" setter="" getter="get_inverse_mass" default="0.0"> + <member name="inverse_mass" type="float" setter="" getter="get_inverse_mass"> The inverse of the mass of the body. </member> - <member name="linear_velocity" type="Vector3" setter="set_linear_velocity" getter="get_linear_velocity" default="Vector3(0, 0, 0)"> + <member name="linear_velocity" type="Vector3" setter="set_linear_velocity" getter="get_linear_velocity"> The body's linear velocity in units per second. </member> - <member name="principal_inertia_axes" type="Basis" setter="" getter="get_principal_inertia_axes" default="Basis(1, 0, 0, 0, 1, 0, 0, 0, 1)"> + <member name="principal_inertia_axes" type="Basis" setter="" getter="get_principal_inertia_axes"> </member> - <member name="sleeping" type="bool" setter="set_sleep_state" getter="is_sleeping" default="false"> + <member name="sleeping" type="bool" setter="set_sleep_state" getter="is_sleeping"> If [code]true[/code], this body is currently sleeping (not active). </member> - <member name="step" type="float" setter="" getter="get_step" default="0.0"> + <member name="step" type="float" setter="" getter="get_step"> The timestep (delta) used for the simulation. </member> - <member name="total_angular_damp" type="float" setter="" getter="get_total_angular_damp" default="0.0"> + <member name="total_angular_damp" type="float" setter="" getter="get_total_angular_damp"> The rate at which the body stops rotating, if there are not any other forces moving it. </member> - <member name="total_gravity" type="Vector3" setter="" getter="get_total_gravity" default="Vector3(0, 0, 0)"> + <member name="total_gravity" type="Vector3" setter="" getter="get_total_gravity"> The total gravity vector being currently applied to this body. </member> - <member name="total_linear_damp" type="float" setter="" getter="get_total_linear_damp" default="0.0"> + <member name="total_linear_damp" type="float" setter="" getter="get_total_linear_damp"> The rate at which the body stops moving, if there are not any other forces moving it. </member> - <member name="transform" type="Transform3D" setter="set_transform" getter="get_transform" default="Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)"> + <member name="transform" type="Transform3D" setter="set_transform" getter="get_transform"> The body's transformation matrix. </member> </members> diff --git a/doc/classes/PlaceholderTexture2D.xml b/doc/classes/PlaceholderTexture2D.xml index 76e575265b..5d8509ec77 100644 --- a/doc/classes/PlaceholderTexture2D.xml +++ b/doc/classes/PlaceholderTexture2D.xml @@ -7,6 +7,7 @@ <tutorials> </tutorials> <members> + <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" /> <member name="size" type="Vector2" setter="set_size" getter="get_size" default="Vector2(1, 1)"> </member> </members> diff --git a/doc/classes/PortableCompressedTexture2D.xml b/doc/classes/PortableCompressedTexture2D.xml index a0492f2c07..b64cda6df5 100644 --- a/doc/classes/PortableCompressedTexture2D.xml +++ b/doc/classes/PortableCompressedTexture2D.xml @@ -58,6 +58,7 @@ When running on the editor, this class will keep the source compressed data in memory. Otherwise, the source compressed data is lost after loading and the resource can't be re saved. This flag allows to keep the compressed data in memory if you intend it to persist after loading. </member> + <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" /> <member name="size_override" type="Vector2" setter="set_size_override" getter="get_size_override" default="Vector2(0, 0)"> Allow overriding the texture size (for 2D only). </member> diff --git a/doc/classes/ProgressBar.xml b/doc/classes/ProgressBar.xml index f8c5dc0e1f..510b8d5bd1 100644 --- a/doc/classes/ProgressBar.xml +++ b/doc/classes/ProgressBar.xml @@ -15,8 +15,6 @@ <member name="show_percentage" type="bool" setter="set_show_percentage" getter="is_percentage_shown" default="true"> If [code]true[/code], the fill percentage is displayed on the bar. </member> - <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" default="0" /> - <member name="step" type="float" setter="set_step" getter="get_step" overrides="Range" default="0.01" /> </members> <constants> <constant name="FILL_BEGIN_TO_END" value="0" enum="FillMode"> diff --git a/doc/classes/Range.xml b/doc/classes/Range.xml index 8aa89015c6..2dcfc90955 100644 --- a/doc/classes/Range.xml +++ b/doc/classes/Range.xml @@ -62,7 +62,8 @@ <member name="rounded" type="bool" setter="set_use_rounded_values" getter="is_using_rounded_values" default="false"> If [code]true[/code], [code]value[/code] will always be rounded to the nearest integer. </member> - <member name="step" type="float" setter="set_step" getter="get_step" default="1.0"> + <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" default="0" /> + <member name="step" type="float" setter="set_step" getter="get_step" default="0.01"> If greater than 0, [code]value[/code] will always be rounded to a multiple of [code]step[/code]. If [code]rounded[/code] is also [code]true[/code], [code]value[/code] will first be rounded to a multiple of [code]step[/code] then rounded to the nearest integer. </member> <member name="value" type="float" setter="set_value" getter="get_value" default="0.0"> diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml index cb13697cc2..2de812f5fc 100644 --- a/doc/classes/RenderingDevice.xml +++ b/doc/classes/RenderingDevice.xml @@ -643,6 +643,15 @@ <description> </description> </method> + <method name="vertex_array_create"> + <return type="RID" /> + <param index="0" name="vertex_count" type="int" /> + <param index="1" name="vertex_format" type="int" /> + <param index="2" name="src_buffers" type="RID[]" /> + <description> + Creates a vertex array based on the specified buffers. + </description> + </method> <method name="vertex_buffer_create"> <return type="RID" /> <param index="0" name="size_bytes" type="int" /> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 1c02d58299..13e5470a56 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -3024,6 +3024,14 @@ <description> </description> </method> + <method name="texture_get_rd_texture" qualifiers="const"> + <return type="RID" /> + <param index="0" name="texture" type="RID" /> + <param index="1" name="srgb" type="bool" default="false" /> + <description> + Returns a texture [RID] that can be used with [RenderingDevice]. + </description> + </method> <method name="texture_proxy_create"> <return type="RID" /> <param index="0" name="base" type="RID" /> diff --git a/doc/classes/ScrollBar.xml b/doc/classes/ScrollBar.xml index 266787c9c8..247e892c24 100644 --- a/doc/classes/ScrollBar.xml +++ b/doc/classes/ScrollBar.xml @@ -12,7 +12,6 @@ <member name="custom_step" type="float" setter="set_custom_step" getter="get_custom_step" default="-1.0"> Overrides the step used when clicking increment and decrement buttons or when using arrow keys when the [ScrollBar] is focused. </member> - <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" default="0" /> <member name="step" type="float" setter="set_step" getter="get_step" overrides="Range" default="0.0" /> </members> <signals> diff --git a/doc/classes/Slider.xml b/doc/classes/Slider.xml index 0e626842bd..cecca0a5fb 100644 --- a/doc/classes/Slider.xml +++ b/doc/classes/Slider.xml @@ -17,7 +17,7 @@ <member name="scrollable" type="bool" setter="set_scrollable" getter="is_scrollable" default="true"> If [code]true[/code], the value can be changed using the mouse wheel. </member> - <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" default="0" /> + <member name="step" type="float" setter="set_step" getter="get_step" overrides="Range" default="1.0" /> <member name="tick_count" type="int" setter="set_ticks" getter="get_ticks" default="0"> Number of ticks displayed on the slider, including border ticks. Ticks are uniformly-distributed value markers. </member> diff --git a/doc/classes/SpinBox.xml b/doc/classes/SpinBox.xml index 93799b58f0..e214867890 100644 --- a/doc/classes/SpinBox.xml +++ b/doc/classes/SpinBox.xml @@ -59,6 +59,8 @@ <member name="select_all_on_focus" type="bool" setter="set_select_all_on_focus" getter="is_select_all_on_focus" default="false"> If [code]true[/code], the [SpinBox] will select the whole text when the [LineEdit] gains focus. Clicking the up and down arrows won't trigger this behavior. </member> + <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" default="1" /> + <member name="step" type="float" setter="set_step" getter="get_step" overrides="Range" default="1.0" /> <member name="suffix" type="String" setter="set_suffix" getter="get_suffix" default=""""> Adds the specified [code]suffix[/code] string after the numerical value of the [SpinBox]. </member> diff --git a/doc/classes/TextureProgressBar.xml b/doc/classes/TextureProgressBar.xml index ded4dac7da..54b77bf5eb 100644 --- a/doc/classes/TextureProgressBar.xml +++ b/doc/classes/TextureProgressBar.xml @@ -41,6 +41,8 @@ <member name="radial_initial_angle" type="float" setter="set_radial_initial_angle" getter="get_radial_initial_angle" default="0.0"> Starting angle for the fill of [member texture_progress] if [member fill_mode] is [constant FILL_CLOCKWISE] or [constant FILL_COUNTER_CLOCKWISE]. When the node's [code]value[/code] is equal to its [code]min_value[/code], the texture doesn't show up at all. When the [code]value[/code] increases, the texture fills and tends towards [member radial_fill_degrees]. </member> + <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" default="1" /> + <member name="step" type="float" setter="set_step" getter="get_step" overrides="Range" default="1.0" /> <member name="stretch_margin_bottom" type="int" setter="set_stretch_margin" getter="get_stretch_margin" default="0"> The height of the 9-patch's bottom row. A margin of 16 means the 9-slice's bottom corners and side will have a height of 16 pixels. You can set all 4 margin values individually to create panels with non-uniform borders. </member> diff --git a/doc/classes/ViewportTexture.xml b/doc/classes/ViewportTexture.xml index 955f054cea..6bd64a50bb 100644 --- a/doc/classes/ViewportTexture.xml +++ b/doc/classes/ViewportTexture.xml @@ -15,7 +15,6 @@ <link title="3D Viewport Scaling Demo">https://godotengine.org/asset-library/asset/586</link> </tutorials> <members> - <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="true" /> <member name="viewport_path" type="NodePath" setter="set_viewport_path_in_scene" getter="get_viewport_path_in_scene" default="NodePath("")"> The path to the [Viewport] node to display. This is relative to the scene root, not to the node which uses the texture. </member> diff --git a/doc/classes/XRInterface.xml b/doc/classes/XRInterface.xml index cc483dbd02..05d5eb6673 100644 --- a/doc/classes/XRInterface.xml +++ b/doc/classes/XRInterface.xml @@ -35,6 +35,16 @@ Returns an array of vectors that denotes the physical play area mapped to the virtual space around the [XROrigin3D] point. The points form a convex polygon that can be used to react to or visualize the play area. This returns an empty array if this feature is not supported or if the information is not yet available. </description> </method> + <method name="get_projection_for_view"> + <return type="Projection" /> + <param index="0" name="view" type="int" /> + <param index="1" name="aspect" type="float" /> + <param index="2" name="near" type="float" /> + <param index="3" name="far" type="float" /> + <description> + Returns the projection matrix for a view/eye. + </description> + </method> <method name="get_render_target_size"> <return type="Vector2" /> <description> @@ -47,6 +57,16 @@ If supported, returns the status of our tracking. This will allow you to provide feedback to the user whether there are issues with positional tracking. </description> </method> + <method name="get_transform_for_view"> + <return type="Transform3D" /> + <param index="0" name="view" type="int" /> + <param index="1" name="cam_transform" type="Transform3D" /> + <description> + Returns the transform for a view/eye. + [param view] is the view/eye index. + [param cam_transform] is the transform that maps device coordinates to scene coordinates, typically the global_transform of the current XROrigin3D. + </description> + </method> <method name="get_view_count"> <return type="int" /> <description> diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index b05817cd8e..0a64cda787 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -1006,13 +1006,15 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, const Tran if (primitive->point_count != state.canvas_instance_batches[state.current_batch_index].primitive_points || state.canvas_instance_batches[state.current_batch_index].command_type != Item::Command::TYPE_PRIMITIVE) { _new_batch(r_batch_broken, r_index); - state.canvas_instance_batches[state.current_batch_index].tex = RID(); + state.canvas_instance_batches[state.current_batch_index].tex = primitive->texture; state.canvas_instance_batches[state.current_batch_index].primitive_points = primitive->point_count; state.canvas_instance_batches[state.current_batch_index].command_type = Item::Command::TYPE_PRIMITIVE; state.canvas_instance_batches[state.current_batch_index].command = c; state.canvas_instance_batches[state.current_batch_index].shader_variant = CanvasShaderGLES3::MODE_PRIMITIVE; } + _prepare_canvas_texture(state.canvas_instance_batches[state.current_batch_index].tex, state.canvas_instance_batches[state.current_batch_index].filter, state.canvas_instance_batches[state.current_batch_index].repeat, r_index, texpixel_size); + for (uint32_t j = 0; j < MIN(3u, primitive->point_count); j++) { state.instance_data_array[r_index].points[j * 2 + 0] = primitive->points[j].x; state.instance_data_array[r_index].points[j * 2 + 1] = primitive->points[j].y; diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 2e8c95fe61..734911ccdb 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1642,6 +1642,9 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ ERR_FAIL_COND(rb.is_null()); } + GLES3::RenderTarget *rt = texture_storage->get_render_target(rb->render_target); + ERR_FAIL_COND(!rt); + // Assign render data // Use the format from rendererRD RenderDataGLES3 render_data; @@ -1729,8 +1732,20 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ scene_state.ubo.emissive_exposure_normalization = -1.0; // Use default exposure normalization. + bool flip_y = !render_data.reflection_probe.is_valid(); + + if (rt->overridden.color.is_valid()) { + // If we've overridden the render target's color texture, then don't render upside down. + // We're probably rendering directly to an XR device. + flip_y = false; + } + if (!flip_y) { + // If we're rendering right-side up, then we need to change the winding order. + glFrontFace(GL_CW); + } + _setup_lights(&render_data, false, render_data.directional_light_count, render_data.omni_light_count, render_data.spot_light_count); - _setup_environment(&render_data, render_data.reflection_probe.is_valid(), screen_size, !render_data.reflection_probe.is_valid(), clear_color, false); + _setup_environment(&render_data, render_data.reflection_probe.is_valid(), screen_size, flip_y, clear_color, false); _fill_render_list(RENDER_LIST_OPAQUE, &render_data, PASS_MODE_COLOR); render_list[RENDER_LIST_OPAQUE].sort_by_key(); @@ -1811,7 +1826,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ } } - glBindFramebuffer(GL_FRAMEBUFFER, rb->framebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo); glViewport(0, 0, rb->width, rb->height); // Do depth prepass if it's explicitly enabled @@ -1917,6 +1932,11 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ _render_list_template<PASS_MODE_COLOR_TRANSPARENT>(&render_list_params_alpha, &render_data, 0, render_list[RENDER_LIST_ALPHA].elements.size(), true); + if (!flip_y) { + // Restore the default winding order. + glFrontFace(GL_CCW); + } + if (rb.is_valid()) { _render_buffers_debug_draw(rb, p_shadow_atlas, p_occluder_debug_tex); } @@ -1973,6 +1993,8 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, } } + bool should_request_redraw = false; + for (uint32_t i = p_from_element; i < p_to_element; i++) { const GeometryInstanceSurface *surf = p_params->elements[i]; GeometryInstanceGLES3 *inst = surf->owner; @@ -2003,6 +2025,11 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, continue; } + //request a redraw if one of the shaders uses TIME + if (shader->uses_time) { + should_request_redraw = true; + } + if constexpr (p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) { if (scene_state.current_depth_test != shader->depth_test) { if (shader->depth_test == GLES3::SceneShaderData::DEPTH_TEST_DISABLED) { @@ -2227,6 +2254,11 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, glDisableVertexAttribArray(15); } } + + // Make the actual redraw request + if (should_request_redraw) { + RenderingServerDefault::redraw_request(); + } } void RasterizerSceneGLES3::render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { diff --git a/drivers/gles3/storage/render_scene_buffers_gles3.cpp b/drivers/gles3/storage/render_scene_buffers_gles3.cpp index b8e4530f56..e0e78de728 100644 --- a/drivers/gles3/storage/render_scene_buffers_gles3.cpp +++ b/drivers/gles3/storage/render_scene_buffers_gles3.cpp @@ -33,17 +33,12 @@ #include "render_scene_buffers_gles3.h" #include "texture_storage.h" -#ifdef ANDROID_ENABLED -#define glFramebufferTextureMultiviewOVR GLES3::Config::get_singleton()->eglFramebufferTextureMultiviewOVR -#endif - RenderSceneBuffersGLES3::~RenderSceneBuffersGLES3() { free_render_buffer_data(); } void RenderSceneBuffersGLES3::configure(RID p_render_target, const Size2i p_internal_size, const Size2i p_target_size, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) { GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); - GLES3::Config *config = GLES3::Config::get_singleton(); //internal_size.x = p_internal_size.x; // ignore for now //internal_size.y = p_internal_size.y; @@ -62,66 +57,9 @@ void RenderSceneBuffersGLES3::configure(RID p_render_target, const Size2i p_inte GLES3::RenderTarget *rt = texture_storage->get_render_target(p_render_target); is_transparent = rt->is_transparent; - - // framebuffer - glGenFramebuffers(1, &framebuffer); - glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); - - if (view_count > 1 && config->multiview_supported) { - glBindTexture(GL_TEXTURE_2D_ARRAY, rt->color); - glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, rt->color, 0, 0, view_count); - } else { - glBindTexture(GL_TEXTURE_2D, rt->color); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0); - } - - glGenTextures(1, &depth_texture); - if (view_count > 1 && config->multiview_supported) { - glBindTexture(GL_TEXTURE_2D_ARRAY, depth_texture); - glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT24, rt->size.x, rt->size.y, view_count, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); - - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } else { - glBindTexture(GL_TEXTURE_2D, depth_texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, rt->size.x, rt->size.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - - if (view_count > 1 && config->multiview_supported) { - glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depth_texture, 0, 0, view_count); - } else { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_texture, 0); - } - - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - - glBindTexture(GL_TEXTURE_2D, 0); - glBindTexture(GL_TEXTURE_2D_ARRAY, 0); - glBindFramebuffer(GL_FRAMEBUFFER, texture_storage->system_fbo); - - if (status != GL_FRAMEBUFFER_COMPLETE) { - free_render_buffer_data(); - WARN_PRINT("Could not create 3D renderbuffer, status: " + texture_storage->get_framebuffer_error(status)); - return; - } } void RenderSceneBuffersGLES3::free_render_buffer_data() { - if (depth_texture) { - glDeleteTextures(1, &depth_texture); - depth_texture = 0; - } - if (framebuffer) { - glDeleteFramebuffers(1, &framebuffer); - framebuffer = 0; - } } #endif // GLES3_ENABLED diff --git a/drivers/gles3/storage/render_scene_buffers_gles3.h b/drivers/gles3/storage/render_scene_buffers_gles3.h index dbedbd22c3..092c14e1b8 100644 --- a/drivers/gles3/storage/render_scene_buffers_gles3.h +++ b/drivers/gles3/storage/render_scene_buffers_gles3.h @@ -61,9 +61,6 @@ public: bool is_transparent = false; RID render_target; - GLuint internal_texture = 0; // Used for rendering when post effects are enabled - GLuint depth_texture = 0; // Main depth texture - GLuint framebuffer = 0; // Main framebuffer, contains internal_texture and depth_texture or render_target->color and depth_texture //built-in textures used for ping pong image processing and blurring struct Blur { diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp index 11151c4100..2c2341e1cf 100644 --- a/drivers/gles3/storage/texture_storage.cpp +++ b/drivers/gles3/storage/texture_storage.cpp @@ -614,7 +614,9 @@ void TextureStorage::texture_free(RID p_texture) { } if (t->tex_id != 0) { - glDeleteTextures(1, &t->tex_id); + if (!t->is_external) { + glDeleteTextures(1, &t->tex_id); + } t->tex_id = 0; } @@ -680,6 +682,35 @@ void TextureStorage::texture_proxy_initialize(RID p_texture, RID p_base) { texture_owner.initialize_rid(p_texture, proxy_tex); } +RID TextureStorage::texture_create_external(Texture::Type p_type, Image::Format p_format, unsigned int p_image, int p_width, int p_height, int p_depth, int p_layers, RS::TextureLayeredType p_layered_type) { + Texture texture; + texture.active = true; + texture.is_external = true; + texture.type = p_type; + + switch (p_type) { + case Texture::TYPE_2D: { + texture.target = GL_TEXTURE_2D; + } break; + case Texture::TYPE_3D: { + texture.target = GL_TEXTURE_3D; + } break; + case Texture::TYPE_LAYERED: { + texture.target = GL_TEXTURE_2D_ARRAY; + } break; + } + + texture.real_format = texture.format = p_format; + texture.tex_id = p_image; + texture.alloc_width = texture.width = p_width; + texture.alloc_height = texture.height = p_height; + texture.depth = p_depth; + texture.layers = p_layers; + texture.layered_type = p_layered_type; + + return texture_owner.make_rid(texture); +} + void TextureStorage::texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer) { texture_set_data(p_texture, p_image, p_layer); #ifdef TOOLS_ENABLED @@ -991,6 +1022,10 @@ Size2 TextureStorage::texture_size_with_proxy(RID p_texture) { } } +RID TextureStorage::texture_get_rd_texture_rid(RID p_texture, bool p_srgb) const { + return RID(); +} + void TextureStorage::texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer) { Texture *texture = texture_owner.get_or_null(p_texture); @@ -1459,43 +1494,74 @@ void TextureStorage::_update_render_target(RenderTarget *rt) { glDepthMask(GL_FALSE); { - /* Front FBO */ + Texture *texture; + bool use_multiview = rt->view_count > 1 && config->multiview_supported; + GLenum texture_target = use_multiview ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D; - Texture *texture = get_texture(rt->texture); - ERR_FAIL_COND(!texture); + /* Front FBO */ - // framebuffer glGenFramebuffers(1, &rt->fbo); glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo); // color - glGenTextures(1, &rt->color); - if (rt->view_count > 1 && config->multiview_supported) { - glBindTexture(GL_TEXTURE_2D_ARRAY, rt->color); - glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, rt->color_internal_format, rt->size.x, rt->size.y, rt->view_count, 0, rt->color_format, rt->color_type, nullptr); - - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + if (rt->overridden.color.is_valid()) { + texture = get_texture(rt->overridden.color); + ERR_FAIL_COND(!texture); + + rt->color = texture->tex_id; + rt->size = Size2i(texture->width, texture->height); } else { - glBindTexture(GL_TEXTURE_2D, rt->color); - glTexImage2D(GL_TEXTURE_2D, 0, rt->color_internal_format, rt->size.x, rt->size.y, 0, rt->color_format, rt->color_type, nullptr); + texture = get_texture(rt->texture); + ERR_FAIL_COND(!texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } + glGenTextures(1, &rt->color); + glBindTexture(texture_target, rt->color); + + if (use_multiview) { + glTexImage3D(texture_target, 0, rt->color_internal_format, rt->size.x, rt->size.y, rt->view_count, 0, rt->color_format, rt->color_type, nullptr); + } else { + glTexImage2D(texture_target, 0, rt->color_internal_format, rt->size.x, rt->size.y, 0, rt->color_format, rt->color_type, nullptr); + } - if (rt->view_count > 1 && config->multiview_supported) { + glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + if (use_multiview) { glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, rt->color, 0, 0, rt->view_count); } else { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0); } - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + // depth + if (rt->overridden.depth.is_valid()) { + texture = get_texture(rt->overridden.depth); + ERR_FAIL_COND(!texture); + rt->depth = texture->tex_id; + } else { + glGenTextures(1, &rt->depth); + glBindTexture(texture_target, rt->depth); + + if (use_multiview) { + glTexImage3D(texture_target, 0, GL_DEPTH_COMPONENT24, rt->size.x, rt->size.y, rt->view_count, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); + } else { + glTexImage2D(texture_target, 0, GL_DEPTH_COMPONENT24, rt->size.x, rt->size.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr); + } + + glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + if (use_multiview) { + glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, rt->depth, 0, 0, rt->view_count); + } else { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0); + } + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { glDeleteFramebuffers(1, &rt->fbo); glDeleteTextures(1, &rt->color); @@ -1503,32 +1569,38 @@ void TextureStorage::_update_render_target(RenderTarget *rt) { rt->size.x = 0; rt->size.y = 0; rt->color = 0; - texture->tex_id = 0; - texture->active = false; + rt->depth = 0; + if (rt->overridden.color.is_null()) { + texture->tex_id = 0; + texture->active = false; + } WARN_PRINT("Could not create render target, status: " + get_framebuffer_error(status)); return; } - texture->format = rt->image_format; - texture->real_format = rt->image_format; - if (rt->view_count > 1 && config->multiview_supported) { - texture->type = Texture::TYPE_LAYERED; - texture->target = GL_TEXTURE_2D_ARRAY; - texture->layers = rt->view_count; + if (rt->overridden.color.is_valid()) { + texture->is_render_target = true; } else { - texture->type = Texture::TYPE_2D; - texture->target = GL_TEXTURE_2D; - texture->layers = 1; + texture->format = rt->image_format; + texture->real_format = rt->image_format; + texture->target = texture_target; + if (rt->view_count > 1 && config->multiview_supported) { + texture->type = Texture::TYPE_LAYERED; + texture->layers = rt->view_count; + } else { + texture->type = Texture::TYPE_2D; + texture->layers = 1; + } + texture->gl_format_cache = rt->color_format; + texture->gl_type_cache = GL_UNSIGNED_BYTE; + texture->gl_internal_format_cache = rt->color_internal_format; + texture->tex_id = rt->color; + texture->width = rt->size.x; + texture->alloc_width = rt->size.x; + texture->height = rt->size.y; + texture->alloc_height = rt->size.y; + texture->active = true; } - texture->gl_format_cache = rt->color_format; - texture->gl_type_cache = GL_UNSIGNED_BYTE; - texture->gl_internal_format_cache = rt->color_internal_format; - texture->tex_id = rt->color; - texture->width = rt->size.x; - texture->alloc_width = rt->size.x; - texture->height = rt->size.y; - texture->alloc_height = rt->size.y; - texture->active = true; } glClearColor(0, 0, 0, 0); @@ -1596,17 +1668,32 @@ void TextureStorage::_clear_render_target(RenderTarget *rt) { if (rt->fbo) { glDeleteFramebuffers(1, &rt->fbo); - glDeleteTextures(1, &rt->color); rt->fbo = 0; + } + + if (rt->overridden.color.is_null()) { + glDeleteTextures(1, &rt->color); rt->color = 0; } - Texture *tex = get_texture(rt->texture); - tex->alloc_height = 0; - tex->alloc_width = 0; - tex->width = 0; - tex->height = 0; - tex->active = false; + if (rt->overridden.depth.is_null()) { + glDeleteTextures(1, &rt->depth); + rt->depth = 0; + } + + if (rt->texture.is_valid()) { + Texture *tex = get_texture(rt->texture); + tex->alloc_height = 0; + tex->alloc_width = 0; + tex->width = 0; + tex->height = 0; + tex->active = false; + } + + if (rt->overridden.color.is_valid()) { + Texture *tex = get_texture(rt->overridden.color); + tex->is_render_target = false; + } if (rt->backbuffer_fbo != 0) { glDeleteFramebuffers(1, &rt->backbuffer_fbo); @@ -1617,6 +1704,15 @@ void TextureStorage::_clear_render_target(RenderTarget *rt) { _render_target_clear_sdf(rt); } +void TextureStorage::_clear_render_target_overridden_fbo_cache(RenderTarget *rt) { + // Dispose of the cached fbo's and the allocated textures + for (KeyValue<uint32_t, RenderTarget::RTOverridden::FBOCacheEntry> &E : rt->overridden.fbo_cache) { + glDeleteTextures(E.value.allocated_textures.size(), E.value.allocated_textures.ptr()); + glDeleteFramebuffers(1, &E.value.fbo); + } + rt->overridden.fbo_cache.clear(); +} + RID TextureStorage::render_target_create() { RenderTarget render_target; //render_target.was_used = false; @@ -1635,11 +1731,14 @@ RID TextureStorage::render_target_create() { void TextureStorage::render_target_free(RID p_rid) { RenderTarget *rt = render_target_owner.get_or_null(p_rid); _clear_render_target(rt); + _clear_render_target_overridden_fbo_cache(rt); Texture *t = get_texture(rt->texture); if (t) { t->is_render_target = false; - texture_free(rt->texture); + if (rt->overridden.color.is_null()) { + texture_free(rt->texture); + } //memdelete(t); } render_target_owner.free(p_rid); @@ -1666,6 +1765,9 @@ void TextureStorage::render_target_set_size(RID p_render_target, int p_width, in if (p_width == rt->size.x && p_height == rt->size.y && p_view_count == rt->view_count) { return; } + if (rt->overridden.color.is_valid()) { + return; + } _clear_render_target(rt); @@ -1683,10 +1785,91 @@ Size2i TextureStorage::render_target_get_size(RID p_render_target) const { return rt->size; } +void TextureStorage::render_target_set_override(RID p_render_target, RID p_color_texture, RID p_depth_texture, RID p_velocity_texture) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND(!rt); + ERR_FAIL_COND(rt->direct_to_screen); + + rt->overridden.velocity = p_velocity_texture; + + if (rt->overridden.color == p_color_texture && rt->overridden.depth == p_depth_texture) { + return; + } + + if (p_color_texture.is_null() && p_depth_texture.is_null()) { + _clear_render_target(rt); + rt->overridden.is_overridden = false; + rt->overridden.color = RID(); + rt->overridden.depth = RID(); + rt->size = Size2i(); + _clear_render_target_overridden_fbo_cache(rt); + return; + } + + if (!rt->overridden.is_overridden) { + _clear_render_target(rt); + } + + rt->overridden.color = p_color_texture; + rt->overridden.depth = p_depth_texture; + rt->overridden.is_overridden = true; + + uint32_t hash_key = hash_murmur3_one_64(p_color_texture.get_id()); + hash_key = hash_murmur3_one_64(p_depth_texture.get_id(), hash_key); + hash_key = hash_fmix32(hash_key); + + RBMap<uint32_t, RenderTarget::RTOverridden::FBOCacheEntry>::Element *cache; + if ((cache = rt->overridden.fbo_cache.find(hash_key)) != nullptr) { + rt->fbo = cache->get().fbo; + rt->size = cache->get().size; + rt->texture = p_color_texture; + return; + } + + _update_render_target(rt); + + RenderTarget::RTOverridden::FBOCacheEntry new_entry; + new_entry.fbo = rt->fbo; + new_entry.size = rt->size; + // Keep track of any textures we had to allocate because they weren't overridden. + if (p_color_texture.is_null()) { + new_entry.allocated_textures.push_back(rt->color); + } + if (p_depth_texture.is_null()) { + new_entry.allocated_textures.push_back(rt->depth); + } + rt->overridden.fbo_cache.insert(hash_key, new_entry); +} + +RID TextureStorage::render_target_get_override_color(RID p_render_target) const { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND_V(!rt, RID()); + + return rt->overridden.color; +} + +RID TextureStorage::render_target_get_override_depth(RID p_render_target) const { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND_V(!rt, RID()); + + return rt->overridden.depth; +} + +RID TextureStorage::render_target_get_override_velocity(RID p_render_target) const { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND_V(!rt, RID()); + + return rt->overridden.velocity; +} + RID TextureStorage::render_target_get_texture(RID p_render_target) { RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, RID()); + if (rt->overridden.color.is_valid()) { + return rt->overridden.color; + } + return rt->texture; } @@ -1696,8 +1879,10 @@ void TextureStorage::render_target_set_transparent(RID p_render_target, bool p_t rt->is_transparent = p_transparent; - _clear_render_target(rt); - _update_render_target(rt); + if (rt->overridden.color.is_null()) { + _clear_render_target(rt); + _update_render_target(rt); + } } bool TextureStorage::render_target_get_transparent(RID p_render_target) const { @@ -1718,6 +1903,11 @@ void TextureStorage::render_target_set_direct_to_screen(RID p_render_target, boo // those functions change how they operate depending on the value of DIRECT_TO_SCREEN _clear_render_target(rt); rt->direct_to_screen = p_direct_to_screen; + if (rt->direct_to_screen) { + rt->overridden.color = RID(); + rt->overridden.depth = RID(); + rt->overridden.velocity = RID(); + } _update_render_target(rt); } @@ -1750,6 +1940,7 @@ void TextureStorage::render_target_set_msaa(RID p_render_target, RS::ViewportMSA } WARN_PRINT("2D MSAA is not yet supported for GLES3."); + _clear_render_target(rt); rt->msaa = p_msaa; _update_render_target(rt); diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h index 35fa16c894..7714e72f62 100644 --- a/drivers/gles3/storage/texture_storage.h +++ b/drivers/gles3/storage/texture_storage.h @@ -126,6 +126,7 @@ struct Texture { RID self; bool is_proxy = false; + bool is_external = false; bool is_render_target = false; RID proxy_to = RID(); @@ -187,6 +188,7 @@ struct Texture { void copy_from(const Texture &o) { proxy_to = o.proxy_to; is_proxy = o.is_proxy; + is_external = o.is_external; width = o.width; height = o.height; alloc_width = o.alloc_width; @@ -310,6 +312,7 @@ struct RenderTarget { RID self; GLuint fbo = 0; GLuint color = 0; + GLuint depth = 0; GLuint backbuffer_fbo = 0; GLuint backbuffer = 0; @@ -333,6 +336,20 @@ struct RenderTarget { bool used_in_frame = false; RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED; + struct RTOverridden { + bool is_overridden = false; + RID color; + RID depth; + RID velocity; + + struct FBOCacheEntry { + GLuint fbo; + Size2i size; + Vector<GLuint> allocated_textures; + }; + RBMap<uint32_t, FBOCacheEntry> fbo_cache; + } overridden; + RID texture; Color clear_color = Color(1, 1, 1, 1); @@ -395,6 +412,7 @@ private: mutable RID_Owner<RenderTarget> render_target_owner; void _clear_render_target(RenderTarget *rt); + void _clear_render_target_overridden_fbo_cache(RenderTarget *rt); void _update_render_target(RenderTarget *rt); void _create_render_target_backbuffer(RenderTarget *rt); void _render_target_allocate_sdf(RenderTarget *rt); @@ -454,6 +472,8 @@ public: virtual void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) override; virtual void texture_proxy_initialize(RID p_texture, RID p_base) override; //all slices, then all the mipmaps, must be coherent + RID texture_create_external(Texture::Type p_type, Image::Format p_format, unsigned int p_image, int p_width, int p_height, int p_depth, int p_layers, RS::TextureLayeredType p_layered_type = RS::TEXTURE_LAYERED_2D_ARRAY); + virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) override; virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) override{}; virtual void texture_proxy_update(RID p_proxy, RID p_base) override; @@ -484,6 +504,8 @@ public: virtual Size2 texture_size_with_proxy(RID p_proxy) override; + virtual RID texture_get_rd_texture_rid(RID p_texture, bool p_srgb = false) const override; + void texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer = 0); void texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, int p_layer = 0); //Ref<Image> texture_get_data(RID p_texture, int p_layer = 0) const; @@ -593,10 +615,10 @@ public: virtual void render_target_set_vrs_texture(RID p_render_target, RID p_texture) override {} virtual RID render_target_get_vrs_texture(RID p_render_target) const override { return RID(); } - virtual void render_target_set_override(RID p_render_target, RID p_color_texture, RID p_depth_texture, RID p_velocity_texture) override {} - virtual RID render_target_get_override_color(RID p_render_target) const override { return RID(); } - virtual RID render_target_get_override_depth(RID p_render_target) const override { return RID(); } - virtual RID render_target_get_override_velocity(RID p_render_target) const override { return RID(); } + virtual void render_target_set_override(RID p_render_target, RID p_color_texture, RID p_depth_texture, RID p_velocity_texture) override; + virtual RID render_target_get_override_color(RID p_render_target) const override; + virtual RID render_target_get_override_depth(RID p_render_target) const override; + virtual RID render_target_get_override_velocity(RID p_render_target) const override; virtual RID render_target_get_texture(RID p_render_target) override; diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp index 6e6416e3ca..14a2640e63 100644 --- a/editor/doc_tools.cpp +++ b/editor/doc_tools.cpp @@ -335,7 +335,7 @@ static Variant get_documentation_default_value(const StringName &p_class_name, c Variant default_value = Variant(); r_default_value_valid = false; - if (ClassDB::can_instantiate(p_class_name)) { // Keep this condition in sync with ClassDB::class_get_default_property_value. + if (ClassDB::can_instantiate(p_class_name) && !ClassDB::is_virtual(p_class_name)) { // Keep this condition in sync with ClassDB::class_get_default_property_value. default_value = ClassDB::class_get_default_property_value(p_class_name, p_property_name, &r_default_value_valid); } else { // Cannot get default value of classes that can't be instantiated diff --git a/modules/noise/doc_classes/NoiseTexture2D.xml b/modules/noise/doc_classes/NoiseTexture2D.xml index 9eea2738c5..0a800a143b 100644 --- a/modules/noise/doc_classes/NoiseTexture2D.xml +++ b/modules/noise/doc_classes/NoiseTexture2D.xml @@ -44,6 +44,7 @@ <member name="noise" type="Noise" setter="set_noise" getter="get_noise"> The instance of the [Noise] object. </member> + <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" /> <member name="seamless" type="bool" setter="set_seamless" getter="get_seamless" default="false"> If [code]true[/code], a seamless texture is requested from the [Noise] resource. [b]Note:[/b] Seamless noise textures may take longer to generate and/or can have a lower contrast compared to non-seamless noise depending on the used [Noise] resource. This is because some implementations use higher dimensions for generating seamless noise. diff --git a/modules/openxr/SCsub b/modules/openxr/SCsub index b5978ab134..84542be3b9 100644 --- a/modules/openxr/SCsub +++ b/modules/openxr/SCsub @@ -90,6 +90,8 @@ if env["platform"] == "android": env_openxr.add_source_files(module_obj, "extensions/openxr_android_extension.cpp") if env["vulkan"]: env_openxr.add_source_files(module_obj, "extensions/openxr_vulkan_extension.cpp") +if env["opengl3"]: + env_openxr.add_source_files(module_obj, "extensions/openxr_opengl_extension.cpp") env_openxr.add_source_files(module_obj, "extensions/openxr_palm_pose_extension.cpp") env_openxr.add_source_files(module_obj, "extensions/openxr_composition_layer_depth_extension.cpp") diff --git a/modules/openxr/extensions/openxr_opengl_extension.cpp b/modules/openxr/extensions/openxr_opengl_extension.cpp new file mode 100644 index 0000000000..ee69144123 --- /dev/null +++ b/modules/openxr/extensions/openxr_opengl_extension.cpp @@ -0,0 +1,466 @@ +/*************************************************************************/ +/* openxr_opengl_extension.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifdef GLES3_ENABLED + +#include "../extensions/openxr_opengl_extension.h" +#include "../openxr_util.h" +#include "drivers/gles3/effects/copy_effects.h" +#include "drivers/gles3/storage/texture_storage.h" +#include "servers/rendering/rendering_server_globals.h" +#include "servers/rendering_server.h" + +OpenXROpenGLExtension::OpenXROpenGLExtension(OpenXRAPI *p_openxr_api) : + OpenXRGraphicsExtensionWrapper(p_openxr_api) { +#ifdef ANDROID_ENABLED + request_extensions[XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME] = nullptr; +#else + request_extensions[XR_KHR_OPENGL_ENABLE_EXTENSION_NAME] = nullptr; +#endif + + ERR_FAIL_NULL(openxr_api); +} + +OpenXROpenGLExtension::~OpenXROpenGLExtension() { +} + +void OpenXROpenGLExtension::on_instance_created(const XrInstance p_instance) { + ERR_FAIL_NULL(openxr_api); + + // Obtain pointers to functions we're accessing here. + +#ifdef ANDROID_ENABLED + EXT_INIT_XR_FUNC(xrGetOpenGLESGraphicsRequirementsKHR); +#else + EXT_INIT_XR_FUNC(xrGetOpenGLGraphicsRequirementsKHR); +#endif + EXT_INIT_XR_FUNC(xrEnumerateSwapchainImages); +} + +bool OpenXROpenGLExtension::check_graphics_api_support(XrVersion p_desired_version) { + ERR_FAIL_NULL_V(openxr_api, false); + + XrSystemId system_id = openxr_api->get_system_id(); + XrInstance instance = openxr_api->get_instance(); + +#ifdef ANDROID_ENABLED + XrGraphicsRequirementsOpenGLESKHR opengl_requirements; + opengl_requirements.type = XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR; + opengl_requirements.next = nullptr; + + XrResult result = xrGetOpenGLESGraphicsRequirementsKHR(instance, system_id, &opengl_requirements); + if (!openxr_api->xr_result(result, "Failed to get OpenGL graphics requirements!")) { + return false; + } +#else + XrGraphicsRequirementsOpenGLKHR opengl_requirements; + opengl_requirements.type = XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR; + opengl_requirements.next = nullptr; + + XrResult result = xrGetOpenGLGraphicsRequirementsKHR(instance, system_id, &opengl_requirements); + if (!openxr_api->xr_result(result, "Failed to get OpenGL graphics requirements!")) { + return false; + } +#endif + + if (p_desired_version < opengl_requirements.minApiVersionSupported) { + print_line("OpenXR: Requested OpenGL version does not meet the minimum version this runtime supports."); + print_line("- desired_version ", OpenXRUtil::make_xr_version_string(p_desired_version)); + print_line("- minApiVersionSupported ", OpenXRUtil::make_xr_version_string(opengl_requirements.minApiVersionSupported)); + print_line("- maxApiVersionSupported ", OpenXRUtil::make_xr_version_string(opengl_requirements.maxApiVersionSupported)); + return false; + } + + if (p_desired_version > opengl_requirements.maxApiVersionSupported) { + print_line("OpenXR: Requested OpenGL version exceeds the maximum version this runtime has been tested on and is known to support."); + print_line("- desired_version ", OpenXRUtil::make_xr_version_string(p_desired_version)); + print_line("- minApiVersionSupported ", OpenXRUtil::make_xr_version_string(opengl_requirements.minApiVersionSupported)); + print_line("- maxApiVersionSupported ", OpenXRUtil::make_xr_version_string(opengl_requirements.maxApiVersionSupported)); + } + + return true; +} + +#ifdef WIN32 +XrGraphicsBindingOpenGLWin32KHR OpenXROpenGLExtension::graphics_binding_gl; +#elif ANDROID_ENABLED +XrGraphicsBindingOpenGLESAndroidKHR OpenXROpenGLExtension::graphics_binding_gl; +#else +XrGraphicsBindingOpenGLXlibKHR OpenXROpenGLExtension::graphics_binding_gl; +#endif + +void *OpenXROpenGLExtension::set_session_create_and_get_next_pointer(void *p_next_pointer) { + XrVersion desired_version = XR_MAKE_VERSION(3, 3, 0); + + if (!check_graphics_api_support(desired_version)) { + print_line("OpenXR: Trying to initialize with OpenGL anyway..."); + //return p_next_pointer; + } + + DisplayServer *display_server = DisplayServer::get_singleton(); + +#ifdef WIN32 + graphics_binding_gl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR, + graphics_binding_gl.next = p_next_pointer; + + graphics_binding_gl.hDC = (HDC)display_server->window_get_native_handle(DisplayServer::WINDOW_VIEW); + graphics_binding_gl.hGLRC = (HGLRC)display_server->window_get_native_handle(DisplayServer::OPENGL_CONTEXT); +#elif ANDROID_ENABLED + graphics_binding_gl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_ES_ANDROID_KHR; + graphics_binding_gl.next = p_next_pointer; + + graphics_binding_gl.display = eglGetCurrentDisplay(); + graphics_binding_gl.config = (EGLConfig)0; // https://github.com/KhronosGroup/OpenXR-SDK-Source/blob/master/src/tests/hello_xr/graphicsplugin_opengles.cpp#L122 + graphics_binding_gl.context = eglGetCurrentContext(); +#else + graphics_binding_gl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR; + graphics_binding_gl.next = p_next_pointer; + + void *display_handle = (void *)display_server->window_get_native_handle(DisplayServer::DISPLAY_HANDLE); + void *glxcontext_handle = (void *)display_server->window_get_native_handle(DisplayServer::OPENGL_CONTEXT); + void *glxdrawable_handle = (void *)display_server->window_get_native_handle(DisplayServer::WINDOW_HANDLE); + + graphics_binding_gl.xDisplay = (Display *)display_handle; + graphics_binding_gl.glxContext = (GLXContext)glxcontext_handle; + graphics_binding_gl.glxDrawable = (GLXDrawable)glxdrawable_handle; + + // spec says to use proper values but runtimes don't care + graphics_binding_gl.visualid = 0; + graphics_binding_gl.glxFBConfig = 0; +#endif + + return &graphics_binding_gl; +} + +void OpenXROpenGLExtension::get_usable_swapchain_formats(Vector<int64_t> &p_usable_swap_chains) { +#ifdef WIN32 + p_usable_swap_chains.push_back(GL_SRGB8_ALPHA8); + p_usable_swap_chains.push_back(GL_RGBA8); +#elif ANDROID_ENABLED + p_usable_swap_chains.push_back(GL_SRGB8_ALPHA8); + p_usable_swap_chains.push_back(GL_RGBA8); +#else + p_usable_swap_chains.push_back(GL_SRGB8_ALPHA8_EXT); + p_usable_swap_chains.push_back(GL_RGBA8_EXT); +#endif +} + +void OpenXROpenGLExtension::get_usable_depth_formats(Vector<int64_t> &p_usable_depth_formats) { + p_usable_depth_formats.push_back(GL_DEPTH_COMPONENT32F); + p_usable_depth_formats.push_back(GL_DEPTH24_STENCIL8); + p_usable_depth_formats.push_back(GL_DEPTH32F_STENCIL8); +} + +bool OpenXROpenGLExtension::get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) { + GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); + ERR_FAIL_NULL_V(texture_storage, false); + + uint32_t swapchain_length; + XrResult result = xrEnumerateSwapchainImages(p_swapchain, 0, &swapchain_length, nullptr); + if (XR_FAILED(result)) { + print_line("OpenXR: Failed to get swapchaim image count [", openxr_api->get_error_string(result), "]"); + return false; + } + +#ifdef ANDROID_ENABLED + XrSwapchainImageOpenGLESKHR *images = (XrSwapchainImageOpenGLESKHR *)memalloc(sizeof(XrSwapchainImageOpenGLESKHR) * swapchain_length); +#else + XrSwapchainImageOpenGLKHR *images = (XrSwapchainImageOpenGLKHR *)memalloc(sizeof(XrSwapchainImageOpenGLKHR) * swapchain_length); +#endif + ERR_FAIL_NULL_V_MSG(images, false, "OpenXR Couldn't allocate memory for swap chain image"); + + for (uint64_t i = 0; i < swapchain_length; i++) { +#ifdef ANDROID_ENABLED + images[i].type = XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR; +#else + images[i].type = XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR; +#endif + images[i].next = nullptr; + images[i].image = 0; + } + + result = xrEnumerateSwapchainImages(p_swapchain, swapchain_length, &swapchain_length, (XrSwapchainImageBaseHeader *)images); + if (XR_FAILED(result)) { + print_line("OpenXR: Failed to get swapchaim images [", openxr_api->get_error_string(result), "]"); + memfree(images); + return false; + } + + SwapchainGraphicsData *data = memnew(SwapchainGraphicsData); + if (data == nullptr) { + print_line("OpenXR: Failed to allocate memory for swapchain data"); + memfree(images); + return false; + } + *r_swapchain_graphics_data = data; + data->is_multiview = (p_array_size > 1); + + Image::Format format = Image::FORMAT_RGBA8; + + Vector<RID> texture_rids; + + for (uint64_t i = 0; i < swapchain_length; i++) { + RID texture_rid = texture_storage->texture_create_external( + p_array_size == 1 ? GLES3::Texture::TYPE_2D : GLES3::Texture::TYPE_LAYERED, + format, + images[i].image, + p_width, + p_height, + 1, + p_array_size); + + texture_rids.push_back(texture_rid); + } + + data->texture_rids = texture_rids; + + memfree(images); + + return true; +} + +bool OpenXROpenGLExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) { + XrMatrix4x4f matrix; + XrMatrix4x4f_CreateProjectionFov(&matrix, GRAPHICS_OPENGL, p_fov, (float)p_z_near, (float)p_z_far); + + for (int j = 0; j < 4; j++) { + for (int i = 0; i < 4; i++) { + r_camera_matrix.columns[j][i] = matrix.m[j * 4 + i]; + } + } + + return true; +} + +RID OpenXROpenGLExtension::get_texture(void *p_swapchain_graphics_data, int p_image_index) { + SwapchainGraphicsData *data = (SwapchainGraphicsData *)p_swapchain_graphics_data; + ERR_FAIL_NULL_V(data, RID()); + + ERR_FAIL_INDEX_V(p_image_index, data->texture_rids.size(), RID()); + return data->texture_rids[p_image_index]; +} + +void OpenXROpenGLExtension::cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) { + if (*p_swapchain_graphics_data == nullptr) { + return; + } + + GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); + ERR_FAIL_NULL(texture_storage); + + SwapchainGraphicsData *data = (SwapchainGraphicsData *)*p_swapchain_graphics_data; + + for (int i = 0; i < data->texture_rids.size(); i++) { + texture_storage->texture_free(data->texture_rids[i]); + } + data->texture_rids.clear(); + + memdelete(data); + *p_swapchain_graphics_data = nullptr; +} + +#define ENUM_TO_STRING_CASE(e) \ + case e: { \ + return String(#e); \ + } break; + +String OpenXROpenGLExtension::get_swapchain_format_name(int64_t p_swapchain_format) const { + // These are somewhat different per platform, will need to weed some stuff out... + switch (p_swapchain_format) { +#ifdef WIN32 + // using definitions from GLAD + ENUM_TO_STRING_CASE(GL_R8_SNORM) + ENUM_TO_STRING_CASE(GL_RG8_SNORM) + ENUM_TO_STRING_CASE(GL_RGB8_SNORM) + ENUM_TO_STRING_CASE(GL_RGBA8_SNORM) + ENUM_TO_STRING_CASE(GL_R16_SNORM) + ENUM_TO_STRING_CASE(GL_RG16_SNORM) + ENUM_TO_STRING_CASE(GL_RGB16_SNORM) + ENUM_TO_STRING_CASE(GL_RGBA16_SNORM) + ENUM_TO_STRING_CASE(GL_RGB4) + ENUM_TO_STRING_CASE(GL_RGB5) + ENUM_TO_STRING_CASE(GL_RGB8) + ENUM_TO_STRING_CASE(GL_RGB10) + ENUM_TO_STRING_CASE(GL_RGB12) + ENUM_TO_STRING_CASE(GL_RGB16) + ENUM_TO_STRING_CASE(GL_RGBA2) + ENUM_TO_STRING_CASE(GL_RGBA4) + ENUM_TO_STRING_CASE(GL_RGB5_A1) + ENUM_TO_STRING_CASE(GL_RGBA8) + ENUM_TO_STRING_CASE(GL_RGB10_A2) + ENUM_TO_STRING_CASE(GL_RGBA12) + ENUM_TO_STRING_CASE(GL_RGBA16) + ENUM_TO_STRING_CASE(GL_RGBA32F) + ENUM_TO_STRING_CASE(GL_RGB32F) + ENUM_TO_STRING_CASE(GL_RGBA16F) + ENUM_TO_STRING_CASE(GL_RGB16F) + ENUM_TO_STRING_CASE(GL_RGBA32UI) + ENUM_TO_STRING_CASE(GL_RGB32UI) + ENUM_TO_STRING_CASE(GL_RGBA16UI) + ENUM_TO_STRING_CASE(GL_RGB16UI) + ENUM_TO_STRING_CASE(GL_RGBA8UI) + ENUM_TO_STRING_CASE(GL_RGB8UI) + ENUM_TO_STRING_CASE(GL_RGBA32I) + ENUM_TO_STRING_CASE(GL_RGB32I) + ENUM_TO_STRING_CASE(GL_RGBA16I) + ENUM_TO_STRING_CASE(GL_RGB16I) + ENUM_TO_STRING_CASE(GL_RGBA8I) + ENUM_TO_STRING_CASE(GL_RGB8I) + ENUM_TO_STRING_CASE(GL_RGB10_A2UI) + ENUM_TO_STRING_CASE(GL_SRGB) + ENUM_TO_STRING_CASE(GL_SRGB8) + ENUM_TO_STRING_CASE(GL_SRGB_ALPHA) + ENUM_TO_STRING_CASE(GL_SRGB8_ALPHA8) + ENUM_TO_STRING_CASE(GL_DEPTH_COMPONENT16) + ENUM_TO_STRING_CASE(GL_DEPTH_COMPONENT24) + ENUM_TO_STRING_CASE(GL_DEPTH_COMPONENT32) + ENUM_TO_STRING_CASE(GL_DEPTH24_STENCIL8) + ENUM_TO_STRING_CASE(GL_R11F_G11F_B10F) + ENUM_TO_STRING_CASE(GL_DEPTH_COMPONENT32F) + ENUM_TO_STRING_CASE(GL_DEPTH32F_STENCIL8) + +#elif ANDROID_ENABLED + // using definitions from GLES3/gl3.h + + ENUM_TO_STRING_CASE(GL_RGBA4) + ENUM_TO_STRING_CASE(GL_RGB5_A1) + ENUM_TO_STRING_CASE(GL_RGB565) + ENUM_TO_STRING_CASE(GL_RGB8) + ENUM_TO_STRING_CASE(GL_RGBA8) + ENUM_TO_STRING_CASE(GL_RGB10_A2) + ENUM_TO_STRING_CASE(GL_RGBA32F) + ENUM_TO_STRING_CASE(GL_RGB32F) + ENUM_TO_STRING_CASE(GL_RGBA16F) + ENUM_TO_STRING_CASE(GL_RGB16F) + ENUM_TO_STRING_CASE(GL_R11F_G11F_B10F) + ENUM_TO_STRING_CASE(GL_UNSIGNED_INT_10F_11F_11F_REV) + ENUM_TO_STRING_CASE(GL_RGB9_E5) + ENUM_TO_STRING_CASE(GL_UNSIGNED_INT_5_9_9_9_REV) + ENUM_TO_STRING_CASE(GL_RGBA32UI) + ENUM_TO_STRING_CASE(GL_RGB32UI) + ENUM_TO_STRING_CASE(GL_RGBA16UI) + ENUM_TO_STRING_CASE(GL_RGB16UI) + ENUM_TO_STRING_CASE(GL_RGBA8UI) + ENUM_TO_STRING_CASE(GL_RGB8UI) + ENUM_TO_STRING_CASE(GL_RGBA32I) + ENUM_TO_STRING_CASE(GL_RGB32I) + ENUM_TO_STRING_CASE(GL_RGBA16I) + ENUM_TO_STRING_CASE(GL_RGB16I) + ENUM_TO_STRING_CASE(GL_RGBA8I) + ENUM_TO_STRING_CASE(GL_RGB8I) + ENUM_TO_STRING_CASE(GL_RG) + ENUM_TO_STRING_CASE(GL_RG_INTEGER) + ENUM_TO_STRING_CASE(GL_R8) + ENUM_TO_STRING_CASE(GL_RG8) + ENUM_TO_STRING_CASE(GL_R16F) + ENUM_TO_STRING_CASE(GL_R32F) + ENUM_TO_STRING_CASE(GL_RG16F) + ENUM_TO_STRING_CASE(GL_RG32F) + ENUM_TO_STRING_CASE(GL_R8I) + ENUM_TO_STRING_CASE(GL_R8UI) + ENUM_TO_STRING_CASE(GL_R16I) + ENUM_TO_STRING_CASE(GL_R16UI) + ENUM_TO_STRING_CASE(GL_R32I) + ENUM_TO_STRING_CASE(GL_R32UI) + ENUM_TO_STRING_CASE(GL_RG8I) + ENUM_TO_STRING_CASE(GL_RG8UI) + ENUM_TO_STRING_CASE(GL_RG16I) + ENUM_TO_STRING_CASE(GL_RG16UI) + ENUM_TO_STRING_CASE(GL_RG32I) + ENUM_TO_STRING_CASE(GL_RG32UI) + ENUM_TO_STRING_CASE(GL_R8_SNORM) + ENUM_TO_STRING_CASE(GL_RG8_SNORM) + ENUM_TO_STRING_CASE(GL_RGB8_SNORM) + ENUM_TO_STRING_CASE(GL_RGBA8_SNORM) + ENUM_TO_STRING_CASE(GL_RGB10_A2UI) + ENUM_TO_STRING_CASE(GL_SRGB) + ENUM_TO_STRING_CASE(GL_SRGB8) + ENUM_TO_STRING_CASE(GL_SRGB8_ALPHA8) + ENUM_TO_STRING_CASE(GL_COMPRESSED_R11_EAC) + ENUM_TO_STRING_CASE(GL_COMPRESSED_SIGNED_R11_EAC) + ENUM_TO_STRING_CASE(GL_COMPRESSED_RG11_EAC) + ENUM_TO_STRING_CASE(GL_COMPRESSED_SIGNED_RG11_EAC) + ENUM_TO_STRING_CASE(GL_COMPRESSED_RGB8_ETC2) + ENUM_TO_STRING_CASE(GL_COMPRESSED_SRGB8_ETC2) + ENUM_TO_STRING_CASE(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2) + ENUM_TO_STRING_CASE(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2) + ENUM_TO_STRING_CASE(GL_COMPRESSED_RGBA8_ETC2_EAC) + ENUM_TO_STRING_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC) + ENUM_TO_STRING_CASE(GL_DEPTH_COMPONENT16) + ENUM_TO_STRING_CASE(GL_DEPTH_COMPONENT24) + ENUM_TO_STRING_CASE(GL_DEPTH24_STENCIL8) + +#else + // using definitions from GL/gl.h + ENUM_TO_STRING_CASE(GL_ALPHA4_EXT) + ENUM_TO_STRING_CASE(GL_ALPHA8_EXT) + ENUM_TO_STRING_CASE(GL_ALPHA12_EXT) + ENUM_TO_STRING_CASE(GL_ALPHA16_EXT) + ENUM_TO_STRING_CASE(GL_LUMINANCE4_EXT) + ENUM_TO_STRING_CASE(GL_LUMINANCE8_EXT) + ENUM_TO_STRING_CASE(GL_LUMINANCE12_EXT) + ENUM_TO_STRING_CASE(GL_LUMINANCE16_EXT) + ENUM_TO_STRING_CASE(GL_LUMINANCE4_ALPHA4_EXT) + ENUM_TO_STRING_CASE(GL_LUMINANCE6_ALPHA2_EXT) + ENUM_TO_STRING_CASE(GL_LUMINANCE8_ALPHA8_EXT) + ENUM_TO_STRING_CASE(GL_LUMINANCE12_ALPHA4_EXT) + ENUM_TO_STRING_CASE(GL_LUMINANCE12_ALPHA12_EXT) + ENUM_TO_STRING_CASE(GL_LUMINANCE16_ALPHA16_EXT) + ENUM_TO_STRING_CASE(GL_INTENSITY_EXT) + ENUM_TO_STRING_CASE(GL_INTENSITY4_EXT) + ENUM_TO_STRING_CASE(GL_INTENSITY8_EXT) + ENUM_TO_STRING_CASE(GL_INTENSITY12_EXT) + ENUM_TO_STRING_CASE(GL_INTENSITY16_EXT) + ENUM_TO_STRING_CASE(GL_RGB2_EXT) + ENUM_TO_STRING_CASE(GL_RGB4_EXT) + ENUM_TO_STRING_CASE(GL_RGB5_EXT) + ENUM_TO_STRING_CASE(GL_RGB8_EXT) + ENUM_TO_STRING_CASE(GL_RGB10_EXT) + ENUM_TO_STRING_CASE(GL_RGB12_EXT) + ENUM_TO_STRING_CASE(GL_RGB16_EXT) + ENUM_TO_STRING_CASE(GL_RGBA2_EXT) + ENUM_TO_STRING_CASE(GL_RGBA4_EXT) + ENUM_TO_STRING_CASE(GL_RGB5_A1_EXT) + ENUM_TO_STRING_CASE(GL_RGBA8_EXT) + ENUM_TO_STRING_CASE(GL_RGB10_A2_EXT) + ENUM_TO_STRING_CASE(GL_RGBA12_EXT) + ENUM_TO_STRING_CASE(GL_RGBA16_EXT) + ENUM_TO_STRING_CASE(GL_SRGB_EXT) + ENUM_TO_STRING_CASE(GL_SRGB8_EXT) + ENUM_TO_STRING_CASE(GL_SRGB_ALPHA_EXT) + ENUM_TO_STRING_CASE(GL_SRGB8_ALPHA8_EXT) +#endif + default: { + return String("Swapchain format 0x") + String::num_int64(p_swapchain_format, 16); + } break; + } +} + +#endif // GLES3_ENABLED diff --git a/modules/openxr/extensions/openxr_opengl_extension.h b/modules/openxr/extensions/openxr_opengl_extension.h new file mode 100644 index 0000000000..b666653c8e --- /dev/null +++ b/modules/openxr/extensions/openxr_opengl_extension.h @@ -0,0 +1,120 @@ +/*************************************************************************/ +/* openxr_opengl_extension.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef OPENXR_OPENGL_EXTENSION_H +#define OPENXR_OPENGL_EXTENSION_H + +#ifdef GLES3_ENABLED + +#include "core/templates/vector.h" +#include "openxr_extension_wrapper.h" + +#include "../openxr_api.h" +#include "../util.h" + +#ifdef ANDROID_ENABLED +#define XR_USE_GRAPHICS_API_OPENGL_ES +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GLES3/gl3.h> +#include <GLES3/gl3ext.h> +#else +#define XR_USE_GRAPHICS_API_OPENGL +#endif + +#ifdef WINDOWS_ENABLED +// Including windows.h here is absolutely evil, we shouldn't be doing this outside of platform +// however due to the way the openxr headers are put together, we have no choice. +#include <windows.h> +#endif + +#ifdef X11_ENABLED +#include OPENGL_INCLUDE_H +#define GL_GLEXT_PROTOTYPES 1 +#define GL3_PROTOTYPES 1 +#include <GL/gl.h> +#include <GL/glext.h> +#include <GL/glx.h> +#include <X11/Xlib.h> +#endif + +#ifdef ANDROID_ENABLED +// The jobject type from jni.h is used by openxr_platform.h on Android. +#include <jni.h> +#endif + +// include platform dependent structs +#include <openxr/openxr_platform.h> + +class OpenXROpenGLExtension : public OpenXRGraphicsExtensionWrapper { +public: + OpenXROpenGLExtension(OpenXRAPI *p_openxr_api); + virtual ~OpenXROpenGLExtension() override; + + virtual void on_instance_created(const XrInstance p_instance) override; + virtual void *set_session_create_and_get_next_pointer(void *p_next_pointer) override; + + virtual void get_usable_swapchain_formats(Vector<int64_t> &p_usable_swap_chains) override; + virtual void get_usable_depth_formats(Vector<int64_t> &p_usable_swap_chains) override; + virtual String get_swapchain_format_name(int64_t p_swapchain_format) const override; + virtual bool get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) override; + virtual void cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) override; + virtual bool create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) override; + virtual RID get_texture(void *p_swapchain_graphics_data, int p_image_index) override; + +private: + static OpenXROpenGLExtension *singleton; + +#ifdef WIN32 + static XrGraphicsBindingOpenGLWin32KHR graphics_binding_gl; +#elif ANDROID_ENABLED + static XrGraphicsBindingOpenGLESAndroidKHR graphics_binding_gl; +#else + static XrGraphicsBindingOpenGLXlibKHR graphics_binding_gl; +#endif + + struct SwapchainGraphicsData { + bool is_multiview; + Vector<RID> texture_rids; + }; + + bool check_graphics_api_support(XrVersion p_desired_version); + +#ifdef ANDROID_ENABLED + EXT_PROTO_XRRESULT_FUNC3(xrGetOpenGLESGraphicsRequirementsKHR, (XrInstance), p_instance, (XrSystemId), p_system_id, (XrGraphicsRequirementsOpenGLESKHR *), p_graphics_requirements) +#else + EXT_PROTO_XRRESULT_FUNC3(xrGetOpenGLGraphicsRequirementsKHR, (XrInstance), p_instance, (XrSystemId), p_system_id, (XrGraphicsRequirementsOpenGLKHR *), p_graphics_requirements) +#endif + EXT_PROTO_XRRESULT_FUNC4(xrEnumerateSwapchainImages, (XrSwapchain), p_swapchain, (uint32_t), p_image_capacity_input, (uint32_t *), p_image_count_output, (XrSwapchainImageBaseHeader *), p_images) +}; + +#endif // GLES3_ENABLED + +#endif // OPENXR_OPENGL_EXTENSION_H diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp index 8b189cf027..88111afede 100644 --- a/modules/openxr/openxr_api.cpp +++ b/modules/openxr/openxr_api.cpp @@ -45,10 +45,40 @@ #include "extensions/openxr_android_extension.h" #endif +// We need to have all the graphics API defines before the Vulkan or OpenGL +// extensions are included, otherwise we'll only get one graphics API. +#ifdef VULKAN_ENABLED +#define XR_USE_GRAPHICS_API_VULKAN +#endif +#ifdef GLES3_ENABLED +#ifdef ANDROID +#define XR_USE_GRAPHICS_API_OPENGL_ES +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GLES3/gl3.h> +#include <GLES3/gl3ext.h> +#else +#define XR_USE_GRAPHICS_API_OPENGL +#endif // ANDROID +#ifdef X11_ENABLED +#include OPENGL_INCLUDE_H +#define GL_GLEXT_PROTOTYPES 1 +#define GL3_PROTOTYPES 1 +#include <GL/gl.h> +#include <GL/glext.h> +#include <GL/glx.h> +#include <X11/Xlib.h> +#endif // X11_ENABLED +#endif // GLES_ENABLED + #ifdef VULKAN_ENABLED #include "extensions/openxr_vulkan_extension.h" #endif +#ifdef GLES3_ENABLED +#include "extensions/openxr_opengl_extension.h" +#endif + #include "extensions/openxr_composition_layer_depth_extension.h" #include "extensions/openxr_fb_display_refresh_rate_extension.h" #include "extensions/openxr_fb_passthrough_extension_wrapper.h" @@ -1142,9 +1172,8 @@ bool OpenXRAPI::initialize(const String &p_rendering_driver) { #endif } else if (p_rendering_driver == "opengl3") { #ifdef GLES3_ENABLED - // graphics_extension = memnew(OpenXROpenGLExtension(this)); - // register_extension_wrapper(graphics_extension); - ERR_FAIL_V_MSG(false, "OpenXR: OpenGL is not supported at this time."); + graphics_extension = memnew(OpenXROpenGLExtension(this)); + register_extension_wrapper(graphics_extension); #else // shouldn't be possible... ERR_FAIL_V(false); diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp index 08369e735d..967f5c7dae 100644 --- a/platform/android/display_server_android.cpp +++ b/platform/android/display_server_android.cpp @@ -321,6 +321,11 @@ int64_t DisplayServerAndroid::window_get_native_handle(HandleType p_handle_type, case WINDOW_VIEW: { return 0; // Not supported. } +#ifdef GLES3_ENABLED + case OPENGL_CONTEXT: { + return eglGetCurrentContext(); + } +#endif default: { return 0; } diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle index 0346625e4b..e1d9dc4cde 100644 --- a/platform/android/java/app/config.gradle +++ b/platform/android/java/app/config.gradle @@ -1,10 +1,10 @@ ext.versions = [ - androidGradlePlugin: '7.0.3', + androidGradlePlugin: '7.2.1', compileSdk : 32, - minSdk : 19, // Also update 'platform/android/java/lib/AndroidManifest.xml#minSdkVersion' & 'platform/android/export/export_plugin.cpp#DEFAULT_MIN_SDK_VERSION' - targetSdk : 32, // Also update 'platform/android/java/lib/AndroidManifest.xml#targetSdkVersion' & 'platform/android/export/export_plugin.cpp#DEFAULT_TARGET_SDK_VERSION' + minSdk : 19, // Also update 'platform/android/export/export_plugin.cpp#DEFAULT_MIN_SDK_VERSION' + targetSdk : 32, // Also update 'platform/android/export/export_plugin.cpp#DEFAULT_TARGET_SDK_VERSION' buildTools : '32.0.0', - kotlinVersion : '1.6.21', + kotlinVersion : '1.7.0', fragmentVersion : '1.3.6', nexusPublishVersion: '1.1.0', javaVersion : 11, diff --git a/platform/android/java/gradle/wrapper/gradle-wrapper.properties b/platform/android/java/gradle/wrapper/gradle-wrapper.properties index ffed3a254e..41dfb87909 100644 --- a/platform/android/java/gradle/wrapper/gradle-wrapper.properties +++ b/platform/android/java/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/platform/android/java/lib/AndroidManifest.xml b/platform/android/java/lib/AndroidManifest.xml index 79b5aadf2a..1f77e2fc34 100644 --- a/platform/android/java/lib/AndroidManifest.xml +++ b/platform/android/java/lib/AndroidManifest.xml @@ -4,9 +4,6 @@ android:versionCode="1" android:versionName="1.0"> - <!-- Should match the mindSdk and targetSdk values in platform/android/java/app/config.gradle --> - <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="32" /> - <application> <!-- Records the version of the Godot library --> diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle index c9e2a5d7d2..841656a240 100644 --- a/platform/android/java/lib/build.gradle +++ b/platform/android/java/lib/build.gradle @@ -176,11 +176,10 @@ android { } } - // TODO: Enable when issues with AGP 7.1+ are resolved (https://github.com/GodotVR/godot_openxr/issues/187). -// publishing { -// singleVariant("templateRelease") { -// withSourcesJar() -// withJavadocJar() -// } -// } + publishing { + singleVariant("templateRelease") { + withSourcesJar() + withJavadocJar() + } + } } diff --git a/platform/linuxbsd/x11/detect_prime_x11.cpp b/platform/linuxbsd/x11/detect_prime_x11.cpp index fb833ab5e6..78a10fa2b0 100644 --- a/platform/linuxbsd/x11/detect_prime_x11.cpp +++ b/platform/linuxbsd/x11/detect_prime_x11.cpp @@ -208,7 +208,10 @@ int detect_prime() { print_verbose("Couldn't write vendor/renderer string."); } close(fdset[1]); - exit(0); + + // The function quick_exit() is used because exit() will call destructors on static objects copied by fork(). + // These objects will be freed anyway when the process finishes execution. + quick_exit(0); } } diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index f477787771..c3a86c69e1 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -1309,6 +1309,11 @@ int64_t DisplayServerX11::window_get_native_handle(HandleType p_handle_type, Win case WINDOW_VIEW: { return 0; // Not supported. } +#ifdef GLES3_ENABLED + case OPENGL_CONTEXT: { + return (int64_t)gl_manager->get_glx_context(p_window); + } +#endif default: { return 0; } diff --git a/platform/linuxbsd/x11/gl_manager_x11.cpp b/platform/linuxbsd/x11/gl_manager_x11.cpp index f586c57dda..893a22e75e 100644 --- a/platform/linuxbsd/x11/gl_manager_x11.cpp +++ b/platform/linuxbsd/x11/gl_manager_x11.cpp @@ -376,6 +376,17 @@ bool GLManager_X11::is_using_vsync() const { return use_vsync; } +void *GLManager_X11::get_glx_context(DisplayServer::WindowID p_window_id) { + if (p_window_id == -1) { + return nullptr; + } + + const GLWindow &win = _windows[p_window_id]; + const GLDisplay &disp = get_display(win.gldisplay_id); + + return (void *)disp.context->glx_context; +} + GLManager_X11::GLManager_X11(const Vector2i &p_size, ContextType p_context_type) { context_type = p_context_type; diff --git a/platform/linuxbsd/x11/gl_manager_x11.h b/platform/linuxbsd/x11/gl_manager_x11.h index 4f78c45c88..1594c82801 100644 --- a/platform/linuxbsd/x11/gl_manager_x11.h +++ b/platform/linuxbsd/x11/gl_manager_x11.h @@ -116,6 +116,8 @@ public: void set_use_vsync(bool p_use); bool is_using_vsync() const; + void *get_glx_context(DisplayServer::WindowID p_window_id); + GLManager_X11(const Vector2i &p_size, ContextType p_context_type); ~GLManager_X11(); }; diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index 4478a635a8..33d8a8dd14 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -2932,6 +2932,11 @@ int64_t DisplayServerMacOS::window_get_native_handle(HandleType p_handle_type, W case WINDOW_VIEW: { return (int64_t)windows[p_window].window_view; } +#ifdef GLES3_ENABLED + case OPENGL_CONTEXT: { + return (int64_t)gl_manager->get_context(p_window); + } +#endif default: { return 0; } diff --git a/platform/macos/gl_manager_macos_legacy.h b/platform/macos/gl_manager_macos_legacy.h index 8752086551..d7ad5b1197 100644 --- a/platform/macos/gl_manager_macos_legacy.h +++ b/platform/macos/gl_manager_macos_legacy.h @@ -89,6 +89,8 @@ public: void set_use_vsync(bool p_use); bool is_using_vsync() const; + NSOpenGLContext *get_context(DisplayServer::WindowID p_window_id); + GLManager_MacOS(ContextType p_context_type); ~GLManager_MacOS(); }; diff --git a/platform/macos/gl_manager_macos_legacy.mm b/platform/macos/gl_manager_macos_legacy.mm index dec4821b86..ea5c36da6c 100644 --- a/platform/macos/gl_manager_macos_legacy.mm +++ b/platform/macos/gl_manager_macos_legacy.mm @@ -215,6 +215,15 @@ bool GLManager_MacOS::is_using_vsync() const { return use_vsync; } +NSOpenGLContext *GLManager_MacOS::get_context(DisplayServer::WindowID p_window_id) { + if (!windows.has(p_window_id)) { + return nullptr; + } + + GLWindow &win = windows[p_window_id]; + return win.context; +} + GLManager_MacOS::GLManager_MacOS(ContextType p_context_type) { context_type = p_context_type; } diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index d6ee712a31..2c8058fdc5 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -741,9 +741,14 @@ int64_t DisplayServerWindows::window_get_native_handle(HandleType p_handle_type, case WINDOW_HANDLE: { return (int64_t)windows[p_window].hWnd; } +#if defined(GLES3_ENABLED) case WINDOW_VIEW: { - return 0; // Not supported. + return (int64_t)gl_manager->get_hdc(p_window); } + case OPENGL_CONTEXT: { + return (int64_t)gl_manager->get_hglrc(p_window); + } +#endif default: { return 0; } diff --git a/platform/windows/gl_manager_windows.cpp b/platform/windows/gl_manager_windows.cpp index 7689751f1b..900bca8258 100644 --- a/platform/windows/gl_manager_windows.cpp +++ b/platform/windows/gl_manager_windows.cpp @@ -339,6 +339,16 @@ bool GLManager_Windows::is_using_vsync() const { return use_vsync; } +HDC GLManager_Windows::get_hdc(DisplayServer::WindowID p_window_id) { + return get_window(p_window_id).hDC; +} + +HGLRC GLManager_Windows::get_hglrc(DisplayServer::WindowID p_window_id) { + const GLWindow &win = get_window(p_window_id); + const GLDisplay &disp = get_display(win.gldisplay_id); + return disp.hRC; +} + GLManager_Windows::GLManager_Windows(ContextType p_context_type) { context_type = p_context_type; diff --git a/platform/windows/gl_manager_windows.h b/platform/windows/gl_manager_windows.h index 5e43a3de2a..c6d5f9f855 100644 --- a/platform/windows/gl_manager_windows.h +++ b/platform/windows/gl_manager_windows.h @@ -113,6 +113,9 @@ public: void set_use_vsync(bool p_use); bool is_using_vsync() const; + HDC get_hdc(DisplayServer::WindowID p_window_id); + HGLRC get_hglrc(DisplayServer::WindowID p_window_id); + GLManager_Windows(ContextType p_context_type); ~GLManager_Windows(); }; diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index 09d31b1ca0..b5b37bf837 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -74,10 +74,6 @@ RID VisualInstance3D::get_instance() const { return instance; } -RID VisualInstance3D::_get_visual_instance_rid() const { - return instance; -} - void VisualInstance3D::set_layer_mask(uint32_t p_mask) { layers = p_mask; RenderingServer::get_singleton()->instance_set_layer_mask(instance, p_mask); @@ -106,7 +102,6 @@ bool VisualInstance3D::get_layer_mask_value(int p_layer_number) const { } void VisualInstance3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("_get_visual_instance_rid"), &VisualInstance3D::_get_visual_instance_rid); ClassDB::bind_method(D_METHOD("set_base", "base"), &VisualInstance3D::set_base); ClassDB::bind_method(D_METHOD("get_base"), &VisualInstance3D::get_base); ClassDB::bind_method(D_METHOD("get_instance"), &VisualInstance3D::get_instance); @@ -216,15 +211,20 @@ GeometryInstance3D::VisibilityRangeFadeMode GeometryInstance3D::get_visibility_r } const StringName *GeometryInstance3D::_instance_uniform_get_remap(const StringName p_name) const { - StringName *r = instance_uniform_property_remap.getptr(p_name); + StringName *r = instance_shader_parameter_property_remap.getptr(p_name); if (!r) { String s = p_name; +#ifndef DISABLE_DEPRECATED if (s.begins_with("shader_uniforms/")) { - StringName name = s.replace("shader_uniforms/", ""); - instance_uniform_property_remap[p_name] = name; - return instance_uniform_property_remap.getptr(p_name); + s = s.replace("shader_uniforms/", "instance_shader_parameters/"); + } +#endif // DISABLE_DEPRECATED + if (s.begins_with("instance_shader_parameters/")) { + StringName pname = StringName(s); + StringName name = s.replace("instance_shader_parameters/", ""); + instance_shader_parameter_property_remap[pname] = name; + return instance_shader_parameter_property_remap.getptr(pname); } - return nullptr; } @@ -247,7 +247,7 @@ bool GeometryInstance3D::_set(const StringName &p_name, const Variant &p_value) set_gi_mode(GI_MODE_DYNAMIC); return true; } -#endif +#endif // DISABLE_DEPRECATED return false; } @@ -270,13 +270,13 @@ void GeometryInstance3D::_get_property_list(List<PropertyInfo> *p_list) const { if (def_value.get_type() != Variant::NIL) { has_def_value = true; } - if (instance_uniforms.has(pi.name)) { + if (instance_shader_parameters.has(pi.name)) { pi.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE | (has_def_value ? (PROPERTY_USAGE_CHECKABLE | PROPERTY_USAGE_CHECKED) : PROPERTY_USAGE_NONE); } else { pi.usage = PROPERTY_USAGE_EDITOR | (has_def_value ? PROPERTY_USAGE_CHECKABLE : PROPERTY_USAGE_NONE); //do not save if not changed } - pi.name = "shader_uniforms/" + pi.name; + pi.name = "instance_shader_parameters/" + pi.name; p_list->push_back(pi); } } @@ -315,9 +315,9 @@ void GeometryInstance3D::set_instance_shader_parameter(const StringName &p_name, if (p_value.get_type() == Variant::NIL) { Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), p_name); RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_name, def_value); - instance_uniforms.erase(p_value); + instance_shader_parameters.erase(p_value); } else { - instance_uniforms[p_name] = p_value; + instance_shader_parameters[p_name] = p_value; if (p_value.get_type() == Variant::OBJECT) { RID tex_id = p_value; RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_name, tex_id); diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h index c9a25d9705..f18bff2ddc 100644 --- a/scene/3d/visual_instance_3d.h +++ b/scene/3d/visual_instance_3d.h @@ -40,8 +40,6 @@ class VisualInstance3D : public Node3D { RID instance; uint32_t layers = 1; - RID _get_visual_instance_rid() const; - protected: void _update_visibility(); @@ -119,8 +117,8 @@ private: float lod_bias = 1.0; - mutable HashMap<StringName, Variant> instance_uniforms; - mutable HashMap<StringName, StringName> instance_uniform_property_remap; + mutable HashMap<StringName, Variant> instance_shader_parameters; + mutable HashMap<StringName, StringName> instance_shader_parameter_property_remap; float extra_cull_margin = 0.0; LightmapScale lightmap_scale = LIGHTMAP_SCALE_1X; diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index dfd9c6eb2f..1eb78f0160 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -5851,18 +5851,18 @@ Variant Animation::interpolate_variant(const Variant &a, const Variant &b, float return dst; } case Variant::PACKED_INT32_ARRAY: { - const Vector<int32_t> *arr_a = Object::cast_to<Vector<int32_t>>(a); - const Vector<int32_t> *arr_b = Object::cast_to<Vector<int32_t>>(b); - int32_t sz = arr_a->size(); - if (sz == 0 || arr_b->size() != sz) { + const Vector<int32_t> arr_a = a; + const Vector<int32_t> arr_b = b; + int32_t sz = arr_a.size(); + if (sz == 0 || arr_b.size() != sz) { return a; } else { Vector<int32_t> v; v.resize(sz); { int32_t *vw = v.ptrw(); - const int32_t *ar = arr_a->ptr(); - const int32_t *br = arr_b->ptr(); + const int32_t *ar = arr_a.ptr(); + const int32_t *br = arr_b.ptr(); Variant va; for (int32_t i = 0; i < sz; i++) { @@ -5874,18 +5874,18 @@ Variant Animation::interpolate_variant(const Variant &a, const Variant &b, float } } case Variant::PACKED_INT64_ARRAY: { - const Vector<int64_t> *arr_a = Object::cast_to<Vector<int64_t>>(a); - const Vector<int64_t> *arr_b = Object::cast_to<Vector<int64_t>>(b); - int64_t sz = arr_a->size(); - if (sz == 0 || arr_b->size() != sz) { + const Vector<int64_t> arr_a = a; + const Vector<int64_t> arr_b = b; + int64_t sz = arr_a.size(); + if (sz == 0 || arr_b.size() != sz) { return a; } else { Vector<int64_t> v; v.resize(sz); { int64_t *vw = v.ptrw(); - const int64_t *ar = arr_a->ptr(); - const int64_t *br = arr_b->ptr(); + const int64_t *ar = arr_a.ptr(); + const int64_t *br = arr_b.ptr(); Variant va; for (int64_t i = 0; i < sz; i++) { @@ -5897,18 +5897,18 @@ Variant Animation::interpolate_variant(const Variant &a, const Variant &b, float } } case Variant::PACKED_FLOAT32_ARRAY: { - const Vector<float> *arr_a = Object::cast_to<Vector<float>>(a); - const Vector<float> *arr_b = Object::cast_to<Vector<float>>(b); - int sz = arr_a->size(); - if (sz == 0 || arr_b->size() != sz) { + const Vector<float> arr_a = a; + const Vector<float> arr_b = b; + int sz = arr_a.size(); + if (sz == 0 || arr_b.size() != sz) { return a; } else { Vector<float> v; v.resize(sz); { float *vw = v.ptrw(); - const float *ar = arr_a->ptr(); - const float *br = arr_b->ptr(); + const float *ar = arr_a.ptr(); + const float *br = arr_b.ptr(); Variant va; for (int i = 0; i < sz; i++) { @@ -5920,18 +5920,18 @@ Variant Animation::interpolate_variant(const Variant &a, const Variant &b, float } } case Variant::PACKED_FLOAT64_ARRAY: { - const Vector<double> *arr_a = Object::cast_to<Vector<double>>(a); - const Vector<double> *arr_b = Object::cast_to<Vector<double>>(b); - int sz = arr_a->size(); - if (sz == 0 || arr_b->size() != sz) { + const Vector<double> arr_a = a; + const Vector<double> arr_b = b; + int sz = arr_a.size(); + if (sz == 0 || arr_b.size() != sz) { return a; } else { Vector<double> v; v.resize(sz); { double *vw = v.ptrw(); - const double *ar = arr_a->ptr(); - const double *br = arr_b->ptr(); + const double *ar = arr_a.ptr(); + const double *br = arr_b.ptr(); Variant va; for (int i = 0; i < sz; i++) { @@ -5943,18 +5943,18 @@ Variant Animation::interpolate_variant(const Variant &a, const Variant &b, float } } case Variant::PACKED_VECTOR2_ARRAY: { - const Vector<Vector2> *arr_a = Object::cast_to<Vector<Vector2>>(a); - const Vector<Vector2> *arr_b = Object::cast_to<Vector<Vector2>>(b); - int sz = arr_a->size(); - if (sz == 0 || arr_b->size() != sz) { + const Vector<Vector2> arr_a = a; + const Vector<Vector2> arr_b = b; + int sz = arr_a.size(); + if (sz == 0 || arr_b.size() != sz) { return a; } else { Vector<Vector2> v; v.resize(sz); { Vector2 *vw = v.ptrw(); - const Vector2 *ar = arr_a->ptr(); - const Vector2 *br = arr_b->ptr(); + const Vector2 *ar = arr_a.ptr(); + const Vector2 *br = arr_b.ptr(); for (int i = 0; i < sz; i++) { vw[i] = ar[i].lerp(br[i], c); @@ -5964,18 +5964,18 @@ Variant Animation::interpolate_variant(const Variant &a, const Variant &b, float } } case Variant::PACKED_VECTOR3_ARRAY: { - const Vector<Vector3> *arr_a = Object::cast_to<Vector<Vector3>>(a); - const Vector<Vector3> *arr_b = Object::cast_to<Vector<Vector3>>(b); - int sz = arr_a->size(); - if (sz == 0 || arr_b->size() != sz) { + const Vector<Vector3> arr_a = a; + const Vector<Vector3> arr_b = b; + int sz = arr_a.size(); + if (sz == 0 || arr_b.size() != sz) { return a; } else { Vector<Vector3> v; v.resize(sz); { Vector3 *vw = v.ptrw(); - const Vector3 *ar = arr_a->ptr(); - const Vector3 *br = arr_b->ptr(); + const Vector3 *ar = arr_a.ptr(); + const Vector3 *br = arr_b.ptr(); for (int i = 0; i < sz; i++) { vw[i] = ar[i].lerp(br[i], c); @@ -5985,18 +5985,18 @@ Variant Animation::interpolate_variant(const Variant &a, const Variant &b, float } } case Variant::PACKED_COLOR_ARRAY: { - const Vector<Color> *arr_a = Object::cast_to<Vector<Color>>(a); - const Vector<Color> *arr_b = Object::cast_to<Vector<Color>>(b); - int sz = arr_a->size(); - if (sz == 0 || arr_b->size() != sz) { + const Vector<Color> arr_a = a; + const Vector<Color> arr_b = b; + int sz = arr_a.size(); + if (sz == 0 || arr_b.size() != sz) { return a; } else { Vector<Color> v; v.resize(sz); { Color *vw = v.ptrw(); - const Color *ar = arr_a->ptr(); - const Color *br = arr_b->ptr(); + const Color *ar = arr_a.ptr(); + const Color *br = arr_b.ptr(); for (int i = 0; i < sz; i++) { vw[i] = ar[i].lerp(br[i], c); diff --git a/servers/display_server.cpp b/servers/display_server.cpp index 1897612562..52d7f66203 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -826,6 +826,7 @@ void DisplayServer::_bind_methods() { BIND_ENUM_CONSTANT(DISPLAY_HANDLE); BIND_ENUM_CONSTANT(WINDOW_HANDLE); BIND_ENUM_CONSTANT(WINDOW_VIEW); + BIND_ENUM_CONSTANT(OPENGL_CONTEXT); BIND_ENUM_CONSTANT(TTS_UTTERANCE_STARTED); BIND_ENUM_CONSTANT(TTS_UTTERANCE_ENDED); diff --git a/servers/display_server.h b/servers/display_server.h index 55e9fb55dc..a796377f88 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -70,6 +70,7 @@ public: DISPLAY_HANDLE, WINDOW_HANDLE, WINDOW_VIEW, + OPENGL_CONTEXT, }; typedef DisplayServer *(*CreateFunction)(const String &, WindowMode, VSyncMode, uint32_t, const Point2i *, const Size2i &, Error &r_error); diff --git a/servers/rendering/dummy/storage/texture_storage.h b/servers/rendering/dummy/storage/texture_storage.h index ad28dd68c3..a17d734e10 100644 --- a/servers/rendering/dummy/storage/texture_storage.h +++ b/servers/rendering/dummy/storage/texture_storage.h @@ -126,6 +126,8 @@ public: virtual Size2 texture_size_with_proxy(RID p_proxy) override { return Size2(); }; + virtual RID texture_get_rd_texture_rid(RID p_texture, bool p_srgb = false) const override { return RID(); }; + /* DECAL API */ virtual RID decal_allocate() override { return RID(); } virtual void decal_initialize(RID p_rid) override {} diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index f76d016ae7..898521ca4d 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -2004,6 +2004,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr RID prev_index_array_rd; RID prev_pipeline_rd; RID prev_xforms_uniform_set; + bool should_request_redraw = false; bool shadow_pass = (p_params->pass_mode == PASS_MODE_SHADOW) || (p_params->pass_mode == PASS_MODE_SHADOW_DP); @@ -2090,6 +2091,11 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr continue; } + //request a redraw if one of the shaders uses TIME + if (shader->uses_time) { + should_request_redraw = true; + } + //find cull variant SceneShaderForwardMobile::ShaderData::CullVariant cull_variant; @@ -2191,6 +2197,11 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instance_count); } + + // Make the actual redraw request + if (should_request_redraw) { + RenderingServerDefault::redraw_request(); + } } /* Geometry instance */ diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index cbc5cc337c..7e0070f8b7 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -706,7 +706,7 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend //bind textures - _bind_canvas_texture(p_draw_list, RID(), current_filter, current_repeat, last_texture, push_constant, texpixel_size); + _bind_canvas_texture(p_draw_list, primitive->texture, current_filter, current_repeat, last_texture, push_constant, texpixel_size); RD::get_singleton()->draw_list_bind_index_array(p_draw_list, primitive_arrays.index_array[MIN(3u, primitive->point_count) - 1]); diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.h b/servers/rendering/renderer_rd/storage_rd/particles_storage.h index 6478e2b5dc..a9cc98abb9 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.h @@ -97,7 +97,7 @@ private: uint32_t type; uint32_t texture_index; //texture index for vector field - real_t scale; + float scale; uint32_t pad[2]; }; @@ -106,8 +106,8 @@ private: float prev_system_phase; uint32_t cycle; - real_t explosiveness; - real_t randomness; + float explosiveness; + float randomness; float time; float delta; diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index 3785c3899b..077fde58b8 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -1336,6 +1336,13 @@ Size2 TextureStorage::texture_size_with_proxy(RID p_proxy) { return texture_2d_get_size(p_proxy); } +RID TextureStorage::texture_get_rd_texture_rid(RID p_texture, bool p_srgb) const { + Texture *tex = texture_owner.get_or_null(p_texture); + ERR_FAIL_COND_V(!tex, RID()); + + return (p_srgb && tex->rd_texture_srgb.is_valid()) ? tex->rd_texture_srgb : tex->rd_texture; +} + Ref<Image> TextureStorage::_validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format) { Ref<Image> image = p_image->duplicate(); diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h index 72d4c90159..f4737eb63d 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h @@ -491,6 +491,8 @@ public: virtual Size2 texture_size_with_proxy(RID p_proxy) override; + virtual RID texture_get_rd_texture_rid(RID p_texture, bool p_srgb = false) const override; + //internal usage _FORCE_INLINE_ TextureType texture_get_type(RID p_texture) { RendererRD::TextureStorage::Texture *tex = texture_owner.get_or_null(p_texture); diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index 93118f39e7..bb4c41df52 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -393,6 +393,7 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("vertex_buffer_create", "size_bytes", "data", "use_as_storage"), &RenderingDevice::vertex_buffer_create, DEFVAL(Vector<uint8_t>()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("vertex_format_create", "vertex_descriptions"), &RenderingDevice::_vertex_format_create); + ClassDB::bind_method(D_METHOD("vertex_array_create", "vertex_count", "vertex_format", "src_buffers"), &RenderingDevice::_vertex_array_create); ClassDB::bind_method(D_METHOD("index_buffer_create", "size_indices", "format", "data", "use_restart_indices"), &RenderingDevice::index_buffer_create, DEFVAL(Vector<uint8_t>()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("index_array_create", "index_buffer", "index_offset", "index_count"), &RenderingDevice::index_array_create); diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index 6d2d0d9906..b77b95bb62 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -212,6 +212,7 @@ public: FUNC1(texture_debug_usage, List<TextureInfo> *) FUNC2(texture_set_force_redraw_if_visible, RID, bool) + FUNC2RC(RID, texture_get_rd_texture_rid, RID, bool) /* SHADER API */ diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 2f5846f520..14c09c1512 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -8178,6 +8178,10 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f } } #endif // DEBUG_ENABLED + if (String(shader_type_identifier) != "spatial") { + _set_error(vformat(RTR("Uniform instances are not yet implemented for '%s' shaders."), shader_type_identifier)); + return ERR_PARSE_ERROR; + } if (uniform_scope == ShaderNode::Uniform::SCOPE_LOCAL) { tk = _get_token(); if (tk.type != TK_UNIFORM) { diff --git a/servers/rendering/storage/texture_storage.h b/servers/rendering/storage/texture_storage.h index 3207181471..31fb5e8791 100644 --- a/servers/rendering/storage/texture_storage.h +++ b/servers/rendering/storage/texture_storage.h @@ -100,6 +100,8 @@ public: virtual Size2 texture_size_with_proxy(RID p_proxy) = 0; + virtual RID texture_get_rd_texture_rid(RID p_texture, bool p_srgb = false) const = 0; + /* Decal API */ virtual RID decal_allocate() = 0; virtual void decal_initialize(RID p_rid) = 0; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 0c4d641a6f..7691bede07 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -1691,6 +1691,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("texture_get_path", "texture"), &RenderingServer::texture_get_path); ClassDB::bind_method(D_METHOD("texture_set_force_redraw_if_visible", "texture", "enable"), &RenderingServer::texture_set_force_redraw_if_visible); + ClassDB::bind_method(D_METHOD("texture_get_rd_texture", "texture", "srgb"), &RenderingServer::texture_get_rd_texture_rid, DEFVAL(false)); BIND_ENUM_CONSTANT(TEXTURE_LAYERED_2D_ARRAY); BIND_ENUM_CONSTANT(TEXTURE_LAYERED_CUBEMAP); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 97fafd1b14..1d364dfcff 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -157,6 +157,8 @@ public: virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) = 0; + virtual RID texture_get_rd_texture_rid(RID p_texture, bool p_srgb = false) const = 0; + /* SHADER API */ enum ShaderMode { diff --git a/servers/xr/xr_interface.cpp b/servers/xr/xr_interface.cpp index a5ee1d5726..4d58d24405 100644 --- a/servers/xr/xr_interface.cpp +++ b/servers/xr/xr_interface.cpp @@ -72,6 +72,8 @@ void XRInterface::_bind_methods() { ClassDB::bind_method(D_METHOD("is_passthrough_enabled"), &XRInterface::is_passthrough_enabled); ClassDB::bind_method(D_METHOD("start_passthrough"), &XRInterface::start_passthrough); ClassDB::bind_method(D_METHOD("stop_passthrough"), &XRInterface::stop_passthrough); + ClassDB::bind_method(D_METHOD("get_transform_for_view", "view", "cam_transform"), &XRInterface::get_transform_for_view); + ClassDB::bind_method(D_METHOD("get_projection_for_view", "view", "aspect", "near", "far"), &XRInterface::get_projection_for_view); ADD_GROUP("AR", "ar_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ar_is_anchor_detection_enabled"), "set_anchor_detection_is_enabled", "get_anchor_detection_is_enabled"); |